add disconnect from account option

This commit is contained in:
Pas 2025-12-27 21:45:05 -07:00
parent 006a45a84a
commit a019f3dab4
3 changed files with 72 additions and 3 deletions

View file

@ -992,9 +992,14 @@
"loadingUserError": {
"logout": "Logout",
"reset": "Reset custom server",
"disconnect": "Disconnect from backend",
"text": "Failed to load your profile",
"reload": "Reload",
"textWithReset": "Failed to load your profile from your custom server, want to reset back to the default server?"
"textWithReset": "Failed to load your profile from your custom server, want to reset back to the default server?",
"disconnectTitle": "Disconnect from backend?",
"disconnectMessage": "Disconnect from the account server, maintaining the most recent local data. Changes and watched content will not sync until you're signed in again.",
"disconnectConfirm": "Confirm",
"disconectCancel": "Cancel"
},
"migration": {
"failed": "Failed to migrate your data. 😿",

View file

@ -102,6 +102,21 @@ export function useAuth() {
await userDataLogout();
}, [userDataLogout, backendUrl, currentAccount]);
const disconnectFromBackend = useCallback(async () => {
if (!currentAccount || !backendUrl) return;
try {
await removeSession(
backendUrl,
currentAccount.token,
currentAccount.sessionId,
);
} catch {
// we dont care about failing to delete session
}
// Only remove the account, keep all local data
useAuthStore.getState().removeAccount();
}, [backendUrl, currentAccount]);
const register = useCallback(
async (registerData: RegistrationData) => {
if (!backendUrl) return;
@ -215,6 +230,7 @@ export function useAuth() {
profile,
login,
logout,
disconnectFromBackend,
register,
restore,
importData,

View file

@ -4,7 +4,7 @@ import "./stores/__old/imports";
import "@/setup/ga";
import "@/assets/css/index.css";
import { StrictMode, Suspense, useCallback } from "react";
import { StrictMode, Suspense, useCallback, useState } from "react";
import type { ReactNode } from "react";
import { createRoot } from "react-dom/client";
import { HelmetProvider } from "react-helmet-async";
@ -62,15 +62,19 @@ function ErrorScreen(props: {
showResetButton?: boolean;
showLogoutButton?: boolean;
showReloadButton?: boolean;
showDisconnectButton?: boolean;
}) {
const { t } = useTranslation();
const { logout } = useAuth();
const { logout, disconnectFromBackend } = useAuth();
const setBackendUrl = useAuthStore((s) => s.setBackendUrl);
const [showDisconnectConfirm, setShowDisconnectConfirm] = useState(false);
const resetBackend = useCallback(() => {
setBackendUrl(null);
// eslint-disable-next-line no-restricted-globals
location.reload();
}, [setBackendUrl]);
const logoutFromBackend = useCallback(() => {
logout().then(() => {
// eslint-disable-next-line no-restricted-globals
@ -78,6 +82,13 @@ function ErrorScreen(props: {
});
}, [logout]);
const handleDisconnectConfirm = useCallback(() => {
disconnectFromBackend().then(() => {
// eslint-disable-next-line no-restricted-globals
location.reload();
});
}, [disconnectFromBackend]);
return (
<LargeTextPart
iconSlot={
@ -99,6 +110,16 @@ function ErrorScreen(props: {
</Button>
</div>
) : null}
{props.showDisconnectButton ? (
<div className="mt-6">
<Button
theme="secondary"
onClick={() => setShowDisconnectConfirm(true)}
>
{t("screens.loadingUserError.disconnect")}
</Button>
</div>
) : null}
{props.showReloadButton ? (
<div className="mt-6">
<Button theme="secondary" onClick={() => window.location.reload()}>
@ -106,6 +127,31 @@ function ErrorScreen(props: {
</Button>
</div>
) : null}
{/* Disconnect Confirmation Modal */}
{showDisconnectConfirm && (
<div className="fixed inset-0 bg-black/50 flex items-center justify-center z-50">
<div className="bg-modal-background rounded-xl p-8 max-w-md mx-4">
<h2 className="text-white text-xl font-semibold mb-4">
{t("screens.loadingUserError.disconnectTitle")}
</h2>
<p className="text-type-secondary mb-6">
{t("screens.loadingUserError.disconnectMessage")}
</p>
<div className="flex gap-3 justify-end">
<Button
theme="secondary"
onClick={() => setShowDisconnectConfirm(false)}
>
{t("screens.loadingUserError.disconectCancel")}
</Button>
<Button theme="danger" onClick={handleDisconnectConfirm}>
{t("screens.loadingUserError.disconnectConfirm")}
</Button>
</div>
</div>
</div>
)}
</LargeTextPart>
);
}
@ -115,6 +161,7 @@ function AuthWrapper() {
const backendUrl = conf().BACKEND_URL;
const userBackendUrl = useBackendUrl();
const { t } = useTranslation();
const isLoggedIn = !!useAuthStore((s) => s.account);
const isCustomUrl = backendUrl !== userBackendUrl;
@ -124,6 +171,7 @@ function AuthWrapper() {
<ErrorScreen
showResetButton={isCustomUrl}
showLogoutButton={!isCustomUrl}
showDisconnectButton={!isCustomUrl}
showReloadButton={!isCustomUrl}
>
{t(