Skip to content

Commit b00712c

Browse files
committed
feat(settings): adds quick action configurations in settings
1 parent 9a788b0 commit b00712c

12 files changed

+311
-32
lines changed

src/components/common/list/ListButtons.vue

+7-7
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ type Query<T extends QuickActions> = T extends typeof QuickAction.Checkin
2828
? CheckinQuery
2929
: T extends typeof QuickAction.List
3030
? AddOrRemoveListQuery
31-
: T extends typeof QuickAction.Collected | typeof QuickAction.Watched
31+
: T extends typeof QuickAction.Collect | typeof QuickAction.Watch
3232
? AddOrRemoveQuery
3333
: CheckinQuery | AddOrRemoveListQuery | AddOrRemoveQuery;
3434
type Payload<T extends QuickActions = QuickActions> = {
@@ -44,8 +44,8 @@ const emit = defineEmits<{
4444
const { getAction, getActionDate, getActionList } = useExtensionSettingsStore();
4545
4646
const actions = computed(() => getAction(route));
47-
const collectionDate = computed(() => getActionDate(QuickAction.Collected));
48-
const watchedDate = computed(() => getActionDate(QuickAction.Watched));
47+
const collectionDate = computed(() => getActionDate(QuickAction.Collect));
48+
const watchedDate = computed(() => getActionDate(QuickAction.Watch));
4949
5050
const { activeList } = useListsStoreRefs();
5151
const list = computed(() => {
@@ -73,18 +73,18 @@ const onClick = <T extends QuickActions>(
7373
@on-click="e => onClick(QuickAction.List, e)"
7474
/>
7575
<ListButtonCollected
76-
v-if="actions?.[QuickAction.Collected]"
76+
v-if="actions?.[QuickAction.Collect]"
7777
:date-type="collectionDate"
7878
:disabled="disabled"
7979
:item="item"
80-
@on-click="e => onClick(QuickAction.Collected, e)"
80+
@on-click="e => onClick(QuickAction.Collect, e)"
8181
/>
8282
<ListButtonWatched
83-
v-if="actions?.[QuickAction.Watched]"
83+
v-if="actions?.[QuickAction.Watch]"
8484
:date-type="watchedDate"
8585
:disabled="disabled"
8686
:item="item"
87-
@on-click="e => onClick(QuickAction.Watched, e)"
87+
@on-click="e => onClick(QuickAction.Watch, e)"
8888
/>
8989
<ListButtonCheckin
9090
v-if="actions?.[QuickAction.Checkin] && isEpisodeOrMovie(item.type)"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
<script lang="ts" setup>
2+
import { NFlex, NSelect, NText } from 'naive-ui';
3+
4+
import { computed, ref } from 'vue';
5+
6+
import SettingsFormItem from '~/components/views/settings/SettingsFormItem.vue';
7+
import {
8+
type DefaultListIds,
9+
DefaultLists,
10+
DefaultListsMap,
11+
type ListEntity,
12+
} from '~/models/list.model';
13+
import { Route } from '~/models/router.model';
14+
import {
15+
QuickAction,
16+
QuickActionDate,
17+
useExtensionSettingsStore,
18+
useExtensionSettingsStoreRefs,
19+
} from '~/stores/settings/extension.store';
20+
import { useI18n } from '~/utils/i18n.utils';
21+
22+
const i18n = useI18n('settings', 'actions');
23+
24+
const { enabledTabs } = useExtensionSettingsStoreRefs();
25+
const {
26+
getAction,
27+
setAction,
28+
getActionDate,
29+
setActionDate,
30+
getActionList,
31+
setActionList,
32+
} = useExtensionSettingsStore();
33+
34+
const getActionArray = (tab: Route) => {
35+
const action = getAction(tab);
36+
if (!action) return [];
37+
return Object.entries(action)
38+
.filter(([, value]) => value)
39+
.map(([key]) => key);
40+
};
41+
42+
const actionOptions = computed(() =>
43+
Object.values(QuickAction).map(value => ({
44+
label: i18n(value, 'common', 'action'),
45+
value,
46+
})),
47+
);
48+
49+
type ListOption = { label: string; value: DefaultListIds; list: ListEntity };
50+
const allowedList = {
51+
[DefaultLists.Watchlist.id]: DefaultLists.Watchlist,
52+
[DefaultLists.Favorites.id]: DefaultLists.Favorites,
53+
};
54+
const listOptions = computed<ListOption[]>(() =>
55+
[DefaultLists.Watchlist, DefaultLists.Favorites].map(list => ({
56+
label: i18n(list.name, 'list'),
57+
value: list.id,
58+
list,
59+
})),
60+
);
61+
62+
const dateOptions = computed(() =>
63+
Object.values(QuickActionDate).map(value => ({
64+
label: i18n(value, 'common', 'action', 'date'),
65+
value,
66+
})),
67+
);
68+
69+
const container = ref();
70+
</script>
71+
72+
<template>
73+
<div ref="container" class="actions-container">
74+
<!-- Quick Action Date Watched -->
75+
<SettingsFormItem class="form-item" :label="i18n('label__date_watched')">
76+
<NSelect
77+
class="date-select"
78+
:value="getActionDate(QuickAction.Watch)"
79+
:to="container"
80+
:options="dateOptions"
81+
@update:value="v => setActionDate(QuickAction.Watch, DefaultLists[v])"
82+
/>
83+
</SettingsFormItem>
84+
85+
<!-- Quick Action Date Collect -->
86+
<SettingsFormItem class="form-item" :label="i18n('label__date_collected')">
87+
<NSelect
88+
class="date-select"
89+
:value="getActionDate(QuickAction.Collect)"
90+
:to="container"
91+
:options="dateOptions"
92+
@update:value="v => setActionDate(QuickAction.Collect, v)"
93+
/>
94+
</SettingsFormItem>
95+
96+
<NText class="description" tag="p">{{ i18n('description') }}</NText>
97+
98+
<NFlex
99+
v-for="[tab] in enabledTabs.filter(([tab]) => tab !== Route.Releases)"
100+
:key="tab"
101+
class="form-row"
102+
align="center"
103+
justify="space-between"
104+
>
105+
<NText class="form-header" tag="h3">{{ i18n(tab, 'route') }}</NText>
106+
<NFlex class="form-selects" align="center" justify="space-around">
107+
<!-- Quick Action -->
108+
<SettingsFormItem class="form-item action-select">
109+
<NSelect
110+
:value="getActionArray(tab)"
111+
:to="container"
112+
:options="actionOptions"
113+
multiple
114+
@update:value="v => setAction(tab, v)"
115+
/>
116+
</SettingsFormItem>
117+
118+
<!-- Quick Action List -->
119+
<SettingsFormItem class="form-item list-select">
120+
<NSelect
121+
:value="getActionList(tab)?.id"
122+
:to="container"
123+
:options="listOptions"
124+
@update:value="
125+
(v: ListOption['value']) => setActionList(tab, DefaultListsMap[v])
126+
"
127+
/>
128+
</SettingsFormItem>
129+
</NFlex>
130+
</NFlex>
131+
</div>
132+
</template>
133+
134+
<style lang="scss" scoped>
135+
.actions-container {
136+
display: flex;
137+
flex-direction: column;
138+
gap: 1.5rem;
139+
140+
.form-row {
141+
padding: 0.25rem 1rem;
142+
background: var(--bg-black-soft);
143+
border: 1px solid var(--white-10);
144+
border-radius: 0.5rem;
145+
transition:
146+
background 0.3s var(--n-bezier),
147+
border 0.3s var(--n-bezier);
148+
149+
&:active,
150+
&:focus-within,
151+
&:hover {
152+
border-color: var(--white-15);
153+
}
154+
}
155+
156+
.form-selects {
157+
flex: 1 1 70%;
158+
}
159+
160+
.form-item {
161+
padding: 0.25rem;
162+
}
163+
164+
.form-header {
165+
flex: 0 1 20%;
166+
}
167+
168+
.action-select {
169+
display: flex;
170+
flex: 1 1 23rem;
171+
172+
:deep(.n-form-item-blank) {
173+
flex: 1 1 auto;
174+
}
175+
}
176+
177+
.list-select {
178+
display: flex;
179+
flex: 1 1 8rem;
180+
181+
:deep(.n-form-item-blank) {
182+
flex: 1 1 auto;
183+
}
184+
}
185+
186+
.date-select {
187+
min-width: 10rem;
188+
}
189+
190+
.description {
191+
margin: 0 0 0 0.25rem;
192+
color: var(--white-70);
193+
font-weight: 600;
194+
font-size: 1rem;
195+
white-space: pre-line;
196+
}
197+
}
198+
</style>

src/components/views/settings/SettingsComponent.vue

+4
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ const SettingsWatching = lazyComponent(
4949
const SettingsImage = lazyComponent(
5050
() => import('~/components/views/settings/SettingsImage.vue'),
5151
);
52+
const SettingsActions = lazyComponent(
53+
() => import('~/components/views/settings/SettingsActions.vue'),
54+
);
5255
5356
const i18n = useI18n('settings');
5457
@@ -71,6 +74,7 @@ const sections = computed<Section[]>(() =>
7174
},
7275
{ title: 'menu__tabs', reference: ref(), component: SettingsTabs },
7376
{ title: 'menu__links', reference: ref(), component: SettingsLinks },
77+
{ title: 'menu__actions', reference: ref(), component: SettingsActions },
7478
{ title: 'menu__images', reference: ref(), component: SettingsImage },
7579
{ title: 'menu__menus', reference: ref(), component: SettingsMenus },
7680
{ title: 'menu__watching', reference: ref(), component: SettingsWatching },

src/components/views/settings/SettingsExport.vue

+1
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@ const container = ref();
175175
:key="index"
176176
:label="label"
177177
:warning="getProgress(index)"
178+
show-warning
178179
>
179180
<NButton
180181
class="export-button"

src/components/views/settings/SettingsFormItem.vue

+8-2
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@ defineProps({
1212
type: String,
1313
required: false,
1414
},
15+
showWarning: {
16+
type: Boolean,
17+
required: false,
18+
default: false,
19+
},
1520
form: {
1621
type: Object as PropType<FormItemGiProps>,
1722
required: false,
@@ -38,8 +43,8 @@ defineProps({
3843
</template>
3944
<slot />
4045
</NFormItem>
41-
<div class="form-warning" :class="{ show: !!warning }">
42-
<span v-if="warning">{{ warning }}</span>
46+
<div v-if="warning" class="form-warning" :class="{ show: showWarning }">
47+
<span>{{ warning }}</span>
4348
</div>
4449
</NFlex>
4550
</template>
@@ -60,6 +65,7 @@ defineProps({
6065
display: flex;
6166
flex: 1 0 100%;
6267
height: 0;
68+
overflow: hidden;
6369
color: var(--color-warning);
6470
transition: height 0.3s var(--n-bezier);
6571

src/components/views/settings/SettingsImage.vue

+4
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,10 @@ const container = ref();
115115
}
116116
117117
.description {
118+
margin: 0 0 0 0.25rem;
119+
color: var(--white-70);
120+
font-weight: 600;
121+
font-size: 1rem;
118122
white-space: pre-line;
119123
}
120124
}

src/components/views/settings/SettingsTabs.vue

+14-11
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,8 @@ const toggleBrand = () => {
270270
<!-- Movie init -->
271271
<SettingsFormItem
272272
:label="i18n('label_movie_init')"
273-
:warning="initMovie ? i18n('label_init_warning') : undefined"
273+
:warning="i18n('label_init_warning')"
274+
:show-warning="initMovie"
274275
>
275276
<NSwitch v-model:value="initMovie" class="form-switch">
276277
<template #checked>{{ i18n('on', 'common', 'button') }}</template>
@@ -287,11 +288,8 @@ const toggleBrand = () => {
287288
>
288289
<SettingsFormItem
289290
:label="i18n(`label_route_${route}`)"
290-
:warning="
291-
state && [Route.Progress, Route.Releases].includes(route)
292-
? i18n(`label_route_${route}_warning`)
293-
: undefined
294-
"
291+
:warning="i18n(`label_route_${ route }_warning`)"
292+
:show-warning="state && [Route.Progress, Route.Releases].includes(route)"
295293
>
296294
<NSwitch
297295
:value="state"
@@ -327,7 +325,8 @@ const toggleBrand = () => {
327325
:class="{ show: state }"
328326
class="hidden-form-item"
329327
:label="i18n('label_calendar_extended')"
330-
:warning="calendarExtended ? i18n('label_extended_warning') : undefined"
328+
:warning="i18n('label_extended_warning')"
329+
:show-warning="calendarExtended"
331330
>
332331
<NSwitch v-model:value="calendarExtended" class="form-switch">
333332
<template #checked>{{ i18n('on', 'common', 'button') }}</template>
@@ -341,7 +340,8 @@ const toggleBrand = () => {
341340
:label="i18n('label_history_extended')"
342341
:class="{ show: state }"
343342
class="hidden-form-item"
344-
:warning="historyExtended ? i18n('label_extended_warning') : undefined"
343+
:warning="i18n('label_extended_warning')"
344+
:show-warning="historyExtended"
345345
>
346346
<NSwitch v-model:value="historyExtended" class="form-switch">
347347
<template #checked>{{ i18n('on', 'common', 'button') }}</template>
@@ -355,7 +355,8 @@ const toggleBrand = () => {
355355
:label="i18n('label_history_init')"
356356
:class="{ show: state }"
357357
class="hidden-form-item"
358-
:warning="initHistory ? i18n('label_init_warning') : undefined"
358+
:warning="i18n('label_init_warning')"
359+
:show-warning="initHistory"
359360
>
360361
<NSwitch v-model:value="initHistory" class="form-switch">
361362
<template #checked>{{ i18n('on', 'common', 'button') }}</template>
@@ -367,7 +368,8 @@ const toggleBrand = () => {
367368
<!-- Enable Ratings -->
368369
<SettingsFormItem
369370
:label="i18n('label_enable_ratings')"
370-
:warning="enableRatings ? i18n('label_enable_ratings_warning') : undefined"
371+
:warning="i18n('label_enable_ratings_warning')"
372+
:show-warning="enableRatings"
371373
>
372374
<NSwitch v-model:value="enableRatings" class="form-switch">
373375
<template #checked>{{ i18n('on', 'common', 'button') }}</template>
@@ -378,7 +380,8 @@ const toggleBrand = () => {
378380
<!-- Rating Page Sizes -->
379381
<SettingsFormItem
380382
:label="i18n('label_ratings_page_size')"
381-
:warning="!ratingPageSize ? i18n('label_page_size_warning') : undefined"
383+
:warning="i18n('label_page_size_warning')"
384+
:show-warning="!ratingPageSize"
382385
>
383386
<NSelect
384387
v-model:value="ratingPageSize"

0 commit comments

Comments
 (0)