Skip to content

Commit 6e5c66e

Browse files
Merge pull request #44 from justinhartman/develop
Merge develop into main
2 parents a3f18f9 + 6f6c919 commit 6e5c66e

File tree

6 files changed

+148
-6
lines changed

6 files changed

+148
-6
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,11 +180,9 @@ OMDb API used in this project. Open the file and begin testing the API to see re
180180
**Would love some help on these...**
181181

182182
- [ ] Work out a way to stop the video player from adding popups when watching[^1].
183-
- [ ] Change layout to include all episodes on the view screen.
184183
- [ ] Add personalised recommendations. _(not so easy to do)_
185184
- [ ] Implement a proper logging mechanism to track errors and user interactions.
186185
- [ ] Improve the error handling mechanism to provide better feedback to the user when an error occurs.
187-
- [ ] Complete test suite.
188186

189187
[^1]: This is a product of not hosting your own video content and the video feed providers try monetise through popups.
190188
I want a way to kill this because there's known malware in these popups!
@@ -203,6 +201,8 @@ I want a way to kill this because there's known malware in these popups!
203201
- [x] Bookmarks to save items to profile
204202
- [x] Add test suite so we can code better.
205203
- [x] Add code coverage reporting
204+
- [x] Change layout to include all episodes on the view screen.
205+
- [x] Complete test suite.
206206

207207
## License
208208

helpers/httpClient.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ const httpsAgent = new https.Agent({ keepAlive: false });
2121
* @property {https.Agent} httpsAgent - HTTPS agent with keep-alive disabled
2222
*/
2323
const client: AxiosInstance = axios.create({
24-
timeout: 10_000,
24+
timeout: 10000,
2525
maxRedirects: 5,
2626
httpAgent,
2727
httpsAgent,
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
module.exports = {
2+
async up(db) {
3+
const COLLECTION = 'histories';
4+
const col = db.collection(COLLECTION);
5+
6+
// If you ever stored season/episode under legacy keys, fold them in first.
7+
// This only copies when lastSeason/lastEpisode are missing; then removes the legacy keys.
8+
await col.updateMany(
9+
{ $or: [{ season: { $exists: true } }, { episode: { $exists: true } }] },
10+
[
11+
{
12+
$set: {
13+
lastSeason: {
14+
$cond: [
15+
{ $and: [{ $ne: ["$season", null] }, { $or: [{ $eq: ["$lastSeason", null] }, { $not: [{ $gt: ["$lastSeason", null] }] }] }] },
16+
"$season",
17+
"$lastSeason"
18+
]
19+
},
20+
lastEpisode: {
21+
$cond: [
22+
{ $and: [{ $ne: ["$episode", null] }, { $or: [{ $eq: ["$lastEpisode", null] }, { $not: [{ $gt: ["$lastEpisode", null] }] }] }] },
23+
"$episode",
24+
"$lastEpisode"
25+
]
26+
}
27+
}
28+
},
29+
{ $unset: ["season", "episode"] }
30+
]
31+
);
32+
33+
// Convert strings (and other coercible types) -> int; leave existing numbers as-is.
34+
await col.updateMany(
35+
{
36+
$or: [
37+
{ lastSeason: { $type: "string" } },
38+
{ lastEpisode: { $type: "string" } }
39+
]
40+
},
41+
[
42+
{
43+
$set: {
44+
lastSeason: {
45+
$convert: {
46+
input: "$lastSeason",
47+
to: "int",
48+
onError: "$lastSeason", // keep original if not numeric (safety)
49+
onNull: "$lastSeason"
50+
}
51+
},
52+
lastEpisode: {
53+
$convert: {
54+
input: "$lastEpisode",
55+
to: "int",
56+
onError: "$lastEpisode",
57+
onNull: "$lastEpisode"
58+
}
59+
}
60+
}
61+
}
62+
]
63+
);
64+
65+
// Optional: also coerce numeric strings that slipped through legacy keys above
66+
await col.updateMany(
67+
{
68+
$or: [
69+
{ lastSeason: { $type: "double" } },
70+
{ lastEpisode: { $type: "double" } },
71+
{ lastSeason: { $type: "long" } },
72+
{ lastEpisode: { $type: "long" } }
73+
]
74+
},
75+
[
76+
{
77+
$set: {
78+
lastSeason: {
79+
$convert: {
80+
input: "$lastSeason",
81+
to: "int",
82+
onError: "$lastSeason",
83+
onNull: "$lastSeason"
84+
}
85+
},
86+
lastEpisode: {
87+
$convert: {
88+
input: "$lastEpisode",
89+
to: "int",
90+
onError: "$lastEpisode",
91+
onNull: "$lastEpisode"
92+
}
93+
}
94+
}
95+
}
96+
]
97+
);
98+
},
99+
100+
async down(db) {
101+
const COLLECTION = 'histories';
102+
const col = db.collection(COLLECTION);
103+
104+
// Revert ints/longs back to strings (best-effort).
105+
await col.updateMany(
106+
{
107+
$or: [
108+
{ lastSeason: { $type: "int" } },
109+
{ lastEpisode: { $type: "int" } },
110+
{ lastSeason: { $type: "long" } },
111+
{ lastEpisode: { $type: "long" } }
112+
]
113+
},
114+
[
115+
{
116+
$set: {
117+
lastSeason: {
118+
$convert: {
119+
input: "$lastSeason",
120+
to: "string",
121+
onError: "$lastSeason",
122+
onNull: "$lastSeason"
123+
}
124+
},
125+
lastEpisode: {
126+
$convert: {
127+
input: "$lastEpisode",
128+
to: "string",
129+
onError: "$lastEpisode",
130+
onNull: "$lastEpisode"
131+
}
132+
}
133+
}
134+
}
135+
]
136+
);
137+
}
138+
};

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
"db:status": "npx migrate-mongo status",
2323
"db:migrate": "npx migrate-mongo up",
2424
"db:rollback": "npx migrate-mongo down",
25+
"db:create": "npx migrate-mongo create",
2526
"publish:patch": "npx grunt",
2627
"publish:minor": "npx grunt minor",
2728
"publish:major": "npx grunt major",

public/css/style.css

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,13 @@ a.btn-primary:hover {
2121
flex-grow: 1;
2222
}
2323

24+
/* Series video view page. */
2425
.series-layout {
2526
display: flex;
2627
flex-direction: column;
2728
}
2829

30+
/* Home page scrolling containers with buttons. */
2931
.scroll-row {
3032
overflow-x: auto;
3133
scroll-behavior: smooth;
@@ -35,18 +37,19 @@ a.btn-primary:hover {
3537
}
3638
.scroll-button {
3739
position: absolute;
38-
top: 50%;
40+
top: 38%;
3941
transform: translateY(-50%);
4042
background: rgba(0,0,0,0.5);
4143
border: none;
4244
color: #fff;
4345
padding: 0.5rem;
46+
margin: 0 0.5rem;
4447
z-index: 10;
4548
}
4649
.scroll-button.left { left: 0; }
4750
.scroll-button.right { right: 0; }
4851

49-
/* Styles that apply at the 'md' breakpoint and above */
52+
/* Styles that apply at the 'md' breakpoint and above. */
5053
@media (min-width: 768px) {
5154
.card-img-top {
5255
height: 360px;

views/index.ejs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@
8181

8282
<script>
8383
document.addEventListener('DOMContentLoaded', () => {
84-
document.querySelectorAll('.scroll-button' h-25 rounded-3).forEach(btn => {
84+
document.querySelectorAll('.scroll-button').forEach(btn => {
8585
btn.addEventListener('click', function() {
8686
const container = document.querySelector(this.dataset.target);
8787
const amount = container.clientWidth;

0 commit comments

Comments
 (0)