Skip to content

Commit 32a3e78

Browse files
committed
feat(store): adds multi account support
1 parent 17968eb commit 32a3e78

File tree

4 files changed

+115
-37
lines changed

4 files changed

+115
-37
lines changed

src/models/trakt/trakt-user.model.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ export type TraktUserLimits = {
8383
};
8484

8585
export type TraktUserSettings = {
86-
user: TraktUser;
86+
user: TraktUserExtended;
8787
account: TraktUserAccount;
8888
connections: TraktUserConnections;
8989
sharing_text: {

src/router/create-router.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { createRouter as createVueRouter, createWebHashHistory } from 'vue-route
22

33
import { Route, routes } from '~/router/routes';
44
import { useRouterStore } from '~/stores/router.store';
5-
import { useSettingsStoreRefs } from '~/stores/settings.store';
5+
import { useAuthSettingsStoreRefs } from '~/stores/settings.store';
66

77
export type RouterOptions = { baseName?: string; baseUrl?: string };
88
export const createRouter = ({ baseName = '', baseUrl = import.meta.env.BASE_URL }: RouterOptions) => {
@@ -24,7 +24,7 @@ export const createRouter = ({ baseName = '', baseUrl = import.meta.env.BASE_URL
2424
],
2525
});
2626

27-
const { isAuthenticated } = useSettingsStoreRefs();
27+
const { isAuthenticated } = useAuthSettingsStoreRefs();
2828
router.beforeResolve(async to => {
2929
const query: Record<string, string> = { ...routeParam };
3030
if (routeParam) setRouteParam(undefined);

src/stores/settings.store.ts

+87-25
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,59 @@
11
import { defineStore, storeToRefs } from 'pinia';
2-
import { computed, reactive } from 'vue';
2+
import { computed, reactive, ref } from 'vue';
33

44
import type { TmdbClientAuthentication } from '~/models/tmdb/tmdb-client.model';
55
import type { TraktClientAuthentication } from '~/models/trakt/trakt-authentication.model';
66

7+
import type { TraktUserSettings } from '~/models/trakt/trakt-user.model';
78
import type { TvdbClientAuthentication } from '~/models/tvdb/tvdb-client.model';
89

910
import { storage } from '~/utils/browser/browser-storage.utils';
1011

12+
type UserSetting = TraktUserSettings | Record<string, never>;
13+
type UserSettings = Record<string, UserSetting>;
14+
15+
export const useUserSettingsStore = defineStore('settings.user', () => {
16+
const userSettings = reactive<UserSettings>({});
17+
const user = ref<string>('default');
18+
const userSetting = computed(() => userSettings[user.value]);
19+
20+
const syncSetUser = (_settings: UserSetting = userSetting.value, account: string = _settings?.user?.username ?? user.value) => {
21+
const _lastUser = storage.sync.set(`settings.last-user`, account);
22+
const _setting = storage.sync.set(`settings.user.${encodeURIComponent(account)}`, _settings);
23+
console.info('settings-store', 'Saving user', account, _settings);
24+
return Promise.all([_lastUser, _setting]);
25+
};
26+
const syncClearUser = (account?: string) => {
27+
console.info('settings-store', 'Clearing user', account);
28+
return storage.sync.remove(`settings.user${account ? `.${encodeURIComponent(account)}` : ''}`);
29+
};
30+
const syncRestoreUser = async (account: string = user.value) => {
31+
if (account === 'default') account = (await storage.sync.get<string>(`settings.last-user`)) || account;
32+
user.value = account;
33+
console.info('settings-store', 'Restoring user', account);
34+
const _setting = await storage.sync.get<UserSetting>(`settings.user.${encodeURIComponent(account)}`);
35+
if (!userSettings[account]) userSettings[account] = {};
36+
if (_setting) Object.assign(userSettings[account], _setting);
37+
return _setting;
38+
};
39+
40+
const setUserSetting = (_settings: UserSetting = {}, account: string = _settings?.user?.username ?? user.value) => {
41+
if (!userSettings[account]) userSettings[account] = {};
42+
Object.assign(userSettings[account], _settings);
43+
console.info('settings-store', 'User changed', account, { ..._settings });
44+
if (_settings) {
45+
user.value = account;
46+
return syncSetUser(_settings, account);
47+
}
48+
user.value = 'default';
49+
return syncClearUser(account);
50+
};
51+
52+
return { user, userSetting, setUserSetting, syncSetUser, syncClearUser, syncRestoreUser };
53+
});
54+
55+
export const useUserSettingsStoreRefs = () => storeToRefs(useUserSettingsStore());
56+
1157
type SettingsAuth = {
1258
trakt?: TraktClientAuthentication;
1359
tvdb?: TvdbClientAuthentication;
@@ -20,40 +66,56 @@ type SettingsAuthenticated = {
2066
tmdb?: boolean;
2167
};
2268

23-
export const useSettingsStore = defineStore('settings', () => {
24-
const auth = reactive<SettingsAuth>({});
69+
type SettingsAuths = Record<string, SettingsAuth>;
70+
71+
export const useAuthSettingsStore = defineStore('settings.auth', () => {
72+
const { user } = useUserSettingsStoreRefs();
73+
74+
const auths = reactive<SettingsAuths>({});
75+
const auth = computed(() => auths[user.value]);
76+
2577
const authenticated = reactive<SettingsAuthenticated>({});
26-
const isAuthenticated = computed(() => Object.values(authenticated).every(Boolean));
78+
const isAuthenticated = computed(() => {
79+
const values = Object.values(authenticated);
80+
return values.length > 0 ? values.every(Boolean) : false;
81+
});
2782

2883
const setAuthenticated = ({ trakt, tvdb, tmdb }: SettingsAuth = {}) => {
2984
if (trakt) authenticated.trakt = !!trakt.access_token;
3085
if (tvdb) authenticated.tvdb = !!tvdb.accessToken;
3186
if (tmdb) authenticated.tmdb = !!tmdb.accessToken;
87+
return authenticated;
88+
};
89+
90+
const syncSetAuth = (_auth: SettingsAuth = auth.value, account: string = user.value) => {
91+
console.info('settings-store', 'Saving auth', account, _auth);
92+
return storage.sync.set(`settings.auth.${encodeURIComponent(account)}`, _auth);
93+
};
94+
const syncClearAuth = (account?: string) => {
95+
console.info('settings-store', 'Clearing auth', account);
96+
return storage.sync.remove(`settings.auth${account ? `.${encodeURIComponent(account)}` : ''}`);
97+
};
98+
const syncRestoreAuth = async (account: string = user.value) => {
99+
console.info('settings-store', 'Restoring auth', account);
100+
const _auth = await storage.sync.get<SettingsAuth>(`settings.auth.${encodeURIComponent(account)}`);
101+
if (!auths[account]) auths[account] = {};
102+
if (_auth) Object.assign(auths[account], _auth);
103+
setAuthenticated(_auth);
104+
return auths[account];
32105
};
33106

34-
const syncSetAuth = (_auth: SettingsAuth) => storage.sync.set('settings.auth', _auth);
35-
const syncClearAuth = () => storage.sync.remove('settings.auth');
36-
const syncRestoreAuth = () =>
37-
storage.sync.get<SettingsAuth>('settings.auth').then(_auth => {
38-
Object.assign(auth, _auth);
39-
setAuthenticated(_auth);
40-
return _auth;
41-
});
42-
43-
const setAuth = (_auth: SettingsAuth = {}) => {
44-
if (_auth.trakt) auth.trakt = _auth.trakt;
45-
if (_auth.tvdb) auth.tvdb = _auth.tvdb;
46-
if (_auth.tmdb) auth.tmdb = _auth.tmdb;
47-
console.info('settings-store', 'Auth changed', { ...auth });
107+
const setAuth = async (_auth: SettingsAuth = {}, account: string = user.value) => {
108+
if (!auths[account]) auths[account] = {};
109+
if (_auth.trakt) auths[account].trakt = _auth.trakt;
110+
if (_auth.tvdb) auths[account].tvdb = _auth.tvdb;
111+
if (_auth.tmdb) auths[account].tmdb = _auth.tmdb;
112+
console.info('settings-store', 'Auth changed', account, { ...auths });
48113
setAuthenticated(_auth);
49-
if (Object.keys(_auth).length > 0) {
50-
syncSetAuth(auth).then(() => console.info('settings-store', 'Auth saved', { ...auth }));
51-
} else {
52-
syncClearAuth().then(() => console.info('settings-store', 'Auth cleared'));
53-
}
114+
if (Object.keys(_auth).length > 0) return syncSetAuth(_auth, account);
115+
return syncClearAuth(account);
54116
};
55117

56-
return { auth, setAuth, authenticated, isAuthenticated, syncRestoreAuth };
118+
return { auth, setAuth, authenticated, isAuthenticated, syncRestoreAuth, syncSetAuth };
57119
});
58120

59-
export const useSettingsStoreRefs = () => storeToRefs(useSettingsStore());
121+
export const useAuthSettingsStoreRefs = () => storeToRefs(useAuthSettingsStore());

src/web/init-services.ts

+25-9
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,38 @@
11
import { tmdbService } from '~/services/tmdb-client/tmdb-client.service';
22
import { traktService } from '~/services/trakt-client/trakt-client.service';
33
import { tvdbService } from '~/services/tvdb-client/tvdb-client.service';
4-
import { useSettingsStore } from '~/stores/settings.store';
4+
import { useAuthSettingsStore, useAuthSettingsStoreRefs, useUserSettingsStore, useUserSettingsStoreRefs } from '~/stores/settings.store';
55

66
export const initServices = async () => {
7-
const { setAuth, syncRestoreAuth } = useSettingsStore();
7+
const { setAuth, syncRestoreAuth, syncSetAuth } = useAuthSettingsStore();
8+
const { setUserSetting, syncRestoreUser } = useUserSettingsStore();
89

9-
const auth = await syncRestoreAuth();
10+
const { user } = useUserSettingsStoreRefs();
11+
const { isAuthenticated } = useAuthSettingsStoreRefs();
12+
13+
const restoredSettings = await syncRestoreUser();
14+
const restoredAuth = await syncRestoreAuth(restoredSettings?.user?.username);
1015

1116
const restore = [];
12-
if (auth.trakt) restore.push(traktService.importAuthentication(auth.trakt).then(_auth => console.info('TraktClient.importAuthentication', _auth)));
13-
if (auth.tvdb) restore.push(tvdbService.importAuthentication(auth.tvdb).then(_auth => console.info('TvdbClient.importAuthentication', _auth)));
14-
if (auth.tmdb) console.info('TmdbClient.importAuthentication', tmdbService.importAuthentication(auth.tmdb));
17+
if (restoredAuth.trakt) restore.push(traktService.importAuthentication(restoredAuth.trakt).then(_auth => console.info('Trakt import', _auth)));
18+
if (restoredAuth.tvdb) restore.push(tvdbService.importAuthentication(restoredAuth.tvdb).then(_auth => console.info('Tvdb import', _auth)));
19+
if (restoredAuth.tmdb) console.info('TmdbClient.importAuthentication', tmdbService.importAuthentication(restoredAuth.tmdb));
1520
await Promise.all(restore);
1621

17-
traktService.onAuthChange(_auth => {
18-
console.info('TraktClient.onAuthChange', _auth);
19-
setAuth({ trakt: _auth });
22+
if (isAuthenticated.value && user.value === 'default') {
23+
console.info('TraktClient.users.settings', user.value);
24+
const settings = await traktService.users.settings().then(res => res.json());
25+
await setUserSetting(settings);
26+
await syncSetAuth();
27+
}
28+
29+
traktService.onAuthChange(async (_auth, prev) => {
30+
console.info('TraktClient.onAuthChange', _auth, prev);
31+
if (_auth?.access_token !== prev?.access_token) {
32+
const settings = await traktService.users.settings().then(res => res.json());
33+
await setUserSetting(settings);
34+
}
35+
await setAuth({ trakt: _auth });
2036
});
2137

2238
traktService.onCall(async call => {

0 commit comments

Comments
 (0)