You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
vizality/src/core/builtins/settings/components/General.jsx

270 lines
10 KiB

import { SwitchItem, ButtonItem, Category } from '@vizality/components/settings';
import { Clickable, Button, FormNotice } from '@vizality/components';
import { Directories, Repositories } from '@vizality/constants';
import { removeDirRecursive } from '@vizality/util/file';
import React, { memo, useState, useEffect } from 'react';
import { Messages, chosenLocale } from '@vizality/i18n';
import { joinClassNames } from '@vizality/util/dom';
import { getModule } from '@vizality/webpack';
import { readdirSync, existsSync } from 'fs';
import { useFilter } from '@vizality/hooks';
import { clipboard } from 'electron';
import moment from 'moment';
export default memo(({ builtin, search = '' }) => {
const [ copyText, setCopyText ] = useState(Messages.COPY);
const [ pathsRevealed, setPathsRevealed ] = useState();
const [ pluginsRevealed, setPluginsRevealed ] = useState();
const [ transparentWindow, setTransparentWindow ] = vizality.api.settings.useSetting('transparentWindow', false);
const [ isDiscordCacheCleared, setDiscordCacheCleared ] = useState(false);
const [ isVizalityCacheCleared, setVizalityCacheCleared ] = useState(false);
/**
* Clears Discord's cache.
* @returns {void}
*/
const clearDiscordCache = () => {
try {
setDiscordCacheCleared(true);
vizality.native.app.clearCache();
setTimeout(() => {
setDiscordCacheCleared(false);
}, 2500);
} catch (err) {
builtin.error(err);
}
};
/**
* Clears Vizality's cache.
* @returns {void}
*/
const clearVizalityCache = () => {
try {
setVizalityCacheCleared(true);
removeDirRecursive(Directories.CACHE)
.then(() => {
setTimeout(() => {
setVizalityCacheCleared(false);
}, 2500);
});
} catch (err) {
builtin.error(err);
}
};
/**
*
* @returns {void}
*/
const handleDebugInfoCopy = () => {
const plugins = vizality.manager.plugins.getEnabledKeys();
const extract = document.querySelector('.vz-updater-debug-info > code')
.innerText.replace(/([A-Z/ ]+) (?=\s(?!C:\\).*?:)/g, '\n[$1]').replace(/(.*?):\s(.*.+)/g, '$1="$2"').replace(/[ -](\w*(?=.*=))/g, '$1');
setCopyText(Messages.COPIED);
clipboard.writeText(
`\`\`\`ini
# Debugging Information | Result created: ${moment().calendar()}
${extract.substring(0, extract.indexOf('\nPlugins', extract.indexOf('\nPlugins') + 1))}
Plugins="${plugins.join(', ')}"
\`\`\``.replace(/ {6}|n\/a/g, '').replace(/(?![0-9]{1,3}) \/ (?=[0-9]{1,3})/g, '/')
);
setTimeout(() => setCopyText(Messages.COPY), 2500);
};
/**
*
* @note Intentionally left english-only.
* @returns {void}
*/
const renderDebugInfo = () => {
const { getRegisteredExperiments, getExperimentOverrides } = getModule('initialize', 'getExperimentOverrides');
const superProperties = getModule('getSuperPropertiesBase64').getSuperProperties();
const plugins = vizality.manager.plugins.getEnabledKeys();
const experimentOverrides = Object.keys(getExperimentOverrides()).length;
const availableExperiments = Object.keys(getRegisteredExperiments()).length;
const discordPath = process.resourcesPath.slice(0, -10);
const maskPath = (path) => {
path = path.replace(/(?:\/home\/|C:\\Users\\|\/Users\/)([ \w.-]+).*/i, (path, username) => {
const usernameIndex = path.indexOf(username);
return [ path.slice(0, usernameIndex), username.charAt(0) + username.slice(1).replace(/[a-zA-Z]/g, '*'),
path.slice(usernameIndex + username.length) ].join('');
});
return path;
};
const cachedFiles = (existsSync(Directories.CACHE) && readdirSync(Directories.CACHE)
.map(d => readdirSync(`${Directories.CACHE}/${d}`))
.flat().length) || 'n/a';
const createPathReveal = (title, path) =>
<div className='full-column'>
{title}:&#10;<a
onMouseEnter={() => setPathsRevealed(true)}
onMouseLeave={() => setPathsRevealed(false)}
onClick={() => window.DiscordNative.fileManager.showItemInFolder(path)}
>{pathsRevealed ? path : maskPath(path)}</a>
</div>;
return <FormNotice
type={FormNotice.Types.PRIMARY}
body={<div className={ joinClassNames('vz-updater-debug-info', { copied: copyText === Messages.COPIED })}>
<code>
<b>System / Discord</b>
<div className='row'>
<div className='column'>Locale:&#10;{chosenLocale}</div>
<div className='column'>OS:&#10;{(window.platform.os).toString()}</div>
<div className='column'>Architecture:&#10;{superProperties.os_arch}</div>
{process.platform === 'linux' && (
<div className='column'>Distro:&#10;{superProperties.distro || 'n/a'}</div>
)}
<div className='column'>Release Channel:&#10;{superProperties.release_channel}</div>
<div className='column'>App Version:&#10;{superProperties.client_version}</div>
<div className='column'>Build Number:&#10;{superProperties.client_build_number}</div>
<div className='column'>Build ID:&#10;{window.GLOBAL_ENV.SENTRY_TAGS.buildId}</div>
<div className='column'>Experiments:&#10;{experimentOverrides} / {availableExperiments}</div>
</div>
<b>Process Versions</b>
<div className='row'>
<div className='column'>React:&#10;{React.version}</div>
{[ 'electron', 'chrome', 'node' ].map(proc =>
<div className='column'>{proc.charAt(0).toUpperCase() + proc.slice(1)}:&#10;{process.versions[proc]}</div>
)}
</div>
<b>Vizality</b>
<div className='row'>
<div className='column'>Commands:&#10;{vizality.api.commands.getAllCommands().length}</div>
<div className='column'>Settings:&#10;{Object.keys(vizality.api.settings?.store?.getAllSettings()).length}</div>
<div className='column'>Plugins:&#10;{vizality.manager.plugins.getEnabledKeys().length} / {vizality.manager.plugins.count}
</div>
<div className='column'>Themes:&#10;{vizality.manager.themes.getEnabledKeys().length} / {vizality.manager.themes.count}
</div>
<div className='column'>Cached Files:&#10;{cachedFiles}</div>
<div className='column'>APIs:&#10;{vizality.manager.apis._apis.length}</div>
</div>
<b>Git</b>
<div className='row'>
<div className='column'>Upstream:&#10;{vizality.git.upstream.replace(Repositories.VIZALITY, 'Official')}</div>
<div className='column'>Revision:&#10;
<a
href={`https://github.com/${vizality.git.upstream}/commit/${vizality.git.revision}`}
target='_blank'
>
[{vizality.git.revision.substring(0, 7)}]
</a>
</div>
<div className='column'>Branch:&#10;{vizality.git.branch}</div>
<div className='column'>{`Latest:\n${!vizality.manager.builtins.get('updater').settings.get('updates', []).find(update => update.updateId === 'vizality')}`}</div>
</div>
<b>Listings</b>
<div className='row'>
{createPathReveal('Vizality Path', vizality.dir)}
{createPathReveal('Discord Path', discordPath)}
<div className='full-column'>Experiments:&#10;{experimentOverrides ? Object.keys(getExperimentOverrides()).join(', ') : 'n/a'}</div>
<div className='full-column'>
Plugins:&#10;
{(plugins.length > 6 ? `${(pluginsRevealed ? plugins : plugins.slice(0, 6)).join(', ')}` : plugins.join(', ')) || 'n/a'}&nbsp;
{plugins.length > 6 &&
<Clickable tag='a' onClick={() => setPluginsRevealed(!pluginsRevealed)}>
{pluginsRevealed ? 'Show less' : 'Show more'}
</Clickable>}
</div>
</div>
</code>
<Button
size={Button.Sizes.SMALL}
color={copyText === Messages.COPIED ? Button.Colors.GREEN : Button.Colors.BRAND}
onClick={() => handleDebugInfoCopy()}
>
{copyText}
</Button>
</div>}
/>;
};
const items = [
{
search: [
Messages.VIZALITY_SETTINGS_TRANSPARENT_WINDOW,
Messages.VIZALITY_SETTINGS_TRANSPARENT_WINDOW_DESC,
'pizza'
],
render: query =>
<SwitchItem
description={Messages.VIZALITY_SETTINGS_TRANSPARENT_WINDOW_DESC}
value={transparentWindow}
onChange={() => setTransparentWindow(!transparentWindow)}
info={Messages.VIZALITY_SETTINGS_TRANSPARENT_WINDOW_INFO.format()}
requiresRestart
>
{Messages.VIZALITY_SETTINGS_TRANSPARENT_WINDOW}
</SwitchItem>
},
{
search: [
Messages.VIZALITY_SETTINGS_CACHE_VIZALITY,
Messages.VIZALITY_SETTINGS_CACHE_VIZALITY_DESC,
'cake'
],
render: query =>
<ButtonItem
note={Messages.VIZALITY_SETTINGS_CACHE_VIZALITY_DESC}
button={isVizalityCacheCleared ? Messages.VIZALITY_SETTINGS_CACHE_CLEARED : Messages.VIZALITY_SETTINGS_CACHE_VIZALITY}
success={isVizalityCacheCleared}
onClick={() => clearVizalityCache()}
>
{Messages.VIZALITY_SETTINGS_CACHE_VIZALITY}
</ButtonItem>
},
{
search: [
Messages.VIZALITY_SETTINGS_CACHE_DISCORD,
Messages.VIZALITY_SETTINGS_CACHE_DISCORD_DESC,
'pie'
],
render: query =>
<ButtonItem
note={Messages.VIZALITY_SETTINGS_CACHE_DISCORD_DESC}
button={isDiscordCacheCleared ? Messages.VIZALITY_SETTINGS_CACHE_CLEARED : Messages.VIZALITY_SETTINGS_CACHE_DISCORD}
success={isDiscordCacheCleared}
onClick={() => clearDiscordCache()}
>
{Messages.VIZALITY_SETTINGS_CACHE_DISCORD}
</ButtonItem>
},
{
search: [
Messages.VIZALITY_UPDATES_OPTS_DEBUG,
Messages.VIZALITY_UPDATES_OPTS_DEBUG_DESC,
'pie'
],
render: query =>
<Category
icon='Bug'
title={Messages.VIZALITY_UPDATES_OPTS_DEBUG}
description={Messages.VIZALITY_UPDATES_OPTS_DEBUG_DESC}
>
{renderDebugInfo()}
</Category>
}
];
const [ query, setQuery, filteredResults ] = useFilter({
keys: [ 'search' ],
data: items
});
useEffect(() => {
setQuery(search);
}, [ search ]);
return filteredResults.map(result => result.render(query));
});