diff --git a/src/Wallets.tsx b/src/Wallets.tsx
index bd41369..5d4cfc6 100644
--- a/src/Wallets.tsx
+++ b/src/Wallets.tsx
@@ -357,7 +357,7 @@ export const Wallets = ({ setExtState, setRawWallet, rawWallet }) => {
}}
>
@@ -549,7 +549,7 @@ const WalletItem = ({ wallet, updateWalletItem, idx, setSelectedWallet }) => {
}}
>
diff --git a/src/components/Apps/AppsDesktop.tsx b/src/components/Apps/AppsDesktop.tsx
index 56c4985..a976534 100644
--- a/src/components/Apps/AppsDesktop.tsx
+++ b/src/components/Apps/AppsDesktop.tsx
@@ -54,13 +54,23 @@ export const AppsDesktop = ({
const myApp = useMemo(() => {
return availableQapps.find(
- (app) => app.name === myName && app.service === 'APP'
+ (app) =>
+ app.name === myName &&
+ app.service ===
+ t('core:app', {
+ postProcess: 'capitalizeAll',
+ })
);
}, [myName, availableQapps]);
const myWebsite = useMemo(() => {
return availableQapps.find(
- (app) => app.name === myName && app.service === 'WEBSITE'
+ (app) =>
+ app.name === myName &&
+ app.service ===
+ t('core:website', {
+ postProcess: 'capitalizeAll',
+ })
);
}, [myName, availableQapps]);
@@ -247,7 +257,6 @@ export const AppsDesktop = ({
setTabs((prev) => [...prev, newTab]);
setSelectedTab(newTab);
setMode('viewer');
-
setIsNewTabWindow(false);
};
@@ -258,6 +267,7 @@ export const AppsDesktop = ({
unsubscribeFromEvent('addTab', addTabFunc);
};
}, [tabs]);
+
const setSelectedTabFunc = (e) => {
const data = e.detail?.data;
if (e.detail?.isDevMode) return;
@@ -327,9 +337,9 @@ export const AppsDesktop = ({
return (
+
)}
+
+
{mode === 'publish' && !selectedTab && (
)}
+
{tabs.map((tab) => {
if (!iframeRefs.current[tab.tabId]) {
iframeRefs.current[tab.tabId] = React.createRef();
diff --git a/src/components/Apps/AppsDevMode.tsx b/src/components/Apps/AppsDevMode.tsx
index 14a289e..846867e 100644
--- a/src/components/Apps/AppsDevMode.tsx
+++ b/src/components/Apps/AppsDevMode.tsx
@@ -1,7 +1,6 @@
import React, { useEffect, useRef, useState } from 'react';
import { AppsDevModeHome } from './AppsDevModeHome';
import { Spacer } from '../../common/Spacer';
-
import {
executeEvent,
subscribeToEvent,
@@ -10,7 +9,6 @@ import {
import { AppsParent } from './Apps-styles';
import AppViewerContainer from './AppViewerContainer';
import ShortUniqueId from 'short-unique-id';
-
import { Box, ButtonBase, useTheme } from '@mui/material';
import { HomeIcon } from '../../assets/Icons/HomeIcon';
import { Save } from '../Save/Save';
@@ -137,7 +135,6 @@ export const AppsDevMode = ({
setTabs(copyTabs);
setSelectedTab(newTab);
setMode('viewer');
-
setIsNewTabWindow(false);
};
@@ -260,6 +257,7 @@ export const AppsDevMode = ({
}
/>
+
{
setDesktopViewMode('apps');
@@ -282,6 +280,7 @@ export const AppsDevMode = ({
/>
+
{
setDesktopViewMode('chat');
@@ -351,6 +350,7 @@ export const AppsDevMode = ({
}}
>
+
{
const { buffer, directoryPath } =
await window.electron.selectAndZipDirectory(existingDirectoryPath);
@@ -79,8 +78,7 @@ export const AppsDevModeHome = ({
setInfoSnackCustom({
type: 'error',
- message:
- 'Please use your local node for dev mode! Logout and use Local node.',
+ message: '',
});
return;
}
@@ -115,20 +113,21 @@ export const AppsDevModeHome = ({
const usingLocal = await isUsingLocal();
if (!usingLocal) {
setOpenSnackGlobal(true);
-
setInfoSnackCustom({
type: 'error',
- message:
- 'Please use your local node for dev mode! Logout and use Local node.',
+ message: t('core:message.generic.devmode_local_node', {
+ postProcess: 'capitalizeFirst',
+ }),
});
return;
}
if (!myName) {
setOpenSnackGlobal(true);
-
setInfoSnackCustom({
type: 'error',
- message: 'You need a name to use preview',
+ message: t('core:message.generic.name_preview', {
+ postProcess: 'capitalizeFirst',
+ }),
});
return;
}
@@ -137,15 +136,16 @@ export const AppsDevModeHome = ({
if (!buffer) {
setOpenSnackGlobal(true);
-
setInfoSnackCustom({
type: 'error',
- message: 'Please select a file',
+ message: t('core:message.generic.select_file', {
+ postProcess: 'capitalizeFirst',
+ }),
});
return;
}
- const postBody = Buffer.from(buffer).toString('base64');
+ const postBody = Buffer.from(buffer).toString('base64');
const endpoint = await createEndpoint(
`/arbitrary/APP/${myName}/zip?preview=true`
);
@@ -156,6 +156,7 @@ export const AppsDevModeHome = ({
},
body: postBody,
});
+
if (!response?.ok) throw new Error('Invalid zip');
const previewPath = await response.text();
if (tabId) {
@@ -192,20 +193,21 @@ export const AppsDevModeHome = ({
const usingLocal = await isUsingLocal();
if (!usingLocal) {
setOpenSnackGlobal(true);
-
setInfoSnackCustom({
type: 'error',
- message:
- 'Please use your local node for dev mode! Logout and use Local node.',
+ message: t('core:message.generic.devmode_local_node', {
+ postProcess: 'capitalizeFirst',
+ }),
});
return;
}
if (!myName) {
setOpenSnackGlobal(true);
-
setInfoSnackCustom({
type: 'error',
- message: 'You need a name to use preview',
+ message: t('core:message.generic.name_preview', {
+ postProcess: 'capitalizeFirst',
+ }),
});
return;
}
@@ -214,15 +216,16 @@ export const AppsDevModeHome = ({
if (!buffer) {
setOpenSnackGlobal(true);
-
setInfoSnackCustom({
type: 'error',
- message: 'Please select a file',
+ message: t('core:message.generic.select_file', {
+ postProcess: 'capitalizeFirst',
+ }),
});
return;
}
- const postBody = Buffer.from(buffer).toString('base64');
+ const postBody = Buffer.from(buffer).toString('base64');
const endpoint = await createEndpoint(
`/arbitrary/APP/${myName}/zip?preview=true`
);
@@ -233,8 +236,15 @@ export const AppsDevModeHome = ({
},
body: postBody,
});
- if (!response?.ok) throw new Error('Invalid zip');
+
+ if (!response?.ok)
+ throw new Error(
+ t('core:message.error.invalid_zip', {
+ postProcess: 'capitalizeFirst',
+ })
+ );
const previewPath = await response.text();
+
if (tabId) {
executeEvent('appsDevModeUpdateTab', {
data: {
@@ -276,7 +286,7 @@ export const AppsDevModeHome = ({
fontSize: '30px',
}}
>
- Dev Mode Apps
+ {t('core:devmode_apps', { postProcess: 'capitalizeFirst' })}
@@ -301,7 +311,9 @@ export const AppsDevModeHome = ({
+
- Server
+
+ {t('core:server', { postProcess: 'capitalizeFirst' })}
+
@@ -319,7 +331,9 @@ export const AppsDevModeHome = ({
+
- Zip
+
+ {t('core:zip', { postProcess: 'capitalizeFirst' })}
+
@@ -336,7 +350,9 @@ export const AppsDevModeHome = ({
+
- Directory
+
+ {t('core:directory', { postProcess: 'capitalizeFirst' })}
+
@@ -365,7 +381,9 @@ export const AppsDevModeHome = ({
objectFit: 'fill',
},
}}
- alt="Q-Sandbox"
+ alt={t('core:q_apps.q_sandbox', {
+ postProcess: 'capitalizeFirst',
+ })}
src={`${getBaseApiReact()}/arbitrary/THUMBNAIL/Q-Sandbox/qortal_avatar?async=true`}
>
- Q-Sandbox
+
+ {t('core:q_apps.q_sandbox', {
+ postProcess: 'capitalizeFirst',
+ })}
+
@@ -407,7 +429,9 @@ export const AppsDevModeHome = ({
objectFit: 'fill',
},
}}
- alt="API"
+ alt={t('core:api', {
+ postProcess: 'capitalizeAll',
+ })}
src={swaggerSVG}
>
- API
+
+ {t('core:api', {
+ postProcess: 'capitalizeAll',
+ })}
+
@@ -437,7 +465,9 @@ export const AppsDevModeHome = ({
}}
>
- {'Add custom framework'}
+ {t('core:action.add_custom_framework', {
+ postProcess: 'capitalizeFirst',
+ })}
@@ -446,15 +476,22 @@ export const AppsDevModeHome = ({
display: 'flex',
flexDirection: 'column',
gap: '5px',
- }} // TODO translate
+ }}
>
-
+
setDomain(e.target.value)}
/>
+
-
+
setPort(e.target.value)}
/>
@@ -474,15 +517,20 @@ export const AppsDevModeHome = ({
+
diff --git a/src/components/Apps/AppsDevModeNavBar.tsx b/src/components/Apps/AppsDevModeNavBar.tsx
index 5a632cd..e011ded 100644
--- a/src/components/Apps/AppsDevModeNavBar.tsx
+++ b/src/components/Apps/AppsDevModeNavBar.tsx
@@ -23,7 +23,6 @@ export const AppsDevModeNavBar = () => {
const [navigationController, setNavigationController] = useAtom(
navigationControllerAtom
);
-
const theme = useTheme();
const [isNewTabWindow, setIsNewTabWindow] = useState(false);
const tabsRef = useRef(null);
diff --git a/src/components/Apps/AppsHomeDesktop.tsx b/src/components/Apps/AppsHomeDesktop.tsx
index 21d9d7d..b2c67cf 100644
--- a/src/components/Apps/AppsHomeDesktop.tsx
+++ b/src/components/Apps/AppsHomeDesktop.tsx
@@ -16,6 +16,7 @@ import ArrowOutwardIcon from '@mui/icons-material/ArrowOutward';
import { AppsPrivate } from './AppsPrivate';
import ThemeSelector from '../Theme/ThemeSelector';
import LanguageSelector from '../Language/LanguageSelector';
+import { useTranslation } from 'react-i18next';
export const AppsHomeDesktop = ({
setMode,
@@ -26,6 +27,7 @@ export const AppsHomeDesktop = ({
}) => {
const [qortalUrl, setQortalUrl] = useState('');
const theme = useTheme();
+ const { t } = useTranslation(['core', 'group']);
const openQortalUrl = () => {
try {
@@ -41,6 +43,7 @@ export const AppsHomeDesktop = ({
console.log(error);
}
};
+
return (
<>
- Apps Dashboard
+ {t('core:apps_dashboard', { postProcess: 'capitalizeFirst' })}
@@ -66,14 +69,14 @@ export const AppsHomeDesktop = ({
>
- Library
+
+ {t('core:library', { postProcess: 'capitalizeFirst' })}
+
diff --git a/src/components/Apps/AppsLibraryDesktop.tsx b/src/components/Apps/AppsLibraryDesktop.tsx
index 64f1007..ebe0ddd 100644
--- a/src/components/Apps/AppsLibraryDesktop.tsx
+++ b/src/components/Apps/AppsLibraryDesktop.tsx
@@ -41,6 +41,7 @@ import { Virtuoso } from 'react-virtuoso';
import { executeEvent } from '../../utils/events';
import { ComposeP, ShowMessageReturnButton } from '../Group/Forum/Mail-styles';
import { ReturnIcon } from '../../assets/Icons/ReturnIcon.tsx';
+import { useTranslation } from 'react-i18next';
const officialAppList = [
'q-tube',
@@ -104,6 +105,7 @@ export const AppsLibraryDesktop = ({
const [searchValue, setSearchValue] = useState('');
const virtuosoRef = useRef(null);
const theme = useTheme();
+ const { t } = useTranslation(['core', 'group']);
const officialApps = useMemo(() => {
return availableQapps.filter(
@@ -210,9 +212,13 @@ export const AppsLibraryDesktop = ({
ml: 1,
paddingLeft: '12px',
}}
- placeholder="Search for apps"
+ placeholder={t('core:action.search_apps', {
+ postProcess: 'capitalizeFirst',
+ })}
inputProps={{
- 'aria-label': 'Search for apps',
+ 'aria-label': t('core:action.search_apps', {
+ postProcess: 'capitalizeFirst',
+ }),
fontSize: '16px',
fontWeight: 400,
}}
@@ -273,10 +279,14 @@ export const AppsLibraryDesktop = ({
}}
onClick={() => {
executeEvent('navigateBack', {});
- }} // TODO translate
+ }}
>
- Return to Apps Dashboard
+
+ {t('core:action.return_apps_dashboard', {
+ postProcess: 'capitalizeFirst',
+ })}
+
@@ -302,7 +312,11 @@ export const AppsLibraryDesktop = ({
) : searchedList?.length === 0 && debouncedValue ? (
- No results
+
+ {t('core:message.generic.no_results', {
+ postProcess: 'capitalizeFirst',
+ })}
+
) : (
<>
@@ -311,7 +325,7 @@ export const AppsLibraryDesktop = ({
fontSize: '30px',
}}
>
- Official Apps
+ {t('core:apps_official', { postProcess: 'capitalizeFirst' })}
@@ -396,7 +410,13 @@ export const AppsLibraryDesktop = ({
textAlign: 'start',
}}
>
- {hasPublishApp ? 'Update your app' : 'Publish your app'}
+ {hasPublishApp
+ ? t('core:action.update_app', {
+ postProcess: 'capitalizeFirst',
+ })
+ : t('core:action.publish_app', {
+ postProcess: 'capitalizeFirst',
+ })}
@@ -422,7 +442,13 @@ export const AppsLibraryDesktop = ({
}}
>
- {hasPublishApp ? 'Update' : 'Publish'}
+ {hasPublishApp
+ ? t('core:action.update', {
+ postProcess: 'capitalizeFirst',
+ })
+ : t('core:action.publish', {
+ postProcess: 'capitalizeFirst',
+ })}
@@ -441,7 +467,9 @@ export const AppsLibraryDesktop = ({
fontSize: '30px',
}}
>
- Categories
+ {t('core:category_other', {
+ postProcess: 'capitalizeFirst',
+ })}
@@ -480,7 +508,7 @@ export const AppsLibraryDesktop = ({
},
}}
>
- All
+ {t('core:all', { postProcess: 'capitalizeFirst' })}
diff --git a/src/components/Apps/AppsNavBarDesktop.tsx b/src/components/Apps/AppsNavBarDesktop.tsx
index 8d45604..f294834 100644
--- a/src/components/Apps/AppsNavBarDesktop.tsx
+++ b/src/components/Apps/AppsNavBarDesktop.tsx
@@ -32,6 +32,7 @@ import {
sortablePinnedAppsAtom,
} from '../../atoms/global';
import { useAtom, useSetAtom } from 'jotai';
+import { useTranslation } from 'react-i18next';
export function saveToLocalStorage(key, subKey, newValue) {
try {
@@ -75,7 +76,7 @@ export const AppsNavBarDesktop = ({ disableBack }) => {
);
const theme = useTheme();
-
+ const { t } = useTranslation(['core', 'group']);
const [isNewTabWindow, setIsNewTabWindow] = useState(false);
const tabsRef = useRef(null);
const [anchorEl, setAnchorEl] = useState(null);
@@ -238,6 +239,7 @@ export const AppsNavBarDesktop = ({ disableBack }) => {
}}
/>
+
{
if (!selectedTab) return;
@@ -274,9 +276,9 @@ export const AppsNavBarDesktop = ({ disableBack }) => {
paper: {
sx: {
backgroundColor: theme.palette.background.default,
+ borderRadius: '5px',
color: theme.palette.text.primary,
width: '148px',
- borderRadius: '5px',
},
},
}}
@@ -375,9 +377,18 @@ export const AppsNavBarDesktop = ({ disableBack }) => {
: theme.palette.text.primary,
},
}}
- primary={`${isSelectedAppPinned ? 'Unpin app' : 'Pin app'}`}
+ primary={`${
+ isSelectedAppPinned
+ ? t('core:action.unpin_app', {
+ postProcess: 'capitalizeFirst',
+ })
+ : t('core:action.pin_app', {
+ postProcess: 'capitalizeFirst',
+ })
+ }}`}
/>
+
)}
diff --git a/src/components/Apps/AppsPrivate.tsx b/src/components/Apps/AppsPrivate.tsx
index cddbc12..fb0a4dd 100644
--- a/src/components/Apps/AppsPrivate.tsx
+++ b/src/components/Apps/AppsPrivate.tsx
@@ -36,6 +36,7 @@ import { fileToBase64 } from '../../utils/fileReading';
import { objectToBase64 } from '../../qdn/encryption/group-encryption';
import { getFee } from '../../background';
import { useAtom } from 'jotai';
+import { useTranslation } from 'react-i18next';
const maxFileSize = 50 * 1024 * 1024; // 50MB
@@ -62,6 +63,7 @@ export const AppsPrivate = ({ myName }) => {
const [memberGroups] = useAtom(memberGroupsAtom);
const theme = useTheme();
+ const { t } = useTranslation(['core', 'group']);
const myGroupsPrivate = useMemo(() => {
return memberGroups?.filter(
@@ -98,9 +100,11 @@ export const AppsPrivate = ({ myName }) => {
errors.forEach((error) => {
if (error.code === 'file-too-large') {
console.error(
- `File ${file.name} is too large. Max size allowed is ${
- maxFileSize / (1024 * 1024)
- } MB.`
+ t('core:message.error.file_too_large', {
+ filename: file.name,
+ size: maxFileSize / (1024 * 1024),
+ postProcess: 'capitalizeFirst',
+ })
);
}
});
@@ -111,7 +115,6 @@ export const AppsPrivate = ({ myName }) => {
const addPrivateApp = async () => {
try {
if (privateAppValues?.groupId === 0) return;
-
await openApp(privateAppValues, true);
} catch (error) {
console.error(error);
@@ -139,9 +142,28 @@ export const AppsPrivate = ({ myName }) => {
const publishPrivateApp = async () => {
try {
if (selectedGroup === 0) return;
- if (!logo) throw new Error('Please select an image for a logo');
- if (!myName) throw new Error('You need a Qortal name to publish');
- if (!newPrivateAppValues?.name) throw new Error('Your app needs a name');
+
+ if (!logo)
+ throw new Error(
+ t('core:message.generic.select_image', {
+ postProcess: 'capitalizeFirst',
+ })
+ );
+
+ if (!myName)
+ throw new Error(
+ t('core:message.generic.name_publish', {
+ postProcess: 'capitalizeFirst',
+ })
+ );
+
+ if (!newPrivateAppValues?.name)
+ throw new Error(
+ t('core:message.error.app_need_name', {
+ postProcess: 'capitalizeFirst',
+ })
+ );
+
const base64Logo = await fileToBase64(logo);
const base64App = await fileToBase64(file);
const objectToSave = {
@@ -160,16 +182,22 @@ export const AppsPrivate = ({ myName }) => {
if (decryptedData?.error) {
throw new Error(
- decryptedData?.error || 'Unable to encrypt app. App not published'
+ decryptedData?.error ||
+ t('core:message.error.unable_encrypt_app', {
+ postProcess: 'capitalizeFirst',
+ })
);
}
const fee = await getFee('ARBITRARY');
await show({
- message: 'Would you like to publish this app?',
+ message: t('core:save_options.publish_app', {
+ postProcess: 'capitalizeFirst',
+ }),
publishFee: fee.fee + ' QORT',
});
+
await new Promise((res, rej) => {
window
.sendMessage('publishOnQDN', {
@@ -185,7 +213,12 @@ export const AppsPrivate = ({ myName }) => {
rej(response.error);
})
.catch((error) => {
- rej(error.message || 'An error occurred');
+ rej(
+ error.message ||
+ t('core:message.error.generic', {
+ postProcess: 'capitalizeFirst',
+ })
+ );
});
});
@@ -203,7 +236,11 @@ export const AppsPrivate = ({ myName }) => {
setOpenSnackGlobal(true);
setInfoSnackCustom({
type: 'error',
- message: error?.message || 'Unable to publish app',
+ message:
+ error?.message ||
+ t('core:message.error.unable_publish_app', {
+ postProcess: 'capitalizeFirst',
+ }),
});
}
};
@@ -241,6 +278,7 @@ export const AppsPrivate = ({ myName }) => {
Private
+
{isOpenPrivateModal && (
+
+
{
marginTop: '15px',
}}
>
-
+
{
}
/>
+
{
marginTop: '15px',
}}
>
-
+
+
setPrivateAppValues((prev) => {
@@ -397,7 +458,7 @@ export const AppsPrivate = ({ myName }) => {
setIsOpenPrivateModal(false);
}}
>
- Close
+ {t('core:action.close', { postProcess: 'capitalizeFirst' })}
>
@@ -424,7 +485,9 @@ export const AppsPrivate = ({ myName }) => {
fontSize: '14px',
}}
>
- Select .zip file containing static content:{' '}
+ {t('core:message.generic.select_zip', {
+ postProcess: 'capitalizeFirst',
+ })}
@@ -435,10 +498,11 @@ export const AppsPrivate = ({ myName }) => {
fontSize: '14px',
}}
>{`
- 50mb MB maximum`}
+ 50mb MB max`}
{file && (
<>
+
{`Selected: (${file?.name})`}
>
)}
@@ -454,7 +518,13 @@ export const AppsPrivate = ({ myName }) => {
>
{' '}
- {file ? 'Change' : 'Choose'} File
+ {file
+ ? t('core:action.change_file', {
+ postProcess: 'capitalizeFirst',
+ })
+ : t('core:action.choose_file', {
+ postProcess: 'capitalizeFirst',
+ })}
@@ -466,10 +536,18 @@ export const AppsPrivate = ({ myName }) => {
gap: '5px',
}}
>
-
+
+
+