mirror of
https://github.com/p-stream/p-stream.git
synced 2026-01-11 20:10:32 +00:00
add disconnect from account option
This commit is contained in:
parent
006a45a84a
commit
a019f3dab4
3 changed files with 72 additions and 3 deletions
|
|
@ -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. 😿",
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
Loading…
Reference in a new issue