mirror of
https://github.com/p-stream/p-stream.git
synced 2026-05-10 02:11:04 +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": {
|
"loadingUserError": {
|
||||||
"logout": "Logout",
|
"logout": "Logout",
|
||||||
"reset": "Reset custom server",
|
"reset": "Reset custom server",
|
||||||
|
"disconnect": "Disconnect from backend",
|
||||||
"text": "Failed to load your profile",
|
"text": "Failed to load your profile",
|
||||||
"reload": "Reload",
|
"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": {
|
"migration": {
|
||||||
"failed": "Failed to migrate your data. 😿",
|
"failed": "Failed to migrate your data. 😿",
|
||||||
|
|
|
||||||
|
|
@ -102,6 +102,21 @@ export function useAuth() {
|
||||||
await userDataLogout();
|
await userDataLogout();
|
||||||
}, [userDataLogout, backendUrl, currentAccount]);
|
}, [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(
|
const register = useCallback(
|
||||||
async (registerData: RegistrationData) => {
|
async (registerData: RegistrationData) => {
|
||||||
if (!backendUrl) return;
|
if (!backendUrl) return;
|
||||||
|
|
@ -215,6 +230,7 @@ export function useAuth() {
|
||||||
profile,
|
profile,
|
||||||
login,
|
login,
|
||||||
logout,
|
logout,
|
||||||
|
disconnectFromBackend,
|
||||||
register,
|
register,
|
||||||
restore,
|
restore,
|
||||||
importData,
|
importData,
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import "./stores/__old/imports";
|
||||||
import "@/setup/ga";
|
import "@/setup/ga";
|
||||||
import "@/assets/css/index.css";
|
import "@/assets/css/index.css";
|
||||||
|
|
||||||
import { StrictMode, Suspense, useCallback } from "react";
|
import { StrictMode, Suspense, useCallback, useState } from "react";
|
||||||
import type { ReactNode } from "react";
|
import type { ReactNode } from "react";
|
||||||
import { createRoot } from "react-dom/client";
|
import { createRoot } from "react-dom/client";
|
||||||
import { HelmetProvider } from "react-helmet-async";
|
import { HelmetProvider } from "react-helmet-async";
|
||||||
|
|
@ -62,15 +62,19 @@ function ErrorScreen(props: {
|
||||||
showResetButton?: boolean;
|
showResetButton?: boolean;
|
||||||
showLogoutButton?: boolean;
|
showLogoutButton?: boolean;
|
||||||
showReloadButton?: boolean;
|
showReloadButton?: boolean;
|
||||||
|
showDisconnectButton?: boolean;
|
||||||
}) {
|
}) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { logout } = useAuth();
|
const { logout, disconnectFromBackend } = useAuth();
|
||||||
const setBackendUrl = useAuthStore((s) => s.setBackendUrl);
|
const setBackendUrl = useAuthStore((s) => s.setBackendUrl);
|
||||||
|
const [showDisconnectConfirm, setShowDisconnectConfirm] = useState(false);
|
||||||
|
|
||||||
const resetBackend = useCallback(() => {
|
const resetBackend = useCallback(() => {
|
||||||
setBackendUrl(null);
|
setBackendUrl(null);
|
||||||
// eslint-disable-next-line no-restricted-globals
|
// eslint-disable-next-line no-restricted-globals
|
||||||
location.reload();
|
location.reload();
|
||||||
}, [setBackendUrl]);
|
}, [setBackendUrl]);
|
||||||
|
|
||||||
const logoutFromBackend = useCallback(() => {
|
const logoutFromBackend = useCallback(() => {
|
||||||
logout().then(() => {
|
logout().then(() => {
|
||||||
// eslint-disable-next-line no-restricted-globals
|
// eslint-disable-next-line no-restricted-globals
|
||||||
|
|
@ -78,6 +82,13 @@ function ErrorScreen(props: {
|
||||||
});
|
});
|
||||||
}, [logout]);
|
}, [logout]);
|
||||||
|
|
||||||
|
const handleDisconnectConfirm = useCallback(() => {
|
||||||
|
disconnectFromBackend().then(() => {
|
||||||
|
// eslint-disable-next-line no-restricted-globals
|
||||||
|
location.reload();
|
||||||
|
});
|
||||||
|
}, [disconnectFromBackend]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<LargeTextPart
|
<LargeTextPart
|
||||||
iconSlot={
|
iconSlot={
|
||||||
|
|
@ -99,6 +110,16 @@ function ErrorScreen(props: {
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
) : null}
|
) : null}
|
||||||
|
{props.showDisconnectButton ? (
|
||||||
|
<div className="mt-6">
|
||||||
|
<Button
|
||||||
|
theme="secondary"
|
||||||
|
onClick={() => setShowDisconnectConfirm(true)}
|
||||||
|
>
|
||||||
|
{t("screens.loadingUserError.disconnect")}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
{props.showReloadButton ? (
|
{props.showReloadButton ? (
|
||||||
<div className="mt-6">
|
<div className="mt-6">
|
||||||
<Button theme="secondary" onClick={() => window.location.reload()}>
|
<Button theme="secondary" onClick={() => window.location.reload()}>
|
||||||
|
|
@ -106,6 +127,31 @@ function ErrorScreen(props: {
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
) : null}
|
) : 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>
|
</LargeTextPart>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -115,6 +161,7 @@ function AuthWrapper() {
|
||||||
const backendUrl = conf().BACKEND_URL;
|
const backendUrl = conf().BACKEND_URL;
|
||||||
const userBackendUrl = useBackendUrl();
|
const userBackendUrl = useBackendUrl();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
const isLoggedIn = !!useAuthStore((s) => s.account);
|
||||||
|
|
||||||
const isCustomUrl = backendUrl !== userBackendUrl;
|
const isCustomUrl = backendUrl !== userBackendUrl;
|
||||||
|
|
||||||
|
|
@ -124,6 +171,7 @@ function AuthWrapper() {
|
||||||
<ErrorScreen
|
<ErrorScreen
|
||||||
showResetButton={isCustomUrl}
|
showResetButton={isCustomUrl}
|
||||||
showLogoutButton={!isCustomUrl}
|
showLogoutButton={!isCustomUrl}
|
||||||
|
showDisconnectButton={!isCustomUrl}
|
||||||
showReloadButton={!isCustomUrl}
|
showReloadButton={!isCustomUrl}
|
||||||
>
|
>
|
||||||
{t(
|
{t(
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue