aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorFuwn <[email protected]>2024-02-12 08:55:11 -0800
committerFuwn <[email protected]>2024-02-12 08:55:11 -0800
commit0fbeaaf6237b62d5220da0418d05cae4487f29bf (patch)
tree036ea9187a07d860e0d65373a8ee5a3137b758f5 /src
parentfix(anime): new list on new episode (diff)
downloaddue.moe-0fbeaaf6237b62d5220da0418d05cae4487f29bf.tar.xz
due.moe-0fbeaaf6237b62d5220da0418d05cae4487f29bf.zip
feat(settings): settings sync
Diffstat (limited to 'src')
-rw-r--r--src/lib/Database/userConfiguration.ts19
-rw-r--r--src/routes/+layout.svelte13
-rw-r--r--src/routes/api/configuration/+server.ts33
-rw-r--r--src/routes/settings/+page.svelte52
-rw-r--r--src/stores/settings.ts18
-rw-r--r--src/stores/settingsSyncPulled.ts5
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 &amp; {$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;