/* * Copyright (C) Contributors to the Suwayomi project * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ import List from '@mui/material/List'; import ListSubheader from '@mui/material/ListSubheader'; import ListItemText from '@mui/material/ListItemText'; import ListItemButton from '@mui/material/ListItemButton'; import { useLingui } from '@lingui/react/macro'; import { requestManager } from '@/lib/requests/RequestManager.ts'; import { SelectSetting } from '@/base/components/settings/SelectSetting.tsx'; import { NumberSetting } from '@/base/components/settings/NumberSetting.tsx'; import { makeToast } from '@/base/utils/Toast.ts'; import { getErrorMessage, noOp } from '@/lib/HelperFunctions.ts'; import { KoreaderSyncChecksumMethod, KoreaderSyncConflictStrategy, KoSyncStatusPayload, } from '@/lib/graphql/generated/graphql.ts'; import { KOREADER_SYNC_CHECKSUM_METHOD_SELECT_VALUES, KOREADER_SYNC_CONFLICT_STRATEGY_SELECT_VALUES, KOREADER_SYNC_PERCENTAGE_TOLERANCE, } from '@/features/settings/Settings.constants.ts'; import { CredentialsLogin } from '@/base/components/modals/LoginDialog.tsx'; import { ServerSettings as ServerSettingsType, ServerSettings } from '@/features/settings/Settings.types.ts'; import { assertIsDefined } from '@/base/Asserts.ts'; export const KoreaderSyncSettings = ({ settings: { koreaderSyncPercentageTolerance, koreaderSyncStrategyBackward, koreaderSyncStrategyForward, koreaderSyncChecksumMethod, }, serverAddress: currentServerAddress, username: currentUsername, isLoggedIn, updateSetting, }: { settings: ServerSettings; updateSetting: ( setting: Setting, value: ServerSettingsType[Setting], onCompletion?: (success: boolean) => void, ) => Promise; } & Omit) => { const { t } = useLingui(); const handleLogout = async () => { const { data } = await requestManager.koSyncLogout().response; if (data?.logoutKoSyncAccount.status.isLoggedIn) { throw new Error(t`Could not log out from KOReader Sync`); } }; const handleLogin = async (serverAddress: string, username: string, password: string) => { const { data } = await requestManager.koSyncLogin(serverAddress, username, password).response; if (!data?.connectKoSyncAccount.status.isLoggedIn) { throw new Error(data?.connectKoSyncAccount.message ?? t`Unknown`); } }; const handleLoginLogout = async ( initialServerAddress: string = 'https://sync.koreader.rocks/', initialUsername?: string, initialPassword?: string, ) => { const controlled = CredentialsLogin.showControlled( { title: isLoggedIn ? t`Disconnect from KOReader Sync server` : t`Connect to KOReader Sync server`, description: isLoggedIn ? t`Connected as ${initialUsername} to ${initialServerAddress}` : undefined, isLoading: false, isLoggedIn, withServerAddress: true, username: initialUsername, password: initialPassword, serverAddress: initialServerAddress, loginLogout: async (username, password, serverAddress) => { controlled.update({ isLoading: true, loginLogout: noOp }); if (isLoggedIn) { try { await handleLogout(); controlled.submit(); } catch (e) { makeToast(t`Failed to disconnect from KOReader Sync server.`, 'error', getErrorMessage(e)); } return; } try { assertIsDefined(serverAddress); await handleLogin(serverAddress, username, password); controlled.submit(); } catch (e) { makeToast(t`Failed to connect to KOReader Sync server.`, 'error', getErrorMessage(e)); const RETRY_KEY = '__retry__'; const retry = await Promise.race([controlled.promise, Promise.resolve(RETRY_KEY)]); if (retry === RETRY_KEY) { handleLoginLogout(serverAddress, username, password); } } }, }, { id: 'koreader-sync-login-logout' }, ); }; return ( {t`KOReader Sync`} } > handleLoginLogout(currentServerAddress ?? undefined, currentUsername ?? undefined)} > settingName={t`Sync to a newer state`} value={koreaderSyncStrategyForward} values={KOREADER_SYNC_CONFLICT_STRATEGY_SELECT_VALUES} handleChange={(value) => updateSetting('koreaderSyncStrategyForward', value)} /> settingName={t`Sync to an older state`} value={koreaderSyncStrategyBackward} values={KOREADER_SYNC_CONFLICT_STRATEGY_SELECT_VALUES} handleChange={(value) => updateSetting('koreaderSyncStrategyBackward', value)} /> settingName={t`Document matching method`} value={koreaderSyncChecksumMethod} values={KOREADER_SYNC_CHECKSUM_METHOD_SELECT_VALUES} handleChange={(value) => updateSetting('koreaderSyncChecksumMethod', value)} /> updateSetting('koreaderSyncPercentageTolerance', value)} /> ); };