mirror of
https://github.com/lux-tel/session-desktop.git
synced 2026-10-30 20:33:24 +00:00
225 lines
6.0 KiB
TypeScript
225 lines
6.0 KiB
TypeScript
import styled from 'styled-components';
|
|
import useUpdate from 'react-use/lib/useUpdate';
|
|
import { type Dispatch, useState, ReactNode } from 'react';
|
|
import { getAppDispatch } from '../../../state/dispatch';
|
|
import { Flex } from '../../basic/Flex';
|
|
import { updateDebugMenuModal } from '../../../state/ducks/modalDialog';
|
|
import {
|
|
AboutInfo,
|
|
DataGenerationActions,
|
|
DebugActions,
|
|
DebugUrlInteractionsSection,
|
|
ExperimentalActions,
|
|
LoggingDebugSection,
|
|
OtherInfo,
|
|
Playgrounds,
|
|
} from './components';
|
|
import {
|
|
ModalBasicHeader,
|
|
SessionWrapperModal,
|
|
WrapperModalWidth,
|
|
} from '../../SessionWrapperModal';
|
|
import {
|
|
DebugFeatureFlags,
|
|
FeatureFlagDumper,
|
|
FeatureFlags,
|
|
ProDebugSection,
|
|
} from './FeatureFlags';
|
|
import { ReleaseChannel } from './ReleaseChannel';
|
|
import { useHotkey } from '../../../hooks/useHotkey';
|
|
import { PopoverPlaygroundPage } from './playgrounds/PopoverPlaygroundPage';
|
|
import { ProPlaygroundPage } from './playgrounds/ProPlaygroundPage';
|
|
import { ModalBackButton } from '../shared/ModalBackButton';
|
|
import { PanelButtonGroup } from '../../buttons';
|
|
import { isDebugMode } from '../../../shared/env_vars';
|
|
|
|
const StyledContent = styled(Flex)`
|
|
padding-inline: var(--margins-sm);
|
|
|
|
h2 {
|
|
font-size: var(--font-size-xl);
|
|
}
|
|
|
|
h2,
|
|
h3 {
|
|
margin: var(--margins-md) 0;
|
|
padding: 0;
|
|
text-decoration: underline;
|
|
}
|
|
|
|
p,
|
|
i {
|
|
line-height: 1.4;
|
|
margin: 0;
|
|
padding: 0;
|
|
text-align: start;
|
|
}
|
|
`;
|
|
|
|
export enum DEBUG_MENU_PAGE {
|
|
MAIN = 0,
|
|
POPOVER = 1,
|
|
Pro = 2,
|
|
}
|
|
|
|
export type DebugMenuPageProps = {
|
|
setPage: Dispatch<DEBUG_MENU_PAGE>;
|
|
};
|
|
|
|
export function DebugMenuSection({
|
|
title,
|
|
titleAdornment,
|
|
children,
|
|
rowWrap,
|
|
}: {
|
|
title?: string;
|
|
titleAdornment?: ReactNode;
|
|
children: ReactNode;
|
|
rowWrap?: boolean;
|
|
}) {
|
|
return (
|
|
<PanelButtonGroup
|
|
style={{
|
|
maxWidth: '550px',
|
|
}}
|
|
containerStyle={{
|
|
paddingBlock: 'var(--margins-md)',
|
|
paddingInline: 'var(--margins-lg)',
|
|
gap: 'var(--margins-sm)',
|
|
width: '100%',
|
|
...(rowWrap
|
|
? {
|
|
flexDirection: 'row',
|
|
flexWrap: 'wrap',
|
|
}
|
|
: {}),
|
|
}}
|
|
>
|
|
{title ? (
|
|
<h2 style={{ width: '100%', display: 'flex', gap: '4px' }}>
|
|
{title}
|
|
{titleAdornment ?? null}
|
|
</h2>
|
|
) : null}
|
|
{children}
|
|
</PanelButtonGroup>
|
|
);
|
|
}
|
|
|
|
function MainPage({ setPage }: DebugMenuPageProps) {
|
|
// NOTE we use forceUpdate here and pass it through so the entire modal refreshes when a flag is toggled
|
|
const forceUpdate = useUpdate();
|
|
const isDebug = isDebugMode();
|
|
return (
|
|
<div
|
|
style={{
|
|
display: 'flex',
|
|
width: '100%',
|
|
flexDirection: 'row',
|
|
flexWrap: 'wrap',
|
|
justifyContent: 'center',
|
|
alignItems: 'flex-start',
|
|
gap: 'var(--margins-lg)',
|
|
}}
|
|
>
|
|
{!isDebug ? (
|
|
<DebugMenuSection>
|
|
{
|
|
"The debug menu contains feature flag controls and experiments for unreleased Session features. They might not work, or may even break your client. Only use this menu if you know what you're doing. Some debug menu options are only available in debug mode."
|
|
}
|
|
</DebugMenuSection>
|
|
) : null}
|
|
<FeatureFlags forceUpdate={forceUpdate} />
|
|
<ProDebugSection forceUpdate={forceUpdate} setPage={setPage} />
|
|
{isDebug ? <FeatureFlagDumper forceUpdate={forceUpdate} /> : null}
|
|
{isDebug ? <DebugFeatureFlags forceUpdate={forceUpdate} /> : null}
|
|
<DebugActions />
|
|
{isDebug ? <ExperimentalActions forceUpdate={forceUpdate} /> : null}
|
|
<LoggingDebugSection forceUpdate={forceUpdate} />
|
|
<Playgrounds setPage={setPage} />
|
|
{isDebug ? <DataGenerationActions /> : null}
|
|
{isDebug ? <DebugUrlInteractionsSection /> : null}
|
|
<ReleaseChannel />
|
|
<div>
|
|
<AboutInfo />
|
|
<OtherInfo />
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
function getPage(page: DEBUG_MENU_PAGE, setPage: Dispatch<DEBUG_MENU_PAGE>) {
|
|
switch (page) {
|
|
case DEBUG_MENU_PAGE.POPOVER:
|
|
return <PopoverPlaygroundPage />;
|
|
case DEBUG_MENU_PAGE.Pro:
|
|
return <ProPlaygroundPage setPage={setPage} />;
|
|
case DEBUG_MENU_PAGE.MAIN:
|
|
default:
|
|
return <MainPage setPage={setPage} />;
|
|
}
|
|
}
|
|
|
|
export function DebugMenuModal() {
|
|
const dispatch = getAppDispatch();
|
|
|
|
const [page, setPage] = useState<DEBUG_MENU_PAGE>(DEBUG_MENU_PAGE.MAIN);
|
|
|
|
const onClose = () => {
|
|
dispatch(updateDebugMenuModal(null));
|
|
};
|
|
|
|
const makeTogglesActive = (query: string, active: boolean) => {
|
|
const elements = document.querySelectorAll(query);
|
|
for (let i = 0; i < elements.length; i++) {
|
|
const toggleElement = elements[i] as any; // See SessionToggle
|
|
if (active && toggleElement.getAttribute('data-active') === 'false') {
|
|
toggleElement.click();
|
|
}
|
|
if (!active && toggleElement.getAttribute('data-active') === 'true') {
|
|
toggleElement.click();
|
|
}
|
|
}
|
|
};
|
|
|
|
useHotkey('d', () => {
|
|
makeTogglesActive('[id*="feature-flag-toggle-debug-debug"] > [role="button"]', true);
|
|
});
|
|
|
|
useHotkey('s', () => {
|
|
makeTogglesActive('[id*="feature-flag-toggle-debug-debug"] > [role="button"]', false);
|
|
});
|
|
|
|
return (
|
|
<SessionWrapperModal
|
|
modalId="debugMenuModal"
|
|
headerChildren={
|
|
<ModalBasicHeader
|
|
title="Debug Menu"
|
|
showExitIcon={true}
|
|
extraLeftButton={
|
|
page !== DEBUG_MENU_PAGE.MAIN ? (
|
|
<ModalBackButton onClick={() => setPage(DEBUG_MENU_PAGE.MAIN)} />
|
|
) : null
|
|
}
|
|
/>
|
|
}
|
|
topAnchor="5vh"
|
|
onClose={onClose}
|
|
$contentMaxWidth={WrapperModalWidth.debug}
|
|
shouldOverflow={true}
|
|
allowOutsideClick={false}
|
|
>
|
|
<StyledContent
|
|
dir="ltr"
|
|
$container={true}
|
|
$flexDirection="column"
|
|
$alignItems="flex-start"
|
|
$padding="var(--margins-sm) 0 var(--margins-xl)"
|
|
>
|
|
{getPage(page, setPage)}
|
|
</StyledContent>
|
|
</SessionWrapperModal>
|
|
);
|
|
}
|