tutu/src/timelines/ProfileMenuButton.tsx
2025-01-02 21:05:05 +08:00

127 lines
3.2 KiB
TypeScript

import {
Avatar,
ButtonBase,
Divider,
ListItemAvatar,
ListItemIcon,
ListItemText,
MenuItem,
} from "@suid/material";
import { Show, createUniqueId, type ParentComponent } from "solid-js";
import {
Settings as SettingsIcon,
Bookmark as BookmarkIcon,
Star as LikeIcon,
FeaturedPlayList as ListIcon,
} from "@suid/icons-material";
import A from "~platform/A";
import Menu, { createManagedMenuState } from "~material/Menu";
import { createTranslator } from "~platform/i18n";
type StringRes = Record<
"nav.bookmarks" | "nav.likes" | "nav.lists" | "nav.settings",
string
>;
const ProfileMenuButton: ParentComponent<{
profile?: {
account: {
site: string;
inf?: {
displayName: string;
avatar: string;
username: string;
id: string;
};
};
};
}> = (props) => {
const menuId = createUniqueId();
const buttonId = createUniqueId();
const [t] = createTranslator(
async (code) =>
(await import(`./i18n/${code}.json`)) as { default: StringRes },
);
const [open, state] = createManagedMenuState();
const onClick = (event: { currentTarget: HTMLElement }) => {
open(event.currentTarget.getBoundingClientRect());
};
const inf = () => props.profile?.account.inf;
return (
<>
<ButtonBase
aria-haspopup="true"
sx={{ borderRadius: "50%" }}
id={buttonId}
onClick={onClick}
aria-controls={state.open ? menuId : undefined}
aria-expanded={state.open ? "true" : "false"}
>
<Avatar
alt={`${inf()?.displayName}'s avatar`}
src={inf()?.avatar}
></Avatar>
</ButtonBase>
<Menu
id={menuId}
MenuListProps={{
"aria-labelledby": menuId,
style: {
"min-width": "220px",
},
}}
{...state}
>
<MenuItem
component={A}
href={`/${encodeURIComponent(`${inf()?.username}@${props.profile?.account.site}`)}/profile/${inf()?.id}`}
disabled={!props.profile}
>
<ListItemAvatar>
<Avatar src={inf()?.avatar}></Avatar>
</ListItemAvatar>
<ListItemText
primary={inf()?.displayName}
secondary={`@${inf()?.username}`}
></ListItemText>
</MenuItem>
<MenuItem disabled>
<ListItemIcon>
<BookmarkIcon />
</ListItemIcon>
<ListItemText>{t("nav.bookmarks")}</ListItemText>
</MenuItem>
<MenuItem disabled>
<ListItemIcon>
<LikeIcon />
</ListItemIcon>
<ListItemText>{t("nav.likes")}</ListItemText>
</MenuItem>
<MenuItem disabled>
<ListItemIcon>
<ListIcon />
</ListItemIcon>
<ListItemText>{t("nav.lists")}</ListItemText>
</MenuItem>
<Divider />
<Show when={props.children}>
{props.children}
<Divider />
</Show>
<MenuItem component={A} href="/settings">
<ListItemIcon>
<SettingsIcon />
</ListItemIcon>
<ListItemText>{t("nav.settings")}</ListItemText>
</MenuItem>
</Menu>
</>
);
};
export default ProfileMenuButton;