Skip to content

Commit 5bd3253

Browse files
committed
feat(simkl): big rework of account management & adding simkl auth
1 parent ebbeacd commit 5bd3253

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

61 files changed

+1396
-528
lines changed

env.d.ts

+3
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,8 @@ interface ImportMeta {
1717
VITE_TMDB_READ_TOKEN: string;
1818

1919
VITE_TVDB_API_KEY: string;
20+
21+
VITE_SIMKL_CLIENT_ID: string;
22+
VITE_SIMKL_CLIENT_SECRET: string;
2023
};
2124
}

env/.env.testing

+4-1
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,7 @@ VITE_TRAKT_STAGING_SECRET=vite_trakt_staging_secret
77
VITE_TMDB_API_KEY=vite_tmdb_api_key
88
VITE_TMDB_READ_TOKEN=vite_tmdb_read_token
99

10-
VITE_TVDB_API_KEY=vite_tvdb_api_key
10+
VITE_TVDB_API_KEY=vite_tvdb_api_key
11+
12+
VITE_SIMKL_CLIENT_ID=vite_mal_client_id
13+
VITE_SIMKL_CLIENT_SECRET=vite_mal_client_secret

package.json

+4-3
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,11 @@
5151
"release:changelog": "extract-changelog-release > RELEASE.md"
5252
},
5353
"dependencies": {
54-
"@dvcol/base-http-client": "^1.12.2",
54+
"@dvcol/base-http-client": "^1.13.1",
5555
"@dvcol/common-utils": "^1.11.1",
56-
"@dvcol/tmdb-http-client": "^1.3.3",
57-
"@dvcol/trakt-http-client": "^1.4.7",
56+
"@dvcol/simkl-http-client": "^1.1.0",
57+
"@dvcol/tmdb-http-client": "^1.3.4",
58+
"@dvcol/trakt-http-client": "^1.4.9",
5859
"@dvcol/web-extension-utils": "^3.3.2",
5960
"@vue/devtools": "^7.0.15",
6061
"iso-3166-2": "^1.0.0",

pnpm-lock.yaml

+37-17
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

scripts/manifest.ts

+34-16
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
import { Config as SimklConfig } from '@dvcol/simkl-http-client/config';
2+
import { Config as TmdbConfig } from '@dvcol/tmdb-http-client/config';
3+
import { Config as TraktConfig } from '@dvcol/trakt-http-client/config';
14
import fs from 'fs-extra';
25

36
import pkg from '../package.json';
@@ -6,17 +9,22 @@ import { getDirName, isDev, port, resolveParent } from './utils';
69

710
import type { Manifest } from 'webextension-polyfill';
811

9-
export const Endpoints = {
10-
trakt: {
11-
Domain: 'https://trakt.tv',
12+
const Endpoints = {
13+
Trakt: {
14+
Domain: TraktConfig.Website.Production,
15+
StagingDomain: TraktConfig.Website.Staging,
1216
SubDomain: 'https://*.trakt.tv',
13-
Production: 'https://api.trakt.tv',
14-
Staging: 'https://api-staging.trakt.tv',
17+
Api: TraktConfig.Endpoint.Production,
18+
StagingApi: TraktConfig.Endpoint.Staging,
1519
},
16-
tvdb: 'https://api4.thetvdb.co',
17-
tmdb: {
18-
api: 'https://api.themoviedb.org',
19-
redirect: 'https://www.themoviedb.org',
20+
Tmdb: {
21+
Api: TmdbConfig.Endpoint,
22+
Domain: TmdbConfig.Website,
23+
},
24+
Simkl: {
25+
Api: SimklConfig.Endpoint,
26+
Data: SimklConfig.Data,
27+
Domain: SimklConfig.Website,
2028
},
2129
} as const;
2230

@@ -48,16 +56,26 @@ export const manifest: Manifest.WebExtensionManifest = {
4856
web_accessible_resources: [
4957
{
5058
resources: ['/views/options/index.html'],
51-
matches: [`${Endpoints.trakt.Production}/*`, `${Endpoints.trakt.Staging}/*`, `${Endpoints.tvdb}/*`, `${Endpoints.tmdb.redirect}/*`],
59+
matches: [
60+
`${Endpoints.Trakt.Api}/*`,
61+
`${Endpoints.Trakt.StagingApi}/*`,
62+
`${Endpoints.Trakt.Domain}/*`,
63+
`${Endpoints.Trakt.StagingDomain}/*`,
64+
`${Endpoints.Tmdb.Domain}/*`,
65+
`${Endpoints.Simkl.Domain}/*`,
66+
],
5267
},
5368
],
5469
host_permissions: [
55-
`${Endpoints.trakt.Domain}/*`,
56-
`${Endpoints.trakt.SubDomain}/*`,
57-
`${Endpoints.trakt.Production}/*`,
58-
`${Endpoints.trakt.Staging}/*`,
59-
`${Endpoints.tvdb}/*`,
60-
`${Endpoints.tmdb.api}/*`,
70+
`${Endpoints.Trakt.Domain}/*`,
71+
`${Endpoints.Trakt.SubDomain}/*`,
72+
`${Endpoints.Trakt.Api}/*`,
73+
`${Endpoints.Trakt.StagingApi}/*`,
74+
`${Endpoints.Tmdb.Api}/*`,
75+
`${Endpoints.Tmdb.Domain}/*`,
76+
`${Endpoints.Simkl.Api}/*`,
77+
`${Endpoints.Simkl.Data}/*`,
78+
`${Endpoints.Simkl.Domain}/*`,
6179
],
6280
content_security_policy: {
6381
// Adds localhost for vite hot reload

src/assets/simkl/simkl.jpg

20.6 KB
Loading

src/components/common/navbar/NavbarSettingsDopdown.vue

+19-16
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import { Logger } from '~/services/logger.service';
2525
import { NavbarService } from '~/services/navbar.service';
2626
import { TraktService } from '~/services/trakt.service';
2727
import { ExternaLinks } from '~/settings/external.links';
28+
import { useAuthSettingsStoreRefs } from '~/stores/settings/auth.store';
2829
import { useExtensionSettingsStoreRefs } from '~/stores/settings/extension.store';
2930
import { useLogout } from '~/stores/settings/use-logout';
3031
import { defaultUser, useUserSettingsStoreRefs } from '~/stores/settings/user.store';
@@ -34,7 +35,8 @@ import { useI18n } from '~/utils/i18n.utils';
3435
const i18n = useI18n('navbar', 'settings');
3536
const router = useRouter();
3637
37-
const { userSetting, userSettings } = useUserSettingsStoreRefs();
38+
const { auths } = useAuthSettingsStoreRefs();
39+
const { userSetting, userSettings, userSettingLoading } = useUserSettingsStoreRefs();
3840
const { enabledRoutes } = useExtensionSettingsStoreRefs();
3941
4042
const avatar = computed(() => userSetting.value?.user?.images?.avatar?.full);
@@ -55,18 +57,21 @@ defineProps({
5557
5658
const users = computed(() => {
5759
return Object.entries(userSettings.value).filter(
58-
([key, value]) => value && key !== username.value && key !== defaultUser,
60+
([key, value]) =>
61+
value && auths.value?.[key] && key !== username.value && key !== defaultUser,
5962
);
6063
});
6164
6265
const toOption = (
6366
key: string,
6467
icon: Component | string,
6568
label?: string,
69+
disabled?: boolean,
6670
): ArrayElement<DropdownProps['options']> => {
6771
return {
6872
label: label ?? i18n(key),
6973
key,
74+
disabled,
7075
icon: () => {
7176
if (typeof icon === 'string') {
7277
return h(NAvatar, { src: icon, size: 16, round: true });
@@ -87,21 +92,19 @@ const options = computed<DropdownProps['options']>(() => {
8792
toOption('logout', IconLogOut),
8893
];
8994
90-
if (users.value.length) {
91-
return [
92-
...users.value.map(([key, value]) =>
93-
toOption(
94-
`user-${key}`,
95-
(chromeRuntimeId && value?.user?.images?.avatar?.full) || IconAccount,
96-
key,
97-
),
95+
if (!users.value.length) return baseOptions;
96+
return [
97+
...users.value.map(([key, value]) =>
98+
toOption(
99+
`user-${key}`,
100+
(chromeRuntimeId && value?.user?.images?.avatar?.full) || IconAccount,
101+
key,
102+
userSettingLoading.value,
98103
),
99-
{ type: 'divider', key: 'users-divider' },
100-
...baseOptions,
101-
];
102-
}
103-
104-
return baseOptions;
104+
),
105+
{ type: 'divider', key: 'users-divider' },
106+
...baseOptions,
107+
];
105108
});
106109
107110
const { loadUser, logout } = useLogout();

src/components/icons/IconLogIn.vue

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<template>
2+
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24">
3+
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-width="1.5">
4+
<path
5+
stroke-dasharray="32"
6+
stroke-dashoffset="32"
7+
d="M13 4L20 4C20.5523 4 21 4.44772 21 5V19C21 19.5523 20.5523 20 20 20H13"
8+
>
9+
<animate
10+
fill="freeze"
11+
attributeName="stroke-dashoffset"
12+
dur="0.4s"
13+
values="32;0"
14+
/>
15+
</path>
16+
<path stroke-dasharray="12" stroke-dashoffset="12" d="M3 12h11.5" opacity="0">
17+
<set attributeName="opacity" begin="0.5s" to="1" />
18+
<animate
19+
fill="freeze"
20+
attributeName="stroke-dashoffset"
21+
begin="0.5s"
22+
dur="0.2s"
23+
values="12;0"
24+
/>
25+
</path>
26+
<path
27+
stroke-dasharray="6"
28+
stroke-dashoffset="6"
29+
d="M14.5 12l-3.5 -3.5M14.5 12l-3.5 3.5"
30+
opacity="0"
31+
>
32+
<set attributeName="opacity" begin="0.7s" to="1" />
33+
<animate
34+
fill="freeze"
35+
attributeName="stroke-dashoffset"
36+
begin="0.7s"
37+
dur="0.2s"
38+
values="6;0"
39+
/>
40+
</path>
41+
</g>
42+
</svg>
43+
</template>

src/components/icons/IconSimkl.vue

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<template>
2+
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" viewBox="0 0 24 24">
3+
<path
4+
fill="currentColor"
5+
d="M3.84 0A3.832 3.832 0 0 0 0 3.84v16.32A3.832 3.832 0 0 0 3.84 24h16.32A3.832 3.832 0 0 0 24 20.16V3.84A3.832 3.832 0 0 0 20.16 0zm8.567 4.11c2.074 0 3.538.061 4.393.186c1.127.168 1.94.46 2.438.877c.672.578 1.009 1.613 1.009 3.104c0 .161-.004.417-.01.768h-4.234c-.014-.358-.039-.607-.074-.746c-.098-.41-.42-.64-.966-.692c-.484-.043-1.66-.066-3.53-.066c-1.85 0-2.946.056-3.289.165c-.385.133-.578.474-.578 1.024c0 .528.203.851.61.969c.343.095 1.887.187 4.633.275c2.487.073 4.073.165 4.76.275c.693.11 1.244.275 1.654.495c.41.22.737.532.983.936c.37.595.557 1.552.557 2.873c0 1.475-.182 2.557-.546 3.247c-.364.683-.96 1.149-1.785 1.398c-.812.25-3.05.374-6.71.374c-2.226 0-3.832-.062-4.82-.187c-1.204-.147-2.068-.434-2.593-.86c-.567-.456-.903-1.1-1.008-1.93a10.522 10.522 0 0 1-.085-1.434v-.789H7.44c-.007.74.136 1.216.43 1.428c.154.102.33.167.525.203c.196.037.54.063 1.03.077a166.2 166.2 0 0 0 2.405.022c1.862-.007 2.94-.018 3.234-.033c.553-.044.917-.12 1.092-.23c.245-.161.368-.52.368-1.077c0-.38-.078-.648-.231-.802c-.211-.212-.712-.325-1.503-.34c-.547 0-1.688-.044-3.425-.132c-1.794-.088-2.956-.14-3.488-.154c-1.387-.044-2.364-.212-2.932-.505c-.728-.373-1.205-1.01-1.429-1.91c-.126-.498-.189-1.15-.189-1.956c0-1.698.309-2.895.925-3.59c.462-.527 1.163-.875 2.102-1.044c.848-.146 2.865-.22 6.053-.22z"
6+
></path>
7+
</svg>
8+
</template>

src/components/views/calendar/CalendarComponent.vue

+19-3
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,14 @@ import ListScroll from '~/components/common/list/ListScroll.vue';
66
import { useListScroll } from '~/components/common/list/use-list-scroll';
77
88
import { usePanelItem } from '~/components/views/panel/use-panel-item';
9+
import { Route } from '~/models/router.model';
910
import { useAppStateStoreRefs } from '~/stores/app-state.store';
11+
import { useActivityStore } from '~/stores/data/activity.store';
1012
import { useCalendarStore, useCalendarStoreRefs } from '~/stores/data/calendar.store';
1113
import { useCalendar, useCenterButton } from '~/utils/calendar.utils';
1214
import { useI18n } from '~/utils/i18n.utils';
1315
import { watchUserChange } from '~/utils/store.utils';
16+
import { useWatchActivated } from '~/utils/watching.utils';
1417
1518
const i18n = useI18n('calendar');
1619
@@ -30,16 +33,29 @@ const { listRef, onClick, onScrollTop, onScrollBottom, reload } = useCalendar({
3033
fetchData: fetchCalendar,
3134
});
3235
33-
watch(center, () => reload());
36+
watch(center, (_is, _was) => {
37+
if (new Date(_is).toLocaleDateString() === new Date(_was).toLocaleDateString()) return;
38+
reload();
39+
});
40+
41+
const { getEvicted } = useActivityStore();
42+
useWatchActivated(
43+
watch(getEvicted(Route.Calendar), async _evicted => {
44+
if (!_evicted) return;
45+
if (scrolledOut.value) return;
46+
await reload();
47+
}),
48+
);
3449
3550
watchUserChange({
3651
mounted: reload,
3752
activated: async changed => {
3853
if (changed) await reload();
3954
},
40-
userChange: async active => {
55+
userChange: async ({ active, authenticated }) => {
4156
clearState();
42-
if (active) await reload();
57+
if (!active || !authenticated) return;
58+
await reload();
4359
},
4460
});
4561

0 commit comments

Comments
 (0)