import { useState, ReactNode } from "react";
import { useNavigate } from "react-router-dom";
import { useTranslation } from "react-i18next";
import classNames from "classnames";
import { useC, I18nText } 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: ReactNode;
}
function SettingSection({ title, children }: SettingSectionProps) {
const c = useC();
return (
{c(title)}
{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;