Skip to content

Commit c4cdea3

Browse files
committed
feat(panel): only mark unwatched in seasons
1 parent bec98d6 commit c4cdea3

10 files changed

+559
-216
lines changed

src/components/icons/IconEyeOff.vue

+70
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
<template>
2+
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24">
3+
<mask id="lineMdWatchOffLoop0">
4+
<g
5+
fill="none"
6+
stroke="#fff"
7+
stroke-linecap="round"
8+
stroke-linejoin="round"
9+
stroke-width="1.5"
10+
>
11+
<circle cx="12" cy="12" r="0" fill="#fff" stroke="none">
12+
<animate
13+
attributeName="r"
14+
dur="6s"
15+
keyTimes="0;0.03;0.97;1"
16+
repeatCount="indefinite"
17+
values="0;3;3;0"
18+
/>
19+
</circle>
20+
<path
21+
d="M4 12c1.38 -0.77 4.42 -1.3 8 -1.3c3.58 0 6.62 0.53 8 1.3c-1.38 0.77 -4.42 1.3 -8 1.3c-3.58 0 -6.62 -0.53 -8 -1.3Z"
22+
>
23+
<animate
24+
attributeName="d"
25+
dur="6s"
26+
keyTimes="0;0.03;0.97;1"
27+
repeatCount="indefinite"
28+
values="M4 12c1.38 -0.77 4.42 -1.3 8 -1.3c3.58 0 6.62 0.53 8 1.3c-1.38 0.77 -4.42 1.3 -8 1.3c-3.58 0 -6.62 -0.53 -8 -1.3Z;M2 12c1.72 -3.83 5.53 -6.5 10 -6.5c4.47 0 8.28 2.67 10 6.5c-1.72 3.83 -5.53 6.5 -10 6.5c-4.47 0 -8.28 -2.67 -10 -6.5Z;M2 12c1.72 -3.83 5.53 -6.5 10 -6.5c4.47 0 8.28 2.67 10 6.5c-1.72 3.83 -5.53 6.5 -10 6.5c-4.47 0 -8.28 -2.67 -10 -6.5Z;M4 12c1.38 -0.77 4.42 -1.3 8 -1.3c3.58 0 6.62 0.53 8 1.3c-1.38 0.77 -4.42 1.3 -8 1.3c-3.58 0 -6.62 -0.53 -8 -1.3Z"
29+
/>
30+
</path>
31+
<path
32+
stroke="#000"
33+
stroke-dasharray="28"
34+
stroke-dashoffset="28"
35+
d="M0 11h24"
36+
transform="rotate(45 12 12)"
37+
>
38+
<animate
39+
fill="freeze"
40+
attributeName="stroke-dashoffset"
41+
begin="0.5s"
42+
dur="0.4s"
43+
values="28;0"
44+
/>
45+
</path>
46+
<path
47+
stroke-dasharray="28"
48+
stroke-dashoffset="28"
49+
d="M-1 13h24"
50+
transform="rotate(45 12 12)"
51+
>
52+
<animate
53+
attributeName="d"
54+
dur="6s"
55+
repeatCount="indefinite"
56+
values="M-1 13h24;M1 13h24;M-1 13h24"
57+
/>
58+
<animate
59+
fill="freeze"
60+
attributeName="stroke-dashoffset"
61+
begin="0.5s"
62+
dur="0.4s"
63+
values="28;0"
64+
/>
65+
</path>
66+
</g>
67+
</mask>
68+
<rect width="24" height="24" fill="currentColor" mask="url(#lineMdWatchOffLoop0)" />
69+
</svg>
70+
</template>

src/components/views/panel/MoviePanel.vue

+65-48
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import {
1919
type ListEntity,
2020
ListType,
2121
} from '~/models/list.model';
22+
import { Logger } from '~/services/logger.service';
2223
import { NotificationService } from '~/services/notification.service';
2324
import { ResolveExternalLinks } from '~/settings/external.links';
2425
import { useAppStateStoreRefs } from '~/stores/app-state.store';
@@ -143,13 +144,17 @@ const onListUpdate = async (value: ListEntity['id'], remove: boolean) => {
143144
const _list = myLists.value.find(list => list.id === value);
144145
if (!_list) return;
145146
146-
panelDirty.value = true;
147-
await addToOrRemoveFromList({
148-
list: _list,
149-
itemType: 'movie',
150-
itemIds: movie.value?.ids,
151-
remove,
152-
});
147+
try {
148+
panelDirty.value = true;
149+
await addToOrRemoveFromList({
150+
list: _list,
151+
itemType: 'movie',
152+
itemIds: movie.value?.ids,
153+
remove,
154+
});
155+
} catch (error) {
156+
Logger.error('Failed to update list', { list: _list, error });
157+
}
153158
};
154159
155160
const releaseDate = computed(() => movie.value?.released);
@@ -163,18 +168,22 @@ const onCollectionUpdate = async (
163168
date = releaseDate.value;
164169
}
165170
166-
panelDirty.value = true;
167-
await addToOrRemoveFromList({
168-
list: DefaultLists.ShowCollection,
169-
itemType: 'movie',
170-
itemIds: movie.value?.ids,
171-
date,
172-
remove: value === PanelButtonsOption.Remove,
173-
});
174-
175-
const _id = movie.value?.ids?.trakt;
176-
if (_id === undefined) return;
177-
return changeMovieCollected(_id, value === PanelButtonsOption.Remove);
171+
try {
172+
panelDirty.value = true;
173+
await addToOrRemoveFromList({
174+
list: DefaultLists.ShowCollection,
175+
itemType: 'movie',
176+
itemIds: movie.value?.ids,
177+
date,
178+
remove: value === PanelButtonsOption.Remove,
179+
});
180+
181+
const _id = movie.value?.ids?.trakt;
182+
if (_id === undefined) return;
183+
return await changeMovieCollected(_id, value === PanelButtonsOption.Remove);
184+
} catch (error) {
185+
Logger.error('Failed to update collection', error);
186+
}
178187
};
179188
180189
const onWatchedUpdate = async (
@@ -186,22 +195,26 @@ const onWatchedUpdate = async (
186195
date = releaseDate.value;
187196
}
188197
189-
panelDirty.value = true;
190-
await addToOrRemoveFromList({
191-
list: {
192-
id: DefaultListId.History,
193-
type: ListType.History,
194-
name: 'list_type__history',
195-
},
196-
itemType: 'movie',
197-
itemIds: movie.value?.ids,
198-
date,
199-
remove: value === PanelButtonsOption.Remove,
200-
});
201-
202-
const _id = movie.value?.ids?.trakt;
203-
if (_id === undefined) return;
204-
return changeMovieWatched(_id, value === PanelButtonsOption.Remove);
198+
try {
199+
panelDirty.value = true;
200+
await addToOrRemoveFromList({
201+
list: {
202+
id: DefaultListId.History,
203+
type: ListType.History,
204+
name: 'list_type__history',
205+
},
206+
itemType: 'movie',
207+
itemIds: movie.value?.ids,
208+
date,
209+
remove: value === PanelButtonsOption.Remove,
210+
});
211+
212+
const _id = movie.value?.ids?.trakt;
213+
if (_id === undefined) return;
214+
return await changeMovieWatched(_id, value === PanelButtonsOption.Remove);
215+
} catch (error) {
216+
Logger.error('Failed to update watched status', error);
217+
}
205218
};
206219
207220
const i18n = useI18n('movie', 'panel');
@@ -233,20 +246,24 @@ const { cancel: cancelCheckin, checkin } = useWatchingStore();
233246
234247
const { onCancel } = useCancelWatching(cancelCheckin);
235248
const onCheckin = async (cancel: boolean) => {
236-
if (cancel) {
237-
const cancelled = await onCancel();
238-
if (!cancelled) return;
239-
} else if (!movie.value?.ids?.trakt) {
240-
return NotificationService.error(
241-
i18n('checkin_failed', 'watching'),
242-
new Error('No movie id'),
243-
);
244-
} else {
245-
panelDirty.value = true;
246-
await checkin({ movie: { ids: movie.value.ids } });
247-
}
249+
try {
250+
if (cancel) {
251+
const cancelled = await onCancel();
252+
if (!cancelled) return;
253+
} else if (!movie.value?.ids?.trakt) {
254+
return NotificationService.error(
255+
i18n('checkin_failed', 'watching'),
256+
new Error('No movie id'),
257+
);
258+
} else {
259+
panelDirty.value = true;
260+
await checkin({ movie: { ids: movie.value.ids } });
261+
}
248262
249-
await fetchMovieWatched(true);
263+
await fetchMovieWatched(true);
264+
} catch (error) {
265+
Logger.error('Failed to checkin', error);
266+
}
250267
};
251268
252269
onMounted(() => {

src/components/views/panel/MoviePanelButtons.vue

+12-27
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,10 @@ import IconPlayFilled from '~/components/icons/IconPlayFilled.vue';
1111
import PanelButtonProgress from '~/components/views/panel/PanelButtonProgress.vue';
1212
import PanelSelectProgress from '~/components/views/panel/PanelSelectProgress.vue';
1313
import {
14+
type PanelButtonsEmit,
1415
PanelButtonsOption,
15-
type PanelButtonsOptions,
1616
usePanelButtons,
17+
usePanelButtonsEmit,
1718
} from '~/components/views/panel/use-panel-buttons';
1819
import { type ListEntity, ListType } from '~/models/list.model';
1920
import { useListsStore, useListsStoreRefs } from '~/stores/data/lists.store';
@@ -62,42 +63,26 @@ const props = defineProps({
6263
},
6364
});
6465
65-
const emit = defineEmits<{
66-
(e: 'onListUpdate', value: ListEntity['id'], remove: boolean): void;
67-
(e: 'onCollectionUpdate', value: PanelButtonsOptions, date?: number): void;
68-
(e: 'onWatchedUpdate', value: PanelButtonsOptions, date?: number): void;
69-
(e: 'onCheckin', cancel: boolean): void;
70-
}>();
66+
const emit = defineEmits<
67+
{
68+
(e: 'onCheckin', cancel: boolean): void;
69+
} & PanelButtonsEmit
70+
>();
7171
7272
const { watched, collected, activeLoading, activeLists, hasRelease, watching } =
7373
toRefs(props);
7474
75-
const onListUpdate = (value: ListEntity['id'] | ListEntity['id'][]) => {
76-
const newList = Array.isArray(value) ? value : [value];
77-
const removed = activeLists?.value?.find(id => !newList.includes(id));
78-
if (removed) emit('onListUpdate', removed, true);
79-
const added = newList.find(id => !activeLists?.value?.includes(id));
80-
if (added) emit('onListUpdate', added, false);
81-
};
82-
83-
const onCollectionUpdate = (value: unknown, date?: number) => {
84-
if (value === PanelButtonsOption.Cancel) return;
85-
if (value === PanelButtonsOption.Now && date === undefined) date = Date.now();
86-
emit('onCollectionUpdate', value as PanelButtonsOptions, date);
87-
};
88-
89-
const onWatchedUpdate = (value: unknown, date?: number) => {
90-
if (value === PanelButtonsOption.Cancel) return;
91-
if (value === PanelButtonsOption.Now && date === undefined) date = Date.now();
92-
emit('onWatchedUpdate', value as PanelButtonsOptions, date);
93-
};
94-
9575
const i18n = useI18n('panel', 'buttons');
9676
9777
const root = ref<HTMLDivElement>();
9878
9979
const { removeOptions, timeOptions } = usePanelButtons();
10080
81+
const { onListUpdate, onCollectionUpdate, onWatchedUpdate } = usePanelButtonsEmit(
82+
emit,
83+
activeLists,
84+
);
85+
10186
const watchedOptions = computed(() => {
10287
const _options = watched.value ? removeOptions : timeOptions;
10388
if (!hasRelease.value) {

0 commit comments

Comments
 (0)