127 lines
3.2 KiB
TypeScript
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;
|