Skip to content

Commit

Permalink
add developer tools settings
Browse files Browse the repository at this point in the history
  • Loading branch information
ajbura committed Dec 18, 2024
1 parent e685eb9 commit ef8d09e
Show file tree
Hide file tree
Showing 4 changed files with 175 additions and 0 deletions.
4 changes: 4 additions & 0 deletions src/app/features/settings/Settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { useMediaAuthentication } from '../../hooks/useMediaAuthentication';
import { UserAvatar } from '../../components/user-avatar';
import { nameInitials } from '../../utils/common';
import { Notifications } from './notifications';
import { DeveloperTools } from './developer-tools';
import { About } from './about';

enum SettingsPages {
Expand Down Expand Up @@ -169,6 +170,9 @@ export function Settings({ initialPage, requestClose }: SettingsProps) {
{activePage === SettingsPages.NotificationPage && (
<Notifications requestClose={handlePageRequestClose} />
)}
{activePage === SettingsPages.DeveloperToolsPage && (
<DeveloperTools requestClose={handlePageRequestClose} />
)}
{activePage === SettingsPages.AboutPage && <About requestClose={handlePageRequestClose} />}
</PageRoot>
);
Expand Down
166 changes: 166 additions & 0 deletions src/app/features/settings/developer-tools/DevelopTools.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
import React, { MouseEventHandler, useCallback, useState } from 'react';
import {
Box,
Text,
IconButton,
Icon,
Icons,
Scroll,
Switch,
Overlay,
OverlayBackdrop,
OverlayCenter,
Modal,
Chip,
config,
} from 'folds';
import { MatrixEvent } from 'matrix-js-sdk';
import FocusTrap from 'focus-trap-react';
import { Page, PageContent, PageHeader } from '../../../components/page';
import { SequenceCard } from '../../../components/sequence-card';
import { SequenceCardStyle } from '../styles.css';
import { SettingTile } from '../../../components/setting-tile';
import { useSetting } from '../../../state/hooks/settings';
import { settingsAtom } from '../../../state/settings';
import { useMatrixClient } from '../../../hooks/useMatrixClient';
import { useAccountDataCallback } from '../../../hooks/useAccountDataCallback';
import { TextViewer } from '../../../components/text-viewer';
import { stopPropagation } from '../../../utils/keyboard';

function AccountData() {
const mx = useMatrixClient();
const [accountData, setAccountData] = useState(() => Array.from(mx.store.accountData.values()));
const [selectedEvent, selectEvent] = useState<MatrixEvent>();

useAccountDataCallback(
mx,
useCallback(
() => setAccountData(Array.from(mx.store.accountData.values())),
[mx, setAccountData]
)
);

const handleView: MouseEventHandler<HTMLButtonElement> = (evt) => {
const target = evt.currentTarget;
const eventType = target.getAttribute('data-event-type');
if (eventType) {
const mEvent = accountData.find((mEvt) => mEvt.getType() === eventType);
selectEvent(mEvent);
}
};

const handleClose = () => selectEvent(undefined);

return (
<Box direction="Column" gap="100">
<Text size="L400">Account Data</Text>
<SequenceCard
className={SequenceCardStyle}
variant="SurfaceVariant"
direction="Column"
gap="400"
>
<SettingTile title="Global" description="Data stored in your global account data.">
<Box style={{ paddingTop: config.space.S200 }} direction="Column" gap="200">
<Text size="L400">Types</Text>
<Box gap="200" wrap="Wrap">
{accountData.map((mEvent) => (
<Chip
key={mEvent.getType()}
variant="Secondary"
fill="Soft"
radii="Pill"
outlined
onClick={handleView}
data-event-type={mEvent.getType()}
>
<Text size="T200" truncate>
{mEvent.getType()}
</Text>
</Chip>
))}
</Box>
</Box>
</SettingTile>
</SequenceCard>
{selectedEvent && (
<Overlay open backdrop={<OverlayBackdrop />}>
<OverlayCenter>
<FocusTrap
focusTrapOptions={{
initialFocus: false,
onDeactivate: handleClose,
clickOutsideDeactivates: true,
escapeDeactivates: stopPropagation,
}}
>
<Modal variant="Surface" size="500">
<TextViewer
name={selectedEvent.getType() ?? 'Source Code'}
langName="json"
text={JSON.stringify(selectedEvent.getContent(), null, 2)}
requestClose={handleClose}
/>
</Modal>
</FocusTrap>
</OverlayCenter>
</Overlay>
)}
</Box>
);
}

type DeveloperToolsProps = {
requestClose: () => void;
};
export function DeveloperTools({ requestClose }: DeveloperToolsProps) {
const [developerTools, setDeveloperTools] = useSetting(settingsAtom, 'developerTools');

return (
<Page>
<PageHeader outlined={false}>
<Box grow="Yes" gap="200">
<Box grow="Yes" alignItems="Center" gap="200">
<Text size="H3" truncate>
Developer Tools
</Text>
</Box>
<Box shrink="No">
<IconButton onClick={requestClose} variant="Surface">
<Icon src={Icons.Cross} />
</IconButton>
</Box>
</Box>
</PageHeader>
<Box grow="Yes">
<Scroll hideTrack visibility="Hover">
<PageContent>
<Box direction="Column" gap="700">
<Box direction="Column" gap="100">
<Text size="L400">Options</Text>
<SequenceCard
className={SequenceCardStyle}
variant="SurfaceVariant"
direction="Column"
gap="400"
>
<SettingTile
title="Enable Developer Tools"
after={
<Switch
variant="Primary"
value={developerTools}
onChange={setDeveloperTools}
/>
}
/>
</SequenceCard>
</Box>
{developerTools && <AccountData />}
</Box>
</PageContent>
</Scroll>
</Box>
</Page>
);
}
1 change: 1 addition & 0 deletions src/app/features/settings/developer-tools/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './DevelopTools';
4 changes: 4 additions & 0 deletions src/app/state/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ export interface Settings {

showNotifications: boolean;
isNotificationSounds: boolean;

developerTools: boolean;
}

const defaultSettings: Settings = {
Expand All @@ -58,6 +60,8 @@ const defaultSettings: Settings = {

showNotifications: true,
isNotificationSounds: true,

developerTools: false,
};

export const getSettings = () => {
Expand Down

0 comments on commit ef8d09e

Please sign in to comment.