import { useState } from "react"; import * as React from "react"; import { useNavigate } from "react-router-dom"; import { useTranslation } from "react-i18next"; import classNames from "classnames"; import { convertI18nText, I18nText, UiLogicError } from "@/common"; import { useUser, userService } from "@/services/user"; import { getHttpUserClient } from "@/http/user"; import { TimelineVisibility } from "@/http/timeline"; import ConfirmDialog from "../common/dialog/ConfirmDialog"; import Card from "../common/Card"; import Spinner from "../common/Spinner"; import ChangePasswordDialog from "./ChangePasswordDialog"; import ChangeAvatarDialog from "./ChangeAvatarDialog"; import ChangeNicknameDialog from "./ChangeNicknameDialog"; import "./index.css"; import { pushAlert } from "@/services/alert"; interface SettingSectionProps { title: I18nText; children: React.ReactNode; } const SettingSection: React.FC = ({ title, children }) => { const { t } = useTranslation(); return (

{convertI18nText(title, t)}

{children}
); }; interface SettingItemContainerWithoutChildrenProps { title: I18nText; subtext?: I18nText; first?: boolean; danger?: boolean; style?: React.CSSProperties; className?: string; onClick?: () => void; } interface SettingItemContainerProps extends SettingItemContainerWithoutChildrenProps { children?: React.ReactNode; } function SettingItemContainer({ title, subtext, first, danger, children, style, className, onClick, }: SettingItemContainerProps): JSX.Element { const { t } = useTranslation(); return (
{convertI18nText(title, t)}
{convertI18nText(subtext, t)}
{children}
); } type ButtonSettingItemProps = SettingItemContainerWithoutChildrenProps; const ButtonSettingItem: React.FC = ({ ...props }) => { return ; }; interface SelectSettingItemProps extends SettingItemContainerWithoutChildrenProps { options: { value: string; label: I18nText; }[]; value?: string; onSelect: (value: string) => void; } const SelectSettingsItem: React.FC = ({ options, value, onSelect, ...props }) => { const { t } = useTranslation(); return ( {value == null ? ( ) : ( )} ); }; const SettingsPage: React.FC = () => { const { i18n } = useTranslation(); const user = useUser(); const navigate = useNavigate(); const [dialog, setDialog] = useState< | null | "changepassword" | "changeavatar" | "changenickname" | "logout" | "renewregistercode" >(null); const [registerCode, setRegisterCode] = useState( undefined, ); const [bookmarkVisibility, setBookmarkVisibility] = useState(); React.useEffect(() => { if (user != null) { void getHttpUserClient() .getBookmarkVisibility(user.username) .then(({ visibility }) => { setBookmarkVisibility(visibility); }); } else { setBookmarkVisibility(undefined); } }, [user]); React.useEffect(() => { setRegisterCode(undefined); }, [user]); React.useEffect(() => { if (user != null && registerCode === undefined) { void getHttpUserClient() .getRegisterCode(user.username) .then((code) => { setRegisterCode(code.registerCode ?? null); }); } }, [user, registerCode]); const language = i18n.language.slice(0, 2); return ( <>
{user ? ( setDialog("renewregistercode")} > {registerCode === undefined ? ( ) : registerCode === null ? ( Noop ) : ( { void navigator.clipboard .writeText(registerCode) .then(() => { pushAlert({ type: "success", message: "settings.myRegisterCodeCopied", }); }); event.stopPropagation(); }} > {registerCode} )} setDialog("changeavatar")} first /> setDialog("changenickname")} /> { void getHttpUserClient() .putBookmarkVisibility(user.username, { visibility: value as TimelineVisibility, }) .then(() => { setBookmarkVisibility(value as TimelineVisibility); }); }} /> setDialog("changepassword")} danger /> { setDialog("logout"); }} danger /> ) : null} { void i18n.changeLanguage(value); }} first />
setDialog(null)} /> setDialog(null)} open={dialog === "logout"} onConfirm={() => { void userService.logout().then(() => { navigate("/"); }); }} /> setDialog(null)} open={dialog === "renewregistercode"} onConfirm={() => { if (user == null) throw new UiLogicError(); void getHttpUserClient() .renewRegisterCode(user.username) .then(() => { setRegisterCode(undefined); }); }} /> setDialog(null)} /> setDialog(null)} /> ); }; export default SettingsPage;