Skip to content

Commit bbe1c13

Browse files
committed
feat(simkl): adds toggle
1 parent 666b14b commit bbe1c13

File tree

5 files changed

+112
-46
lines changed

5 files changed

+112
-46
lines changed

src/components/views/settings/SettingsComponent.vue

+2-2
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,15 @@ type Section = {
2727
disabled?: boolean;
2828
};
2929
30-
const { simklEnabled } = useSimklStoreRefs();
30+
const { simklAllowed } = useSimklStoreRefs();
3131
const sections = computed<Section[]>(() =>
3232
[
3333
{ title: 'menu__account', reference: ref(), component: SettingsAccount },
3434
{
3535
title: 'menu__connect',
3636
reference: ref(),
3737
component: SettingsConnect,
38-
disabled: !simklEnabled.value,
38+
disabled: !simklAllowed.value,
3939
},
4040
{ title: 'menu__tabs', reference: ref(), component: SettingsTabs },
4141
{ title: 'menu__links', reference: ref(), component: SettingsLinks },

src/components/views/settings/SettingsConnect.vue

+96-40
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
<script lang="ts" setup>
22
import { chromeRuntimeId } from '@dvcol/web-extension-utils/chrome/runtime';
3-
import { NAvatar, NButton, NCard, NFlex, NIcon } from 'naive-ui';
3+
import { NAvatar, NButton, NCard, NFlex, NIcon, NSwitch } from 'naive-ui';
44
5-
import { computed, ref, watch } from 'vue';
5+
import { computed, ref, Transition, watch } from 'vue';
66
77
import TextField from '~/components/common/typography/TextField.vue';
88
import IconLogIn from '~/components/icons/IconLogIn.vue';
99
import IconLogOut from '~/components/icons/IconLogOut.vue';
1010
import IconSimkl from '~/components/icons/IconSimkl.vue';
11+
import SettingsFormItem from '~/components/views/settings/SettingsFormItem.vue';
1112
import { Logger } from '~/services/logger.service';
1213
import { TraktService } from '~/services/trakt.service';
1314
import { ResolveExternalLinks } from '~/settings/external.links';
@@ -20,7 +21,7 @@ import { useWatchActivated } from '~/utils/watching.utils';
2021
2122
const i18n = useI18n('settings', 'connect');
2223
23-
const { userSetting, userSettingLoading } = useSimklStoreRefs();
24+
const { userSetting, userSettingLoading, simklEnabled } = useSimklStoreRefs();
2425
2526
const fallback = ref<boolean>(!chromeRuntimeId);
2627
const avatar = computed(() => {
@@ -68,7 +69,13 @@ useWatchActivated(
6869
</script>
6970

7071
<template>
71-
<NFlex vertical align="center">
72+
<NFlex align="center">
73+
<SettingsFormItem :label="i18n('label_enable')" class="flex-auto">
74+
<NSwitch v-model:value="simklEnabled" class="form-switch">
75+
<template #checked>{{ i18n('on', 'common', 'button') }}</template>
76+
<template #unchecked>{{ i18n('off', 'common', 'button') }}</template>
77+
</NSwitch>
78+
</SettingsFormItem>
7279
<NCard
7380
class="account-card"
7481
:style="{ '--n-border-color': 'var(--border-color)' }"
@@ -90,61 +97,86 @@ useWatchActivated(
9097
</NIcon>
9198
</NButton>
9299

93-
<NFlex class="names" size="large" vertical wrap>
94-
<NFlex class="flex-auto" justify="center">
95-
<TextField
96-
:label="i18n('username')"
97-
:value="name"
98-
:loading="userSettingLoading"
99-
label-width="4.5rem"
100-
grow
101-
/>
102-
<TextField
103-
:label="i18n('joined')"
104-
:value="joined"
105-
:loading="userSettingLoading"
106-
label-width="auto"
107-
grow
108-
/>
100+
<Transition name="scale" mode="out-in">
101+
<NFlex
102+
v-if="isSimklAuthenticated"
103+
class="flex-auto names"
104+
size="large"
105+
vertical
106+
wrap
107+
>
108+
<NFlex class="flex-auto" justify="center">
109+
<TextField
110+
:label="i18n('username')"
111+
:value="name"
112+
:loading="userSettingLoading"
113+
label-width="4.5rem"
114+
grow
115+
/>
116+
<TextField
117+
:label="i18n('joined')"
118+
:value="joined"
119+
:loading="userSettingLoading"
120+
label-width="auto"
121+
grow
122+
/>
123+
</NFlex>
124+
<NFlex justify="center">
125+
<TextField
126+
:label="i18n('bio')"
127+
:value="bio"
128+
:loading="userSettingLoading"
129+
label-width="4.5rem"
130+
value-width="auto"
131+
grow
132+
/>
133+
</NFlex>
109134
</NFlex>
110-
<NFlex justify="center">
111-
<TextField
112-
:label="i18n('bio')"
113-
:value="bio"
114-
:loading="userSettingLoading"
115-
label-width="4.5rem"
116-
value-width="auto"
117-
grow
118-
/>
135+
<NFlex v-else class="flex-auto names" size="large" vertical wrap>
136+
<NFlex class="logged-out flex-auto" justify="center">
137+
<NButton
138+
secondary
139+
type="success"
140+
:disabled="!simklEnabled"
141+
@click="loginLogout"
142+
>
143+
<span>{{ i18n('login', 'common', 'button') }}</span>
144+
<template #icon>
145+
<NIcon :component="IconLogIn" />
146+
</template>
147+
</NButton>
148+
</NFlex>
119149
</NFlex>
120-
</NFlex>
150+
</Transition>
121151
</NFlex>
122152
</NCard>
123153
</NFlex>
124154

125155
<!-- Footer -->
126-
<NFlex class="footer" align="center" justify="center">
127-
<NButton
128-
secondary
129-
:type="isSimklAuthenticated ? 'error' : 'success'"
130-
@click="loginLogout"
131-
>
132-
<span>{{
133-
i18n(isSimklAuthenticated ? 'logout' : 'login', 'common', 'button')
134-
}}</span>
156+
<NFlex
157+
class="footer"
158+
:class="{ show: isSimklAuthenticated }"
159+
align="center"
160+
justify="center"
161+
>
162+
<NButton secondary :type="'error'" @click="loginLogout">
163+
<span>{{ i18n('logout', 'common', 'button') }}</span>
135164
<template #icon>
136-
<NIcon :component="isSimklAuthenticated ? IconLogOut : IconLogIn" />
165+
<NIcon :component="IconLogOut" />
137166
</template>
138167
</NButton>
139168
</NFlex>
140169
</template>
141170

142171
<style lang="scss" scoped>
143172
@use '~/styles/mixin' as mixin;
173+
@use '~/styles/transition' as transition;
174+
@include transition.scale($transition: 0.375s var(--n-bezier));
144175
145176
.account-card {
146177
--border-color: var(--white-10);
147178
179+
flex: 1 0 100%;
148180
margin-bottom: 1.5rem;
149181
background: var(--bg-black-soft);
150182
@@ -174,10 +206,34 @@ useWatchActivated(
174206
.flex-auto {
175207
flex: 1 1 auto;
176208
}
209+
210+
.logged-out {
211+
margin-right: 10rem;
212+
}
213+
}
214+
215+
.form-switch {
216+
display: flex;
217+
flex: 1 1 auto;
218+
justify-content: center;
219+
min-width: 5rem;
220+
padding: 0 0.5rem;
221+
font-size: 0.75rem;
177222
}
178223
179224
.footer {
225+
max-height: 0;
180226
margin-bottom: 0.5rem;
181227
padding: 0.5rem;
228+
overflow: hidden;
229+
opacity: 0;
230+
transition:
231+
max-height 0.75s var(--n-bezier),
232+
opacity 0.75s var(--n-bezier);
233+
234+
&.show {
235+
max-height: 6rem;
236+
opacity: 1;
237+
}
182238
}
183239
</style>

src/components/views/settings/SettingsFormItem.vue

+7-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<script lang="ts" setup>
2-
import { type FormItemGiProps, NFormItem } from 'naive-ui';
2+
import { type FormItemGiProps, NFlex, NFormItem } from 'naive-ui';
33
44
import type { PropType } from 'vue';
55
@@ -20,7 +20,7 @@ defineProps({
2020
</script>
2121

2222
<template>
23-
<div>
23+
<NFlex class="flex-auto" wrap justify="space-between" align="center">
2424
<NFormItem
2525
class="form-row"
2626
label-placement="left"
@@ -35,10 +35,14 @@ defineProps({
3535
<div class="form-warning" :class="{ show: !!warning }">
3636
<span v-if="warning">{{ warning }}</span>
3737
</div>
38-
</div>
38+
</NFlex>
3939
</template>
4040

4141
<style lang="scss" scoped>
42+
.flex-auto {
43+
flex: 1 1 auto;
44+
}
45+
4246
.from-label {
4347
color: var(--white-70);
4448
font-weight: 600;

src/i18n/en/settings/settings-connect.json

+4
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,9 @@
1010
"settings__connect__bio": {
1111
"message": "Biography",
1212
"description": "Biography label"
13+
},
14+
"settings__connect__label_enable": {
15+
"message": "Enable Simkl integration",
16+
"description": "Enable Simkl label"
1317
}
1418
}

src/stores/data/simkl.store.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ export const useSimklStore = defineStore(SimklStoreConstants.Store, () => {
2727

2828
const loading = reactive<LoadingDictionary>({});
2929

30+
const simklAllowed = computed(() => ['dvcol', 'Anshur'].includes(user.value));
3031
const userSetting = computed(() => userSettings[user.value]);
3132
const userSettingLoading = computed(() => loading?.[user.value]);
3233

@@ -91,8 +92,9 @@ export const useSimklStore = defineStore(SimklStoreConstants.Store, () => {
9192
userSettingLoading,
9293
fetchUserSettings,
9394
setUserSetting,
95+
simklAllowed,
9496
simklEnabled: computed({
95-
get: () => simklEnabled.value || user.value === 'dvcol',
97+
get: () => simklAllowed.value && simklEnabled.value,
9698
set: (value: boolean) => {
9799
simklEnabled.value = value;
98100
saveState().catch(err => Logger.error('Failed to save simkl state', { value, err }));

0 commit comments

Comments
 (0)