import { isBoolean } from 'lodash';
import useUpdate from 'react-use/lib/useUpdate';
import useAsync from 'react-use/lib/useAsync';
import { shell } from 'electron';
import useBoolean from 'react-use/lib/useBoolean';
import { useDispatch } from 'react-redux';
import type { SessionFeatureFlagsKeys } from '../../../window';
import { Flex } from '../../basic/Flex';
import { SessionToggle } from '../../basic/SessionToggle';
import { HintText, SpacerXS } from '../../basic/Text';
import { localize } from '../../../localization/localeTools';
import { CopyToClipboardIcon } from '../../buttons';
import { saveLogToDesktop } from '../../../util/logging';
import { Localizer } from '../../basic/Localizer';
import { SessionButton, SessionButtonColor } from '../../basic/SessionButton';
import { ToastUtils, UserUtils } from '../../../session/utils';
import { getLatestReleaseFromFileServer } from '../../../session/apis/file_server_api/FileServerApi';
import { SessionSpinner } from '../../loading';
import { setDebugMode } from '../../../state/ducks/debug';
import { updateDebugMenuModal } from '../../../state/ducks/modalDialog';
export const DebugActions = () => {
const [loadingLatestRelease, setLoadingLatestRelease] = useBoolean(false);
const dispatch = useDispatch();
return (
<>
Actions
{
dispatch(setDebugMode(false));
dispatch(updateDebugMenuModal(null));
}}
>
Exit Debug Mode
{
void saveLogToDesktop();
}}
>
{window.getCommitHash() ? (
{
void shell.openExternal(
`https://github.com/session-foundation/session-desktop/commit/${window.getCommitHash()}`
);
}}
>
Go to commit
) : null}
{
void shell.openExternal(
`https://github.com/session-foundation/session-desktop/releases/tag/v${window.getVersion()}`
);
}}
>
{
const userEd25519SecretKey = (await UserUtils.getUserED25519KeyPairBytes())
?.privKeyBytes;
if (!userEd25519SecretKey) {
window.log.error('[debugMenu] no userEd25519SecretKey');
return;
}
setLoadingLatestRelease(true);
const versionNumber = await getLatestReleaseFromFileServer(userEd25519SecretKey);
setLoadingLatestRelease(false);
if (versionNumber) {
ToastUtils.pushToastInfo('debugLatestRelease', `v${versionNumber}`);
} else {
ToastUtils.pushToastError('debugLatestRelease', 'Failed to fetch latest release');
}
}}
>
{!loadingLatestRelease ? 'Check latest release' : null}
>
);
};
const unsupportedFlags = ['useTestNet'];
const untestedFlags = ['useOnionRequests', 'useClosedGroupV3', 'replaceLocalizedStringsWithKeys'];
const handleFeatureFlagToggle = async (
forceUpdate: () => void,
flag: SessionFeatureFlagsKeys,
parentFlag?: SessionFeatureFlagsKeys
) => {
const currentValue = parentFlag
? (window as any).sessionFeatureFlags[parentFlag][flag]
: (window as any).sessionFeatureFlags[flag];
if (parentFlag) {
(window as any).sessionFeatureFlags[parentFlag][flag] = !currentValue;
window.log.debug(`[debugMenu] toggled ${parentFlag}.${flag} to ${!currentValue}`);
} else {
(window as any).sessionFeatureFlags[flag] = !currentValue;
window.log.debug(`[debugMenu] toggled ${flag} to ${!currentValue}`);
}
forceUpdate();
};
const FlagToggle = ({
forceUpdate,
flag,
value,
parentFlag,
}: {
forceUpdate: () => void;
flag: SessionFeatureFlagsKeys;
value: any;
parentFlag?: SessionFeatureFlagsKeys;
}) => {
const key = `feature-flag-toggle${parentFlag ? `-${parentFlag}` : ''}-${flag}`;
return (
{flag}
{untestedFlags.includes(flag) ? Untested : null}
void handleFeatureFlagToggle(forceUpdate, flag, parentFlag)}
/>
);
};
export const FeatureFlags = ({ flags }: { flags: Record }) => {
const forceUpdate = useUpdate();
return (
Feature Flags
Experimental
Changes are temporary. You can clear them by reloading the window or restarting the app.
{Object.entries(flags).map(([key, value]) => {
const flag = key as SessionFeatureFlagsKeys;
if (unsupportedFlags.includes(flag)) {
return null;
}
if (!isBoolean(value)) {
return (
<>
{flag}
{Object.entries(value).map(([k, v]: [string, any]) => {
const nestedFlag = k as SessionFeatureFlagsKeys;
return (
);
})}
>
);
}
return ;
})}
);
};
export const AboutInfo = () => {
const environmentStates = [];
if (window.getEnvironment() !== 'production') {
environmentStates.push(window.getEnvironment());
}
if (window.getAppInstance()) {
environmentStates.push(window.getAppInstance());
}
const aboutInfo = [
`${localize('updateVersion').withArgs({ version: window.getVersion() })}`,
`${localize('systemInformationDesktop').withArgs({ information: window.getOSRelease() })}`,
`${localize('commitHashDesktop').withArgs({ hash: window.getCommitHash() || window.i18n('unknown') })}`,
`${environmentStates.join(' - ')}`,
];
return (
About
{aboutInfo.map((info, index) => (
{info}
))}
);
};
export const OtherInfo = () => {
const otherInfo = useAsync(async () => {
const { id, vbid } = await window.getUserKeys();
return [`${localize('accountIdYours')}: ${id}`, `VBID: ${vbid}`];
}, []);
return (
Other Info
{otherInfo.value ? (
) : null}
{otherInfo.loading ? (
{localize('loading')}
) : otherInfo.error ? (
{localize('theError')}: {otherInfo.error.message || localize('errorUnknown')}
) : null}
{otherInfo.value
? otherInfo.value.map((info, index) => (
{info}
))
: null}
);
};