Skip to content

Commit

Permalink
Rebase warning messages on latest main
Browse files Browse the repository at this point in the history
  • Loading branch information
Marco Rodolfi committed Aug 9, 2024
1 parent 93b3919 commit 457e099
Show file tree
Hide file tree
Showing 6 changed files with 164 additions and 17 deletions.
9 changes: 9 additions & 0 deletions backend/decky_loader/locales/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,15 @@
"testing": "Testing"
}
},
"WarnThirdParty":{
"title_zip": "Third-Party Plugin Installation",
"title_repo": "Third-Party Store Selection",
"button_processing_one": "Please wait {{timer}} second",
"button_processing_many": "Please wait {{timer}} seconds",
"button_idle": "Continue",
"desc_zip": "The Decky Loader team has not reviewed this plugin. It may contain malware, such as software to steal your Steam account or harm your device. By installing this plugin, you agree you have assumed all risks to your device.",
"desc_repo": "The Decky Loader team does not maintain this plugin store. It and its plugins may contain malware, such as software to steal your Steam account or harm your device. By adding this store, you agree you have assumed all risks to your device."
},
"Testing": {
"download": "Download",
"error": "Error Installing PR",
Expand Down
78 changes: 78 additions & 0 deletions frontend/src/components/modals/WarnThirdParty.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import { ConfirmModal } from '@decky/ui';
import { FC, useEffect, useState } from 'react';
import { FaExclamationTriangle } from 'react-icons/fa';

import TranslationHelper, { TranslationClass } from '../../utils/TranslationHelper';
import { WarnThirdPartyType } from '../../utils/globalTypes';

interface WarnThirdPartyProps {
seconds?: number;
type: WarnThirdPartyType;
onOK(): void;
onCancel(): void;
closeModal?(): void;
}

const WarnThirdParty: FC<WarnThirdPartyProps> = ({ seconds = 5, type, onOK, onCancel, closeModal }) => {
const [waitTimer, setWaitTimer] = useState(seconds);

useEffect(() => {
// exit early when we reach 0
if (waitTimer <= 0) return;

// save intervalId to clear the interval when the
// component re-renders
const intervalId = setInterval(() => {
setWaitTimer(waitTimer - 1);
}, 1000);

// clear interval on re-render to avoid memory leaks
return () => clearInterval(intervalId);
// add waitTimer as a dependency to re-rerun the effect
// when we update it
}, [waitTimer]);

return (
<ConfirmModal
bOKDisabled={waitTimer > 0}
closeModal={closeModal}
onOK={async () => {
await onOK();
}}
onCancel={async () => {
await onCancel();
}}
strTitle={
<div>
<FaExclamationTriangle />
<TranslationHelper transClass={TranslationClass.WARN_THIRD_PARTY} transText="title" warnType={type} />
</div>
}
strOKButtonText={
waitTimer > 0 ? (
<div>
<TranslationHelper
transClass={TranslationClass.WARN_THIRD_PARTY}
transText="button_processing"
i18nArgs={{
timer: waitTimer,
}}
/>
</div>
) : (
<div>
<TranslationHelper transClass={TranslationClass.WARN_THIRD_PARTY} transText="button_idle" />
</div>
)
}
>
<span style={{ color: 'red' }}>
<div>
<TranslationHelper transClass={TranslationClass.WARN_THIRD_PARTY} transText="desc" warnType={type} />
</div>
</span>
</ConfirmModal>
);
};

export default WarnThirdParty;
22 changes: 21 additions & 1 deletion frontend/src/components/settings/pages/developer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
Navigation,
TextField,
Toggle,
showModal
} from '@decky/ui';
import { useRef, useState } from 'react';
import { useTranslation } from 'react-i18next';
Expand All @@ -18,6 +19,8 @@ import { installFromURL } from '../../../../store';
import { useSetting } from '../../../../utils/hooks/useSetting';
import { getSetting } from '../../../../utils/settings';
import { FileSelectionType } from '../../../modals/filepicker';
import WarnThirdParty from '../../../modals/WarnThirdParty';
import { WarnThirdPartyType } from '../../../../utils/globalTypes';
import RemoteDebuggingSettings from '../general/RemoteDebugging';

const logger = new Logger('DeveloperIndex');
Expand All @@ -43,6 +46,8 @@ export default function DeveloperSettings() {
const [enableValveInternal, setEnableValveInternal] = useSetting<boolean>('developer.valve_internal', false);
const [reactDevtoolsEnabled, setReactDevtoolsEnabled] = useSetting<boolean>('developer.rdt.enabled', false);
const [reactDevtoolsIP, setReactDevtoolsIP] = useSetting<string>('developer.rdt.ip', '');
const [acceptedWarning, setAcceptedWarning] = useSetting<boolean>('developer.warn.third_party', false);
const waitTime = acceptedWarning ? 0 : 5;
const [pluginURL, setPluginURL] = useState('');
const textRef = useRef<HTMLDivElement>(null);
const { t } = useTranslation();
Expand Down Expand Up @@ -72,7 +77,22 @@ export default function DeveloperSettings() {
}
icon={<FaLink style={{ display: 'block' }} />}
>
<DialogButton disabled={pluginURL.length == 0} onClick={() => installFromURL(pluginURL)}>
<DialogButton
disabled={pluginURL.length == 0}
onClick={() =>
showModal(
<WarnThirdParty
type={WarnThirdPartyType.ZIP}
onOK={() => {
setAcceptedWarning(true);
installFromURL(pluginURL);
}}
onCancel={() => {}}
seconds={waitTime}
/>,
)
}
>
{t('SettingsDeveloperIndex.third_party_plugins.button_install')}
</DialogButton>
</Field>
Expand Down
44 changes: 29 additions & 15 deletions frontend/src/components/settings/pages/general/StoreSelect.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
import { Dropdown, Field, TextField } from '@decky/ui';
import { Dropdown, Field, TextField, showModal } from '@decky/ui';
import { FunctionComponent } from 'react';
import { useTranslation } from 'react-i18next';
import { FaShapes } from 'react-icons/fa';

import Logger from '../../../../logger';
import { Store } from '../../../../store';
import { useSetting } from '../../../../utils/hooks/useSetting';
import WarnThirdParty from '../../../modals/WarnThirdParty';
import { WarnThirdPartyType } from '../../../../utils/globalTypes';

const logger = new Logger('StoreSelect');

const StoreSelect: FunctionComponent<{}> = () => {
const [selectedStore, setSelectedStore] = useSetting<Store>('store', Store.Default);
const [selectedStoreURL, setSelectedStoreURL] = useSetting<string | null>('store-url', null);
const [acceptedWarning, setAcceptedWarning] = useSetting<boolean>('store_select.warn.third_party', false);
const waitTime = acceptedWarning ? 0 : 5;
const { t } = useTranslation();
const tStores = [
t('StoreSelect.store_channel.default'),
Expand All @@ -38,20 +42,30 @@ const StoreSelect: FunctionComponent<{}> = () => {
}}
/>
</Field>
{selectedStore == Store.Custom && (
<Field
label={t('StoreSelect.custom_store.label')}
indentLevel={1}
description={
<TextField
label={t('StoreSelect.custom_store.url_label')}
value={selectedStoreURL || undefined}
onChange={(e) => setSelectedStoreURL(e?.target.value || null)}
/>
}
icon={<FaShapes style={{ display: 'block' }} />}
></Field>
)}
{selectedStore == Store.Custom &&
showModal(
<WarnThirdParty
type={WarnThirdPartyType.REPO}
seconds={waitTime}
onOK={() => {
setAcceptedWarning(true);
}}
onCancel={() => setSelectedStore(Store.Default)}
/>,
) && (
<Field
label={t('StoreSelect.custom_store.label')}
indentLevel={1}
description={
<TextField
label={t('StoreSelect.custom_store.url_label')}
value={selectedStoreURL || undefined}
onChange={(e) => setSelectedStoreURL(e?.target.value || null)}
/>
}
icon={<FaShapes style={{ display: 'block' }} />}
></Field>
)}
</>
);
};
Expand Down
24 changes: 23 additions & 1 deletion frontend/src/utils/TranslationHelper.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,28 @@
import { FC } from 'react';
import { Translation } from 'react-i18next';

import { WarnThirdPartyType } from './globalTypes';
import Logger from '../logger';
import { InstallType } from '../plugin';

export enum TranslationClass {
PLUGIN_LOADER = 'PluginLoader',
PLUGIN_INSTALL_MODAL = 'PluginInstallModal',
DEVELOPER = 'Developer',
WARN_THIRD_PARTY = 'WarnThirdParty',
}

interface TranslationHelperProps {
transClass: TranslationClass;
transText: string;
i18nArgs?: {};
installType?: number;
warnType?: WarnThirdPartyType;
}

const logger = new Logger('TranslationHelper');

const TranslationHelper: FC<TranslationHelperProps> = ({ transClass, transText, i18nArgs = null, installType = 0 }) => {
const TranslationHelper: FC<TranslationHelperProps> = ({ transClass, transText, i18nArgs = null, installType = 0, warnType = WarnThirdPartyType.REPO }) => {
return (
<Translation>
{(t, {}) => {
Expand Down Expand Up @@ -47,6 +50,25 @@ const TranslationHelper: FC<TranslationHelperProps> = ({ transClass, transText,
return i18nArgs
? t(TranslationClass.DEVELOPER + '.' + transText, i18nArgs)
: t(TranslationClass.DEVELOPER + '.' + transText);
//Handle different messages in different class cases
case TranslationClass.WARN_THIRD_PARTY:
//Needed only for title and description
if (!transText.startsWith('button')) {
switch (warnType) {
case WarnThirdPartyType.REPO:
return i18nArgs
? t(TranslationClass.WARN_THIRD_PARTY + '.' + transText + '_repo', i18nArgs)
: t(TranslationClass.WARN_THIRD_PARTY + '.' + transText + '_repo');
case WarnThirdPartyType.ZIP:
return i18nArgs
? t(TranslationClass.WARN_THIRD_PARTY + '.' + transText + '_zip', i18nArgs)
: t(TranslationClass.WARN_THIRD_PARTY + '.' + transText + '_zip');
}
} else {
return i18nArgs
? t(TranslationClass.WARN_THIRD_PARTY + '.' + transText, i18nArgs)
: t(TranslationClass.WARN_THIRD_PARTY + '.' + transText);
}
default:
logger.error('We should never fall in the default case!');
return '';
Expand Down
4 changes: 4 additions & 0 deletions frontend/src/utils/globalTypes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export enum WarnThirdPartyType {
REPO = 0,
ZIP = 1,
}

0 comments on commit 457e099

Please sign in to comment.