From 374be319c443ec44470ad7c016722ac3240aeda6 Mon Sep 17 00:00:00 2001 From: Paul Makles Date: Sat, 18 Jun 2022 11:56:05 +0100 Subject: [PATCH] feat(modals): port SignedOut and SignOutSessions --- src/context/intermediate/Modals.tsx | 6 --- src/context/modals/components/Changelog.tsx | 2 +- src/context/modals/components/OutOfDate.tsx | 4 ++ .../components/SignOutSessions.tsx} | 32 +++++++------- .../components}/SignedOut.tsx | 15 ++++--- src/context/modals/index.tsx | 4 ++ src/context/modals/types.ts | 8 +++- src/context/revoltjs/RevoltClient.tsx | 3 +- src/pages/settings/panes/Sessions.tsx | 42 +++++++------------ 9 files changed, 60 insertions(+), 56 deletions(-) rename src/context/{intermediate/modals/SessionsPrompt.tsx => modals/components/SignOutSessions.tsx} (54%) rename src/context/{intermediate/modals => modals/components}/SignedOut.tsx (57%) diff --git a/src/context/intermediate/Modals.tsx b/src/context/intermediate/Modals.tsx index 9aab5648..55ecb6f8 100644 --- a/src/context/intermediate/Modals.tsx +++ b/src/context/intermediate/Modals.tsx @@ -8,8 +8,6 @@ import { ExternalLinkModal } from "./modals/ExternalLinkPrompt"; import { InputModal } from "./modals/Input"; import { OnboardingModal } from "./modals/Onboarding"; import { PromptModal } from "./modals/Prompt"; -import { SessionsModal } from "./modals/SessionsPrompt"; -import { SignedOutModal } from "./modals/SignedOut"; import { TokenRevealModal } from "./modals/TokenReveal"; export interface Props { @@ -30,8 +28,6 @@ export default function Modals({ screen, openScreen }: Props) { return ; case "error": return ; - case "signed_out": - return ; case "clipboard": return ; case "token_reveal": @@ -40,8 +36,6 @@ export default function Modals({ screen, openScreen }: Props) { return ; case "external_link_prompt": return ; - case "sessions": - return ; } return null; diff --git a/src/context/modals/components/Changelog.tsx b/src/context/modals/components/Changelog.tsx index fd6c0498..217ba109 100644 --- a/src/context/modals/components/Changelog.tsx +++ b/src/context/modals/components/Changelog.tsx @@ -35,7 +35,7 @@ function RenderLog({ post }: { post: ChangelogPost }) { } /** - * Changelog rendering modal + * Changelog modal */ export default function Changelog({ initial, diff --git a/src/context/modals/components/OutOfDate.tsx b/src/context/modals/components/OutOfDate.tsx index 6368e56e..fbbd58fa 100644 --- a/src/context/modals/components/OutOfDate.tsx +++ b/src/context/modals/components/OutOfDate.tsx @@ -7,6 +7,10 @@ import { noop, noopTrue } from "../../../lib/js"; import { APP_VERSION } from "../../../version"; import { ModalProps } from "../types"; +/** + * Out-of-date indicator which instructs users + * that their client needs to be updated + */ export default function OutOfDate({ onClose, version, diff --git a/src/context/intermediate/modals/SessionsPrompt.tsx b/src/context/modals/components/SignOutSessions.tsx similarity index 54% rename from src/context/intermediate/modals/SessionsPrompt.tsx rename to src/context/modals/components/SignOutSessions.tsx index b4df37d8..46afff05 100644 --- a/src/context/intermediate/modals/SessionsPrompt.tsx +++ b/src/context/modals/components/SignOutSessions.tsx @@ -1,31 +1,35 @@ import { Text } from "preact-i18n"; +import { useCallback } from "preact/hooks"; import { Modal } from "@revoltchat/ui"; -interface Props { - onClose: () => void; - confirm: () => void; -} +import { noopTrue } from "../../../lib/js"; + +import { ModalProps } from "../types"; + +/** + * Confirm whether a user wants to sign out of all other sessions + */ +export function SignOutSessions(props: ModalProps<"sign_out_sessions">) { + const onClick = useCallback(() => { + props.onDeleting(); + props.client.api.delete("/auth/session/all").then(props.onDelete); + return true; + }, []); -export function SessionsModal({ onClose, confirm }: Props) { return ( } actions={[ { - onClick: () => { - onClose(); - }, - confirmation: true, + onClick: noopTrue, palette: "accent", + confirmation: true, children: , }, { - onClick: () => { - confirm(); - onClose(); - }, + onClick, confirmation: true, children: , }, diff --git a/src/context/intermediate/modals/SignedOut.tsx b/src/context/modals/components/SignedOut.tsx similarity index 57% rename from src/context/intermediate/modals/SignedOut.tsx rename to src/context/modals/components/SignedOut.tsx index 24f54c3f..21c702e5 100644 --- a/src/context/intermediate/modals/SignedOut.tsx +++ b/src/context/modals/components/SignedOut.tsx @@ -2,18 +2,21 @@ import { Text } from "preact-i18n"; import { Modal } from "@revoltchat/ui"; -interface Props { - onClose: () => void; -} +import { noopTrue } from "../../../lib/js"; -export function SignedOutModal({ onClose }: Props) { +import { ModalProps } from "../types"; + +/** + * Indicate that the user has been signed out of their account + */ +export function SignedOut(props: ModalProps<"signed_out">) { return ( } actions={[ { - onClick: onClose, + onClick: noopTrue, confirmation: true, children: , }, diff --git a/src/context/modals/index.tsx b/src/context/modals/index.tsx index 61bc3e01..df66918e 100644 --- a/src/context/modals/index.tsx +++ b/src/context/modals/index.tsx @@ -13,6 +13,8 @@ import MFAEnableTOTP from "./components/MFAEnableTOTP"; import MFAFlow from "./components/MFAFlow"; import MFARecovery from "./components/MFARecovery"; import OutOfDate from "./components/OutOfDate"; +import { SignOutSessions } from "./components/SignOutSessions"; +import { SignedOut } from "./components/SignedOut"; import Test from "./components/Test"; import { Modal } from "./types"; @@ -142,5 +144,7 @@ export const modalController = new ModalControllerExtended({ mfa_recovery: MFARecovery, mfa_enable_totp: MFAEnableTOTP, out_of_date: OutOfDate, + signed_out: SignedOut, + sign_out_sessions: SignOutSessions, test: Test, }); diff --git a/src/context/modals/types.ts b/src/context/modals/types.ts index be3127af..24efb49c 100644 --- a/src/context/modals/types.ts +++ b/src/context/modals/types.ts @@ -33,7 +33,13 @@ export type Modal = { initial?: number; } | { - type: "test"; + client: Client; + onDelete: () => void; + onDeleting: () => void; + type: "sign_out_sessions"; + } + | { + type: "test" | "signed_out"; } ); diff --git a/src/context/revoltjs/RevoltClient.tsx b/src/context/revoltjs/RevoltClient.tsx index cfb5d4fe..c24915fc 100644 --- a/src/context/revoltjs/RevoltClient.tsx +++ b/src/context/revoltjs/RevoltClient.tsx @@ -10,6 +10,7 @@ import { Preloader } from "@revoltchat/ui"; import { useApplicationState } from "../../mobx/State"; import { useIntermediate } from "../intermediate/Intermediate"; +import { modalController } from "../modals"; import { registerEvents } from "./events"; import { takeError } from "./util"; @@ -68,7 +69,7 @@ export default observer(({ children }: Props) => { const error = takeError(err); if (error === "Forbidden" || error === "Unauthorized") { client.logout(true); - openScreen({ id: "signed_out" }); + modalController.push({ type: "signed_out" }); } else { setStatus(ClientStatus.DISCONNECTED); openScreen({ id: "error", error }); diff --git a/src/pages/settings/panes/Sessions.tsx b/src/pages/settings/panes/Sessions.tsx index e2233608..73e39bc3 100644 --- a/src/pages/settings/panes/Sessions.tsx +++ b/src/pages/settings/panes/Sessions.tsx @@ -27,7 +27,7 @@ import { } from "@revoltchat/ui"; import { dayjs } from "../../../context/Locale"; -import { useIntermediate } from "../../../context/intermediate/Intermediate"; +import { modalController } from "../../../context/modals"; import { AppContext } from "../../../context/revoltjs/RevoltClient"; dayjs.extend(relativeTime); @@ -43,8 +43,6 @@ export function Sessions() { const [attemptingDelete, setDelete] = useState([]); const history = useHistory(); - const { openScreen } = useIntermediate(); - function switchPage(to: string) { history.replace(`/settings/${to}`); } @@ -217,32 +215,22 @@ export function Sessions() { })}
{ - openScreen({ - id: "sessions", - confirm: async () => { - // ! FIXME: add to rAuth - const del: string[] = []; - render.forEach((session) => { - if (deviceId !== session._id) { - del.push(session._id); - } - }); - - setDelete(del); - - for (const id of del) { - await client.api.delete( - `/auth/session/${id as ""}`, - ); - } - + onClick={async () => + modalController.push({ + type: "sign_out_sessions", + client, + onDeleting: () => + setDelete( + render + .filter((x) => x._id !== deviceId) + .map((x) => x._id), + ), + onDelete: () => setSessions( sessions.filter((x) => x._id === deviceId), - ); - }, - }); - }} + ), + }) + } icon={} action={"chevron"} description={