diff options
| author | Fuwn <[email protected]> | 2024-02-12 08:55:11 -0800 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2024-02-12 08:55:11 -0800 |
| commit | 0fbeaaf6237b62d5220da0418d05cae4487f29bf (patch) | |
| tree | 036ea9187a07d860e0d65373a8ee5a3137b758f5 /src | |
| parent | fix(anime): new list on new episode (diff) | |
| download | due.moe-0fbeaaf6237b62d5220da0418d05cae4487f29bf.tar.xz due.moe-0fbeaaf6237b62d5220da0418d05cae4487f29bf.zip | |
feat(settings): settings sync
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib/Database/userConfiguration.ts | 19 | ||||
| -rw-r--r-- | src/routes/+layout.svelte | 13 | ||||
| -rw-r--r-- | src/routes/api/configuration/+server.ts | 33 | ||||
| -rw-r--r-- | src/routes/settings/+page.svelte | 52 | ||||
| -rw-r--r-- | src/stores/settings.ts | 18 | ||||
| -rw-r--r-- | src/stores/settingsSyncPulled.ts | 5 |
6 files changed, 126 insertions, 14 deletions
diff --git a/src/lib/Database/userConfiguration.ts b/src/lib/Database/userConfiguration.ts index 5e2f0c96..1b6f152e 100644 --- a/src/lib/Database/userConfiguration.ts +++ b/src/lib/Database/userConfiguration.ts @@ -2,11 +2,16 @@ import supabase from './supabase'; interface UserConfiguration { user_id: number; - configuration: any; + configuration: JSON; created_at: string; updated_at: string; } +interface NewUserConfiguration { + configuration: JSON; + updated_at?: string; +} + export const getUserConfiguration = async (userId: number) => { const { data, error } = await supabase .from('user_configuration') @@ -18,12 +23,18 @@ export const getUserConfiguration = async (userId: number) => { return data[0] as UserConfiguration; }; -export const setUserConfiguration = async (userId: number, configuration: UserConfiguration) => { +export const setUserConfiguration = async (userId: number, configuration: NewUserConfiguration) => { + if (!configuration.updated_at) configuration.updated_at = new Date().toISOString(); + const { data, error } = await supabase .from('user_configuration') - .upsert({ user_id: userId, configuration }); + .upsert( + { user_id: userId, configuration: configuration.configuration }, + { onConflict: 'user_id' } + ) + .select(); if (error || !data || (data as []).length === 0) return null; - return data[0] as UserConfiguration; + return data[0].configuration as UserConfiguration; }; diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte index 835b59f7..64f3d28d 100644 --- a/src/routes/+layout.svelte +++ b/src/routes/+layout.svelte @@ -23,6 +23,7 @@ import Dropdown from '$lib/Dropdown.svelte'; import { injectSpeedInsights } from '@vercel/speed-insights/sveltekit'; import subtitles from '$lib/Data/Static/subtitles.json'; + import settingsSyncPulled from '$stores/settingsSyncPulled'; injectSpeedInsights(); @@ -72,6 +73,18 @@ if (data.user !== undefined && $userIdentity.id === -2) getUserIdentity(data.user).then((h) => userIdentity.set(h)); + + if ($settings.settingsSync && $userIdentity.id !== -2) + fetch(root(`/api/configuration?id=${$userIdentity.id}`)).then((response) => { + if (response.ok) + response.json().then((data) => { + if (data && data.configuration) { + console.log('Pulled remote configuration'); + settings.set(data.configuration); + settingsSyncPulled.set(true); + } + }); + }); }); $: { diff --git a/src/routes/api/configuration/+server.ts b/src/routes/api/configuration/+server.ts index a42d9c54..418742a8 100644 --- a/src/routes/api/configuration/+server.ts +++ b/src/routes/api/configuration/+server.ts @@ -1,5 +1,8 @@ +import { userIdentity } from '$lib/Data/AniList/identity'; import { getUserConfiguration, setUserConfiguration } from '$lib/Database/userConfiguration.js'; +const unauthorised = new Response('Unauthorised', { status: 401 }); + export const GET = async ({ url }) => Response.json(await getUserConfiguration(Number(url.searchParams.get('id') || 0)), { headers: { @@ -7,17 +10,31 @@ export const GET = async ({ url }) => } }); -export const PUT = async ({ url, request }) => - Response.json( - await setUserConfiguration(Number(url.searchParams.get('id') || 0), { - configuration: await request.json(), - updated_at: new Date().toISOString(), - user_id: Number(url.searchParams.get('id') || 0), - created_at: new Date().toISOString() - }), +export const PUT = async ({ cookies, request }) => { + const userCookie = cookies.get('user'); + + if (!userCookie) return unauthorised; + + const user = JSON.parse(userCookie); + + return Response.json( + await setUserConfiguration( + ( + await userIdentity({ + tokenType: user['token_type'], + expiresIn: user['expires_in'], + accessToken: user['access_token'], + refreshToken: user['refresh_token'] + }) + ).id, + { + configuration: await request.json() + } + ), { headers: { 'Access-Control-Allow-Origin': 'https://due.moe' } } ); +}; diff --git a/src/routes/settings/+page.svelte b/src/routes/settings/+page.svelte index 03dcedde..342e73a3 100644 --- a/src/routes/settings/+page.svelte +++ b/src/routes/settings/+page.svelte @@ -16,6 +16,8 @@ import locale from '$stores/locale.js'; import settings from '$stores/settings'; import LogInRestricted from '$lib/Error/LogInRestricted.svelte'; + import root from '$lib/Utility/root'; + import identity from '$stores/identity.js'; export let data; @@ -66,6 +68,56 @@ {#if data.user === undefined} <LogInRestricted /> {:else} + <button + on:click={() => { + if (!$settings.settingsSync) { + $settings.settingsSync = true; + + fetch(root(`/api/configuration?id=${$identity.id}`)).then((response) => { + if (response.ok) { + response.json().then((data) => { + if (data && data.configuration) { + $settings = data.configuration; + + addNotification( + options({ + heading: 'Pulled remote configuration' + }) + ); + } else { + fetch(root(`/api/configuration`), { + method: 'PUT', + body: JSON.stringify($settings) + }).then((response) => { + if (response.ok) + addNotification( + options({ + heading: 'Created remote configuration' + }) + ); + }); + } + }); + } + }); + } else { + $settings.settingsSync = false; + + addNotification( + options({ + heading: 'Disabled settings sync' + }) + ); + } + }} + > + {$settings.settingsSync ? 'Disable' : 'Enable'} Settings Sync & {$settings.settingsSync + ? 'Keep Local Configuration' + : 'Pull Remote Configuration'} + </button> + + <p /> + <Category title={$locale().settings.rssFeeds.title} id="feeds"> <button on:click={() => { diff --git a/src/stores/settings.ts b/src/stores/settings.ts index 5c27c516..e92d4150 100644 --- a/src/stores/settings.ts +++ b/src/stores/settings.ts @@ -1,5 +1,7 @@ import { browser } from '$app/environment'; -import { writable } from 'svelte/store'; +import root from '$lib/Utility/root'; +import { get, writable } from 'svelte/store'; +import settingsSyncPulled from './settingsSyncPulled'; export interface Settings { cacheMangaMinutes: number; @@ -48,6 +50,7 @@ export interface Settings { displayScheduleListMode: boolean; displayLanguage: 'en' | 'ja'; displayDisableLastActivityWarning: boolean; + settingsSync: boolean; } const defaultSettings: Settings = { @@ -91,7 +94,10 @@ const defaultSettings: Settings = { // Cache cacheMangaMinutes: 120, - cacheMinutes: 30 + cacheMinutes: 30, + + // Sync + settingsSync: false }; const createStore = () => { @@ -134,6 +140,14 @@ const settings = createStore(); settings.subscribe((value) => { if (browser) localStorage.setItem('settings', JSON.stringify(value)); + + if (value.settingsSync && get(settingsSyncPulled) == true) + fetch(root(`/api/configuration`), { + method: 'PUT', + body: JSON.stringify(value) + }).then((response) => { + if (response.ok) console.log('Pushed local configuration'); + }); }); export default settings; diff --git a/src/stores/settingsSyncPulled.ts b/src/stores/settingsSyncPulled.ts new file mode 100644 index 00000000..1e9c3333 --- /dev/null +++ b/src/stores/settingsSyncPulled.ts @@ -0,0 +1,5 @@ +import { writable } from 'svelte/store'; + +const settingsSyncPulled = writable<boolean>(false); + +export default settingsSyncPulled; |