From daa8a9145b650162977d922a49fdfa4bd8e33d42 Mon Sep 17 00:00:00 2001 From: Nicola Benaglia Date: Fri, 16 May 2025 09:08:45 +0200 Subject: [PATCH] Translate app --- src/Wallets.tsx | 4 +- src/components/Apps/AppsDesktop.tsx | 24 ++- src/components/Apps/AppsDevMode.tsx | 6 +- src/components/Apps/AppsDevModeHome.tsx | 130 +++++++++++------ src/components/Apps/AppsDevModeNavBar.tsx | 1 - src/components/Apps/AppsHomeDesktop.tsx | 19 ++- src/components/Apps/AppsLibraryDesktop.tsx | 48 ++++-- src/components/Apps/AppsNavBarDesktop.tsx | 22 ++- src/components/Apps/AppsPrivate.tsx | 162 ++++++++++++++++----- src/i18n/locales/en/auth.json | 1 - src/i18n/locales/en/core.json | 43 +++++- src/i18n/locales/en/group.json | 1 + 12 files changed, 352 insertions(+), 109 deletions(-) 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', + }) + }}`} /> + { if (selectedTab?.refreshFunc) { @@ -404,6 +415,7 @@ export const AppsNavBarDesktop = ({ disableBack }) => { }} /> + { color: theme.palette.text.primary, }, }} - primary="Copy link" + primary={t('core:action.copy_link', { + 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 && ( { display: 'flex', flexDirection: 'column', gap: '5px', - }} // TODO translate + }} > - - + + + + + { 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', }} > - + + + setNewPrivateAppValues((prev) => { @@ -525,9 +611,14 @@ export const AppsPrivate = ({ myName }) => { marginTop: '15px', }} > - + + setNewPrivateAppValues((prev) => { @@ -543,10 +634,15 @@ export const AppsPrivate = ({ myName }) => { setLogo(file)}> - + {logo?.name} + @@ -558,7 +654,7 @@ export const AppsPrivate = ({ myName }) => { clearFields(); }} > - Close + {t('core:action.close', { postProcess: 'capitalizeFirst' })} diff --git a/src/i18n/locales/en/auth.json b/src/i18n/locales/en/auth.json index 8a514fa..d212416 100644 --- a/src/i18n/locales/en/auth.json +++ b/src/i18n/locales/en/auth.json @@ -37,7 +37,6 @@ "your_accounts": "your saved accounts" } }, - "name": "name", "node": { "choose": "choose custom node", "custom_many": "custom nodes", diff --git a/src/i18n/locales/en/core.json b/src/i18n/locales/en/core.json index 90f00b6..e78df4c 100644 --- a/src/i18n/locales/en/core.json +++ b/src/i18n/locales/en/core.json @@ -1,20 +1,26 @@ { "action": { "add": "add", + "add_custom_framework": "add custom framework", "accept": "accept", + "access": "access", "backup_account": "backup account", "backup_wallet": "backup wallet", "cancel": "cancel", "cancel_invitation": "cancel invitation", "change": "change", + "change_file": "change file", "change_language": "change language", "choose": "choose", + "choose_file": "choose file", "close": "close", "continue": "continue", "continue_logout": "continue to logout", + "copy_link": "copy link", "create_apps": "create apps", "create_file": "create file", "create_thread": "create thread", + "choose_logo": "choose a logo", "choose_name": "choose a name", "decline": "decline", "decrypt": "decrypt", @@ -34,30 +40,44 @@ "notify": "notify", "open": "open", "pin": "pin", + "pin_app": "pin app", "pin_from_dashboard": "pin from dashboard", "post": "post", "post_message": "post message", "publish": "publish", + "publish_app": "publish your app", "register_name": "register name", "remove": "remove", + "return_apps_dashboard": "return to Apps Dashboard", "save": "save", + "search_apps": "search for apps", "select_app_type": "select App Type", "select_category": "select Category", "select_name_app": "select Name/App", "start_minting": "start minting", "unpin": "unpin", - "unpin_from_dashboard": "unpin from dashboard" + "unpin_app": "unpin app", + "unpin_from_dashboard": "unpin from dashboard", + "update": "update", + "update_app": "update your app" }, "admin": "admin", + "all": "all", + "api": "API", "app": "app", + "app_name": "app name", "app_service_type": "app service type", + "apps_dashboard": "apps Dashboard", + "apps_official": "official Apps", "category": "category", + "category_other": "categories", "core": { "block_height": "block height", "information": "core information", "peers": "connected peers", "version": "core version" }, + "domain": "domain", "ui": { "version": "UI version" }, @@ -66,14 +86,18 @@ "one": "one" }, "description": "description", + "devmode_apps": "dev Mode Apps", + "directory": "directory", "downloading_qdn": "downloading from QDN", "fee": { "payment": "payment fee", "publish": "publish fee" }, "general_settings": "general settings", + "identifier": "identifier", "last_height": "last height", "level": "level", + "library": "library", "list": { "invite": "invite list", "join_request": "join request list", @@ -85,31 +109,41 @@ "message": { "error": { "address_not_found": "your address was not found", + "app_need_name": "your app needs a name", "file_too_large": "file {{ filename }} is too large. Max size allowed is {{ size }} MB.", "generic": "an error occurred", "incorrect_password": "incorrect password", + "invalid_zip": "invalid zip", "minting_account_add": "unable to add minting account", "minting_account_remove": "unable to remove minting account", "missing_fields": "missing: {{ fields }}", "publish_app": "unable to publish app", "rating_option": "cannot find rating option", "save_qdn": "unable to save to QDN", + "unable_encrypt_app": "unable to encrypt app. App not published'", + "unable_publish_app": "unable to publish app", "unable_rate": "unable to rate" }, "generic": { + "devmode_local_node": "please use your local node for dev mode! Logout and use Local node.", "name_available": "{{ name }} is available", "name_benefits": "benefits of a name", "name_checking": "checking if name already exists", + "name_preview": "you need a name to use preview", + "name_publish": "you need a Qortal name to publish", "name_rate": "you need a name to rate.", "name_registration": "your balance is {{ balance }} QORT. A name registration requires a {{ fee }} QORT fee", "name_unavailable": "{{ name }} is unavailable", "no_description": "no description", "no_notifications": "no new notifications", + "no_results": "no results", "one_app_per_name": "note: Currently, only one App and Website is allowed per Name.", "publish_data": "publish data to Qortal: anything from apps to videos. Fully decentralized!", "publishing": "publishing... Please wait.", "rating": "rating for {{ service }} {{ name }}", "secure_ownership": "secure ownership of data published by your name. You can even sell your name, along with your data to a third party.", + "select_file": "please select a file", + "select_image": "please select an image for a logo", "select_zip": "select .zip file containing static content:" }, "question": { @@ -131,6 +165,7 @@ } }, "minting_status": "minting status", + "name": "name", "name_app": "name/App", "none": "none", "page": { @@ -140,10 +175,12 @@ "previous": "previous" }, "payment_notification": "payment notification", + "port": "port", "price": "price", "q_apps": { "about": "about this Q-App", - "q_mail": "q-mail" + "q_mail": "q-mail", + "q_sandbox": "q-Sandbox" }, "save_options": { "no_pinned_changes": "you currently do not have any changes to your pinned apps", @@ -162,6 +199,7 @@ "settings": "you are using the export/import way of saving settings.", "unsaved_changes": " you have unsaved changes to your pinned apps. Save them to QDN." }, + "server": "server", "settings": "settings", "supply": "supply", "tags": "tags", @@ -180,6 +218,7 @@ "title": "title", "tutorial": "tutorial", "user_lookup": "user lookup", + "zip": "zip", "wallet": { "wallet": "wallet", "wallet_other": "wallets" diff --git a/src/i18n/locales/en/group.json b/src/i18n/locales/en/group.json index 7a8cc23..009ab97 100644 --- a/src/i18n/locales/en/group.json +++ b/src/i18n/locales/en/group.json @@ -78,6 +78,7 @@ "no_selection": "no group selected", "not_part_group": "you are not part of the encrypted group of members. Wait until an admin re-encrypts the keys.", "only_encrypted": "only unencrypted messages will be displayed.", + "only_private_groups": "only private groups will be shown", "private_key_copied": "private key copied", "provide_message": "please provide a first message to the thread", "secure_place": "keep your private key in a secure place. Do not share!",