mirror of
https://github.com/cinnyapp/cinny.git
synced 2025-03-19 17:40:02 +01:00
166 lines
5 KiB
TypeScript
166 lines
5 KiB
TypeScript
import React, { useMemo, useState } from 'react';
|
|
import { Avatar, Box, config, Icon, IconButton, Icons, IconSrc, MenuItem, Text } from 'folds';
|
|
import { General } from './General';
|
|
import { PageNav, PageNavContent, PageNavHeader, PageRoot } from '../../components/page';
|
|
import { ScreenSize, useScreenSizeContext } from '../../hooks/useScreenSize';
|
|
import { Account } from './Account';
|
|
import { useUserProfile } from '../../hooks/useUserProfile';
|
|
import { useMatrixClient } from '../../hooks/useMatrixClient';
|
|
import { getMxIdLocalPart, mxcUrlToHttp } from '../../utils/matrix';
|
|
import { useMediaAuthentication } from '../../hooks/useMediaAuthentication';
|
|
import { UserAvatar } from '../../components/user-avatar';
|
|
import { nameInitials } from '../../utils/common';
|
|
|
|
enum SettingsPages {
|
|
GeneralPage,
|
|
AccountPage,
|
|
NotificationPage,
|
|
SessionPage,
|
|
EncryptionPage,
|
|
EmojisStickersPage,
|
|
DeveloperToolsPage,
|
|
AboutPage,
|
|
}
|
|
|
|
type SettingsMenuItem = {
|
|
page: SettingsPages;
|
|
name: string;
|
|
icon: IconSrc;
|
|
};
|
|
|
|
const useSettingsMenuItems = (): SettingsMenuItem[] =>
|
|
useMemo(
|
|
() => [
|
|
{
|
|
page: SettingsPages.GeneralPage,
|
|
name: 'General',
|
|
icon: Icons.Setting,
|
|
},
|
|
{
|
|
page: SettingsPages.AccountPage,
|
|
name: 'Account',
|
|
icon: Icons.User,
|
|
},
|
|
{
|
|
page: SettingsPages.NotificationPage,
|
|
name: 'Notifications',
|
|
icon: Icons.Bell,
|
|
},
|
|
{
|
|
page: SettingsPages.SessionPage,
|
|
name: 'Sessions',
|
|
icon: Icons.Category,
|
|
},
|
|
{
|
|
page: SettingsPages.EncryptionPage,
|
|
name: 'Encryption',
|
|
icon: Icons.ShieldLock,
|
|
},
|
|
{
|
|
page: SettingsPages.EmojisStickersPage,
|
|
name: 'Emojis & Stickers',
|
|
icon: Icons.Smile,
|
|
},
|
|
{
|
|
page: SettingsPages.DeveloperToolsPage,
|
|
name: 'Developer Tools',
|
|
icon: Icons.Terminal,
|
|
},
|
|
{
|
|
page: SettingsPages.AboutPage,
|
|
name: 'About',
|
|
icon: Icons.Info,
|
|
},
|
|
],
|
|
[]
|
|
);
|
|
|
|
type SettingsProps = {
|
|
requestClose: () => void;
|
|
};
|
|
export function Settings({ requestClose }: SettingsProps) {
|
|
const mx = useMatrixClient();
|
|
const useAuthentication = useMediaAuthentication();
|
|
const userId = mx.getUserId()!;
|
|
const profile = useUserProfile(userId);
|
|
const displayName = profile.displayName ?? getMxIdLocalPart(userId) ?? userId;
|
|
const avatarUrl = profile.avatarUrl
|
|
? mxcUrlToHttp(mx, profile.avatarUrl, useAuthentication, 96, 96, 'crop') ?? undefined
|
|
: undefined;
|
|
|
|
const screenSize = useScreenSizeContext();
|
|
const [activePage, setActivePage] = useState<SettingsPages | undefined>(
|
|
screenSize === ScreenSize.Mobile ? undefined : SettingsPages.GeneralPage
|
|
);
|
|
const menuItems = useSettingsMenuItems();
|
|
|
|
const handlePageRequestClose = () => {
|
|
if (screenSize === ScreenSize.Mobile) {
|
|
setActivePage(undefined);
|
|
return;
|
|
}
|
|
requestClose();
|
|
};
|
|
|
|
return (
|
|
<PageRoot
|
|
nav={
|
|
screenSize === ScreenSize.Mobile && activePage !== undefined ? undefined : (
|
|
<PageNav size="300">
|
|
<PageNavHeader outlined={false}>
|
|
<Box grow="Yes" gap="200">
|
|
<Avatar size="200" radii="300">
|
|
<UserAvatar
|
|
userId={userId}
|
|
src={avatarUrl}
|
|
renderFallback={() => <Text size="H6">{nameInitials(displayName)}</Text>}
|
|
/>
|
|
</Avatar>
|
|
<Text size="H4" truncate>
|
|
Settings
|
|
</Text>
|
|
</Box>
|
|
<Box shrink="No">
|
|
{screenSize === ScreenSize.Mobile && (
|
|
<IconButton onClick={requestClose} variant="Background">
|
|
<Icon src={Icons.Cross} />
|
|
</IconButton>
|
|
)}
|
|
</Box>
|
|
</PageNavHeader>
|
|
<PageNavContent>
|
|
<div>
|
|
{menuItems.map((item) => (
|
|
<MenuItem
|
|
variant="Background"
|
|
radii="400"
|
|
aria-pressed={activePage === item.page}
|
|
before={<Icon src={item.icon} size="100" filled={activePage === item.page} />}
|
|
onClick={() => setActivePage(item.page)}
|
|
>
|
|
<Text
|
|
style={{
|
|
fontWeight: activePage === item.page ? config.fontWeight.W600 : undefined,
|
|
}}
|
|
size="T300"
|
|
truncate
|
|
>
|
|
{item.name}
|
|
</Text>
|
|
</MenuItem>
|
|
))}
|
|
</div>
|
|
</PageNavContent>
|
|
</PageNav>
|
|
)
|
|
}
|
|
>
|
|
{activePage === SettingsPages.GeneralPage && (
|
|
<General requestClose={handlePageRequestClose} />
|
|
)}
|
|
{activePage === SettingsPages.AccountPage && (
|
|
<Account requestClose={handlePageRequestClose} />
|
|
)}
|
|
</PageRoot>
|
|
);
|
|
}
|