mirror of
https://github.com/cinnyapp/cinny.git
synced 2025-11-04 22:40:29 +03:00
Use a common CollapsibleCard element for collapsible settings cards
This commit is contained in:
parent
af9460ef8b
commit
d42bcc6e3d
7 changed files with 322 additions and 390 deletions
|
|
@ -195,8 +195,8 @@ function AccountDataEdit({
|
||||||
type AccountDataViewProps = {
|
type AccountDataViewProps = {
|
||||||
type: string;
|
type: string;
|
||||||
defaultContent: string;
|
defaultContent: string;
|
||||||
onEdit: () => void;
|
|
||||||
requestClose: () => void;
|
requestClose: () => void;
|
||||||
|
onEdit?: () => void;
|
||||||
submitDelete?: AccountDataDeleteCallback;
|
submitDelete?: AccountDataDeleteCallback;
|
||||||
};
|
};
|
||||||
function AccountDataView({ type, defaultContent, onEdit, requestClose, submitDelete }: AccountDataViewProps) {
|
function AccountDataView({ type, defaultContent, onEdit, requestClose, submitDelete }: AccountDataViewProps) {
|
||||||
|
|
@ -231,9 +231,11 @@ function AccountDataView({ type, defaultContent, onEdit, requestClose, submitDel
|
||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
<Button variant="Secondary" size="400" radii="300" onClick={onEdit}>
|
{onEdit && (
|
||||||
<Text size="B400">Edit</Text>
|
<Button variant="Secondary" size="400" radii="300" onClick={onEdit}>
|
||||||
</Button>
|
<Text size="B400">Edit</Text>
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
{submitDelete && (
|
{submitDelete && (
|
||||||
<Button
|
<Button
|
||||||
variant="Critical"
|
variant="Critical"
|
||||||
|
|
@ -269,7 +271,7 @@ function AccountDataView({ type, defaultContent, onEdit, requestClose, submitDel
|
||||||
export type AccountDataEditorProps = {
|
export type AccountDataEditorProps = {
|
||||||
type?: string;
|
type?: string;
|
||||||
content?: unknown;
|
content?: unknown;
|
||||||
submitChange: AccountDataSubmitCallback;
|
submitChange?: AccountDataSubmitCallback;
|
||||||
submitDelete?: AccountDataDeleteCallback;
|
submitDelete?: AccountDataDeleteCallback;
|
||||||
requestClose: () => void;
|
requestClose: () => void;
|
||||||
};
|
};
|
||||||
|
|
@ -328,7 +330,7 @@ export function AccountDataEditor({
|
||||||
</Box>
|
</Box>
|
||||||
</PageHeader>
|
</PageHeader>
|
||||||
<Box grow="Yes" direction="Column">
|
<Box grow="Yes" direction="Column">
|
||||||
{edit ? (
|
{(edit && submitChange) ? (
|
||||||
<AccountDataEdit
|
<AccountDataEdit
|
||||||
type={data.type}
|
type={data.type}
|
||||||
defaultContent={contentJSONStr}
|
defaultContent={contentJSONStr}
|
||||||
|
|
@ -340,8 +342,8 @@ export function AccountDataEditor({
|
||||||
<AccountDataView
|
<AccountDataView
|
||||||
type={data.type}
|
type={data.type}
|
||||||
defaultContent={contentJSONStr}
|
defaultContent={contentJSONStr}
|
||||||
onEdit={() => setEdit(true)}
|
|
||||||
requestClose={requestClose}
|
requestClose={requestClose}
|
||||||
|
onEdit={submitChange ? () => setEdit(true) : undefined}
|
||||||
submitDelete={submitDelete}
|
submitDelete={submitDelete}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
|
||||||
54
src/app/components/CollapsibleCard.tsx
Normal file
54
src/app/components/CollapsibleCard.tsx
Normal file
|
|
@ -0,0 +1,54 @@
|
||||||
|
import React, { ReactNode } from 'react';
|
||||||
|
import { Button, Icon, Icons, Text } from 'folds';
|
||||||
|
import { SequenceCard } from './sequence-card';
|
||||||
|
import { SequenceCardStyle } from '../features/settings/styles.css';
|
||||||
|
import { SettingTile } from './setting-tile';
|
||||||
|
|
||||||
|
type CollapsibleCardProps = {
|
||||||
|
expand: boolean;
|
||||||
|
setExpand: (expand: boolean) => void;
|
||||||
|
title?: ReactNode;
|
||||||
|
description?: ReactNode;
|
||||||
|
before?: ReactNode;
|
||||||
|
children?: ReactNode;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function CollapsibleCard({
|
||||||
|
expand,
|
||||||
|
setExpand,
|
||||||
|
title,
|
||||||
|
description,
|
||||||
|
before,
|
||||||
|
children,
|
||||||
|
}: CollapsibleCardProps) {
|
||||||
|
return (
|
||||||
|
<SequenceCard
|
||||||
|
className={SequenceCardStyle}
|
||||||
|
variant="SurfaceVariant"
|
||||||
|
direction="Column"
|
||||||
|
gap="400"
|
||||||
|
>
|
||||||
|
<SettingTile
|
||||||
|
title={title}
|
||||||
|
description={description}
|
||||||
|
before={before}
|
||||||
|
after={
|
||||||
|
<Button
|
||||||
|
onClick={() => setExpand(!expand)}
|
||||||
|
variant="Secondary"
|
||||||
|
fill="Soft"
|
||||||
|
size="300"
|
||||||
|
radii="300"
|
||||||
|
outlined
|
||||||
|
before={
|
||||||
|
<Icon src={expand ? Icons.ChevronTop : Icons.ChevronBottom} size="100" filled />
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Text size="B300">{expand ? 'Collapse' : 'Expand'}</Text>
|
||||||
|
</Button>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
{expand && children}
|
||||||
|
</SequenceCard>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -30,6 +30,7 @@ import {
|
||||||
AccountDataSubmitCallback,
|
AccountDataSubmitCallback,
|
||||||
} from '../../../components/AccountDataEditor';
|
} from '../../../components/AccountDataEditor';
|
||||||
import { useMatrixClient } from '../../../hooks/useMatrixClient';
|
import { useMatrixClient } from '../../../hooks/useMatrixClient';
|
||||||
|
import { CollapsibleCard } from '../../../components/CollapsibleCard';
|
||||||
|
|
||||||
type DeveloperToolsProps = {
|
type DeveloperToolsProps = {
|
||||||
requestClose: () => void;
|
requestClose: () => void;
|
||||||
|
|
@ -175,216 +176,166 @@ export function DeveloperTools({ requestClose }: DeveloperToolsProps) {
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</SequenceCard>
|
</SequenceCard>
|
||||||
<SequenceCard
|
<CollapsibleCard
|
||||||
className={SequenceCardStyle}
|
expand={expandState}
|
||||||
variant="SurfaceVariant"
|
setExpand={setExpandState}
|
||||||
direction="Column"
|
title="Room State"
|
||||||
gap="400"
|
description="State events of the room."
|
||||||
>
|
>
|
||||||
<SettingTile
|
<Box direction="Column" gap="100">
|
||||||
title="Room State"
|
<Box justifyContent="SpaceBetween">
|
||||||
description="State events of the room."
|
<Text size="L400">Events</Text>
|
||||||
after={
|
<Text size="L400">Total: {roomState.size}</Text>
|
||||||
<Button
|
</Box>
|
||||||
onClick={() => setExpandState(!expandState)}
|
<CutoutCard>
|
||||||
variant="Secondary"
|
<MenuItem
|
||||||
fill="Soft"
|
onClick={() => setComposeEvent({ stateKey: '' })}
|
||||||
|
variant="Surface"
|
||||||
|
fill="None"
|
||||||
size="300"
|
size="300"
|
||||||
radii="300"
|
radii="0"
|
||||||
outlined
|
before={<Icon size="50" src={Icons.Plus} />}
|
||||||
before={
|
|
||||||
<Icon
|
|
||||||
src={expandState ? Icons.ChevronTop : Icons.ChevronBottom}
|
|
||||||
size="100"
|
|
||||||
filled
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
>
|
>
|
||||||
<Text size="B300">{expandState ? 'Collapse' : 'Expand'}</Text>
|
<Box grow="Yes">
|
||||||
</Button>
|
<Text size="T200" truncate>
|
||||||
}
|
Add New
|
||||||
/>
|
</Text>
|
||||||
{expandState && (
|
</Box>
|
||||||
<Box direction="Column" gap="100">
|
</MenuItem>
|
||||||
<Box justifyContent="SpaceBetween">
|
{Array.from(roomState.keys())
|
||||||
<Text size="L400">Events</Text>
|
.sort()
|
||||||
<Text size="L400">Total: {roomState.size}</Text>
|
.map((eventType) => {
|
||||||
</Box>
|
const expanded = eventType === expandStateType;
|
||||||
<CutoutCard>
|
const stateKeyToEvents = roomState.get(eventType);
|
||||||
<MenuItem
|
if (!stateKeyToEvents) return null;
|
||||||
onClick={() => setComposeEvent({ stateKey: '' })}
|
|
||||||
variant="Surface"
|
|
||||||
fill="None"
|
|
||||||
size="300"
|
|
||||||
radii="0"
|
|
||||||
before={<Icon size="50" src={Icons.Plus} />}
|
|
||||||
>
|
|
||||||
<Box grow="Yes">
|
|
||||||
<Text size="T200" truncate>
|
|
||||||
Add New
|
|
||||||
</Text>
|
|
||||||
</Box>
|
|
||||||
</MenuItem>
|
|
||||||
{Array.from(roomState.keys())
|
|
||||||
.sort()
|
|
||||||
.map((eventType) => {
|
|
||||||
const expanded = eventType === expandStateType;
|
|
||||||
const stateKeyToEvents = roomState.get(eventType);
|
|
||||||
if (!stateKeyToEvents) return null;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box id={eventType} key={eventType} direction="Column" gap="100">
|
<Box id={eventType} key={eventType} direction="Column" gap="100">
|
||||||
<MenuItem
|
<MenuItem
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
setExpandStateType(expanded ? undefined : eventType)
|
setExpandStateType(expanded ? undefined : eventType)
|
||||||
}
|
}
|
||||||
variant="Surface"
|
variant="Surface"
|
||||||
fill="None"
|
fill="None"
|
||||||
size="300"
|
size="300"
|
||||||
radii="0"
|
radii="0"
|
||||||
before={
|
before={
|
||||||
<Icon
|
<Icon
|
||||||
size="50"
|
size="50"
|
||||||
src={expanded ? Icons.ChevronBottom : Icons.ChevronRight}
|
src={expanded ? Icons.ChevronBottom : Icons.ChevronRight}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
after={<Text size="L400">{stateKeyToEvents.size}</Text>}
|
after={<Text size="L400">{stateKeyToEvents.size}</Text>}
|
||||||
|
>
|
||||||
|
<Box grow="Yes">
|
||||||
|
<Text size="T200" truncate>
|
||||||
|
{eventType}
|
||||||
|
</Text>
|
||||||
|
</Box>
|
||||||
|
</MenuItem>
|
||||||
|
{expanded && (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
marginLeft: config.space.S400,
|
||||||
|
borderLeft: `${config.borderWidth.B300} solid ${color.Surface.ContainerLine}`,
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<Box grow="Yes">
|
<MenuItem
|
||||||
<Text size="T200" truncate>
|
onClick={() =>
|
||||||
{eventType}
|
setComposeEvent({ type: eventType, stateKey: '' })
|
||||||
</Text>
|
}
|
||||||
</Box>
|
variant="Surface"
|
||||||
</MenuItem>
|
fill="None"
|
||||||
{expanded && (
|
size="300"
|
||||||
<div
|
radii="0"
|
||||||
style={{
|
before={<Icon size="50" src={Icons.Plus} />}
|
||||||
marginLeft: config.space.S400,
|
|
||||||
borderLeft: `${config.borderWidth.B300} solid ${color.Surface.ContainerLine}`,
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<MenuItem
|
<Box grow="Yes">
|
||||||
onClick={() =>
|
<Text size="T200" truncate>
|
||||||
setComposeEvent({ type: eventType, stateKey: '' })
|
Add New
|
||||||
}
|
</Text>
|
||||||
variant="Surface"
|
</Box>
|
||||||
fill="None"
|
</MenuItem>
|
||||||
size="300"
|
{Array.from(stateKeyToEvents.keys())
|
||||||
radii="0"
|
.sort()
|
||||||
before={<Icon size="50" src={Icons.Plus} />}
|
.map((stateKey) => (
|
||||||
>
|
<MenuItem
|
||||||
<Box grow="Yes">
|
onClick={() => {
|
||||||
<Text size="T200" truncate>
|
setOpenStateEvent({
|
||||||
Add New
|
type: eventType,
|
||||||
</Text>
|
stateKey,
|
||||||
</Box>
|
});
|
||||||
</MenuItem>
|
}}
|
||||||
{Array.from(stateKeyToEvents.keys())
|
key={stateKey}
|
||||||
.sort()
|
variant="Surface"
|
||||||
.map((stateKey) => (
|
fill="None"
|
||||||
<MenuItem
|
size="300"
|
||||||
onClick={() => {
|
radii="0"
|
||||||
setOpenStateEvent({
|
after={<Icon size="50" src={Icons.ChevronRight} />}
|
||||||
type: eventType,
|
>
|
||||||
stateKey,
|
<Box grow="Yes">
|
||||||
});
|
<Text size="T200" truncate>
|
||||||
}}
|
{stateKey ? `"${stateKey}"` : 'Default'}
|
||||||
key={stateKey}
|
</Text>
|
||||||
variant="Surface"
|
</Box>
|
||||||
fill="None"
|
</MenuItem>
|
||||||
size="300"
|
))}
|
||||||
radii="0"
|
</div>
|
||||||
after={<Icon size="50" src={Icons.ChevronRight} />}
|
)}
|
||||||
>
|
</Box>
|
||||||
<Box grow="Yes">
|
);
|
||||||
<Text size="T200" truncate>
|
})}
|
||||||
{stateKey ? `"${stateKey}"` : 'Default'}
|
</CutoutCard>
|
||||||
</Text>
|
</Box>
|
||||||
</Box>
|
</CollapsibleCard>
|
||||||
</MenuItem>
|
<CollapsibleCard
|
||||||
))}
|
expand={expandAccountData}
|
||||||
</div>
|
setExpand={setExpandAccountData}
|
||||||
)}
|
title="Account Data"
|
||||||
</Box>
|
description="Private personalization data stored within room"
|
||||||
);
|
|
||||||
})}
|
|
||||||
</CutoutCard>
|
|
||||||
</Box>
|
|
||||||
)}
|
|
||||||
</SequenceCard>
|
|
||||||
<SequenceCard
|
|
||||||
className={SequenceCardStyle}
|
|
||||||
variant="SurfaceVariant"
|
|
||||||
direction="Column"
|
|
||||||
gap="400"
|
|
||||||
>
|
>
|
||||||
<SettingTile
|
<Box direction="Column" gap="100">
|
||||||
title="Account Data"
|
<Box justifyContent="SpaceBetween">
|
||||||
description="Private personalization data stored within room."
|
<Text size="L400">Events</Text>
|
||||||
after={
|
<Text size="L400">Total: {accountData.size}</Text>
|
||||||
<Button
|
|
||||||
onClick={() => setExpandAccountData(!expandAccountData)}
|
|
||||||
variant="Secondary"
|
|
||||||
fill="Soft"
|
|
||||||
size="300"
|
|
||||||
radii="300"
|
|
||||||
outlined
|
|
||||||
before={
|
|
||||||
<Icon
|
|
||||||
src={expandAccountData ? Icons.ChevronTop : Icons.ChevronBottom}
|
|
||||||
size="100"
|
|
||||||
filled
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<Text size="B300">{expandAccountData ? 'Collapse' : 'Expand'}</Text>
|
|
||||||
</Button>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
{expandAccountData && (
|
|
||||||
<Box direction="Column" gap="100">
|
|
||||||
<Box justifyContent="SpaceBetween">
|
|
||||||
<Text size="L400">Events</Text>
|
|
||||||
<Text size="L400">Total: {accountData.size}</Text>
|
|
||||||
</Box>
|
|
||||||
<CutoutCard>
|
|
||||||
<MenuItem
|
|
||||||
variant="Surface"
|
|
||||||
fill="None"
|
|
||||||
size="300"
|
|
||||||
radii="0"
|
|
||||||
before={<Icon size="50" src={Icons.Plus} />}
|
|
||||||
onClick={() => setAccountDataType(null)}
|
|
||||||
>
|
|
||||||
<Box grow="Yes">
|
|
||||||
<Text size="T200" truncate>
|
|
||||||
Add New
|
|
||||||
</Text>
|
|
||||||
</Box>
|
|
||||||
</MenuItem>
|
|
||||||
{Array.from(accountData.keys())
|
|
||||||
.sort()
|
|
||||||
.map((type) => (
|
|
||||||
<MenuItem
|
|
||||||
key={type}
|
|
||||||
variant="Surface"
|
|
||||||
fill="None"
|
|
||||||
size="300"
|
|
||||||
radii="0"
|
|
||||||
after={<Icon size="50" src={Icons.ChevronRight} />}
|
|
||||||
onClick={() => setAccountDataType(type)}
|
|
||||||
>
|
|
||||||
<Box grow="Yes">
|
|
||||||
<Text size="T200" truncate>
|
|
||||||
{type}
|
|
||||||
</Text>
|
|
||||||
</Box>
|
|
||||||
</MenuItem>
|
|
||||||
))}
|
|
||||||
</CutoutCard>
|
|
||||||
</Box>
|
</Box>
|
||||||
)}
|
<CutoutCard>
|
||||||
</SequenceCard>
|
<MenuItem
|
||||||
|
variant="Surface"
|
||||||
|
fill="None"
|
||||||
|
size="300"
|
||||||
|
radii="0"
|
||||||
|
before={<Icon size="50" src={Icons.Plus} />}
|
||||||
|
onClick={() => setAccountDataType(null)}
|
||||||
|
>
|
||||||
|
<Box grow="Yes">
|
||||||
|
<Text size="T200" truncate>
|
||||||
|
Add New
|
||||||
|
</Text>
|
||||||
|
</Box>
|
||||||
|
</MenuItem>
|
||||||
|
{Array.from(accountData.keys())
|
||||||
|
.sort()
|
||||||
|
.map((type) => (
|
||||||
|
<MenuItem
|
||||||
|
key={type}
|
||||||
|
variant="Surface"
|
||||||
|
fill="None"
|
||||||
|
size="300"
|
||||||
|
radii="0"
|
||||||
|
after={<Icon size="50" src={Icons.ChevronRight} />}
|
||||||
|
onClick={() => setAccountDataType(type)}
|
||||||
|
>
|
||||||
|
<Box grow="Yes">
|
||||||
|
<Text size="T200" truncate>
|
||||||
|
{type}
|
||||||
|
</Text>
|
||||||
|
</Box>
|
||||||
|
</MenuItem>
|
||||||
|
))}
|
||||||
|
</CutoutCard>
|
||||||
|
</Box>
|
||||||
|
</CollapsibleCard>
|
||||||
</Box>
|
</Box>
|
||||||
)}
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,6 @@ import {
|
||||||
Chip,
|
Chip,
|
||||||
color,
|
color,
|
||||||
config,
|
config,
|
||||||
Icon,
|
|
||||||
Icons,
|
|
||||||
Input,
|
Input,
|
||||||
Spinner,
|
Spinner,
|
||||||
Text,
|
Text,
|
||||||
|
|
@ -33,6 +31,7 @@ import { useAlive } from '../../../hooks/useAlive';
|
||||||
import { StateEvent } from '../../../../types/matrix/room';
|
import { StateEvent } from '../../../../types/matrix/room';
|
||||||
import { RoomPermissionsAPI } from '../../../hooks/useRoomPermissions';
|
import { RoomPermissionsAPI } from '../../../hooks/useRoomPermissions';
|
||||||
import { getMxIdServer } from '../../../utils/matrix';
|
import { getMxIdServer } from '../../../utils/matrix';
|
||||||
|
import { CollapsibleCard } from '../../../components/CollapsibleCard';
|
||||||
|
|
||||||
type RoomPublishedAddressesProps = {
|
type RoomPublishedAddressesProps = {
|
||||||
permissions: RoomPermissionsAPI;
|
permissions: RoomPermissionsAPI;
|
||||||
|
|
@ -373,64 +372,40 @@ export function RoomLocalAddresses({ permissions }: { permissions: RoomPermissio
|
||||||
const { localAliasesState, addLocalAlias, removeLocalAlias } = useLocalAliases(room.roomId);
|
const { localAliasesState, addLocalAlias, removeLocalAlias } = useLocalAliases(room.roomId);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SequenceCard
|
<CollapsibleCard
|
||||||
className={SequenceCardStyle}
|
expand={expand}
|
||||||
variant="SurfaceVariant"
|
setExpand={setExpand}
|
||||||
direction="Column"
|
title="Local Addresses"
|
||||||
gap="400"
|
description="Set local address so users can join through your homeserver."
|
||||||
>
|
>
|
||||||
<SettingTile
|
<CutoutCard variant="Surface" style={{ padding: config.space.S300 }}>
|
||||||
title="Local Addresses"
|
{localAliasesState.status === AsyncStatus.Loading && (
|
||||||
description="Set local address so users can join through your homeserver."
|
<Box gap="100">
|
||||||
after={
|
<Spinner variant="Secondary" size="100" />
|
||||||
<Button
|
<Text size="T200">Loading...</Text>
|
||||||
type="button"
|
</Box>
|
||||||
onClick={() => setExpand(!expand)}
|
)}
|
||||||
size="300"
|
{localAliasesState.status === AsyncStatus.Success &&
|
||||||
variant="Secondary"
|
(localAliasesState.data.length === 0 ? (
|
||||||
fill="Soft"
|
<Box direction="Column" gap="100">
|
||||||
outlined
|
<Text size="L400">No Addresses</Text>
|
||||||
radii="300"
|
</Box>
|
||||||
before={
|
) : (
|
||||||
<Icon size="100" src={expand ? Icons.ChevronTop : Icons.ChevronBottom} filled />
|
<LocalAddressesList
|
||||||
}
|
localAliases={localAliasesState.data}
|
||||||
>
|
removeLocalAlias={removeLocalAlias}
|
||||||
<Text as="span" size="B300" truncate>
|
canEditCanonical={canEditCanonical}
|
||||||
{expand ? 'Collapse' : 'Expand'}
|
/>
|
||||||
|
))}
|
||||||
|
{localAliasesState.status === AsyncStatus.Error && (
|
||||||
|
<Box gap="100">
|
||||||
|
<Text size="T200" style={{ color: color.Critical.Main }}>
|
||||||
|
{localAliasesState.error.message}
|
||||||
</Text>
|
</Text>
|
||||||
</Button>
|
</Box>
|
||||||
}
|
)}
|
||||||
/>
|
</CutoutCard>
|
||||||
{expand && (
|
|
||||||
<CutoutCard variant="Surface" style={{ padding: config.space.S300 }}>
|
|
||||||
{localAliasesState.status === AsyncStatus.Loading && (
|
|
||||||
<Box gap="100">
|
|
||||||
<Spinner variant="Secondary" size="100" />
|
|
||||||
<Text size="T200">Loading...</Text>
|
|
||||||
</Box>
|
|
||||||
)}
|
|
||||||
{localAliasesState.status === AsyncStatus.Success &&
|
|
||||||
(localAliasesState.data.length === 0 ? (
|
|
||||||
<Box direction="Column" gap="100">
|
|
||||||
<Text size="L400">No Addresses</Text>
|
|
||||||
</Box>
|
|
||||||
) : (
|
|
||||||
<LocalAddressesList
|
|
||||||
localAliases={localAliasesState.data}
|
|
||||||
removeLocalAlias={removeLocalAlias}
|
|
||||||
canEditCanonical={canEditCanonical}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
{localAliasesState.status === AsyncStatus.Error && (
|
|
||||||
<Box gap="100">
|
|
||||||
<Text size="T200" style={{ color: color.Critical.Main }}>
|
|
||||||
{localAliasesState.error.message}
|
|
||||||
</Text>
|
|
||||||
</Box>
|
|
||||||
)}
|
|
||||||
</CutoutCard>
|
|
||||||
)}
|
|
||||||
{expand && <LocalAddressInput addLocalAlias={addLocalAlias} />}
|
{expand && <LocalAddressInput addLocalAlias={addLocalAlias} />}
|
||||||
</SequenceCard>
|
</CollapsibleCard>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,86 +1,54 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Box, Text, Icon, Icons, Button, MenuItem } from 'folds';
|
import { Box, Text, Icon, Icons, MenuItem } from 'folds';
|
||||||
import { SequenceCard } from '../../../components/sequence-card';
|
|
||||||
import { SequenceCardStyle } from '../styles.css';
|
|
||||||
import { SettingTile } from '../../../components/setting-tile';
|
|
||||||
import { CutoutCard } from '../../../components/cutout-card';
|
import { CutoutCard } from '../../../components/cutout-card';
|
||||||
|
|
||||||
type AccountDataListProps = {
|
type AccountDataListProps = {
|
||||||
title?: string;
|
|
||||||
description?: string;
|
|
||||||
expand: boolean;
|
|
||||||
setExpand: (expand: boolean) => void;
|
|
||||||
types: string[];
|
types: string[];
|
||||||
onSelect: (type: string | null) => void;
|
onSelect: (type: string | null) => void;
|
||||||
};
|
};
|
||||||
export function AccountDataList({ types, onSelect, expand, setExpand, title, description }: AccountDataListProps) {
|
export function AccountDataList({
|
||||||
|
types,
|
||||||
|
onSelect,
|
||||||
|
}: AccountDataListProps) {
|
||||||
return (
|
return (
|
||||||
<SequenceCard
|
<Box direction="Column" gap="100">
|
||||||
className={SequenceCardStyle}
|
<Box justifyContent="SpaceBetween">
|
||||||
variant="SurfaceVariant"
|
<Text size="L400">Fields</Text>
|
||||||
direction="Column"
|
<Text size="L400">Total: {types.length}</Text>
|
||||||
gap="400"
|
</Box>
|
||||||
>
|
<CutoutCard>
|
||||||
<SettingTile
|
<MenuItem
|
||||||
title={title}
|
variant="Surface"
|
||||||
description={description}
|
fill="None"
|
||||||
after={
|
size="300"
|
||||||
<Button
|
radii="0"
|
||||||
onClick={() => setExpand(!expand)}
|
before={<Icon size="50" src={Icons.Plus} />}
|
||||||
variant="Secondary"
|
onClick={() => onSelect(null)}
|
||||||
fill="Soft"
|
>
|
||||||
size="300"
|
<Box grow="Yes">
|
||||||
radii="300"
|
<Text size="T200" truncate>
|
||||||
outlined
|
Add New
|
||||||
before={
|
</Text>
|
||||||
<Icon src={expand ? Icons.ChevronTop : Icons.ChevronBottom} size="100" filled />
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<Text size="B300">{expand ? 'Collapse' : 'Expand'}</Text>
|
|
||||||
</Button>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
{expand && (
|
|
||||||
<Box direction="Column" gap="100">
|
|
||||||
<Box justifyContent="SpaceBetween">
|
|
||||||
<Text size="L400">Fields</Text>
|
|
||||||
<Text size="L400">Total: {types.length}</Text>
|
|
||||||
</Box>
|
</Box>
|
||||||
<CutoutCard>
|
</MenuItem>
|
||||||
<MenuItem
|
{types.sort().map((type) => (
|
||||||
variant="Surface"
|
<MenuItem
|
||||||
fill="None"
|
key={type}
|
||||||
size="300"
|
variant="Surface"
|
||||||
radii="0"
|
fill="None"
|
||||||
before={<Icon size="50" src={Icons.Plus} />}
|
size="300"
|
||||||
onClick={() => onSelect(null)}
|
radii="0"
|
||||||
>
|
after={<Icon size="50" src={Icons.ChevronRight} />}
|
||||||
<Box grow="Yes">
|
onClick={() => onSelect(type)}
|
||||||
<Text size="T200" truncate>
|
>
|
||||||
Add New
|
<Box grow="Yes">
|
||||||
</Text>
|
<Text size="T200" truncate>
|
||||||
</Box>
|
{type}
|
||||||
</MenuItem>
|
</Text>
|
||||||
{types.sort().map((type) => (
|
</Box>
|
||||||
<MenuItem
|
</MenuItem>
|
||||||
key={type}
|
))}
|
||||||
variant="Surface"
|
</CutoutCard>
|
||||||
fill="None"
|
</Box>
|
||||||
size="300"
|
|
||||||
radii="0"
|
|
||||||
after={<Icon size="50" src={Icons.ChevronRight} />}
|
|
||||||
onClick={() => onSelect(type)}
|
|
||||||
>
|
|
||||||
<Box grow="Yes">
|
|
||||||
<Text size="T200" truncate>
|
|
||||||
{type}
|
|
||||||
</Text>
|
|
||||||
</Box>
|
|
||||||
</MenuItem>
|
|
||||||
))}
|
|
||||||
</CutoutCard>
|
|
||||||
</Box>
|
|
||||||
)}
|
|
||||||
</SequenceCard>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ import { copyToClipboard } from '../../../utils/dom';
|
||||||
import { AccountDataList } from './AccountDataList';
|
import { AccountDataList } from './AccountDataList';
|
||||||
import { useExtendedProfile } from '../../../hooks/useExtendedProfile';
|
import { useExtendedProfile } from '../../../hooks/useExtendedProfile';
|
||||||
import { useAccountDataCallback } from '../../../hooks/useAccountDataCallback';
|
import { useAccountDataCallback } from '../../../hooks/useAccountDataCallback';
|
||||||
|
import { CollapsibleCard } from '../../../components/CollapsibleCard';
|
||||||
|
|
||||||
type DeveloperToolsPage =
|
type DeveloperToolsPage =
|
||||||
| { name: 'index' }
|
| { name: 'index' }
|
||||||
|
|
@ -165,23 +166,29 @@ export function DeveloperTools({ requestClose }: DeveloperToolsProps) {
|
||||||
{developerTools && (
|
{developerTools && (
|
||||||
<Box direction="Column" gap="100">
|
<Box direction="Column" gap="100">
|
||||||
<Text size="L400">Account Data</Text>
|
<Text size="L400">Account Data</Text>
|
||||||
<AccountDataList
|
<CollapsibleCard
|
||||||
title="Account"
|
|
||||||
description="Private data stored in your account."
|
|
||||||
expand={globalExpand}
|
expand={globalExpand}
|
||||||
setExpand={setGlobalExpand}
|
setExpand={setGlobalExpand}
|
||||||
types={accountDataTypes}
|
title="Account"
|
||||||
onSelect={(type) => setPage({ name: 'account-data', type })}
|
description="Private data stored in your account."
|
||||||
/>
|
>
|
||||||
{extendedProfile && (
|
|
||||||
<AccountDataList
|
<AccountDataList
|
||||||
title="Profile"
|
types={accountDataTypes}
|
||||||
description="Public data attached to your Matrix profile."
|
onSelect={(type) => setPage({ name: 'account-data', type })}
|
||||||
|
/>
|
||||||
|
</CollapsibleCard>
|
||||||
|
{extendedProfile && (
|
||||||
|
<CollapsibleCard
|
||||||
expand={profileExpand}
|
expand={profileExpand}
|
||||||
setExpand={setProfileExpand}
|
setExpand={setProfileExpand}
|
||||||
types={Object.keys(extendedProfile)}
|
title="Profile"
|
||||||
onSelect={(type) => setPage({ name: 'profile-field', type })}
|
description="Public data attached to your Matrix profile."
|
||||||
/>
|
>
|
||||||
|
<AccountDataList
|
||||||
|
types={Object.keys(extendedProfile)}
|
||||||
|
onSelect={(type) => setPage({ name: 'profile-field', type })}
|
||||||
|
/>
|
||||||
|
</CollapsibleCard>
|
||||||
)}
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
)}
|
)}
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ import { AsyncStatus, useAsyncCallback } from '../../../hooks/useAsyncCallback';
|
||||||
import { decryptMegolmKeyFile, encryptMegolmKeyFile } from '../../../../util/cryptE2ERoomKeys';
|
import { decryptMegolmKeyFile, encryptMegolmKeyFile } from '../../../../util/cryptE2ERoomKeys';
|
||||||
import { useAlive } from '../../../hooks/useAlive';
|
import { useAlive } from '../../../hooks/useAlive';
|
||||||
import { useFilePicker } from '../../../hooks/useFilePicker';
|
import { useFilePicker } from '../../../hooks/useFilePicker';
|
||||||
|
import { CollapsibleCard } from '../../../components/CollapsibleCard';
|
||||||
|
|
||||||
function ExportKeys() {
|
function ExportKeys() {
|
||||||
const mx = useMatrixClient();
|
const mx = useMatrixClient();
|
||||||
|
|
@ -121,37 +122,18 @@ function ExportKeys() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function ExportKeysTile() {
|
function ExportKeysCard() {
|
||||||
const [expand, setExpand] = useState(false);
|
const [expand, setExpand] = useState(false);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<CollapsibleCard
|
||||||
<SettingTile
|
expand={expand}
|
||||||
title="Export Messages Data"
|
setExpand={setExpand}
|
||||||
description="Save password protected copy of encryption data on your device to decrypt messages later."
|
title="Export Messages Data"
|
||||||
after={
|
description="Save password protected copy of encryption data on your device to decrypt messages later."
|
||||||
<Box>
|
>
|
||||||
<Button
|
<ExportKeys />
|
||||||
type="button"
|
</CollapsibleCard>
|
||||||
onClick={() => setExpand(!expand)}
|
|
||||||
size="300"
|
|
||||||
variant="Secondary"
|
|
||||||
fill="Soft"
|
|
||||||
outlined
|
|
||||||
radii="300"
|
|
||||||
before={
|
|
||||||
<Icon size="100" src={expand ? Icons.ChevronTop : Icons.ChevronBottom} filled />
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<Text as="span" size="B300" truncate>
|
|
||||||
{expand ? 'Collapse' : 'Expand'}
|
|
||||||
</Text>
|
|
||||||
</Button>
|
|
||||||
</Box>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
{expand && <ExportKeys />}
|
|
||||||
</>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -304,14 +286,7 @@ export function LocalBackup() {
|
||||||
return (
|
return (
|
||||||
<Box direction="Column" gap="100">
|
<Box direction="Column" gap="100">
|
||||||
<Text size="L400">Local Backup</Text>
|
<Text size="L400">Local Backup</Text>
|
||||||
<SequenceCard
|
<ExportKeysCard />
|
||||||
className={SequenceCardStyle}
|
|
||||||
variant="SurfaceVariant"
|
|
||||||
direction="Column"
|
|
||||||
gap="400"
|
|
||||||
>
|
|
||||||
<ExportKeysTile />
|
|
||||||
</SequenceCard>
|
|
||||||
<SequenceCard
|
<SequenceCard
|
||||||
className={SequenceCardStyle}
|
className={SequenceCardStyle}
|
||||||
variant="SurfaceVariant"
|
variant="SurfaceVariant"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue