import { Chrome, Android, Apple, Windows } from "@styled-icons/boxicons-logos"; import { HelpCircle, Desktop, LogOut } from "@styled-icons/boxicons-regular"; import { Safari, Firefoxbrowser, Microsoftedge, Linux, Macos, Opera, Samsung, } from "@styled-icons/simple-icons"; import relativeTime from "dayjs/plugin/relativeTime"; import { useHistory } from "react-router-dom"; import { API } from "revolt.js"; import { decodeTime } from "ulid"; import styles from "./Panes.module.scss"; import { Text } from "preact-i18n"; import { useContext, useEffect, useState } from "preact/hooks"; import { Button, CategoryButton, LineDivider, Preloader, Tip, } from "@revoltchat/ui"; import { dayjs } from "../../../context/Locale"; import { AppContext } from "../../../context/revoltjs/RevoltClient"; import { modalController } from "../../../controllers/modals/ModalController"; dayjs.extend(relativeTime); export function Sessions() { const client = useContext(AppContext); const deviceId = typeof client.session === "object" ? client.session._id : undefined; const [sessions, setSessions] = useState( undefined, ); const [attemptingDelete, setDelete] = useState([]); const history = useHistory(); function switchPage(to: string) { history.replace(`/settings/${to}`); } useEffect(() => { client.api.get("/auth/session/all").then((data) => { data.sort( (a, b) => (b._id === deviceId ? 1 : 0) - (a._id === deviceId ? 1 : 0), ); setSessions(data); }); }, [client, setSessions, deviceId]); if (typeof sessions === "undefined") { return (
); } function getIcon(session: API.SessionInfo) { const name = session.name; switch (true) { case /firefox/i.test(name): return ; case /chrome/i.test(name): return ; case /safari/i.test(name): return ; case /edge/i.test(name): return ; case /opera/i.test(name): return ; case /samsung/i.test(name): return ; case /desktop/i.test(name): return ; default: return ; } } function getSystemIcon(session: API.SessionInfo) { const name = session.name; switch (true) { case /linux/i.test(name): return ; case /android/i.test(name): return ; case /mac.*os/i.test(name): return ; case /i(Pad)?os/i.test(name): return ; case /windows/i.test(name): return ; default: return null; } } const mapped = sessions.map((session) => { return { ...session, timestamp: decodeTime(session._id), }; }); mapped.sort((a, b) => b.timestamp - a.timestamp); const id = mapped.findIndex((x) => x._id === deviceId); const render = [ mapped[id], ...mapped.slice(0, id), ...mapped.slice(id + 1, mapped.length), ]; return (

{render.map((session) => { const systemIcon = getSystemIcon(session); return (
-1 }> {deviceId === session._id && ( {" "} )}
{getIcon(session)} {systemIcon}
{deviceId !== session._id && ( )}
); })}
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={ "Logs you out of all sessions except this device." }> {" "} switchPage("account")}>
); }