From d42bcc6e3d58f4a14c3e8d60aba5905a05f58bdb Mon Sep 17 00:00:00 2001 From: Ginger Date: Mon, 6 Oct 2025 12:21:01 -0400 Subject: [PATCH] Use a common CollapsibleCard element for collapsible settings cards --- src/app/components/AccountDataEditor.tsx | 16 +- src/app/components/CollapsibleCard.tsx | 54 +++ .../developer-tools/DevelopTools.tsx | 355 ++++++++---------- .../common-settings/general/RoomAddress.tsx | 91 ++--- .../developer-tools/AccountDataList.tsx | 118 +++--- .../settings/developer-tools/DevelopTools.tsx | 31 +- .../features/settings/devices/LocalBackup.tsx | 47 +-- 7 files changed, 322 insertions(+), 390 deletions(-) create mode 100644 src/app/components/CollapsibleCard.tsx diff --git a/src/app/components/AccountDataEditor.tsx b/src/app/components/AccountDataEditor.tsx index 3be3911c..ef8d01a1 100644 --- a/src/app/components/AccountDataEditor.tsx +++ b/src/app/components/AccountDataEditor.tsx @@ -195,8 +195,8 @@ function AccountDataEdit({ type AccountDataViewProps = { type: string; defaultContent: string; - onEdit: () => void; requestClose: () => void; + onEdit?: () => void; submitDelete?: AccountDataDeleteCallback; }; function AccountDataView({ type, defaultContent, onEdit, requestClose, submitDelete }: AccountDataViewProps) { @@ -231,9 +231,11 @@ function AccountDataView({ type, defaultContent, onEdit, requestClose, submitDel required /> - + {onEdit && ( + + )} {submitDelete && ( + } + /> + {expand && children} + + ); +} diff --git a/src/app/features/common-settings/developer-tools/DevelopTools.tsx b/src/app/features/common-settings/developer-tools/DevelopTools.tsx index 29b6aa51..4125f6d2 100644 --- a/src/app/features/common-settings/developer-tools/DevelopTools.tsx +++ b/src/app/features/common-settings/developer-tools/DevelopTools.tsx @@ -30,6 +30,7 @@ import { AccountDataSubmitCallback, } from '../../../components/AccountDataEditor'; import { useMatrixClient } from '../../../hooks/useMatrixClient'; +import { CollapsibleCard } from '../../../components/CollapsibleCard'; type DeveloperToolsProps = { requestClose: () => void; @@ -175,216 +176,166 @@ export function DeveloperTools({ requestClose }: DeveloperToolsProps) { } /> - - setExpandState(!expandState)} - variant="Secondary" - fill="Soft" + + + Events + Total: {roomState.size} + + + setComposeEvent({ stateKey: '' })} + variant="Surface" + fill="None" size="300" - radii="300" - outlined - before={ - - } + radii="0" + before={} > - {expandState ? 'Collapse' : 'Expand'} - - } - /> - {expandState && ( - - - Events - Total: {roomState.size} - - - setComposeEvent({ stateKey: '' })} - variant="Surface" - fill="None" - size="300" - radii="0" - before={} - > - - - Add New - - - - {Array.from(roomState.keys()) - .sort() - .map((eventType) => { - const expanded = eventType === expandStateType; - const stateKeyToEvents = roomState.get(eventType); - if (!stateKeyToEvents) return null; + + + Add New + + + + {Array.from(roomState.keys()) + .sort() + .map((eventType) => { + const expanded = eventType === expandStateType; + const stateKeyToEvents = roomState.get(eventType); + if (!stateKeyToEvents) return null; - return ( - - - setExpandStateType(expanded ? undefined : eventType) - } - variant="Surface" - fill="None" - size="300" - radii="0" - before={ - - } - after={{stateKeyToEvents.size}} + return ( + + + setExpandStateType(expanded ? undefined : eventType) + } + variant="Surface" + fill="None" + size="300" + radii="0" + before={ + + } + after={{stateKeyToEvents.size}} + > + + + {eventType} + + + + {expanded && ( +
- - - {eventType} - - - - {expanded && ( -
+ setComposeEvent({ type: eventType, stateKey: '' }) + } + variant="Surface" + fill="None" + size="300" + radii="0" + before={} > - - setComposeEvent({ type: eventType, stateKey: '' }) - } - variant="Surface" - fill="None" - size="300" - radii="0" - before={} - > - - - Add New - - - - {Array.from(stateKeyToEvents.keys()) - .sort() - .map((stateKey) => ( - { - setOpenStateEvent({ - type: eventType, - stateKey, - }); - }} - key={stateKey} - variant="Surface" - fill="None" - size="300" - radii="0" - after={} - > - - - {stateKey ? `"${stateKey}"` : 'Default'} - - - - ))} -
- )} - - ); - })} - - - )} - - + + Add New + + + + {Array.from(stateKeyToEvents.keys()) + .sort() + .map((stateKey) => ( + { + setOpenStateEvent({ + type: eventType, + stateKey, + }); + }} + key={stateKey} + variant="Surface" + fill="None" + size="300" + radii="0" + after={} + > + + + {stateKey ? `"${stateKey}"` : 'Default'} + + + + ))} +
+ )} +
+ ); + })} +
+
+ + - setExpandAccountData(!expandAccountData)} - variant="Secondary" - fill="Soft" - size="300" - radii="300" - outlined - before={ - - } - > - {expandAccountData ? 'Collapse' : 'Expand'} - - } - /> - {expandAccountData && ( - - - Events - Total: {accountData.size} - - - } - onClick={() => setAccountDataType(null)} - > - - - Add New - - - - {Array.from(accountData.keys()) - .sort() - .map((type) => ( - } - onClick={() => setAccountDataType(type)} - > - - - {type} - - - - ))} - + + + Events + Total: {accountData.size} - )} -
+ + } + onClick={() => setAccountDataType(null)} + > + + + Add New + + + + {Array.from(accountData.keys()) + .sort() + .map((type) => ( + } + onClick={() => setAccountDataType(type)} + > + + + {type} + + + + ))} + + + )} diff --git a/src/app/features/common-settings/general/RoomAddress.tsx b/src/app/features/common-settings/general/RoomAddress.tsx index 767a967e..1a618a68 100644 --- a/src/app/features/common-settings/general/RoomAddress.tsx +++ b/src/app/features/common-settings/general/RoomAddress.tsx @@ -7,8 +7,6 @@ import { Chip, color, config, - Icon, - Icons, Input, Spinner, Text, @@ -33,6 +31,7 @@ import { useAlive } from '../../../hooks/useAlive'; import { StateEvent } from '../../../../types/matrix/room'; import { RoomPermissionsAPI } from '../../../hooks/useRoomPermissions'; import { getMxIdServer } from '../../../utils/matrix'; +import { CollapsibleCard } from '../../../components/CollapsibleCard'; type RoomPublishedAddressesProps = { permissions: RoomPermissionsAPI; @@ -373,64 +372,40 @@ export function RoomLocalAddresses({ permissions }: { permissions: RoomPermissio const { localAliasesState, addLocalAlias, removeLocalAlias } = useLocalAliases(room.roomId); return ( - - setExpand(!expand)} - size="300" - variant="Secondary" - fill="Soft" - outlined - radii="300" - before={ - - } - > - - {expand ? 'Collapse' : 'Expand'} + + {localAliasesState.status === AsyncStatus.Loading && ( + + + Loading... + + )} + {localAliasesState.status === AsyncStatus.Success && + (localAliasesState.data.length === 0 ? ( + + No Addresses + + ) : ( + + ))} + {localAliasesState.status === AsyncStatus.Error && ( + + + {localAliasesState.error.message} - - } - /> - {expand && ( - - {localAliasesState.status === AsyncStatus.Loading && ( - - - Loading... - - )} - {localAliasesState.status === AsyncStatus.Success && - (localAliasesState.data.length === 0 ? ( - - No Addresses - - ) : ( - - ))} - {localAliasesState.status === AsyncStatus.Error && ( - - - {localAliasesState.error.message} - - - )} - - )} + + )} + {expand && } - + ); } diff --git a/src/app/features/settings/developer-tools/AccountDataList.tsx b/src/app/features/settings/developer-tools/AccountDataList.tsx index 71b1cf76..9c9cbe6a 100644 --- a/src/app/features/settings/developer-tools/AccountDataList.tsx +++ b/src/app/features/settings/developer-tools/AccountDataList.tsx @@ -1,86 +1,54 @@ import React from 'react'; -import { Box, Text, Icon, Icons, Button, MenuItem } from 'folds'; -import { SequenceCard } from '../../../components/sequence-card'; -import { SequenceCardStyle } from '../styles.css'; -import { SettingTile } from '../../../components/setting-tile'; +import { Box, Text, Icon, Icons, MenuItem } from 'folds'; import { CutoutCard } from '../../../components/cutout-card'; type AccountDataListProps = { - title?: string; - description?: string; - expand: boolean; - setExpand: (expand: boolean) => void; types: string[]; onSelect: (type: string | null) => void; }; -export function AccountDataList({ types, onSelect, expand, setExpand, title, description }: AccountDataListProps) { +export function AccountDataList({ + types, + onSelect, +}: AccountDataListProps) { return ( - - setExpand(!expand)} - variant="Secondary" - fill="Soft" - size="300" - radii="300" - outlined - before={ - - } - > - {expand ? 'Collapse' : 'Expand'} - - } - /> - {expand && ( - - - Fields - Total: {types.length} + + + Fields + Total: {types.length} + + + } + onClick={() => onSelect(null)} + > + + + Add New + - - } - onClick={() => onSelect(null)} - > - - - Add New - - - - {types.sort().map((type) => ( - } - onClick={() => onSelect(type)} - > - - - {type} - - - - ))} - - - )} - + + {types.sort().map((type) => ( + } + onClick={() => onSelect(type)} + > + + + {type} + + + + ))} + + ); } diff --git a/src/app/features/settings/developer-tools/DevelopTools.tsx b/src/app/features/settings/developer-tools/DevelopTools.tsx index 5ee86820..4ac58f46 100644 --- a/src/app/features/settings/developer-tools/DevelopTools.tsx +++ b/src/app/features/settings/developer-tools/DevelopTools.tsx @@ -17,6 +17,7 @@ import { copyToClipboard } from '../../../utils/dom'; import { AccountDataList } from './AccountDataList'; import { useExtendedProfile } from '../../../hooks/useExtendedProfile'; import { useAccountDataCallback } from '../../../hooks/useAccountDataCallback'; +import { CollapsibleCard } from '../../../components/CollapsibleCard'; type DeveloperToolsPage = | { name: 'index' } @@ -165,23 +166,29 @@ export function DeveloperTools({ requestClose }: DeveloperToolsProps) { {developerTools && ( Account Data - setPage({ name: 'account-data', type })} - /> - {extendedProfile && ( + title="Account" + description="Private data stored in your account." + > setPage({ name: 'account-data', type })} + /> + + {extendedProfile && ( + setPage({ name: 'profile-field', type })} - /> + title="Profile" + description="Public data attached to your Matrix profile." + > + setPage({ name: 'profile-field', type })} + /> + )} )} diff --git a/src/app/features/settings/devices/LocalBackup.tsx b/src/app/features/settings/devices/LocalBackup.tsx index 00128c8f..35baa9cb 100644 --- a/src/app/features/settings/devices/LocalBackup.tsx +++ b/src/app/features/settings/devices/LocalBackup.tsx @@ -11,6 +11,7 @@ import { AsyncStatus, useAsyncCallback } from '../../../hooks/useAsyncCallback'; import { decryptMegolmKeyFile, encryptMegolmKeyFile } from '../../../../util/cryptE2ERoomKeys'; import { useAlive } from '../../../hooks/useAlive'; import { useFilePicker } from '../../../hooks/useFilePicker'; +import { CollapsibleCard } from '../../../components/CollapsibleCard'; function ExportKeys() { const mx = useMatrixClient(); @@ -121,37 +122,18 @@ function ExportKeys() { ); } -function ExportKeysTile() { +function ExportKeysCard() { const [expand, setExpand] = useState(false); return ( - <> - - - - } - /> - {expand && } - + + + ); } @@ -304,14 +286,7 @@ export function LocalBackup() { return ( Local Backup - - - +