diff --git a/.gitignore b/.gitignore index 7c68bc4670a5..1429728761ce 100644 --- a/.gitignore +++ b/.gitignore @@ -122,3 +122,4 @@ common/autoinstallers/*/.npmrc /package-lock.json /yarn.lock quick-lint-js.config +.aider* diff --git a/.ignore b/.ignore index 376b54a68a75..c98d244df8cb 100644 --- a/.ignore +++ b/.ignore @@ -1,5 +1,3 @@ # Ignores for rg or ag patches/ -packages/mask/dashboard/assets/images/SetupTutorial.svg - **/locale/*.{po,json} diff --git a/.node-version b/.node-version index 7bceec795e9d..c9758a53fae1 100644 --- a/.node-version +++ b/.node-version @@ -1 +1 @@ -v22.2.0 +v23.6.0 diff --git a/cspell.json b/cspell.json index 91f589c6ff26..d6adcdaa4644 100644 --- a/cspell.json +++ b/cspell.json @@ -241,15 +241,17 @@ "ignoreRegExpList": ["/[A-Za-z0-9]{44}/", "/[A-Za-z0-9]{46}/", "/[A-Za-z0-9]{59}/"], "overrides": [], "words": [ - "Arbitrum", - "Boba", + "arbitrum", + "boba", "cashtags", - "Celo", + "celo", "endregion", "linkedin", "luma", "muln", - "Sepolia", + "reposted", + "reposts", + "sepolia", "tanstack", "tiktok", "tweetnacl", diff --git a/eslint.config.js b/eslint.config.js index 2be082cd7ad2..ab76f3c319c2 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -529,7 +529,7 @@ const moduleSystemRules = { 'import/no-duplicates': 'warn', // duplicate specifiers 'import/no-empty-named-blocks': 'warn', // bans import T, {} 'unused-imports/no-unused-imports': 'warn', - // 'unicorn/prefer-node-protocol': 'warn', + 'unicorn/prefer-node-protocol': 'warn', '@typescript-eslint/consistent-type-exports': ['warn', { fixMixedExportsWithInlineTypeSpecifier: true }], '@typescript-eslint/consistent-type-imports': [ 'warn', @@ -597,7 +597,6 @@ export default tseslint.config( '**/i18n_generated.ts', '**/languages.ts', 'packages/contracts', - 'packages/scripts', 'packages/mask/.webpack', ], }, diff --git a/package.json b/package.json index 091418e1f01d..e24be32b1f77 100644 --- a/package.json +++ b/package.json @@ -3,11 +3,11 @@ "type": "module", "packageManager": "pnpm@9.12.1", "engines": { - "node": ">=22.2.0", + "node": ">=23.6.0", "yarn": ">=999.0.0", "npm": ">=999.0.0" }, - "version": "2.32.2", + "version": "2.32.3", "private": true, "license": "AGPL-3.0-or-later", "scripts": { @@ -70,7 +70,6 @@ "@masknet/eslint-plugin": "^0.3.0", "@masknet/typescript-plugin": "workspace:^", "@nice-labs/git-rev": "^3.5.1", - "@swc-node/register": "^1.10.9", "@swc/core": "1.11.7", "@tanstack/eslint-plugin-query": "^5.66.1", "@types/lodash-es": "^4.17.12", @@ -155,10 +154,10 @@ "@protobufjs/inquire@1.1.0": "patches/@protobufjs__inquire@1.1.0.patch", "eslint-plugin-i@2.29.1": "patches/eslint-plugin-i@2.29.1.patch", "react-use@17.5.0": "patches/react-use@17.5.0.patch", - "gulp@5.0.0": "patches/gulp@5.0.0.patch", "react-devtools-inline@5.3.0": "patches/react-devtools-inline@5.3.0.patch", "@splinetool/runtime@0.9.342": "patches/@splinetool__runtime@0.9.342.patch", - "@scamsniffer/detector": "patches/@scamsniffer__detector.patch" + "@scamsniffer/detector": "patches/@scamsniffer__detector.patch", + "gulp": "patches/gulp.patch" } } } diff --git a/packages/backup-format/src/version-3/index.ts b/packages/backup-format/src/version-3/index.ts index 5dfac57fc913..2f50229a95bf 100644 --- a/packages/backup-format/src/version-3/index.ts +++ b/packages/backup-format/src/version-3/index.ts @@ -14,10 +14,11 @@ export async function encryptBackup(password: BufferSource, binaryBackup: Buffer export async function decryptBackup(password: BufferSource, data: ArrayBuffer | ArrayLike) { const container = await parseEncryptedJSONContainer(SupportedVersions.Version0, data) - const _ = decode(container) - if (!Array.isArray(_) || _.length !== 3) throw new TypeError(BackupErrors.UnknownFormat) - if (!_.every((x): x is Uint8Array => x instanceof Uint8Array)) throw new TypeError(BackupErrors.UnknownFormat) - const [pbkdf2IV, encryptIV, encrypted] = _ + const payloadTuple = decode(container) + if (!Array.isArray(payloadTuple) || payloadTuple.length !== 3) throw new TypeError(BackupErrors.UnknownFormat) + if (!payloadTuple.every((x): x is Uint8Array => x instanceof Uint8Array)) + throw new TypeError(BackupErrors.UnknownFormat) + const [pbkdf2IV, encryptIV, encrypted] = payloadTuple const aes = await getAESFromPassword(password, pbkdf2IV) diff --git a/packages/backup-format/tests/encryption.ts b/packages/backup-format/tests/encryption.ts index 424bc9d077ed..8805cf56c069 100644 --- a/packages/backup-format/tests/encryption.ts +++ b/packages/backup-format/tests/encryption.ts @@ -1,5 +1,5 @@ import { test, expect, beforeAll } from 'vitest' -import { webcrypto } from 'crypto' +import { webcrypto } from 'node:crypto' import { encryptBackup, decryptBackup } from '../src/index.js' beforeAll(() => { diff --git a/packages/gun-utils/builder.mjs b/packages/gun-utils/builder.mjs index cca981f56d0f..612e3ff7c295 100644 --- a/packages/gun-utils/builder.mjs +++ b/packages/gun-utils/builder.mjs @@ -1,5 +1,6 @@ import { createRequire } from 'module' import { readFile, writeFile } from 'fs/promises' +import { minify } from '@swc/core' const require = createRequire(import.meta.url) const files = await Promise.all( [ @@ -69,12 +70,15 @@ const patchedSource = files // patch instanceof Object to instanceof globalThis.Object .replace(/instanceof\s+Object/g, 'instanceof globalThis.Object') -const result = `(() => { +const result = await minify( + `(() => { ${init.toString().replace('// Source Code Here', patchedSource)}; if (!globalThis.Gun) { globalThis.Gun = ${init.name}().Gun; } })(); undefined; -` -writeFile(new URL('./gun.js', import.meta.url), result) +`, + { mangle: false, compress: false }, +) +writeFile(new URL('./gun.js', import.meta.url), result.code) diff --git a/packages/gun-utils/package.json b/packages/gun-utils/package.json index 9e1ca3157e44..5f48ca55a7a6 100644 --- a/packages/gun-utils/package.json +++ b/packages/gun-utils/package.json @@ -17,5 +17,8 @@ "dependencies": { "event-iterator": "^2.0.0", "gun": "0.2020.1234" + }, + "devDependencies": { + "@swc/core": "1.9.3" } } diff --git a/packages/icons/brands/GoogleDrive.svg b/packages/icons/brands/GoogleDrive.svg new file mode 100644 index 000000000000..bef62df4b6ce --- /dev/null +++ b/packages/icons/brands/GoogleDrive.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/packages/icons/brands/X2Y2.svg b/packages/icons/brands/X2Y2.svg deleted file mode 100644 index fcf52da5940b..000000000000 --- a/packages/icons/brands/X2Y2.svg +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - diff --git a/packages/icons/icon-generated-as-jsx.js b/packages/icons/icon-generated-as-jsx.js index 2045693a7a8b..599689192651 100644 --- a/packages/icons/icon-generated-as-jsx.js +++ b/packages/icons/icon-generated-as-jsx.js @@ -239,6 +239,11 @@ export const Gnosis = /*#__PURE__*/ __createIcon('Gnosis', [ u: () => new URL('./brands/Gnosis.svg', import.meta.url).href, }, ]) +export const GoogleDrive = /*#__PURE__*/ __createIcon('GoogleDrive', [ + { + u: () => new URL('./brands/GoogleDrive.svg', import.meta.url).href, + }, +]) export const Highlight = /*#__PURE__*/ __createIcon('Highlight', [ { u: () => new URL('./brands/Highlight.svg', import.meta.url).href, @@ -633,11 +638,6 @@ export const WETH = /*#__PURE__*/ __createIcon('WETH', [ u: () => new URL('./brands/WETH.svg', import.meta.url).href, }, ]) -export const X2Y2 = /*#__PURE__*/ __createIcon('X2Y2', [ - { - u: () => new URL('./brands/X2Y2.svg', import.meta.url).href, - }, -]) export const XLog = /*#__PURE__*/ __createIcon('XLog', [ { u: () => new URL('./brands/XLog.svg', import.meta.url).href, diff --git a/packages/icons/icon-generated-as-url.js b/packages/icons/icon-generated-as-url.js index a8498ee101db..f44f406604e7 100644 --- a/packages/icons/icon-generated-as-url.js +++ b/packages/icons/icon-generated-as-url.js @@ -39,6 +39,7 @@ export function git_hub_url() { return new URL("./brands/GitHub.svg", import.met export function github_dark_url() { return new URL("./brands/GithubDark.svg", import.meta.url).href } export function git_hub_gray_url() { return new URL("./brands/GitHubGray.svg", import.meta.url).href } export function gnosis_url() { return new URL("./brands/Gnosis.svg", import.meta.url).href } +export function google_drive_url() { return new URL("./brands/GoogleDrive.svg", import.meta.url).href } export function highlight_url() { return new URL("./brands/Highlight.svg", import.meta.url).href } export function instagram_url() { return new URL("./brands/Instagram.svg", import.meta.url).href } export function instagram_round_colored_url() { return new URL("./brands/InstagramRoundColored.svg", import.meta.url).href } @@ -114,7 +115,6 @@ export function twitter_x_round_dark_url() { return new URL("./brands/TwitterXRo export function twitter_x_round_light_url() { return new URL("./brands/TwitterXRound.light.svg", import.meta.url).href } export function uniswap_url() { return new URL("./brands/Uniswap.svg", import.meta.url).href } export function weth_url() { return new URL("./brands/WETH.svg", import.meta.url).href } -export function x_2_y_2_url() { return new URL("./brands/X2Y2.svg", import.meta.url).href } export function x_log_dark_url() { return new URL("./brands/XLog.dark.svg", import.meta.url).href } export function x_log_url() { return new URL("./brands/XLog.svg", import.meta.url).href } export function you_tube_url() { return new URL("./brands/YouTube.svg", import.meta.url).href } diff --git a/packages/icons/plugins/GoPlus.svg b/packages/icons/plugins/GoPlus.svg index de636d7e89f9..770ce2c875e8 100644 --- a/packages/icons/plugins/GoPlus.svg +++ b/packages/icons/plugins/GoPlus.svg @@ -1,7 +1,7 @@ - + - + diff --git a/packages/icons/plugins/ScamSniffer.dark.svg b/packages/icons/plugins/ScamSniffer.dark.svg index fdca736c3267..ed1a2b941ff6 100644 --- a/packages/icons/plugins/ScamSniffer.dark.svg +++ b/packages/icons/plugins/ScamSniffer.dark.svg @@ -1,17 +1,15 @@ - - - - - - - - - + + + + + + + - - + + diff --git a/packages/icons/plugins/ScamSniffer.light.svg b/packages/icons/plugins/ScamSniffer.light.svg index 0664681e4498..6442efd8fb57 100644 --- a/packages/icons/plugins/ScamSniffer.light.svg +++ b/packages/icons/plugins/ScamSniffer.light.svg @@ -1,17 +1,15 @@ - - - - - - - - - + + + + + + + - - + + diff --git a/packages/icons/utils/internal.d.ts b/packages/icons/utils/internal.d.ts index 8628c7720774..07dbf9d12a13 100644 --- a/packages/icons/utils/internal.d.ts +++ b/packages/icons/utils/internal.d.ts @@ -20,7 +20,7 @@ export interface GeneratedIconProps export type GeneratedIcon = ComponentType | ComponentType> export interface GeneratedIconNonSquareProps - extends React.HTMLProps { + extends Omit, 'children'> { variant?: Variants[] | Variants height?: number | string width?: number | string diff --git a/packages/mask/.webpack/config.ts b/packages/mask/.webpack/config.ts index 80ac17d8617c..e0b918af7e87 100644 --- a/packages/mask/.webpack/config.ts +++ b/packages/mask/.webpack/config.ts @@ -7,8 +7,8 @@ import { emitJSONFile } from '@nice-labs/emit-file-webpack-plugin' import DevtoolsIgnorePlugin from 'devtools-ignore-webpack-plugin' import WebExtensionPlugin from 'webpack-target-webextension' import ReactCompiler from 'react-compiler-webpack' -import { getGitInfo } from './git-info.js' -import { emitManifestFile } from './plugins/manifest.js' +import { getGitInfo } from './git-info.ts' +import { emitManifestFile } from './plugins/manifest.ts' // @ts-expect-error import LavaMoat from '@lavamoat/webpack' @@ -16,12 +16,12 @@ import { readFile, readdir } from 'node:fs/promises' import { createRequire } from 'node:module' import { join } from 'node:path' -import { computeCacheKey, computedBuildFlags, normalizeBuildFlags, type BuildFlags } from './flags.js' -import { ProfilingPlugin } from './plugins/ProfilingPlugin.js' -import { joinEntryItem, normalizeEntryDescription, type EntryDescription } from './utils.js' +import { computeCacheKey, computedBuildFlags, normalizeBuildFlags, type BuildFlags } from './flags.ts' +import { ProfilingPlugin } from './plugins/ProfilingPlugin.ts' +import { joinEntryItem, normalizeEntryDescription, type EntryDescription } from './utils.ts' -import './clean-hmr.js' -import { TrustedTypesPlugin } from './plugins/TrustedTypesPlugin.js' +import './clean-hmr.ts' +import { TrustedTypesPlugin } from './plugins/TrustedTypesPlugin.ts' const require = createRequire(import.meta.url) const patchesDir = join(import.meta.dirname, '../../../patches') @@ -238,6 +238,7 @@ export async function createConfiguration( NEXT_PUBLIC_FIREFLY_API_URL: process.env.NEXT_PUBLIC_FIREFLY_API_URL || '', SOLANA_DEFAULT_RPC_URL: process.env.SOLANA_DEFAULT_RPC_URL || '', MASK_ENABLE_EXCHANGE: process.env.MASK_ENABLE_EXCHANGE || '', + GOOGLE_CLIENT_ID: JSON.stringify(process.env.GOOGLE_CLIENT_ID) || '', }), new (rspack?.DefinePlugin || webpack.default.DefinePlugin)({ 'process.browser': 'true', @@ -312,7 +313,6 @@ export async function createConfiguration( // Focus on performance optimization. Not for download size/cache stability optimization. optimization: { // we don't need deterministic, and we also don't have chunk request at init we don't need "size" - // @ts-expect-error chunkIds: productionLike ? rspack ? 'deterministic' @@ -492,11 +492,12 @@ export async function createConfiguration( } } -enum TemplateType { - Loading, - NoLoading, - Background, -} +const TemplateType = { + Loading: 0, + NoLoading: 1, + Background: 2, +} as const +type TemplateType = (typeof TemplateType)[keyof typeof TemplateType] const pages = { loading: readFile(join(import.meta.dirname, './with-loading.html'), 'utf8'), noLoading: readFile(join(import.meta.dirname, './with-no-loading.html'), 'utf8'), diff --git a/packages/mask/.webpack/flags.ts b/packages/mask/.webpack/flags.ts index c8238383f940..853e6ed906c9 100644 --- a/packages/mask/.webpack/flags.ts +++ b/packages/mask/.webpack/flags.ts @@ -1,14 +1,15 @@ import type { Configuration } from 'webpack' import { join, isAbsolute } from 'node:path' -export enum ManifestFile { - ChromiumMV2 = 'chromium-mv2', - ChromiumMV3 = 'chromium-mv3', - ChromiumBetaMV3 = 'chromium-beta-mv3', - FirefoxMV2 = 'firefox-mv2', - FirefoxMV3 = 'firefox-mv3', - SafariMV3 = 'safari-mv3', +export const ManifestFile = { + ChromiumMV2: 'chromium-mv2', + ChromiumMV3: 'chromium-mv3', + ChromiumBetaMV3: 'chromium-beta-mv3', + FirefoxMV2: 'firefox-mv2', + FirefoxMV3: 'firefox-mv3', + SafariMV3: 'safari-mv3', } +export type ManifestFile = (typeof ManifestFile)[keyof typeof ManifestFile] export interface BuildFlags { /** If this field is set, manifest.json will copy the content of manifest-*.json */ manifestFile?: ManifestFile diff --git a/packages/mask/.webpack/manifest/manifest-mv3.json b/packages/mask/.webpack/manifest/manifest-mv3.json index af0c5a6a1f07..d2f288b563f8 100644 --- a/packages/mask/.webpack/manifest/manifest-mv3.json +++ b/packages/mask/.webpack/manifest/manifest-mv3.json @@ -3,7 +3,7 @@ "version": "0", "manifest_version": 3, "permissions": ["storage", "webNavigation", "activeTab", "scripting"], - "optional_permissions": ["notifications", "clipboardRead"], + "optional_permissions": ["notifications", "clipboardRead", "identity", "tabs"], "optional_host_permissions": [""], "background": { "service_worker": "/manifest-v3.entry.js" }, "icons": { @@ -32,5 +32,9 @@ "gecko": { "id": "{0e57e2ae-3e13-4d5d-9243-6159219852a6}" } + }, + "oauth2": { + "client_id": "884348965548-npd1mffii0tbrr87eb2fm73ue022k3t3.apps.googleusercontent.com", + "scopes": ["https://www.googleapis.com/auth/drive.file", "https://www.googleapis.com/auth/userinfo.email"] } } diff --git a/packages/mask/.webpack/manifest/manifest.json b/packages/mask/.webpack/manifest/manifest.json index 0c629071825b..4d6e1069c215 100644 --- a/packages/mask/.webpack/manifest/manifest.json +++ b/packages/mask/.webpack/manifest/manifest.json @@ -2,8 +2,8 @@ "name": "Mask Network", "version": "0", "manifest_version": 2, - "permissions": ["storage", "webNavigation", "activeTab"], - "optional_permissions": ["", "notifications", "clipboardRead"], + "permissions": ["storage", "webNavigation", "activeTab", "identity"], + "optional_permissions": ["", "notifications", "clipboardRead", "tabs"], "background": { "page": "background.html" }, "icons": { "16": "assets/16x16.png", @@ -14,5 +14,9 @@ "browser_action": { "default_popup": "popups.html" }, "homepage_url": "https://mask.io", "description": "The portal to the new & open Internet. Send encrypted message and decentralized Apps right on top of social networks.", - "web_accessible_resources": ["js/*", "bundled/*", "entry/*", "*.svg", "*.png", "*.jpg", "*.css", "build-info.json"] + "web_accessible_resources": ["js/*", "bundled/*", "entry/*", "*.svg", "*.png", "*.jpg", "*.css", "build-info.json"], + "oauth2": { + "client_id": "884348965548-npd1mffii0tbrr87eb2fm73ue022k3t3.apps.googleusercontent.com", + "scopes": ["https://www.googleapis.com/auth/drive.file", "https://www.googleapis.com/auth/userinfo.email"] + } } diff --git a/packages/mask/.webpack/plugins/ProfilingPlugin.ts b/packages/mask/.webpack/plugins/ProfilingPlugin.ts index b5897e9e861a..ef6ca3f74423 100644 --- a/packages/mask/.webpack/plugins/ProfilingPlugin.ts +++ b/packages/mask/.webpack/plugins/ProfilingPlugin.ts @@ -11,8 +11,10 @@ export class ProfilingPlugin { apply(compiler: Compiler) { const { javascript, Template, RuntimeModule } = compiler.webpack class HintRuntimeModule extends RuntimeModule { - constructor(private modules: data) { + private modules: data + constructor(modules: data) { super('profiling-hint') + this.modules = modules } override generate() { return `globalThis.measure?.set_compile_info?.(${JSON.stringify(this.modules)});` diff --git a/packages/mask/.webpack/plugins/manifest.ts b/packages/mask/.webpack/plugins/manifest.ts index c22d08cd54b8..f1bfda91e5c5 100644 --- a/packages/mask/.webpack/plugins/manifest.ts +++ b/packages/mask/.webpack/plugins/manifest.ts @@ -1,9 +1,9 @@ /* spell-checker: disable */ import emitFile from '@nice-labs/emit-file-webpack-plugin' -import type { ComputedFlags, NormalizedFlags } from '../flags.js' +import type { ComputedFlags, NormalizedFlags } from '../flags.ts' import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs' import type { Manifest } from 'webextension-polyfill' -import { parseJSONc } from '../utils.js' +import { parseJSONc } from '../utils.ts' import { join } from 'node:path' const cloneDeep = (x: T): T => JSON.parse(JSON.stringify(x)) diff --git a/packages/mask/.webpack/tsconfig.json b/packages/mask/.webpack/tsconfig.json index 96475e1d2b61..815d00884001 100644 --- a/packages/mask/.webpack/tsconfig.json +++ b/packages/mask/.webpack/tsconfig.json @@ -2,7 +2,8 @@ "extends": "../../../tsconfig.json", "compilerOptions": { "incremental": false, - "composite": false + "composite": false, + "allowImportingTsExtensions": true }, "include": ["./**/*.ts"] } diff --git a/packages/mask/.webpack/webpack.config.js b/packages/mask/.webpack/webpack.config.js deleted file mode 100644 index 8e8155aa1b4a..000000000000 --- a/packages/mask/.webpack/webpack.config.js +++ /dev/null @@ -1,2 +0,0 @@ -// webpack-cli does not know swc-node -export { default } from './webpack.config.ts' diff --git a/packages/mask/.webpack/webpack.config.ts b/packages/mask/.webpack/webpack.config.ts index 2fe130d51a58..352cb464ca74 100644 --- a/packages/mask/.webpack/webpack.config.ts +++ b/packages/mask/.webpack/webpack.config.ts @@ -1,4 +1,4 @@ -import { createConfiguration } from './config.js' +import { createConfiguration } from './config.ts' export default async function (cli_env: any) { const flags = JSON.parse(Buffer.from(cli_env.flags, 'hex').toString('utf-8')) return createConfiguration(false, flags) diff --git a/packages/mask/background/services/backup/google_drive.ts b/packages/mask/background/services/backup/google_drive.ts new file mode 100644 index 000000000000..ccbb4a6c353a --- /dev/null +++ b/packages/mask/background/services/backup/google_drive.ts @@ -0,0 +1,17 @@ +import { checkAndRequestPermission, requestDriveAccessToken } from '../../../shared/helpers/index.js' + +/* eslint-disable @typescript-eslint/ban-ts-comment */ +export async function getAccessToken(interactive = false) { + const granted = await checkAndRequestPermission() + if (!granted) return + + return requestDriveAccessToken(interactive) +} + +export async function clearAccessToken() { + const token = await getAccessToken() + return new Promise((resolve) => { + // @ts-expect-error + chrome.identity.removeCachedAuthToken({ token }, () => resolve()) + }) +} diff --git a/packages/mask/background/services/backup/index.ts b/packages/mask/background/services/backup/index.ts index f76aa6aed5b6..b384616dee4e 100644 --- a/packages/mask/background/services/backup/index.ts +++ b/packages/mask/background/services/backup/index.ts @@ -1,3 +1,4 @@ export { generateBackupPreviewInfo, createBackupFile, type BackupOptions } from './create.js' export { generateBackupSummary, restoreBackup } from './restore.js' export { backupPersonaPrivateKey } from './persona.js' +export { getAccessToken, clearAccessToken } from './google_drive.js' diff --git a/packages/mask/background/services/backup/restore.ts b/packages/mask/background/services/backup/restore.ts index 4529a4c2cb68..233389c7434c 100644 --- a/packages/mask/background/services/backup/restore.ts +++ b/packages/mask/background/services/backup/restore.ts @@ -1,4 +1,4 @@ -import { getBackupSummary, normalizeBackup } from '@masknet/backup-format' +import { getBackupSummary, normalizeBackup, type BackupSummary } from '@masknet/backup-format' import { restoreNormalizedBackup } from './internal_restore.js' import { Result } from 'ts-results-es' import { SmartPayBundler, SmartPayOwner } from '@masknet/web3-providers' @@ -7,7 +7,7 @@ import { bytesToHex, privateToPublic, publicToAddress } from '@ethereumjs/util' import { fromBase64URL } from '@masknet/shared-base' export async function generateBackupSummary(raw: string) { - return Result.wrapAsync(async () => { + return Result.wrapAsync(async (): Promise => { const backupObj: unknown = JSON.parse(raw) const backup = await normalizeBackup(backupObj) diff --git a/packages/mask/background/tasks/NotCancellable/OnInstall.ts b/packages/mask/background/tasks/NotCancellable/OnInstall.ts index 290f8c7ca1b2..31acb91a330e 100644 --- a/packages/mask/background/tasks/NotCancellable/OnInstall.ts +++ b/packages/mask/background/tasks/NotCancellable/OnInstall.ts @@ -28,6 +28,7 @@ browser.runtime.onInstalled.addListener(async (detail) => { const localStorage = (globalThis as any).localStorage if (localStorage) { const backupPassword = localStorage.getItem('backupPassword') + // Migration if (backupPassword) { const backupMethod = localStorage.getItem('backupMethod') base.PersistentStorages.Settings.storage.backupConfig.setValue({ @@ -37,6 +38,8 @@ browser.runtime.onInstalled.addListener(async (detail) => { cloudBackupAt: backupMethod && backupMethod === 'cloud' ? localStorage.getItem('backupAt') : null, localBackupAt: backupMethod && backupMethod === 'local' ? localStorage.getItem('backupAt') : null, cloudBackupMethod: null, + googleToken: null, + googleAccount: null, }) } // remove old data after migrate diff --git a/packages/mask/content-script/components/CompositionDialog/Composition.tsx b/packages/mask/content-script/components/CompositionDialog/Composition.tsx index 81eeacc2ed86..a66d5a4d66e5 100644 --- a/packages/mask/content-script/components/CompositionDialog/Composition.tsx +++ b/packages/mask/content-script/components/CompositionDialog/Composition.tsx @@ -1,8 +1,7 @@ -import { useCallback, useEffect, useRef, useState } from 'react' -import { useAsync } from 'react-use' -import { DialogContent, alpha } from '@mui/material' -import { makeStyles } from '@masknet/theme' -import { useCurrentPersonaConnectStatus, InjectedDialog, PersonaAction } from '@masknet/shared' +import Services from '#services' +import { Trans } from '@lingui/react/macro' +import type { CompositionType } from '@masknet/plugin-infra/content-script' +import { InjectedDialog, PersonaAction, useCurrentPersonaConnectStatus } from '@masknet/shared' import { CrossIsolationMessages, EMPTY_OBJECT, @@ -12,19 +11,20 @@ import { currentPersonaIdentifier, } from '@masknet/shared-base' import { useValueRef } from '@masknet/shared-base-ui' +import { makeStyles } from '@masknet/theme' import { Telemetry } from '@masknet/web3-telemetry' import { EventID, EventType } from '@masknet/web3-telemetry/types' -import type { CompositionType } from '@masknet/plugin-infra/content-script' -import Services from '#services' +import { DialogContent, alpha } from '@mui/material' +import { useCallback, useEffect, useRef, useState } from 'react' +import { useAsync } from 'react-use' +import { useCurrentPersona, usePersonasFromDB } from '../../../shared-ui/hooks/index.js' import { activatedSiteAdaptorUI } from '../../site-adaptor-infra/index.js' import { useCurrentIdentity, useLastRecognizedIdentity } from '../DataSource/useActivatedUI.js' import { CompositionDialogUI, type CompositionRef, E2EUnavailableReason } from './CompositionUI.js' +import { EncryptionMethodType } from './EncryptionMethodSelector.js' import { useCompositionClipboardRequest } from './useCompositionClipboardRequest.js' import { useRecipientsList } from './useRecipientsList.js' import { useSubmit } from './useSubmit.js' -import { usePersonasFromDB, useCurrentPersona } from '../../../shared-ui/hooks/index.js' -import { EncryptionMethodType } from './EncryptionMethodSelector.js' -import { Trans } from '@lingui/react/macro' const useStyles = makeStyles()((theme) => ({ dialogRoot: { diff --git a/packages/mask/dashboard/components/BackupPreview/index.tsx b/packages/mask/dashboard/components/BackupPreview/index.tsx index 7a9db487d147..d07a33d04b9d 100644 --- a/packages/mask/dashboard/components/BackupPreview/index.tsx +++ b/packages/mask/dashboard/components/BackupPreview/index.tsx @@ -83,18 +83,25 @@ const useStyles = makeStyles()((theme) => ({ list: { padding: 0, }, + grid: { + display: 'grid', + gridTemplateColumns: 'repeat(2, 1fr)', + }, walletHeaderIcon: { backgroundColor: '#1C68F3', boxShadow: '0px 6px 12px rgba(28, 104, 243, 0.2)', }, wallets: { margin: 0, - display: 'grid', - gridTemplateColumns: 'repeat(3, 1fr)', + display: 'flex', + flexWrap: 'wrap', + gap: 8, }, wallet: { + gap: 10, width: 'auto', flexWrap: 'nowrap', + paddingRight: 0, }, listItemIcon: { marginRight: theme.spacing(1), @@ -103,12 +110,12 @@ const useStyles = makeStyles()((theme) => ({ minWidth: 'unset', }, walletIcon: { - marginRight: theme.spacing(1), color: theme.palette.maskColor.second, minWidth: 'unset', }, listText: { fontSize: 14, + color: theme.palette.maskColor.main, }, link: { color: theme.palette.maskColor.main, @@ -167,7 +174,7 @@ export const PersonasBackupPreview = memo(function P } /> - + {info.accounts}}> @@ -253,6 +260,7 @@ export const WalletsBackupPreview = memo(function Wal pluginID={NetworkPluginID.PLUGIN_EVM} address={wallet} mr="10px" + fontWeight={400} /> diff --git a/packages/mask/dashboard/components/GoogleDriveFileTable.tsx b/packages/mask/dashboard/components/GoogleDriveFileTable.tsx new file mode 100644 index 000000000000..aa70d2b9e04b --- /dev/null +++ b/packages/mask/dashboard/components/GoogleDriveFileTable.tsx @@ -0,0 +1,225 @@ +import { Trans } from '@lingui/react/macro' +import { Icons } from '@masknet/icons' +import { EmptyStatus, formatFileSize } from '@masknet/shared' +import { makeStyles, RadioIndicator } from '@masknet/theme' +import type { DriveFile } from '@masknet/web3-providers' +import { + Paper, + Skeleton, + Table, + TableBody, + TableCell, + TableContainer, + TableHead, + TableRow, + Tooltip, + Typography, + type TableContainerProps, +} from '@mui/material' +import { format } from 'date-fns' +import { range } from 'lodash-es' +import { memo } from 'react' +import { MoreMenu } from './MoreMenu/index.js' + +const useStyles = makeStyles()((theme) => ({ + tableContainer: { + border: `1px solid ${theme.palette.maskColor.line}`, + borderRadius: 8, + overflow: 'hidden', + backgroundColor: theme.palette.maskColor.bottom, + }, + table: { + borderRadius: 8, + borderCollapse: 'collapse', + borderSpacing: 0, + }, + tableHeadCell: { + borderBottom: `1px solid ${theme.palette.maskColor.line}`, + fontSize: 14, + fontWeight: 700, + lineHeight: '18px', + padding: theme.spacing(1.5), + height: 18, + }, + bodyCell: { + padding: theme.spacing(0, 1.5), + fontSize: 14, + height: 42, + lineHeight: '18px', + fontWeight: 400, + color: theme.palette.maskColor.main, + verticalAlign: 'middle', + }, + cellText: { + fontSize: 14, + }, + actionButton: { + color: theme.palette.maskColor.second, + '&:hover': { + color: theme.palette.maskColor.main, + }, + }, + actions: { + display: 'flex', + flexDirection: 'column', + gap: theme.spacing(1.5), + }, + action: { + padding: 6, + height: 30, + display: 'flex', + gap: 4, + alignItems: 'center', + cursor: 'pointer', + borderRadius: 8, + '&:hover': { + backgroundColor: theme.palette.maskColor.bg, + }, + }, + actionLabel: { + fontSize: 14, + fontWeight: 700, + lineHeight: '18px', + color: theme.palette.maskColor.main, + }, + fileName: { + display: 'flex', + gap: theme.spacing(1), + alignItems: 'center', + }, +})) + +interface GoogleDriveFileTableProps extends Omit { + files: DriveFile[] + loading: boolean + selectable?: boolean + selectedFileId?: string + onSelect?: (file: DriveFile) => void + onMerge?: (file: DriveFile) => void + onDownload?: (file: DriveFile) => void +} + +export const GoogleDriveFileTable = memo(function GoogleDriveFileTable({ + files, + loading, + selectable, + selectedFileId, + onSelect, + onMerge, + onDownload, + className, + ...rest +}) { + const { classes, cx, theme } = useStyles() + return ( + + + + + + File name + + + Size + + + Date & Time + + + Actions + + + + {loading ? + + {range(3).map((index) => ( + + + + + + + + + + + + + + + ))} + + : files.length ? + + {files.map((file, index) => ( + + +
+ {selectable ? + onSelect?.(file)} + uncheckedColor={theme.palette.maskColor.secondaryLine} + /> + : null} + {file.name} +
+
+ + {file.size ? formatFileSize(+file.size) : '--'} + + + + + {format(file.modifiedTime, 'LLL d, yyyy')} + + + + + + {({ close }) => ( +
+
{ + close() + onMerge?.(file) + }}> + + + Merge to Browser + +
+
{ + close() + onDownload?.(file) + }}> + + + Download + +
+
+ )} +
+
+
+ ))} +
+ : + + + + No backups found + + + + + } +
+ + ) +}) diff --git a/packages/mask/dashboard/components/GoogleDriveLogin.tsx b/packages/mask/dashboard/components/GoogleDriveLogin.tsx new file mode 100644 index 000000000000..ed0119d92642 --- /dev/null +++ b/packages/mask/dashboard/components/GoogleDriveLogin.tsx @@ -0,0 +1,74 @@ +import { t } from '@lingui/core/macro' +import { Trans } from '@lingui/react/macro' +import { ActionButton, makeStyles, useCustomSnackbar } from '@masknet/theme' +import { GoogleDriveClient } from '@masknet/web3-providers' +import { Box, Typography } from '@mui/material' +import { memo, useMemo } from 'react' +import { useAsyncFn } from 'react-use' +import { UserContext } from '../../shared-ui/index.js' +import { checkAndRequestPermission, requestDriveAccessToken } from '../../shared/helpers/index.js' +import { clearGoogleDriveAccessToken, getGoogleDriveAccessToken } from '../utils/api.js' + +const useStyles = makeStyles()((theme) => ({ + container: { + display: 'flex', + flexDirection: 'column', + gap: theme.spacing(1.5), + paddingBottom: theme.spacing(6), + }, + title: { + fontSize: 16, + fontWeight: 700, + lineHeight: '20px', + }, + subtitle: { + fontSize: 14, + fontWeight: 400, + lineHeight: '18px', + }, +})) + +export const GoogleDriveLogin = memo(function GoogleDriveLogin() { + const { classes } = useStyles() + const googleDriveClient = useMemo( + () => new GoogleDriveClient(getGoogleDriveAccessToken, clearGoogleDriveAccessToken), + [], + ) + const { updateUser } = UserContext.useContainer() + const { showSnackbar } = useCustomSnackbar() + + const [{ loading }, login] = useAsyncFn(async () => { + try { + const granted = await checkAndRequestPermission() + if (!granted) return + + const userInfo = await googleDriveClient.login(true) + await requestDriveAccessToken(true) // request permission to manipulate files + updateUser({ + googleAccount: userInfo.email || '', + }) + } catch (err) { + showSnackbar(t`Authorization Failed`, { + variant: 'warning', + message: t`Failed to authorize Google Drive. Please try again.`, + }) + } + }, [googleDriveClient, updateUser, showSnackbar]) + return ( + + + Add google Drive + + + + when you click Add Google Drive button,you will be forwarded to Google authorization pages. + + + + + Add Google Drive + + + + ) +}) diff --git a/packages/mask/dashboard/components/Mnemonic/DesktopMnemonicConfirm.tsx b/packages/mask/dashboard/components/Mnemonic/DesktopMnemonicConfirm.tsx index 53d7fb64c84f..d88ccb6eb110 100644 --- a/packages/mask/dashboard/components/Mnemonic/DesktopMnemonicConfirm.tsx +++ b/packages/mask/dashboard/components/Mnemonic/DesktopMnemonicConfirm.tsx @@ -9,8 +9,10 @@ const useStyles = makeStyles()((theme) => ({ fontWeight: 700, color: theme.palette.maskColor.main, textAlign: 'center', + fontSize: 14, }, - no: { + end: { + width: 22, color: theme.palette.maskColor.third, fontSize: 14, }, @@ -59,7 +61,12 @@ export const DesktopMnemonicConfirm = memo(function DesktopMnemonicConfirm(props InputProps={{ disableUnderline: true, className: classes.input, - startAdornment: {no}., + startAdornment: {no}., + endAdornment: ( + + {/* balance the input, make the cursor center */} + + ), size: 'small', inputProps: { style: { diff --git a/packages/mask/dashboard/components/MoreMenu/index.tsx b/packages/mask/dashboard/components/MoreMenu/index.tsx new file mode 100644 index 000000000000..71692372e1cc --- /dev/null +++ b/packages/mask/dashboard/components/MoreMenu/index.tsx @@ -0,0 +1,43 @@ +import { Icons, type GeneratedIconProps } from '@masknet/icons' +import { makeStyles } from '@masknet/theme' +import { Popover } from '@mui/material' +import { memo, useState, type ReactNode } from 'react' + +const useStyles = makeStyles()((theme) => ({ + paper: { + padding: theme.spacing(2), + borderRadius: 24, + background: theme.palette.maskColor.bottom, + boxShadow: + theme.palette.mode === 'dark' ? + '0px 4px 30px 0px rgba(255, 255, 255, 0.15)' + : '0px 4px 30px 0px rgba(0, 0, 0, 0.10)', + }, +})) + +interface Props extends GeneratedIconProps { + children?: ReactNode | ((props: { close: () => void }) => ReactNode) +} + +export const MoreMenu = memo(function MoreMenu({ children, ...rest }) { + const { classes } = useStyles() + const [anchorEl, setAnchorEl] = useState(null) + return ( + <> + setAnchorEl(e.currentTarget)} /> + setAnchorEl(null)} + classes={{ paper: classes.paper }} + anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }} + transformOrigin={{ + vertical: 'top', + horizontal: 'right', + }}> + {typeof children === 'function' ? children({ close: () => setAnchorEl(null) }) : children} + + + ) +}) diff --git a/packages/mask/dashboard/components/OnboardingWriter/index.tsx b/packages/mask/dashboard/components/OnboardingWriter/index.tsx index 8a4ccba9b162..a201b6212029 100644 --- a/packages/mask/dashboard/components/OnboardingWriter/index.tsx +++ b/packages/mask/dashboard/components/OnboardingWriter/index.tsx @@ -1,8 +1,7 @@ -import { sum } from 'lodash-es' -import { useState, useMemo, useEffect } from 'react' +import { useState, useMemo, useEffect, type JSX } from 'react' import { makeStyles } from '@masknet/theme' import { Typography } from '@mui/material' -import { useRenderPhraseCallbackOnDepsChange } from '@masknet/shared-base-ui' +import { isNonNull } from '@masknet/kit' const useStyles = makeStyles()((theme) => ({ typed: { @@ -13,75 +12,84 @@ const useStyles = makeStyles()((theme) => ({ color: theme.palette.maskColor.highlight, }, }, - endTyping: { + typing: { opacity: 0.5, }, })) interface OnboardingWriterProps extends withClasses<'typed' | 'endTyping'> { - sentence: Array + sentence: Array + onFinish?: () => void } -let segmenter: Intl.Segmenter -export function OnboardingWriter({ sentence, ...props }: OnboardingWriterProps) { +export function OnboardingWriter({ sentence, onFinish, ...props }: OnboardingWriterProps) { const { classes, cx } = useStyles(undefined, { props }) + const typing = cx(classes.typing, classes.typed) + const [jsx, setJsx] = useState(undefined) - const allChars = useMemo(() => sentence.flat().filter(Boolean).join(''), [sentence]) - const allCharsSegmented = useMemo(() => { - return [...(segmenter ||= new Intl.Segmenter()).segment(allChars)].map((x) => x.segment) - }, [allChars]) - const segmentCount = allCharsSegmented.length - - const [codePointIndex, setCodePointIndex] = useState(0) - const [segmentIndex, setSegmentIndex] = useState(0) - useRenderPhraseCallbackOnDepsChange(() => { - setCodePointIndex(0) - setSegmentIndex(0) - }, [sentence]) + const writer = useMemo(() => onBoardingWriter({ typed: classes.typed, typing }, sentence), [sentence]) useEffect(() => { const timer = setInterval(() => { - setSegmentIndex((segmentIndex) => { - const nextSegmentIndex = segmentIndex + 1 - if (segmentIndex > segmentCount) { - clearInterval(timer) - return segmentIndex - } - setCodePointIndex(allCharsSegmented.slice(0, nextSegmentIndex).join('').length) - return nextSegmentIndex - }) + const next = writer.next() + if (next.done) { + clearInterval(timer) + onFinish?.() + } else { + setJsx(next.value) + } }, 50) return () => { clearInterval(timer) } - }, [allCharsSegmented, segmentCount]) + }, [writer, onFinish]) - const jsx = useMemo(() => { - const newJsx = [] - let remain = codePointIndex - for (const fragment of sentence) { - if (!fragment) continue - if (remain <= 0) break - const size = sum(fragment.map((x) => x.length)) - const take = Math.min(size, remain) - - remain -= take - - const [text, strongText] = fragment + return jsx +} +let segmenter: Intl.Segmenter +function* onBoardingWriter(className: { typed: string; typing: string }, sentences: Array) { + segmenter ||= new Intl.Segmenter() + const previousLines: JSX.Element[] = [] + const currentLine: Array<{ type: 'bold' | 'normal'; text: string }> = [{ type: 'normal', text: '' }] - const className = cx(classes.typed, remain !== 0 ? classes.endTyping : undefined) - // the trailing space gets trimmed by i18n marco - if (take <= text.length) newJsx.push({text.slice(0, take)}) - else - newJsx.push( - - {text} - {strongText.slice(0, take - text.length)} - , - ) + for (const sentence of sentences.filter(isNonNull)) { + const chars = [...segmenter.segment(sentence)] + let currentLineJSX: JSX.Element | undefined + for (let index = 0; index < chars.length; index += 1) { + const char = chars[index].segment + const lastPiece = currentLine.at(-1)! + if (char === '*') { + const nextChar = chars[index + 1]?.segment + if (nextChar === '*') { + currentLine.push({ type: lastPiece.type === 'normal' ? 'bold' : 'normal', text: '' }) + index += 1 + continue + } + } + lastPiece.text += char + const children = currentLine.map((x, index) => + x.type === 'normal' ? x.text : {x.text}, + ) + currentLineJSX = ( + + {children} + + ) + yield ( + <> + {previousLines} + { + + {children} + + } + + ) } - - return newJsx - }, [sentence, codePointIndex]) - - return <>{jsx} + if (currentLineJSX) { + previousLines.push(currentLineJSX) + currentLine.length = 0 + currentLine.push({ type: 'normal', text: '' }) + } + yield <>{previousLines} + } } diff --git a/packages/mask/dashboard/components/OutletPortal.tsx b/packages/mask/dashboard/components/OutletPortal.tsx new file mode 100644 index 000000000000..18f73cafa2bb --- /dev/null +++ b/packages/mask/dashboard/components/OutletPortal.tsx @@ -0,0 +1,13 @@ +import { Portal, type PortalProps } from '@mui/material' +import { memo } from 'react' +import { useOutletContext } from 'react-router-dom' + +export interface PortalContainerProps { + portalContainerRef: React.RefObject +} + +interface OutletPortalProps extends Omit {} +export const OutletPortal = memo(function OutletPortal(props) { + const { portalContainerRef } = useOutletContext() + return portalContainerRef.current} {...props}> +}) diff --git a/packages/mask/dashboard/components/Restore/RestoreFromPrivateKey.tsx b/packages/mask/dashboard/components/Restore/RestoreFromPrivateKey.tsx index 718e9f99b873..b59599b1ad8a 100644 --- a/packages/mask/dashboard/components/Restore/RestoreFromPrivateKey.tsx +++ b/packages/mask/dashboard/components/Restore/RestoreFromPrivateKey.tsx @@ -2,17 +2,17 @@ import { zodResolver } from '@hookform/resolvers/zod' import { Controller, useForm } from 'react-hook-form' import type { UseFormSetError, SubmitHandler } from 'react-hook-form' import { makeStyles } from '@masknet/theme' -import { Box, TextField } from '@mui/material' +import { Box } from '@mui/material' import { memo, useCallback, useLayoutEffect } from 'react' import { useNavigate } from 'react-router-dom' import { z } from 'zod' import { PrimaryButton } from '../PrimaryButton/index.js' import { usePersonaRecovery } from '../../contexts/index.js' import { Trans, useLingui } from '@lingui/react/macro' +import PasswordField from '../PasswordField/index.js' const useStyles = makeStyles()((theme) => ({ input: { - paddingTop: 12, backgroundColor: theme.palette.maskColor.input, color: theme.palette.maskColor.main, }, @@ -74,7 +74,7 @@ export const RestoreFromPrivateKey = memo(function RestoreFromPrivateKey({ ( - ({ uploadedFile: { @@ -26,7 +26,7 @@ interface RestoreFromLocalProps { error: ReactNode } -export const RestoreWalletFromLocal = memo(function RestorePersonaFromLocal({ +export const RestoreWalletFromLocal = memo(function RestoreWalletFromLocal({ onRestore, setError, error, diff --git a/packages/mask/dashboard/components/SetupFrame/index.tsx b/packages/mask/dashboard/components/SetupFrame/index.tsx index b7e4cd3cc5da..4077a1e605c6 100644 --- a/packages/mask/dashboard/components/SetupFrame/index.tsx +++ b/packages/mask/dashboard/components/SetupFrame/index.tsx @@ -1,9 +1,9 @@ -import { lazy, memo, Suspense, useState, type PropsWithChildren } from 'react' -import { Box, Typography } from '@mui/material' import { Icons } from '@masknet/icons' -import { Welcome } from '../../assets/index.js' import { LoadingBase, makeStyles } from '@masknet/theme' +import { Box, Typography } from '@mui/material' +import { lazy, memo, Suspense, useState, type PropsWithChildren } from 'react' import { Outlet } from 'react-router-dom' +import { Welcome } from '../../assets/index.js' const Spline = lazy(() => import('./spline.js')) interface SetupFrameProps { diff --git a/packages/mask/dashboard/contexts/CloudBackupFormContext.tsx b/packages/mask/dashboard/contexts/CloudBackupFormContext.tsx index 6b7c686ab5b1..15d881b63dce 100644 --- a/packages/mask/dashboard/contexts/CloudBackupFormContext.tsx +++ b/packages/mask/dashboard/contexts/CloudBackupFormContext.tsx @@ -1,11 +1,11 @@ +import { zodResolver } from '@hookform/resolvers/zod' +import { useLingui } from '@lingui/react/macro' import { createContainer } from '@masknet/shared-base-ui' +import { useTabs } from '@masknet/theme' +import guessCallingCode from 'guess-calling-code' import { useForm } from 'react-hook-form' -import { zodResolver } from '@hookform/resolvers/zod' import { z } from 'zod' -import { useTabs } from '@masknet/theme' import { emailRegexp, phoneRegexp } from '../utils/regexp.js' -import guessCallingCode from 'guess-calling-code' -import { useLingui } from '@lingui/react/macro' export interface CloudBackupFormInputs { email: string @@ -70,4 +70,5 @@ function useCloudBackupFormContext() { } } +/** @deprecated */ export const CloudBackupFormContext = createContainer(useCloudBackupFormContext) diff --git a/packages/mask/dashboard/hooks/useBackupFormState.ts b/packages/mask/dashboard/hooks/useBackupFormState.ts index f5e08a412ccb..aa1fa092e0e7 100644 --- a/packages/mask/dashboard/hooks/useBackupFormState.ts +++ b/packages/mask/dashboard/hooks/useBackupFormState.ts @@ -1,12 +1,12 @@ +import Services from '#services' import { zodResolver } from '@hookform/resolvers/zod' +import { useLingui } from '@lingui/react/macro' import { useState } from 'react' import { useForm } from 'react-hook-form' import { useAsync } from 'react-use' import { z } from 'zod' import { UserContext } from '../../shared-ui/index.js' -import Services from '#services' import { passwordRegexp } from '../utils/regexp.js' -import { useLingui } from '@lingui/react/macro' export type BackupFormInputs = { backupPassword: string @@ -16,7 +16,6 @@ export type BackupFormInputs = { export function useBackupFormState() { const { t } = useLingui() const { value: hasPassword } = useAsync(Services.Wallet.hasPassword, []) - const { value: previewInfo, loading } = useAsync(Services.Backup.generateBackupPreviewInfo, []) const { user } = UserContext.useContainer() const [backupWallets, setBackupWallets] = useState(false) @@ -24,7 +23,6 @@ export function useBackupFormState() { mode: 'onBlur', context: { user, - backupWallets, hasPassword, }, @@ -38,7 +36,7 @@ export function useBackupFormState() { .string() .min(8, t`Incorrect Password`) .max(20, t`Incorrect Password`) - .refine((password) => password === user.backupPassword, t`Incorrect Password`) + .refine((password) => password === user.backupPassword, t`Incorrect Backup Password`) .refine((password) => passwordRegexp.test(password), t`Incorrect Password`), paymentPassword: backupWallets && hasPassword ? @@ -55,8 +53,6 @@ export function useBackupFormState() { return { hasPassword, - previewInfo, - loading, backupWallets, setBackupWallets, formState, diff --git a/packages/mask/dashboard/hooks/useBackupPreviewInfo.ts b/packages/mask/dashboard/hooks/useBackupPreviewInfo.ts new file mode 100644 index 000000000000..524ad737c5c3 --- /dev/null +++ b/packages/mask/dashboard/hooks/useBackupPreviewInfo.ts @@ -0,0 +1,11 @@ +import { useQuery } from '@tanstack/react-query' +import Services from '#services' + +export function useBackupPreviewInfo() { + return useQuery({ + queryKey: ['backup', 'preview-info'], + queryFn: () => Services.Backup.generateBackupPreviewInfo(), + refetchInterval: 60_0000, + refetchOnWindowFocus: true, + }) +} diff --git a/packages/mask/dashboard/hooks/useGoogleDriveFiles.ts b/packages/mask/dashboard/hooks/useGoogleDriveFiles.ts new file mode 100644 index 000000000000..5cedc47bc2fc --- /dev/null +++ b/packages/mask/dashboard/hooks/useGoogleDriveFiles.ts @@ -0,0 +1,25 @@ +import { type GoogleDriveClient } from '@masknet/web3-providers' +import { useInfiniteQuery } from '@tanstack/react-query' +import { compact } from 'lodash-es' +import { UserContext } from '../../shared-ui/index.js' + +export function useGoogleDriveFiles(client: GoogleDriveClient) { + const { user } = UserContext.useContainer() + + const query = useInfiniteQuery({ + enabled: !!user.googleAccount, + queryKey: ['google-drive', 'files', user.googleAccount], + initialPageParam: '', + queryFn: (param) => { + return client.listBackupFiles({ + pageSize: '100', + pageToken: param.pageParam, + }) + }, + getNextPageParam: () => '', + select(data) { + return compact(data.pages.flatMap((x) => x)) + }, + }) + return query +} diff --git a/packages/mask/dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx b/packages/mask/dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx index 239c540a82da..7053522997f6 100644 --- a/packages/mask/dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx +++ b/packages/mask/dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx @@ -1,25 +1,24 @@ -import { InjectedDialog, LoadingStatus } from '@masknet/shared' -import { memo, useCallback, useMemo, useRef } from 'react' -import { Box, DialogActions, DialogContent, Typography } from '@mui/material' -import { useBackupFormState, type BackupFormInputs } from '../../hooks/useBackupFormState.js' -import { ActionButton, makeStyles, useCustomSnackbar } from '@masknet/theme' -import { Icons } from '@masknet/icons' -import { useAsyncFn, useUpdateEffect } from 'react-use' import Services from '#services' -import type { BackupAccountType } from '@masknet/shared-base' -import { fetchDownloadLink, fetchUploadLink, uploadBackupValue } from '../../utils/api.js' +import { msg } from '@lingui/core/macro' +import { useLingui } from '@lingui/react' +import { Trans } from '@lingui/react/macro' import { encryptBackup } from '@masknet/backup-format' +import { Icons } from '@masknet/icons' +import { InjectedDialog, LoadingStatus } from '@masknet/shared' +import { DashboardRoutes } from '@masknet/shared-base' +import { ActionButton, makeStyles, useCustomSnackbar } from '@masknet/theme' import { encode } from '@msgpack/msgpack' +import { Box, DialogActions, DialogContent, Typography } from '@mui/material' +import { format } from 'date-fns' +import { memo, useCallback, useMemo, useRef } from 'react' import { Controller } from 'react-hook-form' +import { useNavigate } from 'react-router-dom' +import { useAsyncFn, useUpdateEffect } from 'react-use' +import { UserContext } from '../../../shared-ui/index.js' import { PersonasBackupPreview, WalletsBackupPreview } from '../../components/BackupPreview/index.js' import PasswordField from '../../components/PasswordField/index.js' -import { useNavigate, useSearchParams } from 'react-router-dom' -import { DashboardRoutes } from '@masknet/shared-base' -import { format as formatDateTime } from 'date-fns' -import { UserContext } from '../../../shared-ui/index.js' -import { msg } from '@lingui/core/macro' -import { Trans } from '@lingui/react/macro' -import { useLingui } from '@lingui/react' +import { useBackupFormState, type BackupFormInputs } from '../../hooks/useBackupFormState.js' +import { useBackupPreviewInfo } from '../../hooks/useBackupPreviewInfo.js' const useStyles = makeStyles()((theme) => ({ container: { @@ -57,34 +56,36 @@ const useStyles = makeStyles()((theme) => ({ }, })) -interface BackupPreviewDialogProps { +export interface BackupPreviewDialogProps { open: boolean - onClose: () => void - isOverwrite: boolean - code: string - type: BackupAccountType + isUpload?: boolean account: string - abstract?: string + /** + * MaskNetwork backup use account + password as password since legacy version. + * Will be removed in the future when we remove MaskNetwork backup. + */ + encryptWithAccount: boolean + title?: React.ReactNode | string + uploadButtonLabel?: React.ReactNode | string + onClose: () => void + onUpload?: (content: ArrayBuffer, signal: AbortSignal) => Promise } export const BackupPreviewDialog = memo(function BackupPreviewDialog({ open, - onClose, - isOverwrite, - code, - type, + isUpload, account, - abstract, + encryptWithAccount, + title, + uploadButtonLabel, + onClose, + onUpload, }) { const { _ } = useLingui() const controllerRef = useRef(null) const { classes, theme } = useStyles() - const [params, setParams] = useSearchParams() const navigate = useNavigate() - const { updateUser } = UserContext.useContainer() const { hasPassword, - previewInfo, - loading, backupWallets, setBackupWallets, formState: { @@ -96,8 +97,10 @@ export const BackupPreviewDialog = memo(function Backu formState: { errors, isDirty, isValid }, }, } = useBackupFormState() + const { data: previewInfo, isLoading: loading } = useBackupPreviewInfo() const { showSnackbar } = useCustomSnackbar() + const { updateUser } = UserContext.useContainer() const [{ loading: uploadLoading, value }, handleUploadBackup] = useAsyncFn( async (data: BackupFormInputs) => { try { @@ -114,44 +117,35 @@ export const BackupPreviewDialog = memo(function Backu excludeWallet: !backupWallets, }) - const name = `mask-network-keystore-backup-${formatDateTime(new Date(), 'yyyy-MM-dd')}` - const uploadUrl = await fetchUploadLink({ - code, - account, - type, - abstract: name, - }) - const encrypted = await encryptBackup(encode(account + data.backupPassword), encode(file)) + const password = encryptWithAccount ? account + data.backupPassword : data.backupPassword + const encrypted = await encryptBackup(encode(password), encode(file)) const controller = new AbortController() controllerRef.current = controller - const response = await uploadBackupValue(uploadUrl, encrypted, controller.signal) - - if (response.ok) { - const now = formatDateTime(new Date(), 'yyyy-MM-dd HH:mm') - const downloadLinkResponse = await fetchDownloadLink({ - account, - type, - code, - }) - showSnackbar(You have backed up your data., { variant: 'success' }) - updateUser({ cloudBackupAt: now, cloudBackupMethod: type }) - setParams((params) => { - params.set('size', downloadLinkResponse.size.toString()) - params.set('abstract', downloadLinkResponse.abstract) - params.set('uploadedAt', downloadLinkResponse.uploadedAt.toString()) - params.set('downloadURL', downloadLinkResponse.downloadURL) - return params.toString() - }) - } - return true + await onUpload?.(encrypted, controller.signal) + updateUser({ cloudBackupAt: format(new Date(), 'yyyy-MM-dd HH:mm:ss') }) + showSnackbar(Backup Successful, { + variant: 'success', + message: Data backed up successfully!, + }) + onClose() } catch (error) { showSnackbar(Backup Failed, { variant: 'error' }) onClose() - if ((error as any).status === 400) navigate(DashboardRoutes.CloudBackup, { replace: true }) - return false + if ((error as any).status === 400) navigate(DashboardRoutes.BackupCloud, { replace: true }) } }, - [code, hasPassword, backupWallets, abstract, code, account, type, _, navigate, updateUser, params], + [ + backupWallets, + hasPassword, + encryptWithAccount, + account, + onUpload, + showSnackbar, + onClose, + setError, + _, + navigate, + ], ) const handleClose = useCallback(() => { @@ -165,23 +159,6 @@ export const BackupPreviewDialog = memo(function Backu }, [backupWallets, resetField]) const content = useMemo(() => { - if (value) - return ( - - 🎉 - - Congratulations - - - Backup is saved to Mask Cloud Service. - - - ) if (uploadLoading) return ( @@ -233,7 +210,7 @@ export const BackupPreviewDialog = memo(function Backu name="paymentPassword" /> : null} - {isOverwrite ? + {isUpload ? This will overwrite the existing cloud backup with the local data, this cannot be undo. @@ -243,19 +220,21 @@ export const BackupPreviewDialog = memo(function Backu : }, [ + uploadLoading, + classes.container, + classes.icon, loading, previewInfo, control, - _, - // eslint-disable-next-line react-compiler/react-compiler - JSON.stringify(errors), backupWallets, setBackupWallets, - isOverwrite, - theme, - value, - uploadLoading, - classes, + hasPassword, + isUpload, + theme.palette.maskColor.danger, + _, + errors.backupPassword?.message, + errors.paymentPassword?.message, + clearErrors, ]) const action = useMemo(() => { @@ -275,31 +254,27 @@ export const BackupPreviewDialog = memo(function Backu : } - color={isOverwrite ? 'error' : 'primary'} + startIcon={isUpload ? : } + color="primary" disabled={!isDirty || !isValid}> - {isOverwrite ? - Overwrite Backup - : Backup to the Cloud} + {isUpload ? (uploadButtonLabel ?? Backup) : Backup to the Cloud} ) }, [ - backupWallets, - isOverwrite, - isDirty, - isValid, - hasPassword, - backupWallets, value, + onClose, uploadLoading, handleClose, handleSubmit, handleUploadBackup, - onClose, + isUpload, + isDirty, + isValid, + uploadButtonLabel, ]) return ( - Upload backup} open={open} onClose={handleClose}> + Upload backup} open={open} onClose={handleClose}> {content} {action} diff --git a/packages/mask/dashboard/modals/BackupPreviewModal/index.tsx b/packages/mask/dashboard/modals/BackupPreviewModal/index.tsx index 50efe5c71f64..41e5f45ae7c0 100644 --- a/packages/mask/dashboard/modals/BackupPreviewModal/index.tsx +++ b/packages/mask/dashboard/modals/BackupPreviewModal/index.tsx @@ -1,50 +1,22 @@ -import type { BackupAccountType, SingletonModalProps } from '@masknet/shared-base' +import type { SingletonModalProps } from '@masknet/shared-base' import { useSingletonModal } from '@masknet/shared-base-ui' import { useState } from 'react' -import { BackupPreviewDialog } from './BackupPreviewDialog.js' +import { BackupPreviewDialog, type BackupPreviewDialogProps } from './BackupPreviewDialog.js' -export interface BackupPreviewModalOpenProps { - isOverwrite?: boolean - code: string - type: BackupAccountType - account: string - abstract?: string -} +export interface BackupPreviewModalOpenProps extends Omit {} export function BackupPreviewModal({ ref }: SingletonModalProps) { - const [isOverwrite, setIsOverwrite] = useState(false) - const [code, setCode] = useState('') - const [type, setType] = useState() - const [account, setAccount] = useState('') - const [abstract, setAbstract] = useState('') + const [props, setProps] = useState(null) const [open, dispatch] = useSingletonModal(ref, { onOpen(props) { - if (props.isOverwrite) setIsOverwrite(props.isOverwrite) - if (props.abstract) setAbstract(props.abstract) - setCode(props.code) - setType(props.type) - setAccount(props.account) + setProps(props) }, - onClose(props) { - setIsOverwrite(false) - setAbstract('') - setCode('') - setType(undefined) - setAccount('') + onClose() { + setProps(null) }, }) - if (!open || !type) return null - return ( - dispatch?.close()} - isOverwrite={isOverwrite} - code={code} - type={type} - account={account} - abstract={abstract} - /> - ) + if (!props || !open) return null + return dispatch?.close()} {...props} /> } diff --git a/packages/mask/dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx b/packages/mask/dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx deleted file mode 100644 index 42b77845b71d..000000000000 --- a/packages/mask/dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx +++ /dev/null @@ -1,265 +0,0 @@ -import Services from '#services' -import { Trans, useLingui } from '@lingui/react/macro' -import { decryptBackup } from '@masknet/backup-format' -import { Icons } from '@masknet/icons' -import { formatFileSize, InjectedDialog } from '@masknet/shared' -import type { BackupAccountType } from '@masknet/shared-base' -import { DashboardRoutes } from '@masknet/shared-base' -import { ActionButton, makeStyles, useCustomSnackbar } from '@masknet/theme' -import { decode, encode } from '@msgpack/msgpack' -import { Box, DialogActions, DialogContent, LinearProgress, Typography } from '@mui/material' -import { format as formatDateTime, fromUnixTime } from 'date-fns' -import { last } from 'lodash-es' -import { memo, useCallback, useMemo, useState, type ReactNode } from 'react' -import { useNavigate } from 'react-router-dom' -import { useAsync, useAsyncFn } from 'react-use' -import PasswordField from '../../components/PasswordField/index.js' -import { passwordRegexp } from '../../utils/regexp.js' -import { BackupPreviewModal } from '../modals.js' - -const useStyles = makeStyles()((theme) => ({ - account: { - padding: theme.spacing(0.5, 2), - fontSize: 14, - fontWeight: 700, - }, - box: { - background: theme.palette.maskColor.bottom, - borderRadius: 8, - boxShadow: theme.palette.maskColor.bottomBg, - backdropFilter: 'blur(8px)', - padding: theme.spacing(1.5), - display: 'flex', - alignItems: 'center', - margin: theme.spacing(1.5, 0), - columnGap: 8, - }, - fileName: { - fontSize: 14, - lineHeight: '18px', - }, - container: { - display: 'flex', - flexDirection: 'column', - justifyContent: 'center', - alignItems: 'center', - minHeight: 276, - }, -})) - -interface MergeBackupDialogProps { - open: boolean - onClose: () => void - downloadLink: string - account: string - uploadedAt: string - size: string - type?: BackupAccountType - abstract?: string - code: string -} - -export const MergeBackupDialog = memo(function MergeBackupDialog({ - open, - onClose, - downloadLink, - account, - uploadedAt, - size, - type, - code, - abstract, -}) { - const { t } = useLingui() - const { classes, theme } = useStyles() - const [process, setProcess] = useState(0) - const [backupPassword, setBackupPassword] = useState('') - const [backupPasswordError, setBackupPasswordError] = useState() - const [showCongratulation, setShowCongratulation] = useState(false) - const navigate = useNavigate() - const { showSnackbar } = useCustomSnackbar() - - const handleClose = useCallback(() => { - setBackupPassword('') - setBackupPasswordError('') - setShowCongratulation(false) - onClose() - }, [onClose]) - - const { value: encrypted } = useAsync(async () => { - if (!downloadLink || !open) return - - const response = await fetch(downloadLink, { method: 'GET', cache: 'no-store' }) - - if (!response.ok || response.status !== 200) { - showSnackbar(The download link is expired, { variant: 'error' }) - handleClose() - navigate(DashboardRoutes.CloudBackup, { replace: true }) - return - } - const reader = response.body?.getReader() - const contentLength = response.headers.get('Content-Length') - - if (!contentLength || !reader) return - let received = 0 - const chunks: number[] = [] - while (true) { - const { done, value } = await reader.read() - - if (done || !value) { - setProcess(100) - break - } - chunks.push(...value) - received += value.length - - setProcess((received / Number(contentLength)) * 100) - } - return Uint8Array.from(chunks).buffer - }, [downloadLink, handleClose, open]) - - const fileName = useMemo(() => { - try { - if (!downloadLink) return '' - const url = new URL(downloadLink) - return last(url.pathname.split('/')) - } catch { - return '' - } - }, [downloadLink]) - - const [{ loading }, handleClickMerge] = useAsyncFn(async () => { - try { - if (!encrypted) return - const decrypted = await decryptBackup(encode(account + backupPassword), encrypted) - const backupText = JSON.stringify(decode(decrypted)) - const summary = await Services.Backup.generateBackupSummary(backupText) - if (summary.isErr()) { - setBackupPasswordError(Incorrect cloud backup password, please try again.) - return - } - const backupSummary = summary.unwrapOr(undefined) - if (!backupSummary) return - if (backupSummary.countOfWallets) { - const hasPassword = await Services.Wallet.hasPassword() - if (!hasPassword) await Services.Wallet.setDefaultPassword() - } - await Services.Backup.restoreBackup(backupText) - showSnackbar(Download backup, { - variant: 'success', - message: Backup downloaded and merged to local successfully., - }) - setShowCongratulation(true) - } catch { - showSnackbar(Failed to download and merge the backup.) - } - }, [encrypted, backupPassword, account]) - - const handleClickBackup = useCallback(async () => { - if (!type) return - BackupPreviewModal.open({ - isOverwrite: true, - code, - abstract, - type, - account, - }) - handleClose() - }, [code, abstract, type, account, handleClose]) - - if (showCongratulation) - return ( - Merge data to local database} open={open} onClose={handleClose}> - - - 🎉 - - Congratulations - - - - Data merged from Mask Cloud Service to local successfully. Re-enter your password to - encrypt and upload the new backup to Mask Cloud Service. - - - - - - - Backup to Mask Cloud Service - - - - ) - - return ( - Merge data to local database} open={open} onClose={onClose}> - - {account} - - - - {fileName} - - - {process !== 100 ? - Downloading - : <> - - {formatFileSize(Number(size))} - - - {formatDateTime(fromUnixTime(Number(uploadedAt)), 'yyyy-MM-dd HH:mm')} - - - } - - - - - { - setBackupPassword(e.target.value) - setBackupPasswordError('') - }} - onBlur={(e) => { - if (!passwordRegexp.test(e.target.value)) { - setBackupPasswordError(Incorrect cloud backup password, please try again.) - } - }} - error={!!backupPasswordError} - helperText={ - backupPasswordError ? backupPasswordError : ( - Please enter cloud backup password to download file. - ) - } - /> - - - - Merge to local - - - - ) -}) diff --git a/packages/mask/dashboard/modals/MergeBackupModal/index.tsx b/packages/mask/dashboard/modals/MergeBackupModal/index.tsx deleted file mode 100644 index ffdc3dbb0906..000000000000 --- a/packages/mask/dashboard/modals/MergeBackupModal/index.tsx +++ /dev/null @@ -1,57 +0,0 @@ -import type { BackupAccountType, SingletonModalProps } from '@masknet/shared-base' -import { useSingletonModal } from '@masknet/shared-base-ui' -import { useState } from 'react' -import { MergeBackupDialog } from './MergeBackupDialog.js' - -export interface MergeBackupModalOpenProps { - downloadLink: string - account: string - uploadedAt: string - size: string - code: string - abstract?: string - type: BackupAccountType -} - -export function MergeBackupModal({ ref }: SingletonModalProps) { - const [downloadLink, setDownloadLink] = useState('') - const [code, setCode] = useState('') - const [type, setType] = useState() - const [account, setAccount] = useState('') - const [abstract, setAbstract] = useState('') - const [uploadedAt, setUploadedAt] = useState('') - const [size, setSize] = useState('') - const [open, dispatch] = useSingletonModal(ref, { - onOpen(props) { - if (props.abstract) setAbstract(props.abstract) - setCode(props.code) - setType(props.type) - setDownloadLink(props.downloadLink) - setAccount(props.account) - setUploadedAt(props.uploadedAt) - setSize(props.size) - }, - onClose(props) { - setCode('') - setType(undefined) - setDownloadLink('') - setAccount('') - setSize('') - setUploadedAt('') - }, - }) - - return ( - dispatch?.close()} - account={account} - downloadLink={downloadLink} - size={size} - uploadedAt={uploadedAt} - /> - ) -} diff --git a/packages/mask/dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx b/packages/mask/dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx new file mode 100644 index 000000000000..ff321d8bf457 --- /dev/null +++ b/packages/mask/dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx @@ -0,0 +1,244 @@ +import Services from '#services' +import { Trans, useLingui } from '@lingui/react/macro' +import { decryptBackup, type BackupSummary } from '@masknet/backup-format' +import { Icons } from '@masknet/icons' +import { formatFileSize, InjectedDialog } from '@masknet/shared' +import { ActionButton, makeStyles, useCustomSnackbar } from '@masknet/theme' +import { decode, encode } from '@msgpack/msgpack' +import { Box, DialogActions, DialogContent, LinearProgress, Typography } from '@mui/material' +import { format as formatDateTime } from 'date-fns' +import { memo, useCallback, useState, type ReactNode } from 'react' +import { useAsync, useAsyncFn } from 'react-use' +import PasswordField from '../../components/PasswordField/index.js' +import { passwordRegexp } from '../../utils/regexp.js' + +const useStyles = makeStyles()((theme) => ({ + dialog: { + height: 620, + width: 600, + }, + account: { + padding: theme.spacing(0.5, 2), + fontSize: 14, + fontWeight: 700, + }, + box: { + background: theme.palette.maskColor.bottom, + borderRadius: 8, + boxShadow: theme.palette.maskColor.bottomBg, + backdropFilter: 'blur(8px)', + padding: theme.spacing(1.5), + display: 'flex', + alignItems: 'center', + margin: theme.spacing(1.5, 0), + columnGap: 8, + }, + fileName: { + fontSize: 14, + lineHeight: '18px', + }, +})) + +export interface RestoreBackupDialogProps { + account: string + fileName: string + open: boolean + size: string + /** unix time */ + uploadedAt: string | number + strategy?: 'import' | 'merge' + restoreSuccessMessage?: ReactNode + restoreErrorMessage?: ReactNode + /** + * MaskNetwork backup use account + password as password since legacy version. + * Will be removed in the future when we remove MaskNetwork backup. + */ + decryptWithAccount: boolean + /** + * A generator that yield progress of download, + * and return the content of the downloaded file at the end + */ + download: () => AsyncGenerator + onClose: (summary?: BackupSummary) => void +} + +export const RestoreBackupDialog = memo(function RestoreBackupDialog({ + open, + fileName, + account, + decryptWithAccount, + uploadedAt, + size, + strategy = 'import', + restoreSuccessMessage, + restoreErrorMessage, + download, + onClose, +}) { + const { t } = useLingui() + const { classes, theme } = useStyles() + const [progress, setProgress] = useState(0) + const [backupPassword, setBackupPassword] = useState('') + const [backupPasswordError, setBackupPasswordError] = useState() + const { showSnackbar } = useCustomSnackbar() + + const handleClose = useCallback(() => { + setBackupPassword('') + setBackupPasswordError('') + onClose() + }, [onClose]) + + const { value: encrypted } = useAsync(async () => { + if (!open) return + const generator = download() + try { + let step: IteratorResult + while (!(step = await generator.next()).done) { + setProgress(step.value) + } + return step.value + } catch (err) { + showSnackbar((err as Error).message, { variant: 'error' }) + handleClose() + throw err + } + }, [open, download, showSnackbar, handleClose]) + + const isImport = strategy === 'import' + const [{ loading }, handleRestore] = useAsyncFn(async () => { + try { + if (!encrypted) return + const password = decryptWithAccount ? account + backupPassword : backupPassword + const decrypted = await decryptBackup(encode(password), encrypted) + const backupJson = JSON.stringify(decode(decrypted)) + const summary = await Services.Backup.generateBackupSummary(backupJson) + if (summary.isErr()) { + setBackupPasswordError(Incorrect cloud backup password, please try again.) + return + } + const backupSummary = summary.unwrapOr(undefined) + if (!backupSummary) return + if (backupSummary.countOfWallets) { + const hasPassword = await Services.Wallet.hasPassword() + if (!hasPassword) await Services.Wallet.setDefaultPassword() + } + await Services.Backup.restoreBackup(backupJson) + showSnackbar(isImport ? Restore Completed : Merge Completed, { + variant: 'success', + message: + restoreSuccessMessage || + (isImport ? + Your file has been successfully restore into the browser data. + : Your file has been successfully merged into the browser data.), + }) + onClose(backupSummary) + } catch (err) { + if (isImport) { + showSnackbar(Restore Failed, { + variant: 'error', + message: restoreErrorMessage || ( + Failed to restore the backup: {(err as Error).message} + ), + }) + } else { + showSnackbar(Failed to download and merge the backup: {(err as Error).message}, { + variant: 'error', + }) + } + } + }, [ + encrypted, + decryptWithAccount, + account, + backupPassword, + showSnackbar, + isImport, + restoreSuccessMessage, + onClose, + restoreErrorMessage, + ]) + + return ( + Add the file to Chrome's database + : Merge data to local database + } + open={open} + onClose={() => onClose()}> + + {account} + + + + {fileName} + + + {progress !== 100 ? + Downloading + : <> + + {formatFileSize(Number(size))} + + + {formatDateTime(new Date(Number(uploadedAt)), 'yyyy-MM-dd HH:mm')} + + + } + + + + + { + setBackupPassword(e.target.value) + setBackupPasswordError('') + }} + onBlur={(e) => { + if (!passwordRegexp.test(e.target.value)) { + setBackupPasswordError(Incorrect cloud backup password, please try again.) + } + }} + error={!!backupPasswordError} + helperText={ + backupPasswordError ? backupPasswordError : ( + Please enter cloud backup password to download file. + ) + } + /> + + + } + onClick={handleRestore} + loading={loading} + disabled={!!backupPasswordError || !backupPassword || !encrypted}> + {isImport ? + Recover + : Merge to Browser} + + + + ) +}) diff --git a/packages/mask/dashboard/modals/RestoreBackupModal/index.tsx b/packages/mask/dashboard/modals/RestoreBackupModal/index.tsx new file mode 100644 index 000000000000..e1d2c94855c0 --- /dev/null +++ b/packages/mask/dashboard/modals/RestoreBackupModal/index.tsx @@ -0,0 +1,25 @@ +import type { BackupSummary } from '@masknet/backup-format' +import type { SingletonModalProps } from '@masknet/shared-base' +import { useSingletonModal } from '@masknet/shared-base-ui' +import { useState } from 'react' +import { RestoreBackupDialog, type RestoreBackupDialogProps } from './RestoreBackupDialog.js' + +export interface RestoreBackupModalOpenProps extends Omit {} +export type RestoreBackupModalCloseResult = BackupSummary | undefined + +export function RestoreBackupModal({ + ref, +}: SingletonModalProps) { + const [props, setProps] = useState(null) + const [open, dispatch] = useSingletonModal(ref, { + onOpen(props) { + setProps(props) + }, + onClose(props) { + setProps(null) + }, + }) + if (!props) return null + + return dispatch?.close(success)} {...props} /> +} diff --git a/packages/mask/dashboard/modals/index.tsx b/packages/mask/dashboard/modals/index.tsx index 8b4ebcdc9b60..7c2c9bb0c440 100644 --- a/packages/mask/dashboard/modals/index.tsx +++ b/packages/mask/dashboard/modals/index.tsx @@ -1,17 +1,17 @@ import { memo } from 'react' -import { ConfirmDialog } from './ConfirmModal/index.js' import { BackupPreviewModal } from './BackupPreviewModal/index.js' -import { MergeBackupModal } from './MergeBackupModal/index.js' +import { ConfirmDialog } from './ConfirmModal/index.js' import * as modals from './modals.js' +import { RestoreBackupModal } from './RestoreBackupModal/index.js' export const Modals = memo(function Modals() { return ( <> - + ) }) diff --git a/packages/mask/dashboard/modals/modals.ts b/packages/mask/dashboard/modals/modals.ts index 169a6014e5fc..9494fed43d4f 100644 --- a/packages/mask/dashboard/modals/modals.ts +++ b/packages/mask/dashboard/modals/modals.ts @@ -1,8 +1,8 @@ import { SingletonModal } from '@masknet/shared-base' import type { ConfirmDialogOpenProps } from './ConfirmModal/index.js' import type { BackupPreviewModalOpenProps } from './BackupPreviewModal/index.js' -import type { MergeBackupModalOpenProps } from './MergeBackupModal/index.js' +import type { RestoreBackupModalCloseResult, RestoreBackupModalOpenProps } from './RestoreBackupModal/index.js' export const ConfirmDialog = new SingletonModal() export const BackupPreviewModal = new SingletonModal() -export const MergeBackupModal = new SingletonModal() +export const RestoreBackupModal = new SingletonModal() diff --git a/packages/mask/dashboard/pages/CreateMaskWallet/Onboarding/index.tsx b/packages/mask/dashboard/pages/CreateMaskWallet/Onboarding/index.tsx index c2697891ced4..7d53ac5359cd 100644 --- a/packages/mask/dashboard/pages/CreateMaskWallet/Onboarding/index.tsx +++ b/packages/mask/dashboard/pages/CreateMaskWallet/Onboarding/index.tsx @@ -74,14 +74,14 @@ export const Component = memo(function Onboarding() { window.close() }, []) - const sentence: string[][] = useMemo(() => { + const sentence: string[] = useMemo(() => { return [ - [t`Creating your `, t`wallet`], - [t`Generating your `, t`accounts`], - [t`Encrypting your `, t`data`], - [t`Your Wallet is on `, t`ready 🚀`], + t`Creating your **wallet**`, + t`Generating your **accounts**`, + t`Encrypting your **data**`, + t`Your Wallet is on **ready 🚀**`, ] - }, []) + }, [t]) return ( <> diff --git a/packages/mask/dashboard/pages/SetupPersona/Backup/Cloud/CloudBackupFormContext.ts b/packages/mask/dashboard/pages/SetupPersona/Backup/Cloud/CloudBackupFormContext.ts new file mode 100644 index 000000000000..6494465c13d2 --- /dev/null +++ b/packages/mask/dashboard/pages/SetupPersona/Backup/Cloud/CloudBackupFormContext.ts @@ -0,0 +1,67 @@ +import { zodResolver } from '@hookform/resolvers/zod' +import { useLingui } from '@lingui/react/macro' +import { BackupAccountType } from '@masknet/shared-base' +import { createContainer } from '@masknet/shared-base-ui' +import guessCallingCode from 'guess-calling-code' +import { useState } from 'react' +import { useForm } from 'react-hook-form' +import { z } from 'zod' +import { phoneRegexp } from '../../../../utils/regexp.js' + +export interface CloudBackupFormInputs { + email: string + phone: string + code: string + countryCode: string +} + +export function useCloudBackupForm() { + const { t } = useLingui() + + const [backupType, setBackupType] = useState(BackupAccountType.Email) + const isEmail = backupType === BackupAccountType.Email + + const form = useForm({ + mode: 'onSubmit', + context: { + backupType, + }, + defaultValues: { + email: '', + phone: '', + code: '', + countryCode: (guessCallingCode.default || guessCallingCode)(), + }, + resolver: zodResolver( + z + .object({ + email: isEmail ? z.string().email(t`Invalid email address format.`) : z.string().optional(), + countryCode: isEmail ? z.string().optional() : z.string(), + phone: isEmail ? z.string().optional() : z.string().regex(phoneRegexp), + code: z + .string() + .min(1, t`The code is incorrect.`) + .max(6, t`The code is incorrect.`), + }) + .refine( + (data) => { + if (isEmail) return true + if (!data.countryCode || !data.phone) return false + return phoneRegexp.test(`+${data.countryCode} ${data.phone}`) + }, + { + message: t`The phone number is incorrect.`, + path: ['phone'], + }, + ), + ), + }) + + return { + form, + backupType, + setBackupType, + } +} + +export const CloudBackupFormContext = createContainer(useCloudBackupForm) diff --git a/packages/mask/dashboard/pages/SetupPersona/CloudBackup/EmailForm.tsx b/packages/mask/dashboard/pages/SetupPersona/Backup/Cloud/EmailForm.tsx similarity index 93% rename from packages/mask/dashboard/pages/SetupPersona/CloudBackup/EmailForm.tsx rename to packages/mask/dashboard/pages/SetupPersona/Backup/Cloud/EmailForm.tsx index 3435aca27aca..768e02af6158 100644 --- a/packages/mask/dashboard/pages/SetupPersona/CloudBackup/EmailForm.tsx +++ b/packages/mask/dashboard/pages/SetupPersona/Backup/Cloud/EmailForm.tsx @@ -1,13 +1,13 @@ -import { memo, useCallback } from 'react' +import { Trans, useLingui } from '@lingui/react/macro' +import { BackupAccountType } from '@masknet/shared-base' import { CountdownButton, makeStyles, useCustomSnackbar } from '@masknet/theme' -import { Controller } from 'react-hook-form' import { Box, TextField } from '@mui/material' -import { sendCode } from '../../../utils/api.js' -import { BackupAccountType } from '@masknet/shared-base' -import { Locale, Scenario } from '../../../utils/type.js' -import { UserContext, useLanguage } from '../../../../shared-ui/index.js' -import { CloudBackupFormContext } from '../../../contexts/CloudBackupFormContext.js' -import { Trans, useLingui } from '@lingui/react/macro' +import { memo, useCallback } from 'react' +import { Controller } from 'react-hook-form' +import { UserContext, useLanguage } from '../../../../../shared-ui/index.js' +import { sendCode } from '../../../../utils/api.js' +import { Locale, Scenario } from '../../../../utils/type.js' +import { CloudBackupFormContext } from './CloudBackupFormContext.js' const useStyles = makeStyles()((theme) => ({ send: { @@ -23,7 +23,7 @@ export const EmailForm = memo(function EmailForm() { const { user } = UserContext.useContainer() const { showSnackbar } = useCustomSnackbar() const { - formState: { + form: { clearErrors, control, watch, diff --git a/packages/mask/dashboard/pages/SetupPersona/Backup/Cloud/GoogleDrive.tsx b/packages/mask/dashboard/pages/SetupPersona/Backup/Cloud/GoogleDrive.tsx new file mode 100644 index 000000000000..493c6b3c621c --- /dev/null +++ b/packages/mask/dashboard/pages/SetupPersona/Backup/Cloud/GoogleDrive.tsx @@ -0,0 +1,179 @@ +import { Trans } from '@lingui/react/macro' +import { Icons } from '@masknet/icons' +import { EMPTY_LIST } from '@masknet/shared-base' +import { ActionButton, makeStyles } from '@masknet/theme' +import { GoogleDriveClient, type DriveFile } from '@masknet/web3-providers' +import { Box, Typography } from '@mui/material' +import { compact, uniqBy } from 'lodash-es' +import { memo, useMemo, useState } from 'react' +import { useAsyncFn } from 'react-use' +import { UserContext } from '../../../../../shared-ui/index.js' +import { GoogleDriveFileTable } from '../../../../components/GoogleDriveFileTable.js' +import { GoogleDriveLogin } from '../../../../components/GoogleDriveLogin.js' +import { OutletPortal } from '../../../../components/OutletPortal.js' +import { PrimaryButton } from '../../../../components/PrimaryButton/index.js' +import { useGoogleDriveFiles } from '../../../../hooks/useGoogleDriveFiles.js' +import { BackupPreviewModal, RestoreBackupModal } from '../../../../modals/modals.js' +import { + clearGoogleDriveAccessToken, + createBackupName, + downloadBackup, + getGoogleDriveAccessToken, + progressDownload, +} from '../../../../utils/api.js' + +const useStyles = makeStyles()((theme) => ({ + container: { + display: 'flex', + flexDirection: 'column', + gap: theme.spacing(1.5), + }, + header: { + display: 'flex', + justifyContent: 'space-between', + alignItems: 'center', + }, + user: { + display: 'flex', + flexDirection: 'column', + gap: theme.spacing(1), + }, + providerName: { + fontWeight: 400, + fontSize: 14, + lineHeight: '18px', + height: 18, + color: theme.palette.maskColor.second, + }, + userAccount: { + fontWeight: 700, + fontSize: 14, + lineHeight: '18px', + height: 18, + color: theme.palette.maskColor.main, + }, + folder: { + fontSize: 14, + fontWeight: 700, + lineHeight: '18px', + }, + tableContainer: { + height: 340, + marginTop: theme.spacing(2), + }, +})) + +export const Component = memo(function GoogleDriveBackup() { + const { classes } = useStyles() + const { user, updateUser } = UserContext.useContainer() + const googleDriveClient = useMemo( + () => new GoogleDriveClient(getGoogleDriveAccessToken, clearGoogleDriveAccessToken), + [], + ) + const { data: files = EMPTY_LIST, refetch, isLoading } = useGoogleDriveFiles(googleDriveClient) + + const [uploadedFile, setUploadedFile] = useState(null) + + const [{ loading }, uploadFile] = useAsyncFn( + async (content: ArrayBuffer) => { + const name = createBackupName() + const file = new File([content], name, { type: 'application/octet-stream' }) + const result = await googleDriveClient.uploadFile(file) + const date = new Date() + setUploadedFile({ + ...result, + name, + size: file.size.toString(), + createdTime: date.toISOString(), + modifiedTime: date.toISOString(), + }) + refetch() + }, + [googleDriveClient, refetch], + ) + + const [{ loading: logoutLoading }, logout] = useAsyncFn(async () => { + await googleDriveClient.logout() + updateUser({ + googleAccount: '', + googleToken: '', + }) + }, [googleDriveClient, updateUser]) + + const mergedFiles = useMemo(() => uniqBy(compact([...files, uploadedFile]), (x) => x.id), [files, uploadedFile]) + + if (!user.googleAccount) { + return + } + + const downloadAndMerge = async (file: DriveFile) => { + await RestoreBackupModal.openAndWaitForClose({ + decryptWithAccount: false, + strategy: 'merge', + download: () => { + return progressDownload(() => googleDriveClient.requestFile(file.id), file.size ? +file.size : 0) + }, + fileName: file.name, + account: user.googleAccount!, + size: file.size || '0', + uploadedAt: new Date(file.modifiedTime).getTime(), + }) + } + return ( + + + + + Google Drive + + {user.googleAccount} + + + Logout + + + + MaskBackup file + { + const blob = await googleDriveClient.downloadFile(file.id) + const url = URL.createObjectURL(blob) + downloadBackup(url, file.name) + URL.revokeObjectURL(url) + }} + /> + + + } + size="large" + color="primary" + loading={loading} + disabled={loading} + onClick={() => { + if (!user.googleAccount) return + BackupPreviewModal.open({ + encryptWithAccount: false, + account: user.googleAccount!, + isUpload: true, + title: Backup to Google Drive, + uploadButtonLabel: Backup, + onUpload: uploadFile, + }) + }}> + Backup to Google Drive + + + + ) +}) diff --git a/packages/mask/dashboard/pages/SetupPersona/Backup/Cloud/MaskNetwork.tsx b/packages/mask/dashboard/pages/SetupPersona/Backup/Cloud/MaskNetwork.tsx new file mode 100644 index 000000000000..97c6d5e9a6ba --- /dev/null +++ b/packages/mask/dashboard/pages/SetupPersona/Backup/Cloud/MaskNetwork.tsx @@ -0,0 +1,139 @@ +import { t } from '@lingui/core/macro' +import { Trans } from '@lingui/react/macro' +import { Alert, useParamTab } from '@masknet/shared' +import { BackupAccountType, DashboardRoutes } from '@masknet/shared-base' +import { makeStyles } from '@masknet/theme' +import { Box, Radio, RadioGroup, Typography } from '@mui/material' +import { memo, useState } from 'react' +import { useNavigate } from 'react-router-dom' +import { useAsyncFn } from 'react-use' +import urlcat from 'urlcat' +import { UserContext } from '../../../../../shared-ui/index.js' +import { OutletPortal } from '../../../../components/OutletPortal.js' +import { PrimaryButton } from '../../../../components/PrimaryButton/index.js' +import { fetchDownloadLink } from '../../../../utils/api.js' +import { CloudBackupFormContext, type CloudBackupFormInputs } from './CloudBackupFormContext.js' +import { EmailForm } from './EmailForm.js' +import { PhoneForm } from './PhoneForm.js' + +const useStyles = makeStyles()((theme) => ({ + container: { + display: 'flex', + flexDirection: 'column', + gap: theme.spacing(2), + }, + radios: { + flexDirection: 'row', + display: 'flex', + flexWrap: 'nowrap', + justifyContent: 'space-evenly', + }, + radioContainer: { + flexGrow: 1, + '& label': { + cursor: 'pointer', + }, + }, +})) + +export const Component = memo(function MaskNetworkBackup() { + const { classes } = useStyles() + const { user, updateUser } = UserContext.useContainer() + const navigate = useNavigate() + const [showAlert, setShowAlert] = useState(true) + + const [accountType, setAccountType] = useParamTab(BackupAccountType.Email, 'account-type') + const { form } = CloudBackupFormContext.useContainer() + const { setError, formState, reset } = form + + const isEmail = accountType === BackupAccountType.Email + const incorrectCodeMsg = t`The code is incorrect.` + const [{ loading }, handleSubmit] = useAsyncFn( + async (data: CloudBackupFormInputs) => { + try { + const response = await fetchDownloadLink({ + account: isEmail ? data.email : `+${data.countryCode} ${data.phone}`, + type: isEmail ? BackupAccountType.Email : BackupAccountType.Phone, + code: data.code, + }) + + if (!response) return + + updateUser({ + email: data.email || user.email, + phone: data.phone ? `${data.countryCode} ${data.phone}` : user.phone, + }) + reset() + navigate( + urlcat(DashboardRoutes.BackupPreview, { + ...response, + type: isEmail ? BackupAccountType.Email : BackupAccountType.Phone, + account: isEmail ? data.email : `+${data.countryCode} ${data.phone}`, + code: data.code, + }), + ) + } catch (err) { + if ((err as any).status === 400) { + setError('code', { + type: 'custom', + message: incorrectCodeMsg, + }) + } else if ((err as any).status === 404) { + reset() + // No cloud backup file + navigate( + urlcat(DashboardRoutes.BackupPreview, { + type: isEmail ? BackupAccountType.Email : BackupAccountType.Phone, + account: isEmail ? data.email : `+${data.countryCode} ${data.phone}`, + code: data.code, + }), + ) + } + } + }, + [isEmail, setError, reset, navigate, updateUser, user], + ) + + return ( + + { + setAccountType(undefined, isEmail ? BackupAccountType.Phone : BackupAccountType.Email) + }}> +
+ +
+
+ +
+
+ {isEmail ? + + : } + setShowAlert(false)}> + + The Mask Network Cloud Backup feature will be deactivated on April 30, 2025. Please use alternative + cloud backup services or local backup solutions. + + + + + Continue + + +
+ ) +}) diff --git a/packages/mask/dashboard/pages/SetupPersona/CloudBackup/PhoneForm.tsx b/packages/mask/dashboard/pages/SetupPersona/Backup/Cloud/PhoneForm.tsx similarity index 80% rename from packages/mask/dashboard/pages/SetupPersona/CloudBackup/PhoneForm.tsx rename to packages/mask/dashboard/pages/SetupPersona/Backup/Cloud/PhoneForm.tsx index a4b87117b4ad..09bd9e5287d2 100644 --- a/packages/mask/dashboard/pages/SetupPersona/CloudBackup/PhoneForm.tsx +++ b/packages/mask/dashboard/pages/SetupPersona/Backup/Cloud/PhoneForm.tsx @@ -1,14 +1,14 @@ -import { memo, useCallback } from 'react' -import { Controller } from 'react-hook-form' -import { Box, TextField } from '@mui/material' +import { Trans, useLingui } from '@lingui/react/macro' import { PhoneNumberField } from '@masknet/shared' -import { CountdownButton, makeStyles, useCustomSnackbar } from '@masknet/theme' -import { UserContext, useLanguage } from '../../../../shared-ui/index.js' -import { CloudBackupFormContext } from '../../../contexts/CloudBackupFormContext.js' import { BackupAccountType } from '@masknet/shared-base' -import { Scenario, Locale } from '../../../utils/type.js' -import { sendCode } from '../../../utils/api.js' -import { Trans, useLingui } from '@lingui/react/macro' +import { CountdownButton, makeStyles, useCustomSnackbar } from '@masknet/theme' +import { Box, TextField } from '@mui/material' +import { memo, useCallback } from 'react' +import { Controller } from 'react-hook-form' +import { UserContext, useLanguage } from '../../../../../shared-ui/index.js' +import { sendCode } from '../../../../utils/api.js' +import { Locale, Scenario } from '../../../../utils/type.js' +import { CloudBackupFormContext } from './CloudBackupFormContext.js' const useStyles = makeStyles()((theme) => ({ send: { @@ -25,7 +25,7 @@ export const PhoneForm = memo(function PhoneForm() { const { showSnackbar } = useCustomSnackbar() const { - formState: { + form: { control, clearErrors, watch, @@ -37,17 +37,19 @@ export const PhoneForm = memo(function PhoneForm() { const [countryCode, phone] = watch(['countryCode', 'phone']) const handleSendVerificationCode = useCallback(async () => { - const response = await sendCode({ - account: `+${countryCode}${phone}`, - type: BackupAccountType.Phone, - scenario: user.phone ? Scenario.change : Scenario.create, - locale: lang.includes('zh') ? Locale.zh : Locale.en, - }).catch((error) => { - showSnackbar(error.message, { variant: 'error' }) - }) + try { + const response = await sendCode({ + account: `+${countryCode}${phone}`, + type: BackupAccountType.Phone, + scenario: user.phone ? Scenario.change : Scenario.create, + locale: lang.includes('zh') ? Locale.zh : Locale.en, + }) - if (response) { - showSnackbar(Verification code sent, { variant: 'success' }) + if (response) { + showSnackbar(Verification code sent, { variant: 'success' }) + } + } catch (error) { + showSnackbar((error as Error).message, { variant: 'error' }) } }, [phone, user, lang, countryCode]) diff --git a/packages/mask/dashboard/pages/SetupPersona/CloudBackupPreview/index.tsx b/packages/mask/dashboard/pages/SetupPersona/Backup/Cloud/Preview.tsx similarity index 59% rename from packages/mask/dashboard/pages/SetupPersona/CloudBackupPreview/index.tsx rename to packages/mask/dashboard/pages/SetupPersona/Backup/Cloud/Preview.tsx index 3166edb410e1..2d2dba5017f3 100644 --- a/packages/mask/dashboard/pages/SetupPersona/CloudBackupPreview/index.tsx +++ b/packages/mask/dashboard/pages/SetupPersona/Backup/Cloud/Preview.tsx @@ -1,27 +1,41 @@ import { Trans } from '@lingui/react/macro' import { Icons } from '@masknet/icons' import { EmptyStatus, formatFileSize } from '@masknet/shared' -import type { BackupAccountType } from '@masknet/shared-base' import { DashboardRoutes } from '@masknet/shared-base' import { ActionButton, TextOverflowTooltip, makeStyles } from '@masknet/theme' -import { Box, Typography } from '@mui/material' +import { Box, Button, Typography } from '@mui/material' import { format as formatDateTime, fromUnixTime } from 'date-fns' import { memo, useCallback, useMemo } from 'react' import { useNavigate, useSearchParams } from 'react-router-dom' import { useAsyncFn } from 'react-use' -import { SetupFrameController } from '../../../components/SetupFrame/index.js' -import { BackupPreviewModal, ConfirmDialog, MergeBackupModal } from '../../../modals/modals.js' +import { OutletPortal } from '../../../../components/OutletPortal.js' +import { BackupPreviewModal, RestoreBackupModal } from '../../../../modals/modals.js' +import { createBackupName, downloadBackup, getFileName, progressDownload } from '../../../../utils/api.js' const useStyles = makeStyles()((theme) => ({ - title: { - fontSize: 36, - lineHeight: 1.2, - fontWeight: 700, + header: { + display: 'flex', + justifyContent: 'space-between', + alignItems: 'center', + }, + user: { + display: 'flex', + flexDirection: 'column', + gap: theme.spacing(1), }, - description: { + providerName: { + fontWeight: 400, + fontSize: 14, + lineHeight: '18px', + height: 18, color: theme.palette.maskColor.second, + }, + userAccount: { + fontWeight: 700, fontSize: 14, - marginTop: theme.spacing(1.5), + lineHeight: '18px', + height: 18, + color: theme.palette.maskColor.main, }, text: { fontSize: 14, @@ -37,20 +51,19 @@ const useStyles = makeStyles()((theme) => ({ columnGap: 8, alignItems: 'center', }, - button: { - height: 40, - borderRadius: 20, - }, container: { padding: theme.spacing(2), borderRadius: 8, border: `1px solid ${theme.palette.maskColor.line}`, marginTop: theme.spacing(3), }, + button: { + whiteSpace: 'nowrap', + }, })) export const Component = memo(function CloudBackupPreview() { - const { classes, theme, cx } = useStyles() + const { classes, theme } = useStyles() const [params] = useSearchParams() const navigate = useNavigate() @@ -68,84 +81,46 @@ export const Component = memo(function CloudBackupPreview() { }, [params]) const [{ loading: mergeLoading }, handleMergeClick] = useAsyncFn(async () => { - if ( - !previewInfo.downloadLink || - !previewInfo.account || - !previewInfo.size || - !previewInfo.uploadedAt || - !previewInfo.type || - !previewInfo.code - ) - return - await MergeBackupModal.openAndWaitForClose({ - downloadLink: previewInfo.downloadLink, + if (!previewInfo.downloadLink || !previewInfo.account || !previewInfo.size || !previewInfo.uploadedAt) return + await RestoreBackupModal.openAndWaitForClose({ + decryptWithAccount: true, + strategy: 'merge', + download: () => progressDownload(previewInfo.downloadLink), + fileName: getFileName(previewInfo.downloadLink) || createBackupName(), account: previewInfo.account, size: previewInfo.size, uploadedAt: previewInfo.uploadedAt, - code: previewInfo.code, - abstract: previewInfo.abstract ? previewInfo.abstract : undefined, - type: previewInfo.type as BackupAccountType, }) }, [previewInfo]) const handleBackupClick = useCallback(() => { if (!previewInfo.type || !previewInfo.account || !previewInfo.code) return BackupPreviewModal.open({ - isOverwrite: false, - code: previewInfo.code, - abstract: previewInfo.abstract ? previewInfo.abstract : undefined, - type: previewInfo.type as BackupAccountType, + encryptWithAccount: true, + isUpload: false, account: previewInfo.account, }) }, [previewInfo]) - const [{ loading: overwriteLoading }, handleOverwriteClick] = useAsyncFn(async () => { - await ConfirmDialog.openAndWaitForClose({ - title: Overwrite current backup, - message: Are you sure to overwrite the backups stored on Mask Cloud Service?, - confirmLabel: Confirm, - cancelLabel: Cancel, - confirmButtonProps: { - color: 'error', - }, - onConfirm: () => { - ConfirmDialog.close(false) - if (!previewInfo.type || !previewInfo.account || !previewInfo.code) return - - BackupPreviewModal.open({ - isOverwrite: true, - code: previewInfo.code, - abstract: previewInfo.abstract ? previewInfo.abstract : undefined, - type: previewInfo.type as BackupAccountType, - account: previewInfo.account, - }) - }, - }) - }, [previewInfo]) - return ( <> - - Welcome to Mask Cloud Services - - - Please select the appropriate method to restore your personal data. - {previewInfo.downloadLink ? <> - - {previewInfo.account} - navigate(DashboardRoutes.CloudBackup, { replace: true })}> - Switch other account - + + + + Mask Network Cloud + + {previewInfo.account} + + - + - + } color="primary" - className={classes.button} + variant="roundedContained" loading={mergeLoading} onClick={handleMergeClick}> Merge data to local database } - color="error" - className={cx(classes.button)}> - Overwrite Backup + className={classes.button} + onClick={() => { + downloadBackup(previewInfo.downloadLink!) + }} + startIcon={} + color="primary" + variant="roundedContained"> + Download @@ -199,7 +177,7 @@ export const Component = memo(function CloudBackupPreview() { navigate(DashboardRoutes.CloudBackup, { replace: true })}> + onClick={() => navigate(DashboardRoutes.BackupCloud, { replace: true })}> Switch other account @@ -210,11 +188,11 @@ export const Component = memo(function CloudBackupPreview() { } {!previewInfo.downloadLink ? - - }> - Backup + + + Back - + : null} ) diff --git a/packages/mask/dashboard/pages/SetupPersona/Backup/Cloud/index.tsx b/packages/mask/dashboard/pages/SetupPersona/Backup/Cloud/index.tsx new file mode 100644 index 000000000000..85b39ce44da8 --- /dev/null +++ b/packages/mask/dashboard/pages/SetupPersona/Backup/Cloud/index.tsx @@ -0,0 +1,82 @@ +import { Trans } from '@lingui/react/macro' +import { Icons } from '@masknet/icons' +import { DashboardRoutes } from '@masknet/shared-base' +import { makeStyles } from '@masknet/theme' +import { Box, Typography } from '@mui/material' +import { memo } from 'react' +import { Outlet, useMatch, useNavigate, useOutletContext } from 'react-router-dom' +import { CloudBackupFormContext } from './CloudBackupFormContext.js' +import type { PortalContainerProps } from '../../../../components/OutletPortal.js' + +const useStyles = makeStyles()((theme, _, refs) => ({ + container: { + display: 'flex', + flexDirection: 'column', + gap: theme.spacing(2), + }, + providers: { + display: 'flex', + gap: theme.spacing(1.5), + }, + providerName: { + fontWeight: 700, + fontSize: 14, + lineHeight: '18px', + height: 18, + color: theme.palette.maskColor.main, + }, + activeButton: { + backgroundColor: theme.palette.maskColor.input, + }, + toggleButton: { + backgroundColor: theme.palette.maskColor.bottom, + cursor: 'pointer', + boxSizing: 'border-box', + borderRadius: 18, + height: 34, + gap: theme.spacing(1), + border: `1px solid ${theme.palette.maskColor.line}`, + display: 'inline-flex', + padding: theme.spacing(1, 1.5), + [`&.${refs.activeButton}`]: { + backgroundColor: theme.palette.maskColor.input, + }, + }, +})) + +export const Component = memo(function CloudBackup() { + const outletContext = useOutletContext() + const { classes, cx } = useStyles() + + const navigate = useNavigate() + const match = useMatch(DashboardRoutes.BackupCloudGoogleDrive) // MaskBook is index + const isGoogleDrive = !!match + + return ( + + + + + + + + + + ) +}) diff --git a/packages/mask/dashboard/pages/SetupPersona/LocalBackup/index.tsx b/packages/mask/dashboard/pages/SetupPersona/Backup/Local.tsx similarity index 53% rename from packages/mask/dashboard/pages/SetupPersona/LocalBackup/index.tsx rename to packages/mask/dashboard/pages/SetupPersona/Backup/Local.tsx index e8f46ca65270..4de49680129c 100644 --- a/packages/mask/dashboard/pages/SetupPersona/LocalBackup/index.tsx +++ b/packages/mask/dashboard/pages/SetupPersona/Backup/Local.tsx @@ -1,45 +1,29 @@ -import { makeStyles } from '@masknet/theme' -import { Box, Typography } from '@mui/material' -import { memo } from 'react' -import { useAsyncFn } from 'react-use' import Services from '#services' -import { LoadingStatus } from '@masknet/shared' -import PasswordField from '../../../components/PasswordField/index.js' -import { PersonasBackupPreview, WalletsBackupPreview } from '../../../components/BackupPreview/index.js' -import { Controller } from 'react-hook-form' -import { SetupFrameController } from '../../../components/SetupFrame/index.js' -import { PrimaryButton } from '../../../components/PrimaryButton/index.js' -import { Icons } from '@masknet/icons' +import { Trans, useLingui } from '@lingui/react/macro' import { encryptBackup } from '@masknet/backup-format' +import { Icons } from '@masknet/icons' +import { LoadingStatus } from '@masknet/shared' +import { MimeType } from '@masknet/shared-base' import { encode } from '@msgpack/msgpack' +import { Box } from '@mui/material' import { format as formatDateTime } from 'date-fns' -import { MimeType } from '@masknet/shared-base' -import { useBackupFormState, type BackupFormInputs } from '../../../hooks/useBackupFormState.js' +import { memo } from 'react' +import { Controller } from 'react-hook-form' +import { useAsyncFn } from 'react-use' import { UserContext } from '../../../../shared-ui/index.js' -import { Trans, useLingui } from '@lingui/react/macro' - -const useStyles = makeStyles()((theme) => ({ - title: { - fontSize: 36, - lineHeight: 1.2, - fontWeight: 700, - }, - description: { - color: theme.palette.maskColor.second, - fontSize: 14, - marginTop: theme.spacing(1.5), - marginBottom: theme.spacing(3), - }, -})) +import { PersonasBackupPreview, WalletsBackupPreview } from '../../../components/BackupPreview/index.js' +import { OutletPortal } from '../../../components/OutletPortal.js' +import PasswordField from '../../../components/PasswordField/index.js' +import { PrimaryButton } from '../../../components/PrimaryButton/index.js' +import { useBackupFormState, type BackupFormInputs } from '../../../hooks/useBackupFormState.js' +import { useBackupPreviewInfo } from '../../../hooks/useBackupPreviewInfo.js' +import { downloadBackup } from '../../../utils/api.js' export const Component = memo(function LocalBackup() { const { t } = useLingui() - const { classes } = useStyles() const { user, updateUser } = UserContext.useContainer() const { hasPassword, - previewInfo, - loading, backupWallets, setBackupWallets, formState: { @@ -50,6 +34,7 @@ export const Component = memo(function LocalBackup() { formState: { errors, isDirty, isValid }, }, } = useBackupFormState() + const { data: previewInfo, isLoading: loading } = useBackupPreviewInfo() const [{ loading: downloadLoading }, handleFormSubmit] = useAsyncFn( async (data: BackupFormInputs) => { @@ -69,10 +54,7 @@ export const Component = memo(function LocalBackup() { const now = formatDateTime(new Date(), 'yyyy-MM-dd HH:mm') const blob = new Blob([encrypted], { type: MimeType.Binary }) const url = URL.createObjectURL(blob) - const a = document.createElement('a') - a.href = url - a.download = `mask-network-keystore-backup-${now}.bin` - a.click() + downloadBackup(url, `mask-network-keystore-backup-${now}.bin`) await updateUser({ localBackupAt: now, @@ -84,18 +66,34 @@ export const Component = memo(function LocalBackup() { ) return ( - <> -
- - Select the contents of the backup - - - Please select the appropriate method to restore your personal data. - - {!loading && previewInfo ? - - + + {!loading && previewInfo ? + + + ( + clearErrors()} + sx={{ mb: 2 }} + placeholder={t`Backup Password`} + error={!!errors.backupPassword?.message} + helperText={errors.backupPassword?.message} + /> + )} + name="backupPassword" + /> + + + + {backupWallets ? ( @@ -103,51 +101,28 @@ export const Component = memo(function LocalBackup() { {...field} onFocus={() => clearErrors()} sx={{ mb: 2 }} - placeholder={t`Backup Password`} - error={!!errors.backupPassword?.message} - helperText={errors.backupPassword?.message} + placeholder={t`Payment Password`} + error={!!errors.paymentPassword?.message} + helperText={errors.paymentPassword?.message} /> )} - name="backupPassword" + name="paymentPassword" /> - - - - {backupWallets ? - ( - clearErrors()} - sx={{ mb: 2 }} - placeholder={t`Payment Password`} - error={!!errors.paymentPassword?.message} - helperText={errors.paymentPassword?.message} - /> - )} - name="paymentPassword" - /> - : null} - - : } - - + : null} +
+ : } + } size="large" color="primary" + variant="roundedContained" loading={downloadLoading} disabled={!isDirty || !isValid} onClick={handleSubmit(handleFormSubmit)}> Download Backup - - + + ) }) diff --git a/packages/mask/dashboard/pages/SetupPersona/Backup/constants.ts b/packages/mask/dashboard/pages/SetupPersona/Backup/constants.ts new file mode 100644 index 000000000000..293c44bc10a6 --- /dev/null +++ b/packages/mask/dashboard/pages/SetupPersona/Backup/constants.ts @@ -0,0 +1,8 @@ +import { DashboardRoutes } from '@masknet/shared-base' + +export const CloudBackupRoutes: string[] = [ + DashboardRoutes.BackupCloud, + DashboardRoutes.BackupCloudGoogleDrive, + DashboardRoutes.BackupCloudMaskNetwork, + DashboardRoutes.BackupPreview, +] diff --git a/packages/mask/dashboard/pages/SetupPersona/Backup/index.tsx b/packages/mask/dashboard/pages/SetupPersona/Backup/index.tsx new file mode 100644 index 000000000000..25994a653e87 --- /dev/null +++ b/packages/mask/dashboard/pages/SetupPersona/Backup/index.tsx @@ -0,0 +1,99 @@ +import { Trans } from '@lingui/react/macro' +import { MaskTabList, makeStyles } from '@masknet/theme' +import { TabContext } from '@mui/lab' +import { Box, Tab, Typography } from '@mui/material' +import { memo, useRef } from 'react' +import { Outlet } from 'react-router-dom' +import { StorageType } from '../types.js' +import { usePathTab, type TabPathTuple } from '@masknet/shared' +import { DashboardRoutes } from '@masknet/shared-base' + +const useStyles = makeStyles()((theme) => ({ + title: { + fontSize: 36, + lineHeight: 1.2, + fontWeight: 700, + }, + description: { + color: theme.palette.maskColor.second, + fontSize: 14, + marginTop: theme.spacing(1.5), + }, + tabContainer: { + border: `1px solid ${theme.palette.maskColor.line}`, + marginTop: theme.spacing(3), + borderRadius: theme.spacing(1, 1, 0, 0), + overflow: 'hidden', + }, + tabList: { + background: + theme.palette.mode === 'light' ? + 'linear-gradient(180deg, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 100%), linear-gradient(90deg, rgba(98, 152, 234, 0.2) 1.03%, rgba(98, 152, 234, 0.2) 1.04%, rgba(98, 126, 234, 0.2) 100%)' + : 'linear-gradient(180deg, rgba(255, 255, 255, 0.1) 0%, rgba(255, 255, 255, 0.06) 100%)', + padding: theme.spacing('14px', 2, 0), + }, + tab: { + fontSize: 16, + fontWeight: 700, + }, + panelContainer: { + padding: theme.spacing(2), + }, + exclaveActions: { + marginTop: 136, + }, +})) + +const tuples: TabPathTuple[] = [ + [StorageType.Local, DashboardRoutes.BackupLocal], + [ + StorageType.Cloud, + DashboardRoutes.BackupCloud, + DashboardRoutes.BackupCloudMaskNetwork, + DashboardRoutes.BackupCloudGoogleDrive, + ], +] + +export const Component = memo(function Backup() { + const { classes } = useStyles() + + const [tab, handleTabChange] = usePathTab(tuples) + + const portalContainerRef = useRef(null) + + return ( + + + Back Up Your Data Your Way + + + + Choose from multiple backup options, now including encrypted storage via your authorized Google + Drive for added security and flexibility. + + + +
+ + + Locale Backup} + value={StorageType.Local} + /> + Cloud Backup} + value={StorageType.Cloud} + /> + + +
+
+ +
+
+ +
+ ) +}) diff --git a/packages/mask/dashboard/pages/SetupPersona/CloudBackup/index.tsx b/packages/mask/dashboard/pages/SetupPersona/CloudBackup/index.tsx deleted file mode 100644 index 751af6f19074..000000000000 --- a/packages/mask/dashboard/pages/SetupPersona/CloudBackup/index.tsx +++ /dev/null @@ -1,180 +0,0 @@ -import { memo, useMemo } from 'react' -import { useAsyncFn } from 'react-use' -import { useNavigate } from 'react-router-dom' -import urlcat from 'urlcat' -import { Typography, Box, Tab } from '@mui/material' -import { MaskTabList, makeStyles } from '@masknet/theme' -import { UserContext } from '../../../../shared-ui/index.js' -import { TabContext, TabPanel } from '@mui/lab' -import { EmailForm } from './EmailForm.js' -import { CloudBackupFormContext, type CloudBackupFormInputs } from '../../../contexts/CloudBackupFormContext.js' -import { SetupFrameController } from '../../../components/SetupFrame/index.js' -import { PrimaryButton } from '../../../components/PrimaryButton/index.js' -import { fetchDownloadLink } from '../../../utils/api.js' -import { BackupAccountType, DashboardRoutes } from '@masknet/shared-base' -import { PhoneForm } from './PhoneForm.js' -import { msg } from '@lingui/core/macro' -import { Trans } from '@lingui/react/macro' -import { useLingui } from '@lingui/react' - -const useStyles = makeStyles()((theme) => ({ - title: { - fontSize: 36, - lineHeight: 1.2, - fontWeight: 700, - }, - description: { - color: theme.palette.maskColor.second, - fontSize: 14, - marginTop: theme.spacing(1.5), - }, - tabContainer: { - border: `1px solid ${theme.palette.maskColor.line}`, - marginTop: theme.spacing(3), - borderRadius: theme.spacing(1, 1, 0, 0), - overflow: 'hidden', - marginBottom: 46, - }, - tabList: { - background: - theme.palette.mode === 'light' ? - 'linear-gradient(180deg, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 100%), linear-gradient(90deg, rgba(98, 152, 234, 0.2) 1.03%, rgba(98, 152, 234, 0.2) 1.04%, rgba(98, 126, 234, 0.2) 100%)' - : 'linear-gradient(180deg, rgba(255, 255, 255, 0.1) 0%, rgba(255, 255, 255, 0.06) 100%)', - padding: theme.spacing('14px', 2, 0), - }, - tab: { - fontSize: 16, - fontWeight: 700, - }, - panels: { - display: 'flex', - flexDirection: 'column', - alignItems: 'center', - padding: 0, - width: '100%', - }, - panelContainer: { - padding: theme.spacing(2), - }, -})) - -const CloudBackupInner = memo(function CloudBackupInner() { - const { _ } = useLingui() - const { classes } = useStyles() - const { user, updateUser } = UserContext.useContainer() - const navigate = useNavigate() - const tabPanelClasses = useMemo(() => ({ root: classes.panels }), [classes.panels]) - - const { currentTab, onChange, tabs, formState } = CloudBackupFormContext.useContainer() - - const [{ loading }, handleSubmit] = useAsyncFn( - async (data: CloudBackupFormInputs) => { - const response = await fetchDownloadLink({ - account: currentTab === tabs.email ? data.email : `+${data.countryCode} ${data.phone}`, - type: currentTab === tabs.email ? BackupAccountType.Email : BackupAccountType.Phone, - code: data.code, - }).catch((error) => { - if (error.status === 400) { - formState.setError('code', { - type: 'custom', - message: _(msg`The code is incorrect.`), - }) - } else if (error.status === 404) { - // No cloud backup file - navigate( - urlcat(DashboardRoutes.CloudBackupPreview, { - type: currentTab === tabs.email ? BackupAccountType.Email : BackupAccountType.Phone, - account: currentTab === tabs.email ? data.email : `+${data.countryCode} ${data.phone}`, - code: data.code, - }), - ) - } - }) - - if (!response) return - - updateUser({ - email: data.email || user.email, - phone: data.phone ? `${data.countryCode} ${data.phone}` : user.phone, - }) - navigate( - urlcat(DashboardRoutes.CloudBackupPreview, { - ...response, - type: currentTab === tabs.email ? BackupAccountType.Email : BackupAccountType.Phone, - account: currentTab === tabs.email ? data.email : `+${data.countryCode} ${data.phone}`, - code: data.code, - }), - ) - }, - [_, currentTab, tabs, formState, navigate, updateUser, user], - ) - - const description = useMemo(() => { - if (user.cloudBackupMethod === BackupAccountType.Email && user.email) - return ( - - You used {user.email} for the last cloud backup. - - ) - if (user.cloudBackupMethod === BackupAccountType.Phone && user.phone) - return ( - - You used {user.email} for the last cloud backup. - - ) - - return Please use your frequently used email or phone number for backup. - }, [user]) - return ( - <> - - - Login to Mask Cloud - - {description} - - -
- { - onChange(_, value) - formState.reset() - }} - aria-label="Cloud Backup Methods"> - E-mail} value={tabs.email} /> - Mobile} value={tabs.mobile} /> - -
-
- - - - - - -
-
-
-
- - - Continue - - - - ) -}) - -export const Component = memo(function CloudBackup() { - return ( - - - - ) -}) diff --git a/packages/mask/dashboard/pages/SetupPersona/Mnemonic/index.tsx b/packages/mask/dashboard/pages/SetupPersona/Mnemonic/index.tsx index 3bb9797e0bf9..612c6f6c5681 100644 --- a/packages/mask/dashboard/pages/SetupPersona/Mnemonic/index.tsx +++ b/packages/mask/dashboard/pages/SetupPersona/Mnemonic/index.tsx @@ -126,7 +126,7 @@ export const Component = memo(function SignUpMnemonic() { }, [words]) const handleRecovery = useCallback(() => { - navigate(DashboardRoutes.RecoveryPersona) + navigate(DashboardRoutes.Recovery) }, []) const { value } = useAsync(async () => { diff --git a/packages/mask/dashboard/pages/SetupPersona/Onboarding/index.tsx b/packages/mask/dashboard/pages/SetupPersona/Onboarding/index.tsx index 7d6b73fc1608..16a0e9b7c581 100644 --- a/packages/mask/dashboard/pages/SetupPersona/Onboarding/index.tsx +++ b/packages/mask/dashboard/pages/SetupPersona/Onboarding/index.tsx @@ -115,24 +115,21 @@ export const Component = memo(function Onboarding() { }) }, [retry]) - const sentence: Array = useMemo(() => { + const sentence: Array = useMemo(() => { const count = params.get('count') return [ - [t`Creating your `, t`identity`], - [t`Generating your `, t`accounts`], - [t`Encrypting your `, t`data`], - [t`Your Persona is on `, t`ready 🚀`], + t`Creating your **identity**`, + t`Generating your **accounts**`, + t`Encrypting your **data**`, + t`Your Persona is on **ready 🚀**`, count && !isZero(count) ? - [ - t`You have recovered `, - plural(count, { - one: '# Wallet 🚀', - other: '# Wallets 🚀', - }), - ] + plural(count, { + one: 'You have recovered **# Wallet 🚀**', + other: 'You have recovered **# Wallets 🚀**', + }) : undefined, ] - }, []) + }, [t, count]) return ( <> @@ -158,7 +155,15 @@ export const Component = memo(function Onboarding() {
- + { + showSnackbar(Creation Completed, { + variant: 'success', + message: t`Your Persona has been successfully created.`, + }) + }} + /> { + const sentence: string[] = useMemo(() => { return [ - [ - t`We are pleased to inform you that the update for X (formerly named Twitter) website has been completed. You can now continue to enjoy all the features of Mask Network as usual. Thank you for your continuous support!`, - ], + t`We are pleased to inform you that the update for X (formerly named Twitter) website has been completed. You can now continue to enjoy all the features of Mask Network as usual. Thank you for your continuous support!`, ] - }, []) + }, [t]) return ( <> diff --git a/packages/mask/dashboard/components/Restore/RestoreFromCloud/ConfirmBackupInfo.tsx b/packages/mask/dashboard/pages/SetupPersona/Recovery/Cloud/ConfirmBackupInfo.tsx similarity index 80% rename from packages/mask/dashboard/components/Restore/RestoreFromCloud/ConfirmBackupInfo.tsx rename to packages/mask/dashboard/pages/SetupPersona/Recovery/Cloud/ConfirmBackupInfo.tsx index 650e2e333e39..0b33b5eed5aa 100644 --- a/packages/mask/dashboard/components/Restore/RestoreFromCloud/ConfirmBackupInfo.tsx +++ b/packages/mask/dashboard/pages/SetupPersona/Recovery/Cloud/ConfirmBackupInfo.tsx @@ -1,17 +1,17 @@ +import Services from '#services' +import { Trans, useLingui } from '@lingui/react/macro' import { decryptBackup } from '@masknet/backup-format' import { decode, encode } from '@msgpack/msgpack' import { Box } from '@mui/material' -import { memo, useCallback, useLayoutEffect, useState, type ReactNode } from 'react' -import Services from '#services' -import { usePersonaRecovery } from '../../../contexts/index.js' -import { fetchBackupValue } from '../../../utils/api.js' -import PasswordField from '../../PasswordField/index.js' -import { PrimaryButton } from '../../PrimaryButton/index.js' -import { AccountStatusBar } from '../AccountStatusBar.js' -import { BackupInfoCard } from '../BackupInfoCard.js' +import { memo, useCallback, useState, type ReactNode } from 'react' +import { OutletPortal } from '../../../../components/OutletPortal.js' +import PasswordField from '../../../../components/PasswordField/index.js' +import { PrimaryButton } from '../../../../components/PrimaryButton/index.js' +import { AccountStatusBar } from '../../../../components/Restore/AccountStatusBar.js' +import { BackupInfoCard } from '../../../../components/Restore/BackupInfoCard.js' +import { fetchBackupValue } from '../../../../utils/api.js' import { RestoreContext } from './RestoreProvider.js' import { RestoreStep } from './restoreReducer.js' -import { Trans, useLingui } from '@lingui/react/macro' export const ConfirmBackupInfo = memo(function ConfirmBackupInfo() { const { t } = useLingui() @@ -56,15 +56,6 @@ export const ConfirmBackupInfo = memo(function ConfirmBackupInfo() { dispatch({ type: 'TO_INPUT' }) }, []) - const { fillSubmitOutlet } = usePersonaRecovery() - useLayoutEffect(() => { - return fillSubmitOutlet( - - Restore - , - ) - }, [handleNext, loading]) - if (!backupFileInfo) return null return ( @@ -89,6 +80,11 @@ export const ConfirmBackupInfo = memo(function ConfirmBackupInfo() { helperText={errorMessage} />
+ + + Restore + + ) }) diff --git a/packages/mask/dashboard/components/Restore/RestoreFromCloud/EmailField.tsx b/packages/mask/dashboard/pages/SetupPersona/Recovery/Cloud/EmailField.tsx similarity index 66% rename from packages/mask/dashboard/components/Restore/RestoreFromCloud/EmailField.tsx rename to packages/mask/dashboard/pages/SetupPersona/Recovery/Cloud/EmailField.tsx index 72f909e79360..17b7071fa769 100644 --- a/packages/mask/dashboard/components/Restore/RestoreFromCloud/EmailField.tsx +++ b/packages/mask/dashboard/pages/SetupPersona/Recovery/Cloud/EmailField.tsx @@ -1,16 +1,16 @@ +import { Trans, useLingui } from '@lingui/react/macro' +import { BackupAccountType } from '@masknet/shared-base' import { SendingCodeField, useCustomSnackbar } from '@masknet/theme' import { Box, TextField } from '@mui/material' -import { memo, useCallback, useLayoutEffect, useState, type ReactNode } from 'react' +import { memo, useCallback, useState, type ReactNode } from 'react' import { useAsyncFn } from 'react-use' -import { usePersonaRecovery } from '../../../contexts/RecoveryContext.js' -import { sendCode, type RestoreQueryError } from '../../../utils/api.js' -import { emailRegexp } from '../../../utils/regexp.js' -import { BackupAccountType } from '@masknet/shared-base' -import { Locale, Scenario } from '../../../utils/type.js' -import { PrimaryButton } from '../../PrimaryButton/index.js' -import { useLanguage } from '../../../../shared-ui/index.js' +import { useLanguage } from '../../../../../shared-ui/index.js' +import { OutletPortal } from '../../../../components/OutletPortal.js' +import { PrimaryButton } from '../../../../components/PrimaryButton/index.js' +import { sendCode, type RestoreQueryError } from '../../../../utils/api.js' +import { emailRegexp } from '../../../../utils/regexp.js' +import { Locale, Scenario } from '../../../../utils/type.js' import { RestoreContext } from './RestoreProvider.js' -import { Trans, useLingui } from '@lingui/react/macro' export const EmailField = memo(function EmailField() { const { t } = useLingui() @@ -47,35 +47,8 @@ export const EmailField = memo(function EmailField() { setInvalidEmail(!isValid) } - const { fillSubmitOutlet } = usePersonaRecovery() const emailNotReady = !account || invalidEmail const disabled = emailNotReady || code.length !== 6 - useLayoutEffect(() => { - return fillSubmitOutlet( - { - dispatch({ type: 'SET_LOADING', loading: true }) - try { - const backupFileInfo = await downloadBackupInfo(BackupAccountType.Email, account, code) - dispatch({ type: 'SET_BACKUP_INFO', info: backupFileInfo }) - dispatch({ type: 'NEXT_STEP' }) - } catch (err) { - const message = (err as RestoreQueryError).message - if (['code not found', 'code mismatch'].includes(message)) - setCodeError(Invalid verification code.) - else setError(message) - } finally { - dispatch({ type: 'SET_LOADING', loading: false }) - } - }} - loading={loading} - disabled={disabled}> - Continue - , - ) - }, [account, code, loading, disabled]) const hasError = sendCodeError?.message.includes('SendTemplatedEmail') || invalidEmail || !!error const errorMessage = @@ -121,6 +94,31 @@ export const EmailField = memo(function EmailField() { }} /> + + { + dispatch({ type: 'SET_LOADING', loading: true }) + try { + const backupFileInfo = await downloadBackupInfo(BackupAccountType.Email, account, code) + dispatch({ type: 'SET_BACKUP_INFO', info: backupFileInfo }) + dispatch({ type: 'NEXT_STEP' }) + } catch (err) { + const message = (err as RestoreQueryError).message + if (['code not found', 'code mismatch'].includes(message)) + setCodeError(Invalid verification code.) + else setError(message) + } finally { + dispatch({ type: 'SET_LOADING', loading: false }) + } + }} + loading={loading} + disabled={disabled}> + Continue + + ) }) diff --git a/packages/mask/dashboard/pages/SetupPersona/Recovery/Cloud/GoogleDrive.tsx b/packages/mask/dashboard/pages/SetupPersona/Recovery/Cloud/GoogleDrive.tsx new file mode 100644 index 000000000000..bbe895fd8b21 --- /dev/null +++ b/packages/mask/dashboard/pages/SetupPersona/Recovery/Cloud/GoogleDrive.tsx @@ -0,0 +1,187 @@ +import { Trans } from '@lingui/react/macro' +import { Icons } from '@masknet/icons' +import { DashboardRoutes, EMPTY_LIST } from '@masknet/shared-base' +import { ActionButton, makeStyles } from '@masknet/theme' +import { GoogleDriveClient, type DriveFile } from '@masknet/web3-providers' +import { Box, Typography } from '@mui/material' +import { memo, useMemo, useState } from 'react' +import { useNavigate } from 'react-router-dom' +import { useAsyncFn } from 'react-use' +import urlcat from 'urlcat' +import { UserContext } from '../../../../../shared-ui/index.js' +import { GoogleDriveFileTable } from '../../../../components/GoogleDriveFileTable.js' +import { GoogleDriveLogin } from '../../../../components/GoogleDriveLogin.js' +import { OutletPortal } from '../../../../components/OutletPortal.js' +import { PrimaryButton } from '../../../../components/PrimaryButton/index.js' +import { useGoogleDriveFiles } from '../../../../hooks/useGoogleDriveFiles.js' +import { RestoreBackupModal } from '../../../../modals/modals.js' +import { + clearGoogleDriveAccessToken, + downloadBackup, + getGoogleDriveAccessToken, + progressDownload, +} from '../../../../utils/api.js' + +const useStyles = makeStyles()((theme) => ({ + container: { + display: 'flex', + flexDirection: 'column', + gap: theme.spacing(1.5), + }, + header: { + display: 'flex', + justifyContent: 'space-between', + alignItems: 'center', + }, + user: { + display: 'flex', + flexDirection: 'column', + gap: theme.spacing(1), + }, + providerName: { + fontWeight: 400, + fontSize: 14, + lineHeight: '18px', + height: 18, + color: theme.palette.maskColor.second, + }, + userAccount: { + fontWeight: 700, + fontSize: 14, + lineHeight: '18px', + height: 18, + color: theme.palette.maskColor.main, + }, + folder: { + fontSize: 14, + fontWeight: 700, + lineHeight: '18px', + }, + tableContainer: { + height: 340, + marginTop: theme.spacing(2), + }, +})) + +export const Component = memo(function GoogleDriveRecovery() { + const { classes } = useStyles() + const navigate = useNavigate() + const { user, updateUser } = UserContext.useContainer() + const googleDriveClient = useMemo( + () => new GoogleDriveClient(getGoogleDriveAccessToken, clearGoogleDriveAccessToken), + [], + ) + const { data: files = EMPTY_LIST, isLoading } = useGoogleDriveFiles(googleDriveClient) + const [{ loading: logoutLoading }, logout] = useAsyncFn(async () => { + await googleDriveClient.logout() + updateUser({ + googleAccount: '', + googleToken: '', + }) + }, [googleDriveClient]) + + const [selectedFile, setSelectedFile] = useState(null) + + if (!user.googleAccount) { + return + } + + const downloadAndMerge = async (file: DriveFile) => { + await RestoreBackupModal.openAndWaitForClose({ + decryptWithAccount: false, + strategy: 'merge', + download: () => { + return progressDownload(() => googleDriveClient.requestFile(file.id), file.size ? +file.size : 0) + }, + fileName: file.name, + account: user.googleAccount!, + size: file.size || '0', + uploadedAt: new Date(file.modifiedTime).getTime(), + }) + } + return ( + + + + + Google Drive + + {user.googleAccount} + + + Logout + + + + MaskBackup file + { + const blob = await googleDriveClient.downloadFile(file.id) + const url = URL.createObjectURL(blob) + downloadBackup(url, file.name) + URL.revokeObjectURL(url) + }} + /> + + + } + size="large" + color="primary" + disabled={!selectedFile} + onClick={async () => { + if (!user.googleAccount || !selectedFile?.id) return + const result = await RestoreBackupModal.openAndWaitForClose({ + decryptWithAccount: false, + download: () => { + return progressDownload( + () => googleDriveClient.requestFile(selectedFile.id), + selectedFile.size ? +selectedFile.size : 0, + ) + }, + fileName: selectedFile.name, + account: user.googleAccount, + size: selectedFile.size || '0', + uploadedAt: new Date(selectedFile.modifiedTime).getTime(), + restoreSuccessMessage: ( + + You have successfully restored the backup from Google Drive to your browser. + + ), + restoreErrorMessage: ( + + Failed to restore the backup from Google Drive to your browser. Please try again. + + ), + }) + setSelectedFile(null) + if (result) { + navigate( + urlcat(DashboardRoutes.SignUpPersonaOnboarding, { + count: result.countOfWallets, + }), + { + replace: true, + }, + ) + } + }}> + Recover + + + + ) +}) diff --git a/packages/mask/dashboard/components/Restore/RestoreFromCloud/InputForm.tsx b/packages/mask/dashboard/pages/SetupPersona/Recovery/Cloud/InputForm.tsx similarity index 100% rename from packages/mask/dashboard/components/Restore/RestoreFromCloud/InputForm.tsx rename to packages/mask/dashboard/pages/SetupPersona/Recovery/Cloud/InputForm.tsx index 460f94435a3e..1ed8c88549f4 100644 --- a/packages/mask/dashboard/components/Restore/RestoreFromCloud/InputForm.tsx +++ b/packages/mask/dashboard/pages/SetupPersona/Recovery/Cloud/InputForm.tsx @@ -3,9 +3,9 @@ import { makeStyles } from '@masknet/theme' import { Box, FormControlLabel, Radio, RadioGroup, type BoxProps } from '@mui/material' import { memo, useState } from 'react' import { BackupAccountType } from '@masknet/shared-base' -import { RestoreContext } from './RestoreProvider.js' import { EmailField } from './EmailField.js' import { PhoneField } from './PhoneField.js' +import { RestoreContext } from './RestoreProvider.js' import { RestoreStep } from './restoreReducer.js' const useStyles = makeStyles()((theme) => ({ diff --git a/packages/mask/dashboard/components/Restore/RestoreFromCloud/index.tsx b/packages/mask/dashboard/pages/SetupPersona/Recovery/Cloud/MaskNetwork.tsx similarity index 63% rename from packages/mask/dashboard/components/Restore/RestoreFromCloud/index.tsx rename to packages/mask/dashboard/pages/SetupPersona/Recovery/Cloud/MaskNetwork.tsx index 66ac26731eb9..df3f45ea53bc 100644 --- a/packages/mask/dashboard/components/Restore/RestoreFromCloud/index.tsx +++ b/packages/mask/dashboard/pages/SetupPersona/Recovery/Cloud/MaskNetwork.tsx @@ -1,45 +1,24 @@ -import urlcat from 'urlcat' -import { memo, useCallback, useLayoutEffect, useState } from 'react' -import { useNavigate } from 'react-router-dom' -import { Box } from '@mui/material' -import { DashboardRoutes, BackupAccountType } from '@masknet/shared-base' -import { useCustomSnackbar } from '@masknet/theme' import Services from '#services' +import { BackupAccountType, DashboardRoutes } from '@masknet/shared-base' +import { useCustomSnackbar } from '@masknet/theme' +import { Box } from '@mui/material' +import { memo, useCallback, useState } from 'react' +import { useNavigate } from 'react-router-dom' +import urlcat from 'urlcat' -import { ConfirmSynchronizePasswordDialog } from '../ConfirmSynchronizePasswordDialog.js' -import { usePersonaRecovery } from '../../../contexts/index.js' -import { PrimaryButton } from '../../PrimaryButton/index.js' +import { Trans } from '@lingui/react/macro' +import { Alert, PersonaContext } from '@masknet/shared' +import { UserContext } from '../../../../../shared-ui/index.js' +import { BackupPreview } from '../../../../components/BackupPreview/index.js' +import { OutletPortal } from '../../../../components/OutletPortal.js' +import { PrimaryButton } from '../../../../components/PrimaryButton/index.js' +import { ConfirmSynchronizePasswordDialog } from '../../../../components/Restore/ConfirmSynchronizePasswordDialog.js' +import { ConfirmBackupInfo } from './ConfirmBackupInfo.js' +import { InputForm } from './InputForm.js' import { RestoreContext } from './RestoreProvider.js' import { RestoreStep } from './restoreReducer.js' -import { InputForm } from './InputForm.js' -import { ConfirmBackupInfo } from './ConfirmBackupInfo.js' -import { UserContext } from '../../../../shared-ui/index.js' -import { BackupPreview } from '../../BackupPreview/index.js' -import { PersonaContext } from '@masknet/shared' -import { Trans } from '@lingui/react/macro' - -interface RestoreProps { - onRestore: () => Promise -} - -const Restore = memo(function Restore({ onRestore }: RestoreProps) { - const { fillSubmitOutlet } = usePersonaRecovery() - const { state } = RestoreContext.useContainer() - - useLayoutEffect(() => { - return fillSubmitOutlet( - - Restore - , - ) - }, [onRestore, state.loading]) - if (!state.backupSummary) return null - - return -}) - -const RestoreFromCloudInner = memo(function RestoreFromCloudInner() { +const MaskNetworkInner = memo(function MaskNetworkInner() { const navigate = useNavigate() const { showSnackbar } = useCustomSnackbar() const { user, updateUser } = UserContext.useContainer() @@ -96,13 +75,25 @@ const RestoreFromCloudInner = memo(function RestoreFromCloudInner() { onCloseSynchronizePassword() }, [account, password, updateUser]) + const showButton = ![RestoreStep.InputEmail, RestoreStep.InputPhone, RestoreStep.Decrypt].includes(state.step) + const [showAlert, setShowAlert] = useState(true) return ( {[RestoreStep.InputEmail, RestoreStep.InputPhone].includes(state.step) ? - + <> + + setShowAlert(false)}> + + The Mask Network Cloud Backup feature will be deactivated on April 30, 2025. Please use + alternative cloud backup services or local backup solutions. + + + : state.step === RestoreStep.Decrypt ? - : } + : state.backupSummary ? + + : null} {openSynchronizePasswordDialog ? : null} + {showButton ? + + + Restore + + + : null} ) }) -export const RestoreFromCloud = memo(function RestoreFromCloud() { +export const Component = memo(function RestoreFromCloud() { return ( - + ) }) diff --git a/packages/mask/dashboard/components/Restore/RestoreFromCloud/PhoneField.tsx b/packages/mask/dashboard/pages/SetupPersona/Recovery/Cloud/PhoneField.tsx similarity index 68% rename from packages/mask/dashboard/components/Restore/RestoreFromCloud/PhoneField.tsx rename to packages/mask/dashboard/pages/SetupPersona/Recovery/Cloud/PhoneField.tsx index 789c0330aca9..5f8d2568e696 100644 --- a/packages/mask/dashboard/components/Restore/RestoreFromCloud/PhoneField.tsx +++ b/packages/mask/dashboard/pages/SetupPersona/Recovery/Cloud/PhoneField.tsx @@ -1,19 +1,19 @@ +import { Trans, useLingui } from '@lingui/react/macro' +import { PhoneNumberField } from '@masknet/shared' +import { BackupAccountType } from '@masknet/shared-base' import { SendingCodeField, useCustomSnackbar } from '@masknet/theme' import { Box } from '@mui/material' import guessCallingCode from 'guess-calling-code' import { pick } from 'lodash-es' -import { memo, useCallback, useEffect, useLayoutEffect, useMemo, useState, type ReactNode } from 'react' +import { memo, useCallback, useEffect, useMemo, useState, type ReactNode } from 'react' import { useAsyncFn } from 'react-use' -import { usePersonaRecovery } from '../../../contexts/index.js' -import { useLanguage } from '../../../../shared-ui/index.js' -import { sendCode, type RestoreQueryError } from '../../../utils/api.js' -import { phoneRegexp } from '../../../utils/regexp.js' -import { BackupAccountType } from '@masknet/shared-base' -import { Locale, Scenario } from '../../../utils/type.js' -import { PrimaryButton } from '../../PrimaryButton/index.js' +import { useLanguage } from '../../../../../shared-ui/index.js' +import { OutletPortal } from '../../../../components/OutletPortal.js' +import { PrimaryButton } from '../../../../components/PrimaryButton/index.js' +import { sendCode, type RestoreQueryError } from '../../../../utils/api.js' +import { phoneRegexp } from '../../../../utils/regexp.js' +import { Locale, Scenario } from '../../../../utils/type.js' import { RestoreContext } from './RestoreProvider.js' -import { PhoneNumberField } from '@masknet/shared' -import { Trans, useLingui } from '@lingui/react/macro' export const PhoneField = memo(function PhoneField() { const { t } = useLingui() @@ -60,35 +60,8 @@ export const PhoneField = memo(function PhoneField() { }) }, [account, language]) - const { fillSubmitOutlet } = usePersonaRecovery() const phoneNotReady = !account || invalidPhone || !phoneRegexp.test(account) const disabled = phoneNotReady || code.length !== 6 || !!error || loading - useLayoutEffect(() => { - return fillSubmitOutlet( - { - dispatch({ type: 'SET_LOADING', loading: true }) - try { - const backupInfo = await downloadBackupInfo(BackupAccountType.Phone, account, code) - dispatch({ type: 'SET_BACKUP_INFO', info: backupInfo }) - dispatch({ type: 'NEXT_STEP' }) - } catch (err) { - const message = (err as RestoreQueryError).message - if (['code not found', 'code mismatch'].includes(message)) - setCodeError(Invalid verification code.) - else setError(message) - } finally { - dispatch({ type: 'SET_LOADING', loading: false }) - } - }} - loading={loading} - disabled={disabled}> - Continue - , - ) - }, [account, code, disabled, loading]) return ( <> @@ -121,6 +94,31 @@ export const PhoneField = memo(function PhoneField() { }} /> + + { + dispatch({ type: 'SET_LOADING', loading: true }) + try { + const backupInfo = await downloadBackupInfo(BackupAccountType.Phone, account, code) + dispatch({ type: 'SET_BACKUP_INFO', info: backupInfo }) + dispatch({ type: 'NEXT_STEP' }) + } catch (err) { + const message = (err as RestoreQueryError).message + if (['code not found', 'code mismatch'].includes(message)) + setCodeError(Invalid verification code.) + else setError(message) + } finally { + dispatch({ type: 'SET_LOADING', loading: false }) + } + }} + loading={loading} + disabled={disabled}> + Continue + + ) }) diff --git a/packages/mask/dashboard/components/Restore/RestoreFromCloud/RestoreProvider.tsx b/packages/mask/dashboard/pages/SetupPersona/Recovery/Cloud/RestoreProvider.tsx similarity index 91% rename from packages/mask/dashboard/components/Restore/RestoreFromCloud/RestoreProvider.tsx rename to packages/mask/dashboard/pages/SetupPersona/Recovery/Cloud/RestoreProvider.tsx index 29696cb8da40..9567cc994721 100644 --- a/packages/mask/dashboard/components/Restore/RestoreFromCloud/RestoreProvider.tsx +++ b/packages/mask/dashboard/pages/SetupPersona/Recovery/Cloud/RestoreProvider.tsx @@ -1,8 +1,8 @@ import { useCallback, useReducer } from 'react' import { createContainer } from '@masknet/shared-base-ui' -import { fetchDownloadLink } from '../../../utils/api.js' import type { BackupAccountType } from '@masknet/shared-base' import { initialState, restoreReducer } from './restoreReducer.js' +import { fetchDownloadLink } from '../../../../utils/api.js' function useRestoreState() { const [state, dispatch] = useReducer(restoreReducer, initialState) diff --git a/packages/mask/dashboard/pages/SetupPersona/Recovery/Cloud/index.tsx b/packages/mask/dashboard/pages/SetupPersona/Recovery/Cloud/index.tsx new file mode 100644 index 000000000000..14fb77646064 --- /dev/null +++ b/packages/mask/dashboard/pages/SetupPersona/Recovery/Cloud/index.tsx @@ -0,0 +1,79 @@ +import { Trans } from '@lingui/react/macro' +import { Icons } from '@masknet/icons' +import { DashboardRoutes } from '@masknet/shared-base' +import { makeStyles } from '@masknet/theme' +import { Box, Typography } from '@mui/material' +import { memo } from 'react' +import { Outlet, useMatch, useNavigate, useOutletContext } from 'react-router-dom' +import type { PortalContainerProps } from '../../../../components/OutletPortal.js' + +const useStyles = makeStyles()((theme, _, refs) => ({ + container: { + display: 'flex', + flexDirection: 'column', + gap: theme.spacing(2), + }, + providers: { + display: 'flex', + gap: theme.spacing(1.5), + }, + providerName: { + fontWeight: 700, + fontSize: 14, + lineHeight: '18px', + height: 18, + color: theme.palette.maskColor.main, + }, + activeButton: { + backgroundColor: theme.palette.maskColor.input, + }, + toggleButton: { + backgroundColor: theme.palette.maskColor.bottom, + cursor: 'pointer', + boxSizing: 'border-box', + borderRadius: 18, + height: 34, + gap: theme.spacing(1), + border: `1px solid ${theme.palette.maskColor.line}`, + display: 'inline-flex', + padding: theme.spacing(1, 1.5), + [`&.${refs.activeButton}`]: { + backgroundColor: theme.palette.maskColor.input, + }, + }, +})) + +export const Component = memo(function CloudBackup() { + const outletContext = useOutletContext() + const { classes, cx } = useStyles() + + const navigate = useNavigate() + const match = useMatch(DashboardRoutes.RecoveryCloudGoogleDrive) // MaskBook is index + const isGoogleDrive = !!match + + return ( + + + + + + + + ) +}) diff --git a/packages/mask/dashboard/components/Restore/RestoreFromCloud/restoreReducer.ts b/packages/mask/dashboard/pages/SetupPersona/Recovery/Cloud/restoreReducer.ts similarity index 98% rename from packages/mask/dashboard/components/Restore/RestoreFromCloud/restoreReducer.ts rename to packages/mask/dashboard/pages/SetupPersona/Recovery/Cloud/restoreReducer.ts index dc09023815c6..edb290be9b5e 100644 --- a/packages/mask/dashboard/components/Restore/RestoreFromCloud/restoreReducer.ts +++ b/packages/mask/dashboard/pages/SetupPersona/Recovery/Cloud/restoreReducer.ts @@ -1,7 +1,7 @@ import type { BackupSummary } from '@masknet/backup-format' import { produce } from 'immer' -import { type BackupFileInfo } from '../../../utils/type.js' import { BackupAccountType } from '@masknet/shared-base' +import type { BackupFileInfo } from '../../../../utils/type.js' export enum RestoreStep { InputEmail = 'InputEmail', diff --git a/packages/mask/dashboard/components/Restore/RestorePersonaFromLocal.tsx b/packages/mask/dashboard/pages/SetupPersona/Recovery/Local.tsx similarity index 75% rename from packages/mask/dashboard/components/Restore/RestorePersonaFromLocal.tsx rename to packages/mask/dashboard/pages/SetupPersona/Recovery/Local.tsx index 76c504d1042d..02fbe430fe9a 100644 --- a/packages/mask/dashboard/components/Restore/RestorePersonaFromLocal.tsx +++ b/packages/mask/dashboard/pages/SetupPersona/Recovery/Local.tsx @@ -1,19 +1,22 @@ -import { memo, useCallback, useLayoutEffect, useMemo, useState, type ReactNode } from 'react' -import { useAsync } from 'react-use' -import { Box, Button, Typography } from '@mui/material' -import { type BackupSummary, decryptBackup } from '@masknet/backup-format' +import Services from '#services' +import { Trans, useLingui } from '@lingui/react/macro' +import { decryptBackup, type BackupSummary } from '@masknet/backup-format' import { Icons } from '@masknet/icons' import { delay } from '@masknet/kit' -import { FileFrame, UploadDropArea } from '@masknet/shared' +import { FileFrame, PersonaContext, UploadDropArea } from '@masknet/shared' +import { DashboardRoutes } from '@masknet/shared-base' import { makeStyles, useCustomSnackbar } from '@masknet/theme' import { decode, encode } from '@msgpack/msgpack' -import Services from '#services' -import { usePersonaRecovery } from '../../contexts/RecoveryContext.js' -import PasswordField from '../PasswordField/index.js' -import { PrimaryButton } from '../PrimaryButton/index.js' -import { AccountStatusBar } from './AccountStatusBar.js' -import { BackupPreview } from '../BackupPreview/index.js' -import { Trans, useLingui } from '@lingui/react/macro' +import { Box, Button, Typography } from '@mui/material' +import { memo, useCallback, useMemo, useState, type ReactNode } from 'react' +import { useNavigate } from 'react-router-dom' +import { useAsync } from 'react-use' +import urlcat from 'urlcat' +import { BackupPreview } from '../../../components/BackupPreview/index.js' +import { OutletPortal } from '../../../components/OutletPortal.js' +import PasswordField from '../../../components/PasswordField/index.js' +import { PrimaryButton } from '../../../components/PrimaryButton/index.js' +import { AccountStatusBar } from '../../../components/Restore/AccountStatusBar.js' enum RestoreStatus { WaitingInput = 0, @@ -39,15 +42,12 @@ const useStyles = makeStyles()((theme) => ({ marginTop: 7, }, })) -interface RestoreFromLocalProps { - onRestore: (count?: number) => Promise -} -export const RestorePersonaFromLocal = memo(function RestorePersonaFromLocal({ onRestore }: RestoreFromLocalProps) { +export const Component = memo(function RecoveryLocalBackup() { const { t } = useLingui() const { classes, theme } = useStyles() const { showSnackbar } = useCustomSnackbar() - const { fillSubmitOutlet } = usePersonaRecovery() + const navigate = useNavigate() const [file, setFile] = useState(null) const [summary, setSummary] = useState(null) @@ -114,6 +114,22 @@ export const RestorePersonaFromLocal = memo(function RestorePersonaFromLocal({ o } }, [file, password]) + const { currentPersona } = PersonaContext.useContainer() + const hasNoPersona = !currentPersona + const onRestore = useCallback( + async (count?: number) => { + if (hasNoPersona) { + const lastedPersona = await Services.Identity.queryLastPersonaCreated() + if (lastedPersona) { + await Services.Settings.setCurrentPersonaIdentifier(lastedPersona) + await delay(1000) + } + } + navigate(urlcat(DashboardRoutes.SignUpPersonaOnboarding, { count }), { replace: true }) + }, + [hasNoPersona, Services.Settings.setCurrentPersonaIdentifier, navigate], + ) + const restoreDB = useCallback(async () => { try { setProcessing(true) @@ -140,21 +156,6 @@ export const RestorePersonaFromLocal = memo(function RestorePersonaFromLocal({ o return !file }, [loading, !file, restoreStatus, summary, !password]) - useLayoutEffect(() => { - return fillSubmitOutlet( - - {restoreStatus !== RestoreStatus.Verified ? - Continue - : Restore} - , - ) - }, [restoreStatus, decryptBackupFile, restoreDB, disabled, loading]) - return ( {restoreStatus !== RestoreStatus.Verified ? @@ -194,6 +195,19 @@ export const RestorePersonaFromLocal = memo(function RestorePersonaFromLocal({ o : null} + + + {restoreStatus !== RestoreStatus.Verified ? + Continue + : Restore} + + ) }) diff --git a/packages/mask/dashboard/pages/SetupPersona/Recovery/Phrase.tsx b/packages/mask/dashboard/pages/SetupPersona/Recovery/Phrase.tsx new file mode 100644 index 000000000000..f067fc8dbb53 --- /dev/null +++ b/packages/mask/dashboard/pages/SetupPersona/Recovery/Phrase.tsx @@ -0,0 +1,79 @@ +import Services from '#services' +import { Trans } from '@lingui/react/macro' +import { delay } from '@masknet/kit' +import { DashboardRoutes } from '@masknet/shared-base' +import { makeStyles } from '@masknet/theme' +import { Box, Typography } from '@mui/material' +import { some } from 'lodash-es' +import { memo, useCallback, useState, type ReactNode } from 'react' +import { useNavigate } from 'react-router-dom' +import { useList } from 'react-use' +import { DesktopMnemonicConfirm } from '../../../components/Mnemonic/index.js' +import { OutletPortal } from '../../../components/OutletPortal.js' +import { PrimaryButton } from '../../../components/PrimaryButton/index.js' +import { SignUpRoutePath } from '../../SignUp/routePath.js' + +const useStyles = makeStyles()((theme) => ({ + error: { + marginTop: theme.spacing(2), + color: theme.palette.maskColor.danger, + }, +})) + +export const Component = memo(function Phrase() { + const { classes } = useStyles() + const [error, setError] = useState() + + const [values, { updateAt, set: setMnemonic }] = useList(() => Array.from({ length: 12 }, () => '')) + const handleWordChange = useCallback((word: string, index: number) => { + updateAt(index, word) + setError?.(undefined) + }, []) + + const disabled = some(values, (value) => !value) + const navigate = useNavigate() + + const handleRestoreFromMnemonic = useCallback( + async (values: string[]) => { + try { + const persona = await Services.Identity.queryPersonaByMnemonic(values.join(' '), '') + if (persona) { + await Services.Settings.setCurrentPersonaIdentifier(persona) + // Waiting persona changed event notify + await delay(100) + navigate(DashboardRoutes.SignUpPersonaOnboarding, { replace: true }) + } else { + navigate(`${DashboardRoutes.SignUp}/${SignUpRoutePath.PersonaRecovery}`, { + replace: false, + state: { mnemonic: values }, + }) + } + } catch { + setError(Incorrect recovery phrase.) + } + }, + [navigate], + ) + const handleImport = useCallback(async () => handleRestoreFromMnemonic(values), [values, handleRestoreFromMnemonic]) + return ( + + + {error ? + + {error} + + : null} + + + + Continue + + + + ) +}) diff --git a/packages/mask/dashboard/pages/SetupPersona/Recovery/PrivateKey.tsx b/packages/mask/dashboard/pages/SetupPersona/Recovery/PrivateKey.tsx new file mode 100644 index 000000000000..38d86ce858d9 --- /dev/null +++ b/packages/mask/dashboard/pages/SetupPersona/Recovery/PrivateKey.tsx @@ -0,0 +1,111 @@ +import Services from '#services' +import { zodResolver } from '@hookform/resolvers/zod' +import { msg } from '@lingui/core/macro' +import { useLingui } from '@lingui/react' +import { Trans, useLingui as useLinguiMacro } from '@lingui/react/macro' +import { delay } from '@masknet/kit' +import { DashboardRoutes } from '@masknet/shared-base' +import { makeStyles } from '@masknet/theme' +import { Box } from '@mui/material' +import { memo, useCallback } from 'react' +import { Controller, useForm, type SubmitHandler, type UseFormSetError } from 'react-hook-form' +import { useNavigate } from 'react-router-dom' +import { z } from 'zod' +import { OutletPortal } from '../../../components/OutletPortal.js' +import PasswordField from '../../../components/PasswordField/index.js' +import { PrimaryButton } from '../../../components/PrimaryButton/index.js' +import { SignUpRoutePath } from '../../SignUp/routePath.js' + +const useStyles = makeStyles()((theme) => ({ + input: { + backgroundColor: theme.palette.maskColor.input, + color: theme.palette.maskColor.main, + }, +})) +const schema = z.object({ + privateKey: z.string(), +}) +export type FormInputs = z.infer +export const Component = memo(function RecoveryPrivateKey() { + const { classes } = useStyles() + const { t } = useLinguiMacro() + const { _ } = useLingui() + const navigate = useNavigate() + + const { + control, + handleSubmit, + setError, + formState: { errors, isSubmitting, isDirty }, + } = useForm({ + mode: 'onChange', + resolver: zodResolver(schema), + defaultValues: { + privateKey: '', + }, + }) + + const handleRestoreFromPrivateKey = useCallback( + async (data: FormInputs, onError: UseFormSetError) => { + try { + const persona = await Services.Identity.loginExistPersonaByPrivateKey(data.privateKey) + if (persona) { + await Services.Settings.setCurrentPersonaIdentifier(persona) + // Waiting persona changed event notify + await delay(100) + navigate(DashboardRoutes.SignUpPersonaOnboarding) + } else { + navigate(`${DashboardRoutes.SignUp}/${SignUpRoutePath.PersonaRecovery}`, { + replace: false, + state: { privateKey: data.privateKey }, + }) + } + } catch { + onError('privateKey', { type: 'value', message: _(msg`Incorrect Private Key`) }) + } + }, + [_, navigate], + ) + + const onSubmit: SubmitHandler = useCallback( + async (data) => { + await handleRestoreFromPrivateKey(data, setError) + }, + [navigate, setError, handleRestoreFromPrivateKey], + ) + + return ( + + ( + + )} + name="privateKey" + /> + + + Continue + + + + ) +}) diff --git a/packages/mask/dashboard/pages/SetupPersona/Recovery/index.tsx b/packages/mask/dashboard/pages/SetupPersona/Recovery/index.tsx index 99187d39ac49..7920bf6c5cd6 100644 --- a/packages/mask/dashboard/pages/SetupPersona/Recovery/index.tsx +++ b/packages/mask/dashboard/pages/SetupPersona/Recovery/index.tsx @@ -1,54 +1,50 @@ -import { DashboardRoutes } from '@masknet/shared-base' -import type { UseFormSetError } from 'react-hook-form' -import { MaskTabList, makeStyles, useTabs } from '@masknet/theme' -import { TabContext, TabPanel } from '@mui/lab' -import { Button, Tab, Typography } from '@mui/material' -import { Box } from '@mui/system' -import { memo, use, useCallback, useMemo, useState, type ReactNode } from 'react' -import { useNavigate } from 'react-router-dom' -import { SetupFrameController } from '../../../components/SetupFrame/index.js' -import { RestoreFromPrivateKey, type FormInputs } from '../../../components/Restore/RestoreFromPrivateKey.js' -import { RestorePersonaFromLocal } from '../../../components/Restore/RestorePersonaFromLocal.js' -import { RestoreFromCloud } from '../../../components/Restore/RestoreFromCloud/index.js' -import { RecoveryProvider, RecoveryContext } from '../../../contexts/index.js' -import { RestoreFromMnemonic } from '../../../components/Restore/RestoreFromMnemonic.js' -import Services from '#services' -import { delay } from '@masknet/kit' - -import urlcat from 'urlcat' -import { SignUpRoutePath } from '../../SignUp/routePath.js' -import { PersonaContext } from '@masknet/shared' -import { msg } from '@lingui/core/macro' import { Trans } from '@lingui/react/macro' -import { useLingui } from '@lingui/react' +import { usePathTab, type TabPathTuple } from '@masknet/shared' +import { DashboardRoutes } from '@masknet/shared-base' +import { MaskTabList, makeStyles } from '@masknet/theme' +import { TabContext } from '@mui/lab' +import { Box, Tab, Typography } from '@mui/material' +import { memo, useRef } from 'react' +import { Link, Outlet } from 'react-router-dom' +import { RecoveryMethod } from './types.js' const useStyles = makeStyles()((theme) => ({ + container: { + display: 'flex', + flexDirection: 'column', + height: '100%', + }, header: { display: 'flex', - justifyContent: 'space-between', + gap: theme.spacing(1.5), }, - second: { - fontSize: 14, - lineHeight: '18px', - color: theme.palette.maskColor.second, + texts: { + display: 'flex', + flexDirection: 'column', + gap: theme.spacing(1.5), + marginRight: 'auto', }, setup: { fontSize: 14, lineHeight: '18px', color: theme.palette.maskColor.main, fontWeight: 700, + textDecoration: 'none', }, title: { fontSize: 36, lineHeight: 1.2, fontWeight: 700, }, + description: { + color: theme.palette.maskColor.second, + fontSize: 14, + }, tabContainer: { border: `1px solid ${theme.palette.maskColor.line}`, marginTop: theme.spacing(3), borderRadius: theme.spacing(1, 1, 0, 0), overflow: 'hidden', - marginBottom: 46, }, tabList: { background: @@ -61,157 +57,75 @@ const useStyles = makeStyles()((theme) => ({ fontSize: 16, fontWeight: 700, }, - panels: { - display: 'flex', - flexDirection: 'column', - alignItems: 'center', - padding: 0, - width: '100%', - }, panelContainer: { padding: theme.spacing(2), }, - buttonGroup: { - display: 'flex', - columnGap: 12, + exclaveActions: { + marginTop: 'auto', }, })) +const tuples: TabPathTuple[] = [ + [RecoveryMethod.Phrase, DashboardRoutes.RecoveryPhrase], + [RecoveryMethod.PrivateKey, DashboardRoutes.RecoveryPrivateKey], + [RecoveryMethod.Local, DashboardRoutes.RecoveryLocal], + [RecoveryMethod.Cloud, DashboardRoutes.RecoveryCloudMaskNetwork, DashboardRoutes.RecoveryCloudGoogleDrive], +] + export const Component = memo(function Recovery() { - const { _ } = useLingui() const { classes } = useStyles() - const { currentPersona } = PersonaContext.useContainer() - const tabPanelClasses = useMemo(() => ({ root: classes.panels }), [classes.panels]) - const navigate = useNavigate() - const [error, setError] = useState() - - const [currentTab, onChange, tabs] = useTabs('mnemonic', 'privateKey', 'local', 'cloud') - - const handleRestoreFromMnemonic = useCallback( - async (values: string[]) => { - try { - const persona = await Services.Identity.queryPersonaByMnemonic(values.join(' '), '') - if (persona) { - await Services.Settings.setCurrentPersonaIdentifier(persona) - // Waiting persona changed event notify - await delay(100) - navigate(DashboardRoutes.SignUpPersonaOnboarding, { replace: true }) - } else { - navigate(`${DashboardRoutes.SignUp}/${SignUpRoutePath.PersonaRecovery}`, { - replace: false, - state: { mnemonic: values }, - }) - } - } catch { - setError(Incorrect recovery phrase.) - } - }, - [navigate], - ) - const handleRestoreFromPrivateKey = useCallback( - async (data: FormInputs, onError: UseFormSetError) => { - try { - const persona = await Services.Identity.loginExistPersonaByPrivateKey(data.privateKey) - if (persona) { - await Services.Settings.setCurrentPersonaIdentifier(persona) - // Waiting persona changed event notify - await delay(100) - navigate(DashboardRoutes.SignUpPersonaOnboarding) - } else { - navigate(`${DashboardRoutes.SignUp}/${SignUpRoutePath.PersonaRecovery}`, { - replace: false, - state: { privateKey: data.privateKey }, - }) - } - } catch { - onError('privateKey', { type: 'value', message: _(msg`Incorrect Private Key`) }) - } - }, - [_, navigate], - ) + const [tab, handleTabChange] = usePathTab(tuples) - const hasNoPersona = !currentPersona - const onRestore = useCallback( - async (count?: number) => { - if (hasNoPersona) { - const lastedPersona = await Services.Identity.queryLastPersonaCreated() - if (lastedPersona) { - await Services.Settings.setCurrentPersonaIdentifier(lastedPersona) - await delay(1000) - } - } - navigate(urlcat(DashboardRoutes.SignUpPersonaOnboarding, { count }), { replace: true }) - }, - [hasNoPersona, Services.Settings.setCurrentPersonaIdentifier, navigate], - ) + const portalContainerRef = useRef(null) return ( - <> + - - Recover your data +
+ + Recover your data + + + Please select the appropriate method to restore your personal data. + +
+ + Create Persona -
- - - Please select the appropriate method to restore your personal data. - - -
- -
- - Recovery Phrase} - value={tabs.mnemonic} - /> - Private Key} - value={tabs.privateKey} - /> - Local Backup} value={tabs.local} /> - Cloud Backup} value={tabs.cloud} /> - -
-
- - - - - - - - - - - - -
+ +
+ + + Recovery Phrase} + value={RecoveryMethod.Phrase} + /> + Private Key} + value={RecoveryMethod.PrivateKey} + /> + Local Backup} + value={RecoveryMethod.Local} + /> + Cloud Backup} + value={RecoveryMethod.Cloud} + /> +
- - - - - +
+ +
+
+ + ) }) -function Outlet() { - const { classes } = useStyles() - return
{use(RecoveryContext).SubmitOutlet}
-} diff --git a/packages/mask/dashboard/pages/SetupPersona/Recovery/types.ts b/packages/mask/dashboard/pages/SetupPersona/Recovery/types.ts new file mode 100644 index 000000000000..d6c1e8e51187 --- /dev/null +++ b/packages/mask/dashboard/pages/SetupPersona/Recovery/types.ts @@ -0,0 +1,6 @@ +export enum RecoveryMethod { + Phrase = 'phrase', + PrivateKey = 'private-key', + Local = 'local', + Cloud = 'cloud', +} diff --git a/packages/mask/dashboard/pages/SetupPersona/SignUp/index.tsx b/packages/mask/dashboard/pages/SetupPersona/SignUp/index.tsx index 98cf9dfe37c0..5ee8e1083915 100644 --- a/packages/mask/dashboard/pages/SetupPersona/SignUp/index.tsx +++ b/packages/mask/dashboard/pages/SetupPersona/SignUp/index.tsx @@ -1,17 +1,17 @@ -import { DashboardRoutes, EnhanceableSite, userGuideStatus } from '@masknet/shared-base' -import { useState, useCallback, memo, type ReactNode } from 'react' -import { useNavigate } from 'react-router-dom' import Services from '#services' +import { Trans, useLingui } from '@lingui/react/macro' import { delay } from '@masknet/kit' +import { DashboardRoutes, EnhanceableSite, userGuideStatus } from '@masknet/shared-base' import { makeStyles } from '@masknet/theme' -import { Typography, Button, TextField } from '@mui/material' +import { Button, TextField, Typography } from '@mui/material' import { Box } from '@mui/system' +import { memo, useCallback, useState, type ReactNode } from 'react' +import { useNavigate } from 'react-router-dom' +import { requestPermissionFromExtensionPage } from '../../../../shared-ui/index.js' +import { TwitterAdaptor } from '../../../../shared/site-adaptors/implementations/twitter.com.js' import { PrimaryButton } from '../../../components/PrimaryButton/index.js' import { SecondaryButton } from '../../../components/SecondaryButton/index.js' import { SetupFrameController } from '../../../components/SetupFrame/index.js' -import { TwitterAdaptor } from '../../../../shared/site-adaptors/implementations/twitter.com.js' -import { requestPermissionFromExtensionPage } from '../../../../shared-ui/index.js' -import { Trans, useLingui } from '@lingui/react/macro' const useStyles = makeStyles()((theme) => ({ header: { @@ -79,7 +79,7 @@ export const Component = memo(function SignUp() { }, []) const handleRecovery = useCallback(() => { - navigate(DashboardRoutes.RecoveryPersona) + navigate(DashboardRoutes.Recovery) }, []) return ( diff --git a/packages/mask/dashboard/pages/SetupPersona/index.tsx b/packages/mask/dashboard/pages/SetupPersona/index.tsx index 46a9612124ca..2c4bade8bcb8 100644 --- a/packages/mask/dashboard/pages/SetupPersona/index.tsx +++ b/packages/mask/dashboard/pages/SetupPersona/index.tsx @@ -1,19 +1,92 @@ import { useMatch, type RouteObject } from 'react-router-dom' -import { DashboardRoutes, relativeRouteOf } from '@masknet/shared-base' +import { DashboardRoutes, relativeRoute as rr, relativeRouteOf } from '@masknet/shared-base' import { SetupFrame } from '../../components/SetupFrame/index.js' const r = relativeRouteOf(DashboardRoutes.Setup) +const Routes = DashboardRoutes export const personaRoutes: RouteObject[] = [ - { path: r(DashboardRoutes.Welcome), lazy: () => import('./Welcome/index.js') }, - { path: r(DashboardRoutes.Permissions), lazy: () => import('./Permissions/index.js') }, - { path: r(DashboardRoutes.PermissionsOnboarding), lazy: () => import('./PermissionOnboarding/index.js') }, - { path: r(DashboardRoutes.SignUpPersona), lazy: () => import('./SignUp/index.js') }, - { path: r(DashboardRoutes.RecoveryPersona), lazy: () => import('./Recovery/index.js') }, - { path: r(DashboardRoutes.SignUpPersonaMnemonic), lazy: () => import('./Mnemonic/index.js') }, - { path: r(DashboardRoutes.SignUpPersonaOnboarding), lazy: () => import('./Onboarding/index.js') }, - { path: r(DashboardRoutes.LocalBackup), lazy: () => import('./LocalBackup/index.js') }, - { path: r(DashboardRoutes.CloudBackup), lazy: () => import('./CloudBackup/index.js') }, - { path: r(DashboardRoutes.CloudBackupPreview), lazy: () => import('./CloudBackupPreview/index.js') }, + { path: r(Routes.Welcome), lazy: () => import('./Welcome/index.js') }, + { path: r(Routes.Permissions), lazy: () => import('./Permissions/index.js') }, + { path: r(Routes.PermissionsOnboarding), lazy: () => import('./PermissionOnboarding/index.js') }, + { path: r(Routes.SignUpPersona), lazy: () => import('./SignUp/index.js') }, + { path: r(Routes.SignUpPersonaMnemonic), lazy: () => import('./Mnemonic/index.js') }, + { path: r(Routes.SignUpPersonaOnboarding), lazy: () => import('./Onboarding/index.js') }, + { + path: r(Routes.Backup), + lazy: () => import('./Backup/index.js'), + children: [ + { + index: true, + lazy: () => import('./Backup/Local.js'), + }, + { + path: rr(Routes.Backup, Routes.BackupLocal), + lazy: () => import('./Backup/Local.js'), + }, + { + path: rr(Routes.Backup, Routes.BackupCloud), + lazy: () => import('./Backup/Cloud/index.js'), + children: [ + { + index: true, + lazy: () => import('./Backup/Cloud/MaskNetwork.js'), + }, + { + path: rr(Routes.BackupCloud, Routes.BackupCloudMaskNetwork), + lazy: () => import('./Backup/Cloud/MaskNetwork.js'), + }, + { + path: rr(Routes.BackupCloud, Routes.BackupCloudGoogleDrive), + lazy: () => import('./Backup/Cloud/GoogleDrive.js'), + }, + { + path: rr(Routes.BackupCloud, Routes.BackupPreview), + lazy: () => import('./Backup/Cloud/Preview.js'), + }, + ], + }, + ], + }, + { + path: r(Routes.Recovery), + lazy: () => import('./Recovery/index.js'), + children: [ + { + index: true, + lazy: () => import('./Recovery/Phrase.js'), + }, + { + path: rr(Routes.Recovery, Routes.RecoveryPhrase), + lazy: () => import('./Recovery/Phrase.js'), + }, + { + path: rr(Routes.Recovery, Routes.RecoveryPrivateKey), + lazy: () => import('./Recovery/PrivateKey.js'), + }, + { + path: rr(Routes.Recovery, Routes.RecoveryLocal), + lazy: () => import('./Recovery/Local.js'), + }, + { + path: rr(Routes.Recovery, Routes.RecoveryCloud), + lazy: () => import('./Recovery/Cloud/index.js'), + children: [ + { + index: true, + lazy: () => import('./Recovery/Cloud/MaskNetwork.js'), + }, + { + path: rr(Routes.RecoveryCloud, Routes.RecoveryCloudMaskNetwork), + lazy: () => import('./Recovery/Cloud/MaskNetwork.js'), + }, + { + path: rr(Routes.RecoveryCloud, Routes.RecoveryCloudGoogleDrive), + lazy: () => import('./Recovery/Cloud/GoogleDrive.js'), + }, + ], + }, + ], + }, ] export function PersonaFrame() { const matchPersonaOnboarding = useMatch(DashboardRoutes.SignUpPersonaOnboarding) diff --git a/packages/mask/dashboard/pages/SetupPersona/types.ts b/packages/mask/dashboard/pages/SetupPersona/types.ts new file mode 100644 index 000000000000..7869ac6684e8 --- /dev/null +++ b/packages/mask/dashboard/pages/SetupPersona/types.ts @@ -0,0 +1,4 @@ +export enum StorageType { + Local = 'local', + Cloud = 'cloud', +} diff --git a/packages/mask/dashboard/utils/api.ts b/packages/mask/dashboard/utils/api.ts index 15a88614c043..8febf02eaae2 100644 --- a/packages/mask/dashboard/utils/api.ts +++ b/packages/mask/dashboard/utils/api.ts @@ -1,5 +1,8 @@ +import Services from '#services' +import { t } from '@lingui/core/macro' import type { BackupAccountType } from '@masknet/shared-base' -import type { BackupFileInfo, Scenario, Locale } from './type.js' +import { format as formatDateTime } from 'date-fns' +import type { BackupFileInfo, Locale, Scenario } from './type.js' const BASE_RUL = 'https://vaalh28dbi.execute-api.ap-east-1.amazonaws.com/api' @@ -106,3 +109,69 @@ export function uploadBackupValue(uploadLink: string, content: ArrayBuffer, sign body: content, }) } + +export function downloadBackup(url: string, name?: string) { + const a = document.createElement('a') + a.href = url + if (name) a.download = name + a.click() +} + +export function createBackupName() { + return `mask-network-keystore-backup-${formatDateTime(new Date(), 'yyyy-MM-dd')}.bin` +} + +export function getFileName(url: string) { + try { + const urlObj = new URL(url) + return urlObj.pathname.split('/').pop() + } catch { + return '' + } +} + +/** + * Download general backup file (no need to authenticate) + */ +export async function* progressDownload(request: string | null | (() => Promise), size?: number) { + if (!request) return + const response = + typeof request === 'function' ? + await request() + : await fetch(request, { + method: 'GET', + cache: 'no-store', + }) + + if (!response.ok || response.status !== 200) { + throw new Error(t`The download link is expired`) + } + if (!response.body) return + const reader = response.body.getReader() + const contentLength = response.headers.get('Content-Length') || size + + if (!contentLength || !reader) return + + let received = 0 + const chunks: number[] = [] + while (true) { + const { done, value } = await reader.read() + + if (done || !value) { + yield 100 + break + } + chunks.push(...value) + received += value.length + + yield (received / Number(contentLength)) * 100 + } + return Uint8Array.from(chunks).buffer +} + +export function getGoogleDriveAccessToken(interactive?: boolean) { + return Services.Backup.getAccessToken(interactive) +} +export function clearGoogleDriveAccessToken() { + return Services.Backup.clearAccessToken() +} diff --git a/packages/mask/dashboard/utils/regexp.ts b/packages/mask/dashboard/utils/regexp.ts index 6dc401584d23..e0dbc6c212a3 100644 --- a/packages/mask/dashboard/utils/regexp.ts +++ b/packages/mask/dashboard/utils/regexp.ts @@ -1,5 +1,8 @@ export const passwordRegexp = /^(?=.{8,20}$)(?=.*[A-Z])(?=.*[a-z])(?=.*\d)(?=.*[^\dA-Za-z]).*/ +/** + * @deprecated use z.string().email() instead + */ export const emailRegexp = /^([\w!#$%&*+./=?^`{|}~’-]{1,64}@([\dA-Za-z-]{1,255}.[\dA-Za-z-]{2,}))$/ export const phoneRegexp = /^(\+?([ .-])?\d{1,2}([ .-])?)?(\(?\d{3}\)?|\d{3})([ .-])?(\d{3}([ .-])?\d{4})/ diff --git a/packages/mask/popups/Popup.tsx b/packages/mask/popups/Popup.tsx index c0175a71ebf8..62c4f4fb95cb 100644 --- a/packages/mask/popups/Popup.tsx +++ b/packages/mask/popups/Popup.tsx @@ -50,7 +50,7 @@ const PopupShell = memo(function PopupShell() { const navigate = useNavigate() useEffect(() => { return MaskMessages.events.popupRouteUpdated.on((url) => navigate(url, { replace: true })) - }, []) + }, [navigate]) useEffect(() => { document.getElementById('app-spinner')?.remove() diff --git a/packages/mask/popups/components/ActionModal/ActionModalContext.tsx b/packages/mask/popups/components/ActionModal/ActionModalContext.tsx index 8b60f286b17d..d5859237c6a8 100644 --- a/packages/mask/popups/components/ActionModal/ActionModalContext.tsx +++ b/packages/mask/popups/components/ActionModal/ActionModalContext.tsx @@ -1,8 +1,8 @@ -import { useTheme } from '@mui/material' -import { useCallback, useRef, useState } from 'react' -import { useNavigate, useLocation, useSearchParams } from 'react-router-dom' import type { PopupModalRoutes } from '@masknet/shared-base' import { createContainer } from '@masknet/shared-base-ui' +import { useTheme } from '@mui/material' +import { useCallback, useRef, useState } from 'react' +import { useNavigate, useSearchParams } from 'react-router-dom' import urlcat from 'urlcat' function useModal() { @@ -42,16 +42,17 @@ export function useActionModal() { * Open a modal */ export function useModalNavigate() { - const location = useLocation() - const [, setSearchParams] = useSearchParams() + const [searchParams] = useSearchParams() + const navigate = useNavigate() const openModal = useCallback( (path: PopupModalRoutes, params?: Record) => { - setSearchParams((prev) => { - prev.set('modal', urlcat(path, params || {})) - return prev - }) + searchParams.set('modal', urlcat(path, params || {})) + // useLocation().pathname is pathname of modal Routes (maybe since a certain version) + // So we use pathname in hash instead + const mainLocationPathname = location.hash.slice(1).replace(/\?.*$/, '') + navigate(`${mainLocationPathname}?${searchParams.toString()}`) }, - [location, setSearchParams], + [navigate, searchParams], ) return openModal } diff --git a/packages/mask/popups/components/NFTAvatarPicker/index.tsx b/packages/mask/popups/components/NFTAvatarPicker/index.tsx index 69753d7ae893..b36f45206a54 100644 --- a/packages/mask/popups/components/NFTAvatarPicker/index.tsx +++ b/packages/mask/popups/components/NFTAvatarPicker/index.tsx @@ -1,16 +1,16 @@ +import { Trans } from '@lingui/react/macro' +import { Flags } from '@masknet/flags' import { ElementAnchor, NetworkTab, PluginVerifiedWalletStatusBar, RetryHint } from '@masknet/shared' -import { Box, Button, Stack } from '@mui/material' -import { memo, useCallback, useMemo, useState } from 'react' -import { getRegisteredWeb3Networks } from '@masknet/web3-providers' -import { useChainContext, useNetworkContext, useNonFungibleAssets, useWallet } from '@masknet/web3-hooks-base' -import { first, uniqBy } from 'lodash-es' +import { EMPTY_LIST, PopupModalRoutes, type BindingProof, type NetworkPluginID } from '@masknet/shared-base' import { LoadingBase, makeStyles } from '@masknet/theme' import type { Web3Helper } from '@masknet/web3-helpers' -import { CollectionList } from './CollectionList.js' -import { EMPTY_LIST, type NetworkPluginID, PopupModalRoutes, type BindingProof } from '@masknet/shared-base' +import { useChainContext, useNetworkContext, useNonFungibleAssets, useWallet } from '@masknet/web3-hooks-base' +import { getRegisteredWeb3Networks } from '@masknet/web3-providers' +import { Box, Button, Stack } from '@mui/material' +import { first, uniqBy } from 'lodash-es' +import { memo, useCallback, useMemo, useState } from 'react' import { useModalNavigate } from '../index.js' -import { Flags } from '@masknet/flags' -import { Trans } from '@lingui/react/macro' +import { CollectionList } from './CollectionList.js' const useStyles = makeStyles()((theme) => ({ picker: { @@ -54,7 +54,7 @@ export const NFTAvatarPicker = memo(function NFTAvatarPick const chains = useMemo(() => { const networks = getRegisteredWeb3Networks(pluginID) return networks.filter((x) => (Flags.support_testnet_switch ? true : x.isMainnet)).map((x) => x.chainId) - }, []) + }, [pluginID]) const [selected, setSelected] = useState() diff --git a/packages/mask/popups/hooks/useSearchValue.ts b/packages/mask/popups/hooks/useSearchValue.ts index 267ab4d04c8f..59827fcfd1f3 100644 --- a/packages/mask/popups/hooks/useSearchValue.ts +++ b/packages/mask/popups/hooks/useSearchValue.ts @@ -1,18 +1,25 @@ -import { useAsyncRetry } from 'react-use' -import type { AsyncStateRetry } from 'react-use/lib/useAsyncRetry.js' +import { useLensClient } from '@masknet/shared' import { ECKeyIdentifier, NextIDPlatform } from '@masknet/shared-base' -import { ENS, Lens } from '@masknet/web3-providers' +import { ENS } from '@masknet/web3-providers' +import { useQuery } from '@tanstack/react-query' -export function useSearchValue(value: string, type?: NextIDPlatform): AsyncStateRetry { - return useAsyncRetry(async () => { - if (!type) return '' - if (value.length === 44) return new ECKeyIdentifier('secp256k1', value).publicKeyAsHex ?? value - if (type === NextIDPlatform.Twitter) return value.replace(/^@/, '').toLowerCase() +export function useSearchValue(value: string, type?: NextIDPlatform) { + const lensClient = useLensClient() + return useQuery({ + queryKey: ['search-value', value, type, !lensClient], + queryFn: async () => { + if (!type) return '' + if (value.length === 44) return new ECKeyIdentifier('secp256k1', value).publicKeyAsHex ?? value + if (type === NextIDPlatform.Twitter) return value.replace(/^@/, '').toLowerCase() - if (value.endsWith('.eth')) return (await ENS.lookup(value))?.toLowerCase() + if (value.endsWith('.eth')) return (await ENS.lookup(value))?.toLowerCase() - if (value.endsWith('.lens')) return (await Lens.getProfileByHandle(value)).ownedBy.address?.toLowerCase() + if (value.endsWith('.lens') && lensClient) { + const account = await lensClient?.getAccountByHandle(value) + return (account?.username?.ownedBy as string).toLowerCase() + } - return value.toLowerCase() - }, [value]) + return value.toLowerCase() + }, + }) } diff --git a/packages/mask/popups/modals/SwitchPersonaModal/index.tsx b/packages/mask/popups/modals/SwitchPersonaModal/index.tsx index d9faeea286bc..f25c5ed42d21 100644 --- a/packages/mask/popups/modals/SwitchPersonaModal/index.tsx +++ b/packages/mask/popups/modals/SwitchPersonaModal/index.tsx @@ -56,7 +56,7 @@ export const SwitchPersonaModal = memo(function SwitchPers size="small" variant="outlined" startIcon={} - onClick={() => handleOpenDashboard(DashboardRoutes.RecoveryPersona)}> + onClick={() => handleOpenDashboard(DashboardRoutes.Recovery)}> Recovery (function VerifyBackupPasswordModal() { const { t } = useLingui() diff --git a/packages/mask/popups/pages/Friends/Home/index.tsx b/packages/mask/popups/pages/Friends/Home/index.tsx index c65dfd9bace5..3f63fef83eb5 100644 --- a/packages/mask/popups/pages/Friends/Home/index.tsx +++ b/packages/mask/popups/pages/Friends/Home/index.tsx @@ -22,7 +22,7 @@ export const Component = memo(function FriendsHome() { const friends = useMemo(() => data?.pages.flatMap((x) => x.friends) ?? EMPTY_LIST, [data]) const [searchValue, setSearchValue] = useState('') const type = resolveNextIDPlatform(searchValue) - const { loading: resolveLoading, value: keyword = '' } = useSearchValue(searchValue, type) + const { isLoading: resolveLoading, data: keyword = '' } = useSearchValue(searchValue, type) const fuse = useMemo(() => { return new Fuse(records, { keys: ['profile.userId'], diff --git a/packages/mask/popups/pages/Personas/Home/index.tsx b/packages/mask/popups/pages/Personas/Home/index.tsx index 782dc920a664..d6166d2e06f5 100644 --- a/packages/mask/popups/pages/Personas/Home/index.tsx +++ b/packages/mask/popups/pages/Personas/Home/index.tsx @@ -36,7 +36,7 @@ export const Component = memo(function PersonaHome() { const onRestore = useCallback(() => { browser.tabs.create({ active: true, - url: browser.runtime.getURL(`/dashboard.html#${DashboardRoutes.RecoveryPersona}`), + url: browser.runtime.getURL(`/dashboard.html#${DashboardRoutes.Recovery}`), }) if (navigator.userAgent.includes('Firefox')) { window.close() diff --git a/packages/mask/popups/pages/Settings/index.tsx b/packages/mask/popups/pages/Settings/index.tsx index 3b21d61efe98..245e94496c8d 100644 --- a/packages/mask/popups/pages/Settings/index.tsx +++ b/packages/mask/popups/pages/Settings/index.tsx @@ -245,7 +245,7 @@ export const Component = memo(function SettingsPage() { if (!user.backupPassword) { modalNavigate(PopupModalRoutes.SetBackupPassword) } else { - handleOpenDashboard(DashboardRoutes.CloudBackup) + handleOpenDashboard(DashboardRoutes.BackupCloud) } }}> handleOpenDashboard(DashboardRoutes.RecoveryPersona)}> + onClick={() => handleOpenDashboard(DashboardRoutes.Recovery)}> Restore Database} diff --git a/packages/mask/shared-ui/hooks/useUserContext.ts b/packages/mask/shared-ui/hooks/useUserContext.ts index 47dd2217ff0a..8496501aeafc 100644 --- a/packages/mask/shared-ui/hooks/useUserContext.ts +++ b/packages/mask/shared-ui/hooks/useUserContext.ts @@ -9,11 +9,11 @@ function useUserContext() { ) const updateUser = useCallback( - async (obj: Partial) => { + async (userConfig: Partial) => { await PersistentStorages.Settings.storage.backupConfig.setValue({ ...user, - ...obj, - backupPassword: obj.backupPassword ? btoa(obj.backupPassword) : user.backupPassword, + ...userConfig, + backupPassword: userConfig.backupPassword ? btoa(userConfig.backupPassword) : user.backupPassword, }) }, [user], @@ -30,7 +30,7 @@ function useUserContext() { // Maybe `backupPassword` is not base64-encoded. return user } - }, [user, updateUser]) + }, [user]) return { user: result, diff --git a/packages/mask/shared-ui/initialization/fetch.ts b/packages/mask/shared-ui/initialization/fetch.ts index 393375f9cc78..471e51c75d44 100644 --- a/packages/mask/shared-ui/initialization/fetch.ts +++ b/packages/mask/shared-ui/initialization/fetch.ts @@ -8,7 +8,7 @@ const { fetch: original_fetch } = globalThis function contentFetch(input: RequestInfo | URL, init?: RequestInit) { const request = new Request(input, init) - if (canAccessAsContent(request.url)) { + if (shouldAccessViaContent(request.url)) { if ( navigator.userAgent.includes('Firefox') && browser.runtime.getManifest().manifest_version === 2 && @@ -48,12 +48,18 @@ function fetchingTwitterResource(target: URL) { function fetchingInsResource(target: URL) { // cspell:disable-next-line - return location.origin.endsWith('instagram.com') && target.origin.match(/(fbcdn\.net|cdninstagram\.com)$/) + if (isHostName(location, 'instagram.com') && target.origin.match(/(fbcdn\.net|cdninstagram\.com)$/)) return true + return target.host === 'api.lens.xyz' } -function canAccessAsContent(url: string) { +function fetchingGoogleDriveResource(target: URL) { + return target.origin === 'https://www.googleapis.com' +} + +function shouldAccessViaContent(url: string) { const target = new URL(url, location.href) - if (fetchingTwitterResource(target) || fetchingInsResource(target)) return true + if (fetchingTwitterResource(target) || fetchingInsResource(target) || fetchingGoogleDriveResource(target)) + return true // eg: https://maskbook-backup-server-staging.s3.ap-east-1.amazonaws.com/backups/xxx.zip // The content-length needs to be used in the client request in order to realize the progress of the download. diff --git a/packages/mask/shared-ui/initialization/storage.ts b/packages/mask/shared-ui/initialization/storage.ts index d3bc387f97a8..5b2563a0a605 100644 --- a/packages/mask/shared-ui/initialization/storage.ts +++ b/packages/mask/shared-ui/initialization/storage.ts @@ -25,3 +25,5 @@ const indexedDB: KVStorageBackend = { } setupMaskKVStorageBackend(indexedDB, memory) setupLegacySettingsAtNonBackground(Services.Settings.getLegacySettingsInitialValue) + +indexedDB diff --git a/packages/mask/shared-ui/locale/en-US.json b/packages/mask/shared-ui/locale/en-US.json index 7cc6ffaef207..a940cd5df605 100644 --- a/packages/mask/shared-ui/locale/en-US.json +++ b/packages/mask/shared-ui/locale/en-US.json @@ -7,6 +7,16 @@ "y6VCOb": [["0"], " Mins"], "MpnSqP": [["0"], " Pending"], "FKrzPv": [["count", "plural", { "one": ["#", " Wallet 🚀"], "other": ["#", " Wallets 🚀"] }]], + "5s6EhU": [ + [ + "count", + "plural", + { + "one": ["You have recovered **", "#", " Wallet 🚀**"], + "other": ["You have recovered **", "#", " Wallets 🚀**"] + } + ] + ], "yx3mb0": [ [ "decryptProgress", @@ -61,9 +71,11 @@ "5YfW3S": ["Add an encrypted comment..."], "aTzTyw": ["Add Assets"], "M0FgOk": ["Add Contact"], + "FAKSZG": ["Add google Drive"], "LP+1Z7": ["Add Network"], "68m9Nl": ["Add new address to an existing group"], "1LkMSp": ["Add Suggested Token"], + "O8PsYe": ["Add the file to Chrome's database"], "GtJJAj": ["Add Wallet"], "uv94aG": ["Added by user"], "8RF/Sx": ["Added successfully"], @@ -96,10 +108,13 @@ "iTiwqa": ["Asset is hidden."], "2jQko7": ["Associated Accounts"], "CEk7Nc": ["At least 6 characters"], + "gp6A8z": ["Authorization Failed"], "Wvnsx1": ["Auto-lock"], "7QptC5": ["Auto-lock Time"], "nTFx7o": ["Avatar set successfully"], "iH8pgl": ["Back"], + "npsHM5": ["Back Up to Google Drive"], + "V+1pjj": ["Back Up Your Data Your Way"], "rLgPvm": ["Backup"], "h7+V7K": ["Backup & Recovery"], "QrHM/A": ["Backup downloaded and merged to local successfully."], @@ -113,6 +128,8 @@ ], "hUF4dG": ["Backup password set successfully"], "UtKGok": ["Backup Persona"], + "+m7x4e": ["Backup Successful"], + "3iUAE7": ["Backup to Google Drive"], "7Ry254": ["Backup to Mask Cloud Service"], "6IHgRq": ["Backup to the Cloud"], "QQPCqQ": ["Backup Wallet"], @@ -140,6 +157,9 @@ "tcHpvG": ["Change Owner"], "fDP2k4": ["Change Payment Password"], "IXbRbM": ["Choose another wallet"], + "lU6uRb": [ + "Choose from multiple backup options, now including encrypted storage via your authorized Google Drive for added security and flexibility." + ], "xH6cn+": ["Choose Token"], "+adBn3": ["Chrome - external extension"], "EsKgLS": ["Click here to have a quick start."], @@ -195,6 +215,9 @@ "PjBWOL": ["Create your persona to get started"], "WgawP2": ["Creating your"], "cEnmTp": ["Creating your "], + "L82H5Z": ["Creating your **identity**"], + "F7U8uz": ["Creating your **wallet**"], + "aF8kci": ["Creation Completed"], "Q2lUR2": ["Currency"], "OgPkDe": ["Currency Symbol (Optional)"], "oOQfsI": ["Current account is not the verifying account."], @@ -211,6 +234,7 @@ "pvnfJD": ["Dark"], "Sp/me1": ["data"], "HKH+W+": ["Data"], + "K8jCIB": ["Data backed up successfully!"], "3B4jmY": ["Data correlation"], "rAcOY1": [ "Data merged from Mask Cloud Service to local successfully. Re-enter your password to encrypt and upload the new backup to Mask Cloud Service." @@ -265,6 +289,7 @@ "w1ctdJ": ["Encrypted Post"], "MRIXE3": ["Encrypting your"], "zutir1": ["Encrypting your "], + "XB3tfc": ["Encrypting your **data**"], "Cz6Lx7": ["Encryption Method"], "N/fqDa": ["Ens or Address(0x)"], "mPxxVq": ["Enter a gas limit"], @@ -284,9 +309,14 @@ "GS+Mus": ["Export"], "7Bj3x9": ["Failed"], "SLEDBF": ["Failed to add the wallet, please try again."], + "r92tNP": ["Failed to authorize Google Drive. Please try again."], "09vHB+": ["Failed to decrypt."], "jK7nvW": ["Failed to disconnect wallet"], + "9hzYBR": ["Failed to download and merge the backup: ", ["0"]], "0tkvsz": ["Failed to download and merge the backup."], + "etATpN": ["Failed to login: ", ["0"]], + "qDIxZ+": ["Failed to restore the backup from Google Drive to your browser. Please try again."], + "e3I0CA": ["Failed to restore the backup: ", ["0"]], "mrAv9J": ["Failed to save network"], "ZsjtYe": ["Failed to set Avatar."], "RWoEqV": ["Failed to transfer token: ", ["message"]], @@ -322,7 +352,9 @@ "fUn3xA": ["Generate a new wallet address"], "tdZPpe": ["Generating your"], "CiU2m/": ["Generating your "], + "RL5m+x": ["Generating your **accounts**"], "2p7WMm": ["Give permission to access <0/> your ", ["0"], "?"], + "w9Xmw/": ["Google Drive"], "76gPWk": ["Got it"], "HqiAyF": ["Gwei"], "pu3rTn": ["GWEI"], @@ -354,6 +386,7 @@ "fza4cg": ["Import Wallets"], "HvDfH/": ["Imported"], "m3XvO+": ["Imported Wallets"], + "ANk/Zy": ["Incorrect Backup Password"], "a23gJr": ["Incorrect backup password."], "bapItf": ["Incorrect Backup Password."], "bassMa": ["Incorrect cloud backup password, please try again."], @@ -394,9 +427,11 @@ "jygqM9": ["Loading account information..."], "EBC6hj": ["Local Backup"], "shPV5O": ["Local persona or wallet only"], + "crVIc7": ["Locale Backup"], "KGHnSc": ["Lock Wallet"], "FgAxTj": ["Log out"], "kC3Q3d": ["Login to Mask Cloud"], + "nOhz3x": ["Logout"], "NkgvWN": ["Logout failed"], "o4Iu2W": ["Logout successfully"], "nTWWCZ": ["Low"], @@ -406,6 +441,7 @@ ], "lET9my": ["Mask needs the following permissions"], "siroPf": ["Mask Network"], + "jhoAzY": ["Mask Network Cloud"], "lWOC+h": ["Mask Network requires you to authorize the following websites before using it."], "HsoakN": ["masknetwork"], "CK1KXz": ["Max"], @@ -422,7 +458,9 @@ "sQJ3RN": ["Max priority fee is too low for network conditions."], "ITBQO3": ["Max priority fee must be greater than 0 GWEI"], "agPptk": ["Medium"], + "lPsa94": ["Merge Completed"], "RH8jSA": ["Merge data to local database"], + "E6YUtc": ["Merge to Browser"], "QTomF0": ["Merge to local"], "xDAtGP": ["Message"], "pGElS5": ["Mnemonic"], @@ -554,6 +592,7 @@ "TZ0npN": ["ready 🚀"], "nVT2pJ": ["realMaskNetwork"], "lDgVWA": ["Receive"], + "OkofjH": ["Recover"], "XC7RGa": ["Recover your data"], "UBzbea": ["Recover your wallet"], "P9wzG/": ["Recovery"], @@ -575,8 +614,10 @@ "nvAt0H": ["Resource"], "yKu/3Y": ["Restore"], "Z3+V9p": ["Restore backup failed."], + "nGl2Ng": ["Restore Completed"], "AKLbfQ": ["Restore Database"], "uM6jnS": ["Restore failed"], + "KFwID2": ["Restore Failed"], "/LkuGq": ["Restore from a previous database backup"], "KisOjk": ["Restore or Login"], "6gRgw8": ["Retry"], @@ -655,6 +696,9 @@ "VdhBp2": ["The chainID is not equal to the currently connected one."], "h3Vpnw": ["The code is incorrect."], "7w1rTm": ["The download link is expired"], + "oYkran": [ + "The Mask Network Cloud Backup feature will be deactivated on April 30, 2025. Please use alternative cloud backup services or local backup solutions." + ], "o+zDNQ": ["The mnemonic word has been copied, please keep it in a safe place."], "yRuvmU": ["The mnemonic words has been copied, please keep it in a safe place."], "thX7xs": [ @@ -793,6 +837,7 @@ "m74yjp": ["Welcome to Mask Cloud Services"], "hEpXzO": ["Welcome to Mask Network"], "fFYJ8f": ["Welcome to use Mask Network"], + "OLUEnY": ["when you click Add Google Drive button,you will be forwarded to Google authorization pages."], "Qbo7Ev": ["Write down mnemonic words"], "f5AidZ": ["Write down recovery phrase"], "yGyJ1l": [ @@ -802,6 +847,7 @@ "dyqtoj": ["You have recovered"], "V8x6o5": ["You have recovered "], "QU9aqK": ["You have signed with your wallet."], + "PeT3a5": ["You have successfully restored the backup from Google Drive to your browser."], "zkEW09": [ "You have verified your cloud password and recovered your backup. Do you want to let your cloud password and local backup password be the same?" ], @@ -810,12 +856,17 @@ "FnQek5": [ "Your connection to this site is not encrypted which can be modified by a hostile third party, we strongly suggest you reject this request." ], + "UDKbPj": ["Your file has been successfully merged into the browser data."], + "S2JNMm": ["Your file has been successfully restore into the browser data."], "Q68Nuc": [ "Your payment password encrypts wallet data and is needed to unlocking the wallet, transaction confirmations and signing. The password is never stored, and there is no way to recover it if you forget it." ], + "4EN5JL": ["Your Persona has been successfully created."], "N19nSk": ["Your Persona is on"], "WC7pDz": ["Your Persona is on "], + "PDW/HG": ["Your Persona is on **ready 🚀**"], "0kr+x1": ["Your Wallet is on"], - "v7OL2k": ["Your Wallet is on "] + "v7OL2k": ["Your Wallet is on "], + "wCtp6y": ["Your Wallet is on **ready 🚀**"] } } diff --git a/packages/mask/shared-ui/locale/en-US.po b/packages/mask/shared-ui/locale/en-US.po index 1daa31d66fa2..449747cd0cfa 100644 --- a/packages/mask/shared-ui/locale/en-US.po +++ b/packages/mask/shared-ui/locale/en-US.po @@ -41,7 +41,11 @@ msgid "{0} Pending" msgstr "" #: dashboard/pages/SetupPersona/Onboarding/index.tsx -msgid "{count, plural, one {# Wallet 🚀} other {# Wallets 🚀}}" +#~ msgid "{count, plural, one {# Wallet 🚀} other {# Wallets 🚀}}" +#~ msgstr "" + +#: dashboard/pages/SetupPersona/Onboarding/index.tsx +msgid "{count, plural, one {You have recovered **# Wallet 🚀**} other {You have recovered **# Wallets 🚀**}}" msgstr "" #: content-script/components/InjectedComponents/DecryptedPost/DecryptPostAwaiting.tsx @@ -127,8 +131,8 @@ msgstr "" #: dashboard/pages/SetupPersona/Onboarding/index.tsx #: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx -msgid "accounts" -msgstr "" +#~ msgid "accounts" +#~ msgstr "" #: popups/pages/Wallet/components/WalletAssets/index.tsx msgid "Activities" @@ -157,6 +161,10 @@ msgstr "" msgid "Add Contact" msgstr "" +#: dashboard/components/GoogleDriveLogin.tsx +msgid "Add google Drive" +msgstr "" + #: popups/pages/Wallet/NetworkManagement/index.tsx #: popups/pages/Wallet/EditNetwork/index.tsx msgid "Add Network" @@ -170,6 +178,10 @@ msgstr "" msgid "Add Suggested Token" msgstr "" +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx +msgid "Add the file to Chrome's database" +msgstr "" + #: popups/pages/Wallet/components/StartUp/index.tsx #: popups/pages/Wallet/SwitchWallet/index.tsx #: popups/pages/Wallet/CreateWallet/index.tsx @@ -253,8 +265,8 @@ msgid "Approve amount" msgstr "" #: dashboard/pages/SetupPersona/CloudBackupPreview/index.tsx -msgid "Are you sure to overwrite the backups stored on Mask Cloud Service?" -msgstr "" +#~ msgid "Are you sure to overwrite the backups stored on Mask Cloud Service?" +#~ msgstr "" #. placeholder {0}: formatEthereumAddress(wallet.identity, 4) #: popups/components/ConnectedWallet/index.tsx @@ -287,6 +299,10 @@ msgstr "" msgid "At least 6 characters" msgstr "" +#: dashboard/components/GoogleDriveLogin.tsx +msgid "Authorization Failed" +msgstr "" + #: popups/pages/Wallet/WalletSettings/AutoLock.tsx msgid "Auto-lock" msgstr "" @@ -300,13 +316,24 @@ msgid "Avatar set successfully" msgstr "" #: content-script/components/shared/SelectRecipients/SelectRecipientsDialog.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/Preview.tsx #: dashboard/pages/CreateMaskWallet/CreateMnemonic/index.tsx #: popups/pages/Personas/ExportPrivateKey/index.tsx #: popups/pages/Personas/AccountDetail/UI.tsx msgid "Back" msgstr "" -#: dashboard/pages/SetupPersona/CloudBackupPreview/index.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/GoogleDrive.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/GoogleDrive.tsx +#~ msgid "Back Up to Google Drive" +#~ msgstr "" + +#: dashboard/pages/SetupPersona/Backup/index.tsx +msgid "Back Up Your Data Your Way" +msgstr "" + +#: dashboard/pages/SetupPersona/Backup/Cloud/GoogleDrive.tsx +#: dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx #: popups/pages/Personas/Logout/index.tsx #: popups/modals/SwitchPersonaModal/index.tsx msgid "Backup" @@ -317,16 +344,16 @@ msgid "Backup & Recovery" msgstr "" #: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx -msgid "Backup downloaded and merged to local successfully." -msgstr "" +#~ msgid "Backup downloaded and merged to local successfully." +#~ msgstr "" #: dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx msgid "Backup Failed" msgstr "" #: dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx -msgid "Backup is saved to Mask Cloud Service." -msgstr "" +#~ msgid "Backup is saved to Mask Cloud Service." +#~ msgstr "" #. placeholder {0}: user.localBackupAt #. placeholder {0}: user.cloudBackupAt @@ -335,13 +362,13 @@ msgstr "" msgid "Backup on {0}" msgstr "" -#: dashboard/components/Restore/RestorePersonaFromLocal.tsx -#: dashboard/components/Restore/RestoreFromCloud/ConfirmBackupInfo.tsx +#: dashboard/pages/SetupPersona/Recovery/Local.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/ConfirmBackupInfo.tsx msgid "Backup password" msgstr "" -#: dashboard/pages/SetupPersona/LocalBackup/index.tsx -#: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx +#: dashboard/pages/SetupPersona/Backup/Local.tsx +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx #: dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx #: popups/pages/Settings/index.tsx #: popups/modals/SetBackupPasswordModal/index.tsx @@ -363,10 +390,19 @@ msgstr "" msgid "Backup Persona" msgstr "" -#: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx -msgid "Backup to Mask Cloud Service" +#: dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx +msgid "Backup Successful" msgstr "" +#: dashboard/pages/SetupPersona/Backup/Cloud/GoogleDrive.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/GoogleDrive.tsx +msgid "Backup to Google Drive" +msgstr "" + +#: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx +#~ msgid "Backup to Mask Cloud Service" +#~ msgstr "" + #: dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx msgid "Backup to the Cloud" msgstr "" @@ -432,7 +468,6 @@ msgstr "" #: content-script/components/InjectedComponents/SelectPeopleDialog.tsx #: dashboard/pages/SetupPersona/Welcome/index.tsx #: dashboard/pages/SetupPersona/Permissions/index.tsx -#: dashboard/pages/SetupPersona/CloudBackupPreview/index.tsx #: dashboard/modals/ConfirmModal/index.tsx #: dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx #: dashboard/components/Restore/ConfirmSynchronizePasswordDialog.tsx @@ -505,6 +540,10 @@ msgstr "" msgid "Choose another wallet" msgstr "" +#: dashboard/pages/SetupPersona/Backup/index.tsx +msgid "Choose from multiple backup options, now including encrypted storage via your authorized Google Drive for added security and flexibility." +msgstr "" + #: popups/modals/ChooseToken/index.tsx msgid "Choose Token" msgstr "" @@ -530,6 +569,7 @@ msgid "Close" msgstr "" #: dashboard/pages/SetupPersona/Recovery/index.tsx +#: dashboard/pages/SetupPersona/Backup/index.tsx #: dashboard/components/Restore/ConfirmSynchronizePasswordDialog.tsx #: popups/pages/Settings/index.tsx msgid "Cloud Backup" @@ -543,12 +583,11 @@ msgstr "" msgid "Coming soon" msgstr "" +#: dashboard/pages/SetupPersona/Recovery/Local.tsx #: dashboard/components/Restore/RestoreWalletFromLocal.tsx -#: dashboard/components/Restore/RestorePersonaFromLocal.tsx msgid "Completed" msgstr "" -#: dashboard/pages/SetupPersona/CloudBackupPreview/index.tsx #: dashboard/modals/ConfirmModal/index.tsx #: dashboard/components/Restore/ConfirmSynchronizePasswordDialog.tsx #: popups/pages/Wallet/components/DisconnectModal/index.tsx @@ -602,8 +641,6 @@ msgstr "" msgid "Confirm to hide {name}? You can redisplay it by re-adding this NFT at any time." msgstr "" -#: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx -#: dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx #: popups/pages/Personas/ConnectWallet/index.tsx msgid "Congratulations" msgstr "" @@ -704,16 +741,18 @@ msgstr "" #: dashboard/pages/SignUp/steps/PersonaNameUI.tsx #: dashboard/pages/SetupPersona/SignUp/index.tsx +#: dashboard/pages/SetupPersona/Recovery/PrivateKey.tsx +#: dashboard/pages/SetupPersona/Recovery/Phrase.tsx +#: dashboard/pages/SetupPersona/Recovery/Local.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/PhoneField.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/EmailField.tsx #: dashboard/pages/SetupPersona/Mnemonic/index.tsx -#: dashboard/pages/SetupPersona/CloudBackup/index.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/MaskNetwork.tsx #: dashboard/pages/CreateMaskWallet/CreateWalletForm/index.tsx #: dashboard/pages/CreateMaskWallet/AddDeriveWallet/index.tsx #: dashboard/components/Restore/RestoreWalletFromLocal.tsx -#: dashboard/components/Restore/RestorePersonaFromLocal.tsx #: dashboard/components/Restore/RestoreFromPrivateKey.tsx #: dashboard/components/Restore/RestoreFromMnemonic.tsx -#: dashboard/components/Restore/RestoreFromCloud/PhoneField.tsx -#: dashboard/components/Restore/RestoreFromCloud/EmailField.tsx msgid "Continue" msgstr "" @@ -769,6 +808,7 @@ msgstr "" msgid "Create Password" msgstr "" +#: dashboard/pages/SetupPersona/Recovery/index.tsx #: popups/pages/Personas/Home/UI.tsx msgid "Create Persona" msgstr "" @@ -784,7 +824,19 @@ msgstr "" #: dashboard/pages/SetupPersona/Onboarding/index.tsx #: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx -msgid "Creating your " +#~ msgid "Creating your " +#~ msgstr "" + +#: dashboard/pages/SetupPersona/Onboarding/index.tsx +msgid "Creating your **identity**" +msgstr "" + +#: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx +msgid "Creating your **wallet**" +msgstr "" + +#: dashboard/pages/SetupPersona/Onboarding/index.tsx +msgid "Creation Completed" msgstr "" #: popups/pages/Wallet/WalletSettings/ChangeCurrency.tsx @@ -825,23 +877,27 @@ msgstr "" #: dashboard/pages/SetupPersona/Onboarding/index.tsx #: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx -msgid "data" -msgstr "" +#~ msgid "data" +#~ msgstr "" #: popups/pages/Wallet/Interaction/TransactionRequest.tsx msgid "Data" msgstr "" +#: dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx +msgid "Data backed up successfully!" +msgstr "" + #: popups/pages/Settings/index.tsx msgid "Data correlation" msgstr "" #: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx -msgid "Data merged from Mask Cloud Service to local successfully. Re-enter your password to encrypt and upload the new backup to Mask Cloud Service." -msgstr "" +#~ msgid "Data merged from Mask Cloud Service to local successfully. Re-enter your password to encrypt and upload the new backup to Mask Cloud Service." +#~ msgstr "" -#: dashboard/components/Restore/RestoreFromCloud/ConfirmBackupInfo.tsx -#: dashboard/components/Restore/RestoreFromCloud/ConfirmBackupInfo.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/ConfirmBackupInfo.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/ConfirmBackupInfo.tsx msgid "Decrypt failed, please check password" msgstr "" @@ -946,18 +1002,20 @@ msgid "Done" msgstr "" #: content-script/components/InjectedComponents/AutoPasteFailedDialog.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/Preview.tsx +#: dashboard/components/GoogleDriveFileTable.tsx msgid "Download" msgstr "" #: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx -msgid "Download backup" -msgstr "" +#~ msgid "Download backup" +#~ msgstr "" -#: dashboard/pages/SetupPersona/LocalBackup/index.tsx +#: dashboard/pages/SetupPersona/Backup/Local.tsx msgid "Download Backup" msgstr "" -#: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx msgid "Downloading" msgstr "" @@ -966,8 +1024,8 @@ msgid "Drag & Drop your file here" msgstr "" #: dashboard/pages/SetupPersona/CloudBackup/index.tsx -msgid "E-mail" -msgstr "" +#~ msgid "E-mail" +#~ msgstr "" #: popups/pages/Wallet/ContactList/index.tsx msgid "Edit" @@ -982,13 +1040,14 @@ msgstr "" msgid "eg: X accounts, persona public keys, wallet addresses or ENS" msgstr "" -#: dashboard/pages/SetupPersona/CloudBackup/EmailForm.tsx -#: dashboard/components/Restore/RestoreFromCloud/EmailField.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/EmailField.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/MaskNetwork.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/EmailForm.tsx msgid "Email" msgstr "" -#: dashboard/pages/SetupPersona/CloudBackup/EmailForm.tsx -#: dashboard/components/Restore/RestoreFromCloud/EmailField.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/EmailField.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/EmailForm.tsx msgid "Email verification code" msgstr "" @@ -1019,7 +1078,12 @@ msgstr "" #: dashboard/pages/SetupPersona/Onboarding/index.tsx #: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx -msgid "Encrypting your " +#~ msgid "Encrypting your " +#~ msgstr "" + +#: dashboard/pages/SetupPersona/Onboarding/index.tsx +#: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx +msgid "Encrypting your **data**" msgstr "" #: content-script/components/CompositionDialog/EncryptionMethodSelector.tsx @@ -1105,6 +1169,10 @@ msgstr "" msgid "Failed to add the wallet, please try again." msgstr "" +#: dashboard/components/GoogleDriveLogin.tsx +msgid "Failed to authorize Google Drive. Please try again." +msgstr "" + #: content-script/components/InjectedComponents/DecryptedPost/DecryptPostFailed.tsx msgid "Failed to decrypt." msgstr "" @@ -1113,8 +1181,26 @@ msgstr "" msgid "Failed to disconnect wallet" msgstr "" +#. placeholder {0}: (err as Error).message +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx +msgid "Failed to download and merge the backup: {0}" +msgstr "" + #: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx -msgid "Failed to download and merge the backup." +#~ msgid "Failed to download and merge the backup." +#~ msgstr "" + +#: dashboard/components/GoogleDriveLogin.tsx +#~ msgid "Failed to login: {0}" +#~ msgstr "" + +#: dashboard/pages/SetupPersona/Recovery/Cloud/GoogleDrive.tsx +msgid "Failed to restore the backup from Google Drive to your browser. Please try again." +msgstr "" + +#. placeholder {0}: (err as Error).message +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx +msgid "Failed to restore the backup: {0}" msgstr "" #: popups/pages/Wallet/EditNetwork/index.tsx @@ -1264,7 +1350,12 @@ msgstr "" #: dashboard/pages/SetupPersona/Onboarding/index.tsx #: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx -msgid "Generating your " +#~ msgid "Generating your " +#~ msgstr "" + +#: dashboard/pages/SetupPersona/Onboarding/index.tsx +#: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx +msgid "Generating your **accounts**" msgstr "" #. placeholder {0}: contract?.symbol || '' @@ -1274,6 +1365,13 @@ msgstr "" msgid "Give permission to access <0/> your {0}?" msgstr "" +#: dashboard/pages/SetupPersona/Recovery/Cloud/index.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/GoogleDrive.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/index.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/GoogleDrive.tsx +msgid "Google Drive" +msgstr "" + #: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx msgid "Got it" msgstr "" @@ -1339,8 +1437,8 @@ msgid "I wrote down those words in the correct order" msgstr "" #: dashboard/pages/SetupPersona/Onboarding/index.tsx -msgid "identity" -msgstr "" +#~ msgid "identity" +#~ msgstr "" #: dashboard/pages/SetupPersona/Mnemonic/ComponentToPrint.tsx msgid "Identity ID" @@ -1384,17 +1482,21 @@ msgstr "" msgid "Imported Wallets" msgstr "" +#: dashboard/hooks/useBackupFormState.ts +msgid "Incorrect Backup Password" +msgstr "" + #: popups/modals/VerifyBackupPasswordModal/index.tsx #: popups/modals/ChangeBackupPasswordModal/index.tsx msgid "Incorrect backup password." msgstr "" -#: dashboard/components/Restore/RestorePersonaFromLocal.tsx +#: dashboard/pages/SetupPersona/Recovery/Local.tsx msgid "Incorrect Backup Password." msgstr "" -#: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx -#: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx msgid "Incorrect cloud backup password, please try again." msgstr "" @@ -1412,7 +1514,7 @@ msgstr "" msgid "Incorrect password" msgstr "" -#: dashboard/pages/SetupPersona/LocalBackup/index.tsx +#: dashboard/pages/SetupPersona/Backup/Local.tsx #: dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx #: dashboard/hooks/useBackupFormState.ts #: dashboard/hooks/useBackupFormState.ts @@ -1420,7 +1522,6 @@ msgstr "" #: dashboard/hooks/useBackupFormState.ts #: dashboard/hooks/useBackupFormState.ts #: dashboard/hooks/useBackupFormState.ts -#: dashboard/hooks/useBackupFormState.ts msgid "Incorrect Password" msgstr "" @@ -1433,12 +1534,12 @@ msgstr "" msgid "Incorrect Payment Password." msgstr "" -#: dashboard/pages/SetupPersona/Recovery/index.tsx +#: dashboard/pages/SetupPersona/Recovery/PrivateKey.tsx #: dashboard/pages/CreateMaskWallet/Recovery/index.tsx msgid "Incorrect Private Key" msgstr "" -#: dashboard/pages/SetupPersona/Recovery/index.tsx +#: dashboard/pages/SetupPersona/Recovery/Phrase.tsx msgid "Incorrect recovery phrase." msgstr "" @@ -1451,6 +1552,7 @@ msgstr "" msgid "Incorrect words selected. Please try again!" msgstr "" +#: dashboard/pages/SetupPersona/Recovery/PrivateKey.tsx #: dashboard/components/Restore/RestoreFromPrivateKey.tsx msgid "Input your Private Key" msgstr "" @@ -1468,12 +1570,13 @@ msgstr "" msgid "Invalid Block Explorer URL." msgstr "" -#: dashboard/pages/SetupPersona/CloudBackup/EmailForm.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/EmailForm.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/CloudBackupFormContext.ts #: dashboard/contexts/CloudBackupFormContext.tsx msgid "Invalid email address format." msgstr "" -#: dashboard/components/Restore/RestoreFromCloud/EmailField.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/EmailField.tsx msgid "Invalid email address." msgstr "" @@ -1481,7 +1584,7 @@ msgstr "" msgid "Invalid number" msgstr "" -#: dashboard/components/Restore/RestoreFromCloud/PhoneField.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/PhoneField.tsx msgid "Invalid phone number, please check and try again." msgstr "" @@ -1489,8 +1592,8 @@ msgstr "" msgid "Invalid RPC URL." msgstr "" -#: dashboard/components/Restore/RestoreFromCloud/PhoneField.tsx -#: dashboard/components/Restore/RestoreFromCloud/EmailField.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/PhoneField.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/EmailField.tsx msgid "Invalid verification code." msgstr "" @@ -1571,6 +1674,10 @@ msgstr "" msgid "Local persona or wallet only" msgstr "" +#: dashboard/pages/SetupPersona/Backup/index.tsx +msgid "Locale Backup" +msgstr "" + #: popups/pages/Wallet/SwitchWallet/index.tsx msgid "Lock Wallet" msgstr "" @@ -1582,7 +1689,13 @@ msgid "Log out" msgstr "" #: dashboard/pages/SetupPersona/CloudBackup/index.tsx -msgid "Login to Mask Cloud" +#~ msgid "Login to Mask Cloud" +#~ msgstr "" + +#: dashboard/pages/SetupPersona/Recovery/Cloud/GoogleDrive.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/Preview.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/GoogleDrive.tsx +msgid "Logout" msgstr "" #: popups/pages/Personas/Logout/index.tsx @@ -1613,9 +1726,15 @@ msgstr "" #: content-script/components/InjectedComponents/ToolboxUnstyled.tsx #: content-script/components/InjectedComponents/PostDialogHint.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/index.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/index.tsx msgid "Mask Network" msgstr "" +#: dashboard/pages/SetupPersona/Backup/Cloud/Preview.tsx +msgid "Mask Network Cloud" +msgstr "" + #: content-script/components/InjectedComponents/PermissionBoundary.tsx msgid "Mask Network requires you to authorize the following websites before using it." msgstr "" @@ -1687,16 +1806,24 @@ msgstr "" msgid "Medium" msgstr "" -#: dashboard/pages/SetupPersona/CloudBackupPreview/index.tsx -#: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx -#: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx +msgid "Merge Completed" +msgstr "" + +#: dashboard/pages/SetupPersona/Backup/Cloud/Preview.tsx +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx msgid "Merge data to local database" msgstr "" -#: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx -msgid "Merge to local" +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx +#: dashboard/components/GoogleDriveFileTable.tsx +msgid "Merge to Browser" msgstr "" +#: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx +#~ msgid "Merge to local" +#~ msgstr "" + #: popups/components/SignRequestInfo/index.tsx msgid "Message" msgstr "" @@ -1710,15 +1837,15 @@ msgstr "" msgid "Mnemonic word" msgstr "" -#: dashboard/pages/SetupPersona/CloudBackup/index.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/MaskNetwork.tsx msgid "Mobile" msgstr "" -#: dashboard/pages/SetupPersona/CloudBackup/PhoneForm.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/PhoneForm.tsx msgid "Mobile number" msgstr "" -#: dashboard/components/Restore/RestoreFromCloud/PhoneField.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/PhoneField.tsx msgid "Mobile verification code" msgstr "" @@ -1831,7 +1958,8 @@ msgstr "" msgid "No back up" msgstr "" -#: dashboard/pages/SetupPersona/CloudBackupPreview/index.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/Preview.tsx +#: dashboard/components/GoogleDriveFileTable.tsx msgid "No backups found" msgstr "" @@ -1944,13 +2072,12 @@ msgid "Other social networking platforms, such as <0>Instagram, <1>Facebook, msgstr "" #: dashboard/pages/SetupPersona/CloudBackupPreview/index.tsx -#: dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx -msgid "Overwrite Backup" -msgstr "" +#~ msgid "Overwrite Backup" +#~ msgstr "" #: dashboard/pages/SetupPersona/CloudBackupPreview/index.tsx -msgid "Overwrite current backup" -msgstr "" +#~ msgid "Overwrite current backup" +#~ msgstr "" #: popups/modals/VerifyBackupPasswordModal/index.tsx #: popups/modals/SetBackupPasswordModal/index.tsx @@ -1962,7 +2089,7 @@ msgstr "" msgid "Paste manually" msgstr "" -#: dashboard/pages/SetupPersona/LocalBackup/index.tsx +#: dashboard/pages/SetupPersona/Backup/Local.tsx #: dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx #: popups/pages/Wallet/SetPaymentPassword/index.tsx #: popups/modals/WalletRemoveModal/index.tsx @@ -2043,7 +2170,7 @@ msgstr "" msgid "Personas" msgstr "" -#: dashboard/pages/SetupPersona/CloudBackup/PhoneForm.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/PhoneForm.tsx msgid "Phone verification code" msgstr "" @@ -2070,7 +2197,7 @@ msgstr "" msgid "Please enter backup password to export persona private key." msgstr "" -#: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx msgid "Please enter cloud backup password to download file." msgstr "" @@ -2098,8 +2225,6 @@ msgid "Please note: This Persona {0} is the management account of above listed S msgstr "" #: dashboard/pages/SetupPersona/Recovery/index.tsx -#: dashboard/pages/SetupPersona/LocalBackup/index.tsx -#: dashboard/pages/SetupPersona/CloudBackupPreview/index.tsx msgid "Please select the appropriate method to restore your personal data." msgstr "" @@ -2129,8 +2254,8 @@ msgid "Please switch to <0>@{expectAccount} to continue the account verifica msgstr "" #: dashboard/pages/SetupPersona/CloudBackup/index.tsx -msgid "Please use your frequently used email or phone number for backup." -msgstr "" +#~ msgid "Please use your frequently used email or phone number for backup." +#~ msgstr "" #: dashboard/pages/CreateMaskWallet/CreateMnemonic/index.tsx msgid "Please write down or copy these words and save them in a secure place." @@ -2208,8 +2333,8 @@ msgstr "" #: dashboard/pages/SetupPersona/Onboarding/index.tsx #: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx -msgid "ready 🚀" -msgstr "" +#~ msgid "ready 🚀" +#~ msgstr "" #: content-script/components/CompositionDialog/useSubmit.ts msgid "realMaskNetwork" @@ -2220,6 +2345,11 @@ msgstr "" msgid "Receive" msgstr "" +#: dashboard/pages/SetupPersona/Recovery/Cloud/GoogleDrive.tsx +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx +msgid "Recover" +msgstr "" + #: dashboard/pages/SetupPersona/Recovery/index.tsx msgid "Recover your data" msgstr "" @@ -2287,13 +2417,13 @@ msgstr "" msgid "Request Source" msgstr "" -#: dashboard/components/Restore/RestorePersonaFromLocal.tsx +#: dashboard/pages/SetupPersona/Recovery/Local.tsx msgid "Reselect" msgstr "" #: content-script/components/InjectedComponents/SetupGuide/VerifyNextID.tsx -#: dashboard/pages/SetupPersona/CloudBackup/PhoneForm.tsx -#: dashboard/pages/SetupPersona/CloudBackup/EmailForm.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/PhoneForm.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/EmailForm.tsx msgid "Resend" msgstr "" @@ -2305,24 +2435,32 @@ msgstr "" msgid "Resource" msgstr "" -#: dashboard/components/Restore/RestorePersonaFromLocal.tsx -#: dashboard/components/Restore/RestoreFromCloud/index.tsx -#: dashboard/components/Restore/RestoreFromCloud/ConfirmBackupInfo.tsx +#: dashboard/pages/SetupPersona/Recovery/Local.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/MaskNetwork.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/ConfirmBackupInfo.tsx msgid "Restore" msgstr "" -#: dashboard/components/Restore/RestorePersonaFromLocal.tsx +#: dashboard/pages/SetupPersona/Recovery/Local.tsx msgid "Restore backup failed." msgstr "" +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx +msgid "Restore Completed" +msgstr "" + #: popups/pages/Settings/index.tsx msgid "Restore Database" msgstr "" -#: dashboard/components/Restore/RestoreFromCloud/index.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/MaskNetwork.tsx msgid "Restore failed" msgstr "" +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx +msgid "Restore Failed" +msgstr "" + #: popups/pages/Settings/index.tsx msgid "Restore from a previous database backup" msgstr "" @@ -2394,8 +2532,8 @@ msgid "Select Liquidity" msgstr "" #: dashboard/pages/SetupPersona/LocalBackup/index.tsx -msgid "Select the contents of the backup" -msgstr "" +#~ msgid "Select the contents of the backup" +#~ msgstr "" #: popups/pages/Wallet/Interaction/PermissionRequest.tsx msgid "Select the wallet(s) to use on this site. You should not connect to website you don't trust." @@ -2406,8 +2544,8 @@ msgid "Select Wallet" msgstr "" #: content-script/components/InjectedComponents/SetupGuide/VerifyNextID.tsx -#: dashboard/pages/SetupPersona/CloudBackup/PhoneForm.tsx -#: dashboard/pages/SetupPersona/CloudBackup/EmailForm.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/PhoneForm.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/EmailForm.tsx #: popups/pages/Wallet/components/ActivityList/ActivityItem.tsx #: popups/pages/Wallet/components/ActionGroup/index.tsx #: popups/pages/Wallet/Transfer/index.tsx @@ -2481,8 +2619,8 @@ msgid "Sign" msgstr "" #: dashboard/pages/SetupPersona/Recovery/index.tsx -msgid "Sign Up" -msgstr "" +#~ msgid "Sign Up" +#~ msgstr "" #: popups/components/SignRequestInfo/index.tsx msgid "Sign-in Request" @@ -2609,8 +2747,7 @@ msgstr "" msgid "Swap" msgstr "" -#: dashboard/pages/SetupPersona/CloudBackupPreview/index.tsx -#: dashboard/pages/SetupPersona/CloudBackupPreview/index.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/Preview.tsx msgid "Switch other account" msgstr "" @@ -2618,7 +2755,7 @@ msgstr "" msgid "Switch Persona" msgstr "" -#: dashboard/components/Restore/RestoreFromCloud/ConfirmBackupInfo.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/ConfirmBackupInfo.tsx msgid "Switch to other accounts" msgstr "" @@ -2647,16 +2784,23 @@ msgstr "" msgid "The chainID is not equal to the currently connected one." msgstr "" -#: dashboard/pages/SetupPersona/CloudBackup/index.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/MaskNetwork.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/CloudBackupFormContext.ts +#: dashboard/pages/SetupPersona/Backup/Cloud/CloudBackupFormContext.ts #: dashboard/contexts/CloudBackupFormContext.tsx #: dashboard/contexts/CloudBackupFormContext.tsx msgid "The code is incorrect." msgstr "" -#: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx +#: dashboard/utils/api.ts msgid "The download link is expired" msgstr "" +#: dashboard/pages/SetupPersona/Recovery/Cloud/MaskNetwork.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/MaskNetwork.tsx +msgid "The Mask Network Cloud Backup feature will be deactivated on April 30, 2025. Please use alternative cloud backup services or local backup solutions." +msgstr "" + #: dashboard/pages/CreateMaskWallet/CreateMnemonic/index.tsx msgid "The mnemonic word has been copied, please keep it in a safe place." msgstr "" @@ -2695,6 +2839,7 @@ msgstr "" msgid "The persona name already exists." msgstr "" +#: dashboard/pages/SetupPersona/Backup/Cloud/CloudBackupFormContext.ts #: dashboard/contexts/CloudBackupFormContext.tsx msgid "The phone number is incorrect." msgstr "" @@ -2917,13 +3062,13 @@ msgstr "" msgid "Unlock" msgstr "" +#: dashboard/pages/SetupPersona/Recovery/Local.tsx #: dashboard/components/Restore/RestoreWalletFromLocal.tsx -#: dashboard/components/Restore/RestorePersonaFromLocal.tsx msgid "Unpacking" msgstr "" -#: dashboard/components/Restore/RestorePersonaFromLocal.tsx -#: dashboard/components/Restore/RestorePersonaFromLocal.tsx +#: dashboard/pages/SetupPersona/Recovery/Local.tsx +#: dashboard/pages/SetupPersona/Recovery/Local.tsx msgid "Unsupported data backup" msgstr "" @@ -2971,16 +3116,16 @@ msgstr "" msgid "value" msgstr "" -#: dashboard/components/Restore/RestoreFromCloud/EmailField.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/EmailField.tsx msgid "Verification code has been sent to your email. Please check your mailbox." msgstr "" -#: dashboard/components/Restore/RestoreFromCloud/PhoneField.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/PhoneField.tsx msgid "Verification code has been sent to your phone." msgstr "" -#: dashboard/pages/SetupPersona/CloudBackup/PhoneForm.tsx -#: dashboard/pages/SetupPersona/CloudBackup/EmailForm.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/PhoneForm.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/EmailForm.tsx msgid "Verification code sent" msgstr "" @@ -3033,8 +3178,8 @@ msgid "Waiting for {providerType}" msgstr "" #: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx -msgid "wallet" -msgstr "" +#~ msgid "wallet" +#~ msgstr "" #: popups/pages/Wallet/SwitchWallet/index.tsx #: popups/modals/WalletGroupModal/index.tsx @@ -3091,8 +3236,8 @@ msgid "Welcome Back" msgstr "" #: dashboard/pages/SetupPersona/CloudBackupPreview/index.tsx -msgid "Welcome to Mask Cloud Services" -msgstr "" +#~ msgid "Welcome to Mask Cloud Services" +#~ msgstr "" #: popups/pages/Personas/Home/UI.tsx msgid "Welcome to Mask Network" @@ -3102,6 +3247,10 @@ msgstr "" msgid "Welcome to use Mask Network" msgstr "" +#: dashboard/components/GoogleDriveLogin.tsx +msgid "when you click Add Google Drive button,you will be forwarded to Google authorization pages." +msgstr "" + #: popups/pages/Wallet/ExportPrivateKey/index.tsx msgid "Write down mnemonic words" msgstr "" @@ -3115,21 +3264,25 @@ msgid "You could check the verification result on Mask Pop-up after few minutes. msgstr "" #: dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx -msgid "You have backed up your data." -msgstr "" +#~ msgid "You have backed up your data." +#~ msgstr "" #: dashboard/pages/SetupPersona/Onboarding/index.tsx #~ msgid "You have recovered" #~ msgstr "" #: dashboard/pages/SetupPersona/Onboarding/index.tsx -msgid "You have recovered " -msgstr "" +#~ msgid "You have recovered " +#~ msgstr "" #: popups/pages/Personas/ConnectWallet/index.tsx msgid "You have signed with your wallet." msgstr "" +#: dashboard/pages/SetupPersona/Recovery/Cloud/GoogleDrive.tsx +msgid "You have successfully restored the backup from Google Drive to your browser." +msgstr "" + #: dashboard/components/Restore/ConfirmSynchronizePasswordDialog.tsx msgid "You have verified your cloud password and recovered your backup. Do you want to let your cloud password and local backup password be the same?" msgstr "" @@ -3138,26 +3291,41 @@ msgstr "" msgid "You need to open the dApp to view the specific content." msgstr "" -#. placeholder {0}: user.email #: dashboard/pages/SetupPersona/CloudBackup/index.tsx #: dashboard/pages/SetupPersona/CloudBackup/index.tsx -msgid "You used <0>{0} for the last cloud backup." -msgstr "" +#~ msgid "You used <0>{0} for the last cloud backup." +#~ msgstr "" #: popups/components/SignRequestInfo/index.tsx msgid "Your connection to this site is not encrypted which can be modified by a hostile third party, we strongly suggest you reject this request." msgstr "" +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx +msgid "Your file has been successfully merged into the browser data." +msgstr "" + +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx +msgid "Your file has been successfully restore into the browser data." +msgstr "" + #: dashboard/pages/CreateMaskWallet/CreateWalletForm/index.tsx msgid "Your payment password encrypts wallet data and is needed to unlocking the wallet, transaction confirmations and signing. The password is never stored, and there is no way to recover it if you forget it." msgstr "" +#: dashboard/pages/SetupPersona/Onboarding/index.tsx +msgid "Your Persona has been successfully created." +msgstr "" + #: dashboard/pages/SetupPersona/Onboarding/index.tsx #~ msgid "Your Persona is on" #~ msgstr "" #: dashboard/pages/SetupPersona/Onboarding/index.tsx -msgid "Your Persona is on " +#~ msgid "Your Persona is on " +#~ msgstr "" + +#: dashboard/pages/SetupPersona/Onboarding/index.tsx +msgid "Your Persona is on **ready 🚀**" msgstr "" #: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx @@ -3165,5 +3333,9 @@ msgstr "" #~ msgstr "" #: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx -msgid "Your Wallet is on " +#~ msgid "Your Wallet is on " +#~ msgstr "" + +#: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx +msgid "Your Wallet is on **ready 🚀**" msgstr "" diff --git a/packages/mask/shared-ui/locale/ja-JP.json b/packages/mask/shared-ui/locale/ja-JP.json index 30f542f10f27..2edb1c0b56b6 100644 --- a/packages/mask/shared-ui/locale/ja-JP.json +++ b/packages/mask/shared-ui/locale/ja-JP.json @@ -7,6 +7,16 @@ "y6VCOb": [["0"], " 分"], "MpnSqP": [["0"], " Pending"], "FKrzPv": [["count", "plural", { "one": ["#", " Wallet 🚀"], "other": ["#", " Wallets 🚀"] }]], + "5s6EhU": [ + [ + "count", + "plural", + { + "one": ["You have recovered **", "#", " Wallet 🚀**"], + "other": ["You have recovered **", "#", " Wallets 🚀**"] + } + ] + ], "yx3mb0": [ [ "decryptProgress", @@ -54,16 +64,18 @@ "pv5v6j": ["About Permit"], "k0USDt": ["Account connected.<0/><1/>Try to explore more features powered by Mask Network."], "R2K7XH": ["ソーシャルメディアで Web3 dApps の機能を探索してみてください。"], - "6c6xyD": ["アカウント"], + "6c6xyD": ["accounts"], "39ohdf": ["アクティビティ"], "I5kL4f": ["行動記録"], "m16xKo": ["追加"], "5YfW3S": ["Add an encrypted comment..."], "aTzTyw": ["資産を追加"], "M0FgOk": ["連絡先を追加する"], + "FAKSZG": ["Add google Drive"], "LP+1Z7": ["ネットワークを追加"], "68m9Nl": ["既存のグループに新しいアドレスを追加"], "1LkMSp": ["提案されたトークンを追加"], + "O8PsYe": ["Add the file to Chrome's database"], "GtJJAj": ["ウォレットを追加"], "uv94aG": ["ユーザーが追加しました"], "8RF/Sx": ["正常に追加されました。"], @@ -96,13 +108,16 @@ "iTiwqa": ["Asset is hidden."], "2jQko7": ["関連アカウント"], "CEk7Nc": ["6 文字以上"], + "gp6A8z": ["Authorization Failed"], "Wvnsx1": ["自動ロック"], "7QptC5": ["自動ロック時間"], "nTFx7o": ["アバターを設定しました"], "iH8pgl": ["Back"], + "npsHM5": ["Back Up to Google Drive"], + "V+1pjj": ["Back Up Your Data Your Way"], "rLgPvm": ["バックアップ"], "h7+V7K": ["バックアップと復元"], - "QrHM/A": ["バックアップがダウンロードされ、ローカルに正常に統合されました。"], + "QrHM/A": ["Backup downloaded and merged to local successfully."], "zp7Ha3": ["バックアップ失敗"], "5Cowlg": ["Backup is saved to Mask Cloud Service."], "qZ6p7p": ["Backup on ", ["0"]], @@ -111,7 +126,9 @@ "ERYJcj": ["バックアップパスワードは、大文字、小文字、特殊文字および数字を含む8-20文字でなければなりません。"], "hUF4dG": ["バックアップパスワードの設定が完了しました"], "UtKGok": ["ペルソナをバックアップする"], - "7Ry254": ["マスククラウドサービスにバックアップ"], + "+m7x4e": ["Backup Successful"], + "3iUAE7": ["Backup to Google Drive"], + "7Ry254": ["Backup to Mask Cloud Service"], "6IHgRq": ["Backup to the Cloud"], "QQPCqQ": ["ウォレットをバックアップする"], "fsBGk0": ["残高"], @@ -138,6 +155,9 @@ "tcHpvG": ["所有者変更"], "fDP2k4": ["支払いパスワードを変更する"], "IXbRbM": ["他のウォレットを選択してください"], + "lU6uRb": [ + "Choose from multiple backup options, now including encrypted storage via your authorized Google Drive for added security and flexibility." + ], "xH6cn+": ["トークンを選択"], "+adBn3": ["Chrome - external extension"], "EsKgLS": ["ここをクリックしてクイックスタートを切りましょう。"], @@ -193,6 +213,9 @@ "PjBWOL": ["あなたのペルソナを作成して始めましょう"], "WgawP2": ["Creating your"], "cEnmTp": ["Creating your "], + "L82H5Z": ["Creating your **identity**"], + "F7U8uz": ["Creating your **wallet**"], + "aF8kci": ["Creation Completed"], "Q2lUR2": ["通貨"], "OgPkDe": ["通貨記号(オプション)"], "oOQfsI": ["Current account is not the verifying account."], @@ -207,8 +230,9 @@ ], "8Tg/JR": ["カスタム"], "pvnfJD": ["ダーク"], - "Sp/me1": ["データ"], + "Sp/me1": ["data"], "HKH+W+": ["データ"], + "K8jCIB": ["Data backed up successfully!"], "3B4jmY": ["データの相関値"], "rAcOY1": [ "Data merged from Mask Cloud Service to local successfully. Re-enter your password to encrypt and upload the new backup to Mask Cloud Service." @@ -246,11 +270,11 @@ "XZ/B+f": ["NFTが見つかりませんか?"], "DPfwMq": ["完了!"], "mzI/c+": ["ダウンロード"], - "1vSYsG": ["バックアップをダウンロード"], + "1vSYsG": ["Download backup"], "1+6BOG": ["バックアップのダウンロード"], "9hg9mc": ["ダウンロード中"], "F8Wc3I": ["ここにファイルをドラッグ&ドロップしてください"], - "5Sa1Ss": ["メールアドレス"], + "5Sa1Ss": ["E-mail"], "ePK91l": ["編集"], "mQpWAe": ["連絡先を編集"], "iZLoa2": ["eg: X accounts, persona public keys, wallet addresses or ENS"], @@ -263,6 +287,7 @@ "w1ctdJ": ["Mask: 作成"], "MRIXE3": ["Encrypting your"], "zutir1": ["Encrypting your "], + "XB3tfc": ["Encrypting your **data**"], "Cz6Lx7": ["暗号化方法"], "N/fqDa": ["Ens または Address(0x)"], "mPxxVq": ["ガスの制限を入力してください"], @@ -282,9 +307,14 @@ "GS+Mus": ["エクスポート"], "7Bj3x9": ["失敗しました"], "SLEDBF": ["ウォレットを追加できませんでした。もう一度やり直してください。"], + "r92tNP": ["Failed to authorize Google Drive. Please try again."], "09vHB+": ["Failed to decrypt."], "jK7nvW": ["Failed to disconnect wallet"], + "9hzYBR": ["Failed to download and merge the backup: ", ["0"]], "0tkvsz": ["Failed to download and merge the backup."], + "etATpN": ["Failed to login: ", ["0"]], + "qDIxZ+": ["Failed to restore the backup from Google Drive to your browser. Please try again."], + "e3I0CA": ["Failed to restore the backup: ", ["0"]], "mrAv9J": ["ネットワークを保存できませんでした"], "ZsjtYe": ["アバターを設定できませんでした。"], "RWoEqV": ["Failed to transfer token: ", ["message"]], @@ -320,7 +350,9 @@ "fUn3xA": ["新しいウォレットアドレスを生成する"], "tdZPpe": ["Generating your"], "CiU2m/": ["Generating your "], + "RL5m+x": ["Generating your **accounts**"], "2p7WMm": ["Give permission to access <0/> your ", ["0"], "?"], + "w9Xmw/": ["Google Drive"], "76gPWk": ["了解"], "HqiAyF": ["Gwei(グワイ)"], "pu3rTn": ["GWEI"], @@ -339,7 +371,7 @@ "yx/fMc": ["高い"], "0caMy7": ["History"], "uip9JY": ["I wrote down those words in the correct order"], - "b5d759": ["アイデンティティ"], + "b5d759": ["identity"], "RRw7LE": ["アイデンティティ ID"], "/WfDJy": [ "If you forget payment password, you can type 'RESET' to reset your wallet. <0>Remember, this action will erase all your previous wallets." @@ -352,6 +384,7 @@ "fza4cg": ["ウォレットをインポート"], "HvDfH/": ["インポートされました"], "m3XvO+": ["インポートされたウォレット"], + "ANk/Zy": ["Incorrect Backup Password"], "a23gJr": ["バックアップパスワードが正しくありません。"], "bapItf": ["バックアップパスワードが正しくありません。"], "bassMa": ["クラウドバックアップのパスワードが正しくありません。もう一度やり直してください。"], @@ -392,9 +425,11 @@ "jygqM9": ["Loading account information..."], "EBC6hj": ["ローカルバックアップ"], "shPV5O": ["ローカルペルソナまたはウォレットのみ"], + "crVIc7": ["Locale Backup"], "KGHnSc": ["ウォレットをロックする"], "FgAxTj": ["ログアウト"], "kC3Q3d": ["Login to Mask Cloud"], + "nOhz3x": ["Logout"], "NkgvWN": ["ログアウトに失敗しました。"], "o4Iu2W": ["ログアウト完了"], "nTWWCZ": ["低い"], @@ -404,6 +439,7 @@ ], "lET9my": ["マスクには次の権限が必要です"], "siroPf": ["Mask Network"], + "jhoAzY": ["Mask Network Cloud"], "lWOC+h": ["Mask Network requires you to authorize the following websites before using it."], "HsoakN": ["masknetwork"], "CK1KXz": ["最大"], @@ -420,8 +456,10 @@ "sQJ3RN": ["最大優先料金がネットワーク状況に対して低すぎます。"], "ITBQO3": ["最大優先手数料は0GWEIより大きくなければなりません"], "agPptk": ["中間"], + "lPsa94": ["Merge Completed"], "RH8jSA": ["ローカルデータベースにデータを統合"], - "QTomF0": ["ローカルに統合"], + "E6YUtc": ["Merge to Browser"], + "QTomF0": ["Merge to local"], "xDAtGP": ["メッセージ"], "pGElS5": ["ニーモニック"], "yFrxQj": ["ニーモニック単語"], @@ -483,8 +521,8 @@ "YKSmxE": [ "Other social networking platforms, such as <0>Instagram, <1>Facebook, and <2>Minds, do not have a verified relationship like X's Next.ID verified connection.<3/><4/>When connecting a persona with an account on these platforms, they only support sending encrypted posts." ], - "MXOdMY": ["バックアップを上書き"], - "p2xE4C": ["既存のバックアップを上書き"], + "MXOdMY": ["Overwrite Backup"], + "p2xE4C": ["Overwrite current backup"], "8ZsakT": ["パスワード"], "9w2hgY": ["手動でペーストする"], "GAvnvl": ["支払いパスワードの設定"], @@ -547,9 +585,10 @@ "3AP6p1": ["Public Key: <0>", ["publicKey"], ""], "82+n6o": ["Quote Route"], "AV+9wg": ["再入力"], - "TZ0npN": ["準備完了🚀"], + "TZ0npN": ["ready 🚀"], "nVT2pJ": ["realMaskNetwork"], "lDgVWA": ["受取"], + "OkofjH": ["Recover"], "XC7RGa": ["データを復元する"], "UBzbea": ["ウォレットを復元する"], "P9wzG/": ["復旧"], @@ -571,8 +610,10 @@ "nvAt0H": ["リソース"], "yKu/3Y": ["復元"], "Z3+V9p": ["Restore backup failed."], + "nGl2Ng": ["Restore Completed"], "AKLbfQ": ["データベースの復元"], "uM6jnS": ["復元に失敗しました"], + "KFwID2": ["Restore Failed"], "/LkuGq": ["以前のデータベースバックアップから復元します。"], "KisOjk": ["復元またはログイン"], "6gRgw8": ["再試行"], @@ -590,7 +631,7 @@ "nTif4K": ["選択してウォレットに接続"], "k/sb6z": ["言語を選択"], "LSwUJb": ["Select Liquidity"], - "RjF5dk": ["バックアップの内容を選択します"], + "RjF5dk": ["Select the contents of the backup"], "PI/VCJ": ["このサイトで使用するウォレットを選択してください。信頼しないウェブサイトに接続しないでください。"], "a1SmQh": ["ウォレットを選択"], "JlFcis": ["送信"], @@ -608,7 +649,7 @@ "iJLEZF": ["方法を確認"], "nOCyT5": ["$1未満のトークンを表示"], "c+Fnce": ["サイン"], - "mErq7F": ["新規登録"], + "mErq7F": ["Sign Up"], "t3rUZr": ["サインインリクエスト"], "py6hU8": ["署名リクエスト"], "9KKhJV": ["署名中..."], @@ -653,6 +694,9 @@ "VdhBp2": ["chainIDは現在接続されているものと等しくありません。"], "h3Vpnw": ["このコードは正しくありません"], "7w1rTm": ["The download link is expired"], + "oYkran": [ + "The Mask Network Cloud Backup feature will be deactivated on April 30, 2025. Please use alternative cloud backup services or local backup solutions." + ], "o+zDNQ": ["The mnemonic word has been copied, please keep it in a safe place."], "yRuvmU": ["The mnemonic words has been copied, please keep it in a safe place."], "thX7xs": [ @@ -775,7 +819,7 @@ "vVEene": ["View your Tokens and NFTs"], "kbfp5m": ["表示対象:"], "PTXNyo": ["Waiting for ", ["providerType"]], - "6XyieG": ["ウォレット"], + "6XyieG": ["wallet"], "VECuJk": ["ウォレットアカウント"], "KtMMzG": ["Wallet disconnected"], "Kl9gHp": ["ウォレットグループ", ["0"]], @@ -790,9 +834,10 @@ "EGWr+Q": ["Web3 プロフィールカード"], "On0aF2": ["ウェブサイト"], "CWsYB3": ["おかえりなさい"], - "m74yjp": ["マスククラウドサービスへようこそ"], + "m74yjp": ["Welcome to Mask Cloud Services"], "hEpXzO": ["Mask Networkへようこそ"], "fFYJ8f": ["Mask Networkへようこそ"], + "OLUEnY": ["when you click Add Google Drive button,you will be forwarded to Google authorization pages."], "Qbo7Ev": ["ニーモニックワードを書き留めてください"], "f5AidZ": ["Write down recovery phrase"], "yGyJ1l": [ @@ -802,6 +847,7 @@ "dyqtoj": ["You have recovered"], "V8x6o5": ["You have recovered "], "QU9aqK": ["You have signed with your wallet."], + "PeT3a5": ["You have successfully restored the backup from Google Drive to your browser."], "zkEW09": [ "You have verified your cloud password and recovered your backup. Do you want to let your cloud password and local backup password be the same?" ], @@ -810,12 +856,17 @@ "FnQek5": [ "このサイトへの接続は暗号化されていないため、敵対的な第三者によって変更されます。このリクエストを拒否することを強くお勧めします。" ], + "UDKbPj": ["Your file has been successfully merged into the browser data."], + "S2JNMm": ["Your file has been successfully restore into the browser data."], "Q68Nuc": [ "Your payment password encrypts wallet data and is needed to unlocking the wallet, transaction confirmations and signing. The password is never stored, and there is no way to recover it if you forget it." ], + "4EN5JL": ["Your Persona has been successfully created."], "N19nSk": ["Your Persona is on"], "WC7pDz": ["Your Persona is on "], + "PDW/HG": ["Your Persona is on **ready 🚀**"], "0kr+x1": ["Your Wallet is on"], - "v7OL2k": ["Your Wallet is on "] + "v7OL2k": ["Your Wallet is on "], + "wCtp6y": ["Your Wallet is on **ready 🚀**"] } } diff --git a/packages/mask/shared-ui/locale/ja-JP.po b/packages/mask/shared-ui/locale/ja-JP.po index 5c070b9bbbe4..d4e6dfad07a9 100644 --- a/packages/mask/shared-ui/locale/ja-JP.po +++ b/packages/mask/shared-ui/locale/ja-JP.po @@ -3,7 +3,7 @@ msgstr "" "Project-Id-Version: mask-network\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2025-01-08 06:53\n" +"PO-Revision-Date: 2025-04-10 05:53\n" "Last-Translator: \n" "Language: ja_JP\n" "Language-Team: Japanese\n" @@ -46,7 +46,11 @@ msgid "{0} Pending" msgstr "" #: dashboard/pages/SetupPersona/Onboarding/index.tsx -msgid "{count, plural, one {# Wallet 🚀} other {# Wallets 🚀}}" +#~ msgid "{count, plural, one {# Wallet 🚀} other {# Wallets 🚀}}" +#~ msgstr "" + +#: dashboard/pages/SetupPersona/Onboarding/index.tsx +msgid "{count, plural, one {You have recovered **# Wallet 🚀**} other {You have recovered **# Wallets 🚀**}}" msgstr "" #: content-script/components/InjectedComponents/DecryptedPost/DecryptPostAwaiting.tsx @@ -132,8 +136,8 @@ msgstr "ソーシャルメディアで Web3 dApps の機能を探索してみて #: dashboard/pages/SetupPersona/Onboarding/index.tsx #: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx -msgid "accounts" -msgstr "アカウント" +#~ msgid "accounts" +#~ msgstr "" #: popups/pages/Wallet/components/WalletAssets/index.tsx msgid "Activities" @@ -162,6 +166,10 @@ msgstr "資産を追加" msgid "Add Contact" msgstr "連絡先を追加する" +#: dashboard/components/GoogleDriveLogin.tsx +msgid "Add google Drive" +msgstr "" + #: popups/pages/Wallet/NetworkManagement/index.tsx #: popups/pages/Wallet/EditNetwork/index.tsx msgid "Add Network" @@ -175,6 +183,10 @@ msgstr "既存のグループに新しいアドレスを追加" msgid "Add Suggested Token" msgstr "提案されたトークンを追加" +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx +msgid "Add the file to Chrome's database" +msgstr "" + #: popups/pages/Wallet/components/StartUp/index.tsx #: popups/pages/Wallet/SwitchWallet/index.tsx #: popups/pages/Wallet/CreateWallet/index.tsx @@ -258,8 +270,8 @@ msgid "Approve amount" msgstr "承認金額" #: dashboard/pages/SetupPersona/CloudBackupPreview/index.tsx -msgid "Are you sure to overwrite the backups stored on Mask Cloud Service?" -msgstr "" +#~ msgid "Are you sure to overwrite the backups stored on Mask Cloud Service?" +#~ msgstr "" #. placeholder {0}: formatEthereumAddress(wallet.identity, 4) #: popups/components/ConnectedWallet/index.tsx @@ -292,6 +304,10 @@ msgstr "関連アカウント" msgid "At least 6 characters" msgstr "6 文字以上" +#: dashboard/components/GoogleDriveLogin.tsx +msgid "Authorization Failed" +msgstr "" + #: popups/pages/Wallet/WalletSettings/AutoLock.tsx msgid "Auto-lock" msgstr "自動ロック" @@ -305,13 +321,24 @@ msgid "Avatar set successfully" msgstr "アバターを設定しました" #: content-script/components/shared/SelectRecipients/SelectRecipientsDialog.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/Preview.tsx #: dashboard/pages/CreateMaskWallet/CreateMnemonic/index.tsx #: popups/pages/Personas/ExportPrivateKey/index.tsx #: popups/pages/Personas/AccountDetail/UI.tsx msgid "Back" msgstr "" -#: dashboard/pages/SetupPersona/CloudBackupPreview/index.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/GoogleDrive.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/GoogleDrive.tsx +#~ msgid "Back Up to Google Drive" +#~ msgstr "" + +#: dashboard/pages/SetupPersona/Backup/index.tsx +msgid "Back Up Your Data Your Way" +msgstr "" + +#: dashboard/pages/SetupPersona/Backup/Cloud/GoogleDrive.tsx +#: dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx #: popups/pages/Personas/Logout/index.tsx #: popups/modals/SwitchPersonaModal/index.tsx msgid "Backup" @@ -322,16 +349,16 @@ msgid "Backup & Recovery" msgstr "バックアップと復元" #: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx -msgid "Backup downloaded and merged to local successfully." -msgstr "バックアップがダウンロードされ、ローカルに正常に統合されました。" +#~ msgid "Backup downloaded and merged to local successfully." +#~ msgstr "" #: dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx msgid "Backup Failed" msgstr "バックアップ失敗" #: dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx -msgid "Backup is saved to Mask Cloud Service." -msgstr "" +#~ msgid "Backup is saved to Mask Cloud Service." +#~ msgstr "" #. placeholder {0}: user.localBackupAt #. placeholder {0}: user.cloudBackupAt @@ -340,13 +367,13 @@ msgstr "" msgid "Backup on {0}" msgstr "" -#: dashboard/components/Restore/RestorePersonaFromLocal.tsx -#: dashboard/components/Restore/RestoreFromCloud/ConfirmBackupInfo.tsx +#: dashboard/pages/SetupPersona/Recovery/Local.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/ConfirmBackupInfo.tsx msgid "Backup password" msgstr "バックアップパスワード" -#: dashboard/pages/SetupPersona/LocalBackup/index.tsx -#: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx +#: dashboard/pages/SetupPersona/Backup/Local.tsx +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx #: dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx #: popups/pages/Settings/index.tsx #: popups/modals/SetBackupPasswordModal/index.tsx @@ -368,9 +395,18 @@ msgstr "バックアップパスワードの設定が完了しました" msgid "Backup Persona" msgstr "ペルソナをバックアップする" +#: dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx +msgid "Backup Successful" +msgstr "" + +#: dashboard/pages/SetupPersona/Backup/Cloud/GoogleDrive.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/GoogleDrive.tsx +msgid "Backup to Google Drive" +msgstr "" + #: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx -msgid "Backup to Mask Cloud Service" -msgstr "マスククラウドサービスにバックアップ" +#~ msgid "Backup to Mask Cloud Service" +#~ msgstr "" #: dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx msgid "Backup to the Cloud" @@ -437,7 +473,6 @@ msgstr "" #: content-script/components/InjectedComponents/SelectPeopleDialog.tsx #: dashboard/pages/SetupPersona/Welcome/index.tsx #: dashboard/pages/SetupPersona/Permissions/index.tsx -#: dashboard/pages/SetupPersona/CloudBackupPreview/index.tsx #: dashboard/modals/ConfirmModal/index.tsx #: dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx #: dashboard/components/Restore/ConfirmSynchronizePasswordDialog.tsx @@ -510,6 +545,10 @@ msgstr "支払いパスワードを変更する" msgid "Choose another wallet" msgstr "他のウォレットを選択してください" +#: dashboard/pages/SetupPersona/Backup/index.tsx +msgid "Choose from multiple backup options, now including encrypted storage via your authorized Google Drive for added security and flexibility." +msgstr "" + #: popups/modals/ChooseToken/index.tsx msgid "Choose Token" msgstr "トークンを選択" @@ -535,6 +574,7 @@ msgid "Close" msgstr "閉じる" #: dashboard/pages/SetupPersona/Recovery/index.tsx +#: dashboard/pages/SetupPersona/Backup/index.tsx #: dashboard/components/Restore/ConfirmSynchronizePasswordDialog.tsx #: popups/pages/Settings/index.tsx msgid "Cloud Backup" @@ -548,12 +588,11 @@ msgstr "コレクティブ" msgid "Coming soon" msgstr "近日公開" +#: dashboard/pages/SetupPersona/Recovery/Local.tsx #: dashboard/components/Restore/RestoreWalletFromLocal.tsx -#: dashboard/components/Restore/RestorePersonaFromLocal.tsx msgid "Completed" msgstr "完了しました" -#: dashboard/pages/SetupPersona/CloudBackupPreview/index.tsx #: dashboard/modals/ConfirmModal/index.tsx #: dashboard/components/Restore/ConfirmSynchronizePasswordDialog.tsx #: popups/pages/Wallet/components/DisconnectModal/index.tsx @@ -607,8 +646,6 @@ msgstr "" msgid "Confirm to hide {name}? You can redisplay it by re-adding this NFT at any time." msgstr "" -#: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx -#: dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx #: popups/pages/Personas/ConnectWallet/index.tsx msgid "Congratulations" msgstr "おめでとうございます!" @@ -709,16 +746,18 @@ msgstr "コンタクト" #: dashboard/pages/SignUp/steps/PersonaNameUI.tsx #: dashboard/pages/SetupPersona/SignUp/index.tsx +#: dashboard/pages/SetupPersona/Recovery/PrivateKey.tsx +#: dashboard/pages/SetupPersona/Recovery/Phrase.tsx +#: dashboard/pages/SetupPersona/Recovery/Local.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/PhoneField.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/EmailField.tsx #: dashboard/pages/SetupPersona/Mnemonic/index.tsx -#: dashboard/pages/SetupPersona/CloudBackup/index.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/MaskNetwork.tsx #: dashboard/pages/CreateMaskWallet/CreateWalletForm/index.tsx #: dashboard/pages/CreateMaskWallet/AddDeriveWallet/index.tsx #: dashboard/components/Restore/RestoreWalletFromLocal.tsx -#: dashboard/components/Restore/RestorePersonaFromLocal.tsx #: dashboard/components/Restore/RestoreFromPrivateKey.tsx #: dashboard/components/Restore/RestoreFromMnemonic.tsx -#: dashboard/components/Restore/RestoreFromCloud/PhoneField.tsx -#: dashboard/components/Restore/RestoreFromCloud/EmailField.tsx msgid "Continue" msgstr "続行" @@ -774,6 +813,7 @@ msgstr "新規Mask IDを作成" msgid "Create Password" msgstr "パスワードを作成" +#: dashboard/pages/SetupPersona/Recovery/index.tsx #: popups/pages/Personas/Home/UI.tsx msgid "Create Persona" msgstr "ペルソナを作成" @@ -789,7 +829,19 @@ msgstr "あなたのペルソナを作成して始めましょう" #: dashboard/pages/SetupPersona/Onboarding/index.tsx #: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx -msgid "Creating your " +#~ msgid "Creating your " +#~ msgstr "" + +#: dashboard/pages/SetupPersona/Onboarding/index.tsx +msgid "Creating your **identity**" +msgstr "" + +#: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx +msgid "Creating your **wallet**" +msgstr "" + +#: dashboard/pages/SetupPersona/Onboarding/index.tsx +msgid "Creation Completed" msgstr "" #: popups/pages/Wallet/WalletSettings/ChangeCurrency.tsx @@ -830,23 +882,27 @@ msgstr "ダーク" #: dashboard/pages/SetupPersona/Onboarding/index.tsx #: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx -msgid "data" -msgstr "データ" +#~ msgid "data" +#~ msgstr "" #: popups/pages/Wallet/Interaction/TransactionRequest.tsx msgid "Data" msgstr "データ" +#: dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx +msgid "Data backed up successfully!" +msgstr "" + #: popups/pages/Settings/index.tsx msgid "Data correlation" msgstr "データの相関値" #: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx -msgid "Data merged from Mask Cloud Service to local successfully. Re-enter your password to encrypt and upload the new backup to Mask Cloud Service." -msgstr "" +#~ msgid "Data merged from Mask Cloud Service to local successfully. Re-enter your password to encrypt and upload the new backup to Mask Cloud Service." +#~ msgstr "" -#: dashboard/components/Restore/RestoreFromCloud/ConfirmBackupInfo.tsx -#: dashboard/components/Restore/RestoreFromCloud/ConfirmBackupInfo.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/ConfirmBackupInfo.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/ConfirmBackupInfo.tsx msgid "Decrypt failed, please check password" msgstr "復号に失敗しました。パスワードを確認してください。" @@ -951,18 +1007,20 @@ msgid "Done" msgstr "完了!" #: content-script/components/InjectedComponents/AutoPasteFailedDialog.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/Preview.tsx +#: dashboard/components/GoogleDriveFileTable.tsx msgid "Download" msgstr "ダウンロード" #: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx -msgid "Download backup" -msgstr "バックアップをダウンロード" +#~ msgid "Download backup" +#~ msgstr "" -#: dashboard/pages/SetupPersona/LocalBackup/index.tsx +#: dashboard/pages/SetupPersona/Backup/Local.tsx msgid "Download Backup" msgstr "バックアップのダウンロード" -#: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx msgid "Downloading" msgstr "ダウンロード中" @@ -971,8 +1029,8 @@ msgid "Drag & Drop your file here" msgstr "ここにファイルをドラッグ&ドロップしてください" #: dashboard/pages/SetupPersona/CloudBackup/index.tsx -msgid "E-mail" -msgstr "メールアドレス" +#~ msgid "E-mail" +#~ msgstr "" #: popups/pages/Wallet/ContactList/index.tsx msgid "Edit" @@ -987,13 +1045,14 @@ msgstr "連絡先を編集" msgid "eg: X accounts, persona public keys, wallet addresses or ENS" msgstr "" -#: dashboard/pages/SetupPersona/CloudBackup/EmailForm.tsx -#: dashboard/components/Restore/RestoreFromCloud/EmailField.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/EmailField.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/MaskNetwork.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/EmailForm.tsx msgid "Email" msgstr "メールアドレス" -#: dashboard/pages/SetupPersona/CloudBackup/EmailForm.tsx -#: dashboard/components/Restore/RestoreFromCloud/EmailField.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/EmailField.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/EmailForm.tsx msgid "Email verification code" msgstr "電子メール検証コード" @@ -1024,7 +1083,12 @@ msgstr "Mask: 作成" #: dashboard/pages/SetupPersona/Onboarding/index.tsx #: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx -msgid "Encrypting your " +#~ msgid "Encrypting your " +#~ msgstr "" + +#: dashboard/pages/SetupPersona/Onboarding/index.tsx +#: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx +msgid "Encrypting your **data**" msgstr "" #: content-script/components/CompositionDialog/EncryptionMethodSelector.tsx @@ -1110,6 +1174,10 @@ msgstr "失敗しました" msgid "Failed to add the wallet, please try again." msgstr "ウォレットを追加できませんでした。もう一度やり直してください。" +#: dashboard/components/GoogleDriveLogin.tsx +msgid "Failed to authorize Google Drive. Please try again." +msgstr "" + #: content-script/components/InjectedComponents/DecryptedPost/DecryptPostFailed.tsx msgid "Failed to decrypt." msgstr "" @@ -1118,8 +1186,26 @@ msgstr "" msgid "Failed to disconnect wallet" msgstr "" +#. placeholder {0}: (err as Error).message +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx +msgid "Failed to download and merge the backup: {0}" +msgstr "" + #: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx -msgid "Failed to download and merge the backup." +#~ msgid "Failed to download and merge the backup." +#~ msgstr "" + +#: dashboard/components/GoogleDriveLogin.tsx +#~ msgid "Failed to login: {0}" +#~ msgstr "" + +#: dashboard/pages/SetupPersona/Recovery/Cloud/GoogleDrive.tsx +msgid "Failed to restore the backup from Google Drive to your browser. Please try again." +msgstr "" + +#. placeholder {0}: (err as Error).message +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx +msgid "Failed to restore the backup: {0}" msgstr "" #: popups/pages/Wallet/EditNetwork/index.tsx @@ -1269,7 +1355,12 @@ msgstr "新しいウォレットアドレスを生成する" #: dashboard/pages/SetupPersona/Onboarding/index.tsx #: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx -msgid "Generating your " +#~ msgid "Generating your " +#~ msgstr "" + +#: dashboard/pages/SetupPersona/Onboarding/index.tsx +#: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx +msgid "Generating your **accounts**" msgstr "" #. placeholder {0}: contract?.symbol || '' @@ -1279,6 +1370,13 @@ msgstr "" msgid "Give permission to access <0/> your {0}?" msgstr "" +#: dashboard/pages/SetupPersona/Recovery/Cloud/index.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/GoogleDrive.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/index.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/GoogleDrive.tsx +msgid "Google Drive" +msgstr "" + #: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx msgid "Got it" msgstr "了解" @@ -1344,8 +1442,8 @@ msgid "I wrote down those words in the correct order" msgstr "" #: dashboard/pages/SetupPersona/Onboarding/index.tsx -msgid "identity" -msgstr "アイデンティティ" +#~ msgid "identity" +#~ msgstr "" #: dashboard/pages/SetupPersona/Mnemonic/ComponentToPrint.tsx msgid "Identity ID" @@ -1389,17 +1487,21 @@ msgstr "インポートされました" msgid "Imported Wallets" msgstr "インポートされたウォレット" +#: dashboard/hooks/useBackupFormState.ts +msgid "Incorrect Backup Password" +msgstr "" + #: popups/modals/VerifyBackupPasswordModal/index.tsx #: popups/modals/ChangeBackupPasswordModal/index.tsx msgid "Incorrect backup password." msgstr "バックアップパスワードが正しくありません。" -#: dashboard/components/Restore/RestorePersonaFromLocal.tsx +#: dashboard/pages/SetupPersona/Recovery/Local.tsx msgid "Incorrect Backup Password." msgstr "バックアップパスワードが正しくありません。" -#: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx -#: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx msgid "Incorrect cloud backup password, please try again." msgstr "クラウドバックアップのパスワードが正しくありません。もう一度やり直してください。" @@ -1417,7 +1519,7 @@ msgstr "" msgid "Incorrect password" msgstr "パスワードが間違っています" -#: dashboard/pages/SetupPersona/LocalBackup/index.tsx +#: dashboard/pages/SetupPersona/Backup/Local.tsx #: dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx #: dashboard/hooks/useBackupFormState.ts #: dashboard/hooks/useBackupFormState.ts @@ -1425,7 +1527,6 @@ msgstr "パスワードが間違っています" #: dashboard/hooks/useBackupFormState.ts #: dashboard/hooks/useBackupFormState.ts #: dashboard/hooks/useBackupFormState.ts -#: dashboard/hooks/useBackupFormState.ts msgid "Incorrect Password" msgstr "パスワードが間違っています" @@ -1438,12 +1539,12 @@ msgstr "パスワードが正しくありません。" msgid "Incorrect Payment Password." msgstr "現在のパスワードが正しくありません。" -#: dashboard/pages/SetupPersona/Recovery/index.tsx +#: dashboard/pages/SetupPersona/Recovery/PrivateKey.tsx #: dashboard/pages/CreateMaskWallet/Recovery/index.tsx msgid "Incorrect Private Key" msgstr "IDコードが間違っています" -#: dashboard/pages/SetupPersona/Recovery/index.tsx +#: dashboard/pages/SetupPersona/Recovery/Phrase.tsx msgid "Incorrect recovery phrase." msgstr "アイデンティティニーモニックが正しくありません。" @@ -1456,6 +1557,7 @@ msgstr "ウォレットアドレスが正しくありません。" msgid "Incorrect words selected. Please try again!" msgstr "" +#: dashboard/pages/SetupPersona/Recovery/PrivateKey.tsx #: dashboard/components/Restore/RestoreFromPrivateKey.tsx msgid "Input your Private Key" msgstr "秘密鍵を入力してください" @@ -1473,12 +1575,13 @@ msgstr "手数料付けるには残高が足りません" msgid "Invalid Block Explorer URL." msgstr "無効なブロックエクスプローラのURLです。" -#: dashboard/pages/SetupPersona/CloudBackup/EmailForm.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/EmailForm.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/CloudBackupFormContext.ts #: dashboard/contexts/CloudBackupFormContext.tsx msgid "Invalid email address format." msgstr "メールアドレスが正しくありません。" -#: dashboard/components/Restore/RestoreFromCloud/EmailField.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/EmailField.tsx msgid "Invalid email address." msgstr "" @@ -1486,7 +1589,7 @@ msgstr "" msgid "Invalid number" msgstr "無効な番号です" -#: dashboard/components/Restore/RestoreFromCloud/PhoneField.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/PhoneField.tsx msgid "Invalid phone number, please check and try again." msgstr "電話番号が無効です。確認してもう一度お試しください。" @@ -1494,8 +1597,8 @@ msgstr "電話番号が無効です。確認してもう一度お試しくださ msgid "Invalid RPC URL." msgstr "RPCのURLが無効です。" -#: dashboard/components/Restore/RestoreFromCloud/PhoneField.tsx -#: dashboard/components/Restore/RestoreFromCloud/EmailField.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/PhoneField.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/EmailField.tsx msgid "Invalid verification code." msgstr "認証コードが無効です。" @@ -1576,6 +1679,10 @@ msgstr "ローカルバックアップ" msgid "Local persona or wallet only" msgstr "ローカルペルソナまたはウォレットのみ" +#: dashboard/pages/SetupPersona/Backup/index.tsx +msgid "Locale Backup" +msgstr "" + #: popups/pages/Wallet/SwitchWallet/index.tsx msgid "Lock Wallet" msgstr "ウォレットをロックする" @@ -1587,7 +1694,13 @@ msgid "Log out" msgstr "ログアウト" #: dashboard/pages/SetupPersona/CloudBackup/index.tsx -msgid "Login to Mask Cloud" +#~ msgid "Login to Mask Cloud" +#~ msgstr "" + +#: dashboard/pages/SetupPersona/Recovery/Cloud/GoogleDrive.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/Preview.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/GoogleDrive.tsx +msgid "Logout" msgstr "" #: popups/pages/Personas/Logout/index.tsx @@ -1618,9 +1731,15 @@ msgstr "マスクには次の権限が必要です" #: content-script/components/InjectedComponents/ToolboxUnstyled.tsx #: content-script/components/InjectedComponents/PostDialogHint.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/index.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/index.tsx msgid "Mask Network" msgstr "" +#: dashboard/pages/SetupPersona/Backup/Cloud/Preview.tsx +msgid "Mask Network Cloud" +msgstr "" + #: content-script/components/InjectedComponents/PermissionBoundary.tsx msgid "Mask Network requires you to authorize the following websites before using it." msgstr "" @@ -1692,15 +1811,23 @@ msgstr "最大優先手数料は0GWEIより大きくなければなりません" msgid "Medium" msgstr "中間" -#: dashboard/pages/SetupPersona/CloudBackupPreview/index.tsx -#: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx -#: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx +msgid "Merge Completed" +msgstr "" + +#: dashboard/pages/SetupPersona/Backup/Cloud/Preview.tsx +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx msgid "Merge data to local database" msgstr "ローカルデータベースにデータを統合" +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx +#: dashboard/components/GoogleDriveFileTable.tsx +msgid "Merge to Browser" +msgstr "" + #: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx -msgid "Merge to local" -msgstr "ローカルに統合" +#~ msgid "Merge to local" +#~ msgstr "" #: popups/components/SignRequestInfo/index.tsx msgid "Message" @@ -1715,15 +1842,15 @@ msgstr "ニーモニック" msgid "Mnemonic word" msgstr "ニーモニック単語" -#: dashboard/pages/SetupPersona/CloudBackup/index.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/MaskNetwork.tsx msgid "Mobile" msgstr "モバイル" -#: dashboard/pages/SetupPersona/CloudBackup/PhoneForm.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/PhoneForm.tsx msgid "Mobile number" msgstr "携帯番号" -#: dashboard/components/Restore/RestoreFromCloud/PhoneField.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/PhoneField.tsx msgid "Mobile verification code" msgstr "モバイル認証コード" @@ -1836,7 +1963,8 @@ msgstr "" msgid "No back up" msgstr "バックアップはありません" -#: dashboard/pages/SetupPersona/CloudBackupPreview/index.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/Preview.tsx +#: dashboard/components/GoogleDriveFileTable.tsx msgid "No backups found" msgstr "バックアップが見つかりません" @@ -1949,13 +2077,12 @@ msgid "Other social networking platforms, such as <0>Instagram, <1>Facebook, msgstr "" #: dashboard/pages/SetupPersona/CloudBackupPreview/index.tsx -#: dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx -msgid "Overwrite Backup" -msgstr "バックアップを上書き" +#~ msgid "Overwrite Backup" +#~ msgstr "" #: dashboard/pages/SetupPersona/CloudBackupPreview/index.tsx -msgid "Overwrite current backup" -msgstr "既存のバックアップを上書き" +#~ msgid "Overwrite current backup" +#~ msgstr "" #: popups/modals/VerifyBackupPasswordModal/index.tsx #: popups/modals/SetBackupPasswordModal/index.tsx @@ -1967,7 +2094,7 @@ msgstr "パスワード" msgid "Paste manually" msgstr "手動でペーストする" -#: dashboard/pages/SetupPersona/LocalBackup/index.tsx +#: dashboard/pages/SetupPersona/Backup/Local.tsx #: dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx #: popups/pages/Wallet/SetPaymentPassword/index.tsx #: popups/modals/WalletRemoveModal/index.tsx @@ -2048,7 +2175,7 @@ msgstr "" msgid "Personas" msgstr "ペルソナ" -#: dashboard/pages/SetupPersona/CloudBackup/PhoneForm.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/PhoneForm.tsx msgid "Phone verification code" msgstr "モバイル認証コード" @@ -2075,7 +2202,7 @@ msgstr "" msgid "Please enter backup password to export persona private key." msgstr "ペルソナ秘密鍵をエクスポートするには、バックアップパスワードを入力してください。" -#: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx msgid "Please enter cloud backup password to download file." msgstr "ファイルをダウンロードするには、クラウドバックアップパスワードを入力してください。" @@ -2103,8 +2230,6 @@ msgid "Please note: This Persona {0} is the management account of above listed S msgstr "" #: dashboard/pages/SetupPersona/Recovery/index.tsx -#: dashboard/pages/SetupPersona/LocalBackup/index.tsx -#: dashboard/pages/SetupPersona/CloudBackupPreview/index.tsx msgid "Please select the appropriate method to restore your personal data." msgstr "12単語の復元フレーズは、ペルソナデータを回復するために使用されます。" @@ -2134,8 +2259,8 @@ msgid "Please switch to <0>@{expectAccount} to continue the account verifica msgstr "" #: dashboard/pages/SetupPersona/CloudBackup/index.tsx -msgid "Please use your frequently used email or phone number for backup." -msgstr "" +#~ msgid "Please use your frequently used email or phone number for backup." +#~ msgstr "" #: dashboard/pages/CreateMaskWallet/CreateMnemonic/index.tsx msgid "Please write down or copy these words and save them in a secure place." @@ -2213,8 +2338,8 @@ msgstr "再入力" #: dashboard/pages/SetupPersona/Onboarding/index.tsx #: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx -msgid "ready 🚀" -msgstr "準備完了🚀" +#~ msgid "ready 🚀" +#~ msgstr "" #: content-script/components/CompositionDialog/useSubmit.ts msgid "realMaskNetwork" @@ -2225,6 +2350,11 @@ msgstr "" msgid "Receive" msgstr "受取" +#: dashboard/pages/SetupPersona/Recovery/Cloud/GoogleDrive.tsx +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx +msgid "Recover" +msgstr "" + #: dashboard/pages/SetupPersona/Recovery/index.tsx msgid "Recover your data" msgstr "データを復元する" @@ -2292,13 +2422,13 @@ msgstr "リクエストは以前には有効ではありません" msgid "Request Source" msgstr "リクエストソース" -#: dashboard/components/Restore/RestorePersonaFromLocal.tsx +#: dashboard/pages/SetupPersona/Recovery/Local.tsx msgid "Reselect" msgstr "選びなおす" #: content-script/components/InjectedComponents/SetupGuide/VerifyNextID.tsx -#: dashboard/pages/SetupPersona/CloudBackup/PhoneForm.tsx -#: dashboard/pages/SetupPersona/CloudBackup/EmailForm.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/PhoneForm.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/EmailForm.tsx msgid "Resend" msgstr "再送信" @@ -2310,24 +2440,32 @@ msgstr "ウォレットをリセットする" msgid "Resource" msgstr "リソース" -#: dashboard/components/Restore/RestorePersonaFromLocal.tsx -#: dashboard/components/Restore/RestoreFromCloud/index.tsx -#: dashboard/components/Restore/RestoreFromCloud/ConfirmBackupInfo.tsx +#: dashboard/pages/SetupPersona/Recovery/Local.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/MaskNetwork.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/ConfirmBackupInfo.tsx msgid "Restore" msgstr "復元" -#: dashboard/components/Restore/RestorePersonaFromLocal.tsx +#: dashboard/pages/SetupPersona/Recovery/Local.tsx msgid "Restore backup failed." msgstr "" +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx +msgid "Restore Completed" +msgstr "" + #: popups/pages/Settings/index.tsx msgid "Restore Database" msgstr "データベースの復元" -#: dashboard/components/Restore/RestoreFromCloud/index.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/MaskNetwork.tsx msgid "Restore failed" msgstr "復元に失敗しました" +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx +msgid "Restore Failed" +msgstr "" + #: popups/pages/Settings/index.tsx msgid "Restore from a previous database backup" msgstr "以前のデータベースバックアップから復元します。" @@ -2399,8 +2537,8 @@ msgid "Select Liquidity" msgstr "" #: dashboard/pages/SetupPersona/LocalBackup/index.tsx -msgid "Select the contents of the backup" -msgstr "バックアップの内容を選択します" +#~ msgid "Select the contents of the backup" +#~ msgstr "" #: popups/pages/Wallet/Interaction/PermissionRequest.tsx msgid "Select the wallet(s) to use on this site. You should not connect to website you don't trust." @@ -2411,8 +2549,8 @@ msgid "Select Wallet" msgstr "ウォレットを選択" #: content-script/components/InjectedComponents/SetupGuide/VerifyNextID.tsx -#: dashboard/pages/SetupPersona/CloudBackup/PhoneForm.tsx -#: dashboard/pages/SetupPersona/CloudBackup/EmailForm.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/PhoneForm.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/EmailForm.tsx #: popups/pages/Wallet/components/ActivityList/ActivityItem.tsx #: popups/pages/Wallet/components/ActionGroup/index.tsx #: popups/pages/Wallet/Transfer/index.tsx @@ -2486,8 +2624,8 @@ msgid "Sign" msgstr "サイン" #: dashboard/pages/SetupPersona/Recovery/index.tsx -msgid "Sign Up" -msgstr "新規登録" +#~ msgid "Sign Up" +#~ msgstr "" #: popups/components/SignRequestInfo/index.tsx msgid "Sign-in Request" @@ -2614,8 +2752,7 @@ msgstr "サポートされるサイト" msgid "Swap" msgstr "" -#: dashboard/pages/SetupPersona/CloudBackupPreview/index.tsx -#: dashboard/pages/SetupPersona/CloudBackupPreview/index.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/Preview.tsx msgid "Switch other account" msgstr "他のアカウントを切り替え" @@ -2623,7 +2760,7 @@ msgstr "他のアカウントを切り替え" msgid "Switch Persona" msgstr "ペルソナを切り替え" -#: dashboard/components/Restore/RestoreFromCloud/ConfirmBackupInfo.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/ConfirmBackupInfo.tsx msgid "Switch to other accounts" msgstr "" @@ -2652,16 +2789,23 @@ msgstr "" msgid "The chainID is not equal to the currently connected one." msgstr "chainIDは現在接続されているものと等しくありません。" -#: dashboard/pages/SetupPersona/CloudBackup/index.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/MaskNetwork.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/CloudBackupFormContext.ts +#: dashboard/pages/SetupPersona/Backup/Cloud/CloudBackupFormContext.ts #: dashboard/contexts/CloudBackupFormContext.tsx #: dashboard/contexts/CloudBackupFormContext.tsx msgid "The code is incorrect." msgstr "このコードは正しくありません" -#: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx +#: dashboard/utils/api.ts msgid "The download link is expired" msgstr "" +#: dashboard/pages/SetupPersona/Recovery/Cloud/MaskNetwork.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/MaskNetwork.tsx +msgid "The Mask Network Cloud Backup feature will be deactivated on April 30, 2025. Please use alternative cloud backup services or local backup solutions." +msgstr "" + #: dashboard/pages/CreateMaskWallet/CreateMnemonic/index.tsx msgid "The mnemonic word has been copied, please keep it in a safe place." msgstr "" @@ -2700,6 +2844,7 @@ msgstr "" msgid "The persona name already exists." msgstr "このペルソナ名は既に存在しています." +#: dashboard/pages/SetupPersona/Backup/Cloud/CloudBackupFormContext.ts #: dashboard/contexts/CloudBackupFormContext.tsx msgid "The phone number is incorrect." msgstr "電話番号が間違っています。" @@ -2922,13 +3067,13 @@ msgstr "不明なEIP-4361メッセージバージョンです。" msgid "Unlock" msgstr "ロック解除" +#: dashboard/pages/SetupPersona/Recovery/Local.tsx #: dashboard/components/Restore/RestoreWalletFromLocal.tsx -#: dashboard/components/Restore/RestorePersonaFromLocal.tsx msgid "Unpacking" msgstr "" -#: dashboard/components/Restore/RestorePersonaFromLocal.tsx -#: dashboard/components/Restore/RestorePersonaFromLocal.tsx +#: dashboard/pages/SetupPersona/Recovery/Local.tsx +#: dashboard/pages/SetupPersona/Recovery/Local.tsx msgid "Unsupported data backup" msgstr "サポートされていないバックアップ" @@ -2976,16 +3121,16 @@ msgstr "テキスト暗号化を使用する" msgid "value" msgstr "価値" -#: dashboard/components/Restore/RestoreFromCloud/EmailField.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/EmailField.tsx msgid "Verification code has been sent to your email. Please check your mailbox." msgstr "" -#: dashboard/components/Restore/RestoreFromCloud/PhoneField.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/PhoneField.tsx msgid "Verification code has been sent to your phone." msgstr "" -#: dashboard/pages/SetupPersona/CloudBackup/PhoneForm.tsx -#: dashboard/pages/SetupPersona/CloudBackup/EmailForm.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/PhoneForm.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/EmailForm.tsx msgid "Verification code sent" msgstr "認証コードを送信しました" @@ -3038,8 +3183,8 @@ msgid "Waiting for {providerType}" msgstr "" #: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx -msgid "wallet" -msgstr "ウォレット" +#~ msgid "wallet" +#~ msgstr "" #: popups/pages/Wallet/SwitchWallet/index.tsx #: popups/modals/WalletGroupModal/index.tsx @@ -3096,8 +3241,8 @@ msgid "Welcome Back" msgstr "おかえりなさい" #: dashboard/pages/SetupPersona/CloudBackupPreview/index.tsx -msgid "Welcome to Mask Cloud Services" -msgstr "マスククラウドサービスへようこそ" +#~ msgid "Welcome to Mask Cloud Services" +#~ msgstr "" #: popups/pages/Personas/Home/UI.tsx msgid "Welcome to Mask Network" @@ -3107,6 +3252,10 @@ msgstr "Mask Networkへようこそ" msgid "Welcome to use Mask Network" msgstr "Mask Networkへようこそ" +#: dashboard/components/GoogleDriveLogin.tsx +msgid "when you click Add Google Drive button,you will be forwarded to Google authorization pages." +msgstr "" + #: popups/pages/Wallet/ExportPrivateKey/index.tsx msgid "Write down mnemonic words" msgstr "ニーモニックワードを書き留めてください" @@ -3120,21 +3269,25 @@ msgid "You could check the verification result on Mask Pop-up after few minutes. msgstr "" #: dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx -msgid "You have backed up your data." -msgstr "" +#~ msgid "You have backed up your data." +#~ msgstr "" #: dashboard/pages/SetupPersona/Onboarding/index.tsx #~ msgid "You have recovered" #~ msgstr "" #: dashboard/pages/SetupPersona/Onboarding/index.tsx -msgid "You have recovered " -msgstr "" +#~ msgid "You have recovered " +#~ msgstr "" #: popups/pages/Personas/ConnectWallet/index.tsx msgid "You have signed with your wallet." msgstr "" +#: dashboard/pages/SetupPersona/Recovery/Cloud/GoogleDrive.tsx +msgid "You have successfully restored the backup from Google Drive to your browser." +msgstr "" + #: dashboard/components/Restore/ConfirmSynchronizePasswordDialog.tsx msgid "You have verified your cloud password and recovered your backup. Do you want to let your cloud password and local backup password be the same?" msgstr "" @@ -3143,26 +3296,41 @@ msgstr "" msgid "You need to open the dApp to view the specific content." msgstr "" -#. placeholder {0}: user.email #: dashboard/pages/SetupPersona/CloudBackup/index.tsx #: dashboard/pages/SetupPersona/CloudBackup/index.tsx -msgid "You used <0>{0} for the last cloud backup." -msgstr "" +#~ msgid "You used <0>{0} for the last cloud backup." +#~ msgstr "" #: popups/components/SignRequestInfo/index.tsx msgid "Your connection to this site is not encrypted which can be modified by a hostile third party, we strongly suggest you reject this request." msgstr "このサイトへの接続は暗号化されていないため、敵対的な第三者によって変更されます。このリクエストを拒否することを強くお勧めします。" +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx +msgid "Your file has been successfully merged into the browser data." +msgstr "" + +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx +msgid "Your file has been successfully restore into the browser data." +msgstr "" + #: dashboard/pages/CreateMaskWallet/CreateWalletForm/index.tsx msgid "Your payment password encrypts wallet data and is needed to unlocking the wallet, transaction confirmations and signing. The password is never stored, and there is no way to recover it if you forget it." msgstr "" +#: dashboard/pages/SetupPersona/Onboarding/index.tsx +msgid "Your Persona has been successfully created." +msgstr "" + #: dashboard/pages/SetupPersona/Onboarding/index.tsx #~ msgid "Your Persona is on" #~ msgstr "" #: dashboard/pages/SetupPersona/Onboarding/index.tsx -msgid "Your Persona is on " +#~ msgid "Your Persona is on " +#~ msgstr "" + +#: dashboard/pages/SetupPersona/Onboarding/index.tsx +msgid "Your Persona is on **ready 🚀**" msgstr "" #: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx @@ -3170,5 +3338,9 @@ msgstr "" #~ msgstr "" #: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx -msgid "Your Wallet is on " +#~ msgid "Your Wallet is on " +#~ msgstr "" + +#: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx +msgid "Your Wallet is on **ready 🚀**" msgstr "" diff --git a/packages/mask/shared-ui/locale/ko-KR.json b/packages/mask/shared-ui/locale/ko-KR.json index 261484d2096f..7290bd819280 100644 --- a/packages/mask/shared-ui/locale/ko-KR.json +++ b/packages/mask/shared-ui/locale/ko-KR.json @@ -7,6 +7,16 @@ "y6VCOb": [["0"], " 분"], "MpnSqP": [["0"], " Pending"], "FKrzPv": [["count", "plural", { "one": ["#", " Wallet 🚀"], "other": ["#", " Wallets 🚀"] }]], + "5s6EhU": [ + [ + "count", + "plural", + { + "one": ["You have recovered **", "#", " Wallet 🚀**"], + "other": ["You have recovered **", "#", " Wallets 🚀**"] + } + ] + ], "yx3mb0": [ [ "decryptProgress", @@ -54,16 +64,18 @@ "pv5v6j": ["About Permit"], "k0USDt": ["Account connected.<0/><1/>Try to explore more features powered by Mask Network."], "R2K7XH": ["소결 미디어에서 웹3 앱을 탐색해 보세요."], - "6c6xyD": ["계정"], + "6c6xyD": ["accounts"], "39ohdf": ["활동"], "I5kL4f": ["Activity Log"], "m16xKo": ["추가"], "5YfW3S": ["Add an encrypted comment..."], "aTzTyw": ["자산 추가"], "M0FgOk": ["연락처 추가"], + "FAKSZG": ["Add google Drive"], "LP+1Z7": ["네트워크 추가"], "68m9Nl": ["현존 그룹에 새로운 주소 추가"], "1LkMSp": ["Add Suggested Token"], + "O8PsYe": ["Add the file to Chrome's database"], "GtJJAj": ["월렛 추가"], "uv94aG": ["사용자별추가"], "8RF/Sx": ["추가 완료"], @@ -96,13 +108,16 @@ "iTiwqa": ["Asset is hidden."], "2jQko7": ["관련 계정"], "CEk7Nc": ["최소 8 글자 이상 이용하세요"], + "gp6A8z": ["Authorization Failed"], "Wvnsx1": ["Auto-lock"], "7QptC5": ["Auto-lock 시간"], "nTFx7o": ["아바타 설정 성공"], "iH8pgl": ["뒤로"], + "npsHM5": ["Back Up to Google Drive"], + "V+1pjj": ["Back Up Your Data Your Way"], "rLgPvm": ["백업"], "h7+V7K": ["백업 맟 복구"], - "QrHM/A": ["백업을 다운로드하여 로컬로 병합했습니다."], + "QrHM/A": ["Backup downloaded and merged to local successfully."], "zp7Ha3": ["백업 실패"], "5Cowlg": ["Backup is saved to Mask Cloud Service."], "qZ6p7p": ["백업 시간 ", ["0"]], @@ -111,7 +126,9 @@ "ERYJcj": ["백업 비밀번호는 대문자, 소문자, 특수 문자 및 숫자를 포함하여 8-20자여야 합니다."], "hUF4dG": ["백업 비밀번호가 설정되었습니다."], "UtKGok": ["페르소나 백업"], - "7Ry254": ["Mask Cloud Service 백업"], + "+m7x4e": ["Backup Successful"], + "3iUAE7": ["Backup to Google Drive"], + "7Ry254": ["Backup to Mask Cloud Service"], "6IHgRq": ["Backup to the Cloud"], "QQPCqQ": ["지갑 백업"], "fsBGk0": ["잔액"], @@ -138,6 +155,9 @@ "tcHpvG": ["소유자 변경"], "fDP2k4": ["결제 비밀번호 변경"], "IXbRbM": ["다른 월렛을 선택하세요"], + "lU6uRb": [ + "Choose from multiple backup options, now including encrypted storage via your authorized Google Drive for added security and flexibility." + ], "xH6cn+": ["토큰 선택"], "+adBn3": ["Chrome - external extension"], "EsKgLS": ["퀵 스타트"], @@ -193,6 +213,9 @@ "PjBWOL": ["이용하기 전에 페르소나 한번 만들어 보세요"], "WgawP2": ["Creating your"], "cEnmTp": ["Creating your "], + "L82H5Z": ["Creating your **identity**"], + "F7U8uz": ["Creating your **wallet**"], + "aF8kci": ["Creation Completed"], "Q2lUR2": ["통화"], "OgPkDe": ["통화 기호(옵션)"], "oOQfsI": ["Current account is not the verifying account."], @@ -207,8 +230,9 @@ ], "8Tg/JR": ["커스텀"], "pvnfJD": ["다크"], - "Sp/me1": ["데이터"], + "Sp/me1": ["data"], "HKH+W+": ["데이터"], + "K8jCIB": ["Data backed up successfully!"], "3B4jmY": ["데이터 수정"], "rAcOY1": [ "Data merged from Mask Cloud Service to local successfully. Re-enter your password to encrypt and upload the new backup to Mask Cloud Service." @@ -246,11 +270,11 @@ "XZ/B+f": ["NFT를 보셨나요?"], "DPfwMq": ["완료"], "mzI/c+": ["다운로드"], - "1vSYsG": ["백업 다운로드"], + "1vSYsG": ["Download backup"], "1+6BOG": ["백업 다운로드"], "9hg9mc": ["다운로드 중"], "F8Wc3I": ["파일을 끌어서 여기에 놓으세요"], - "5Sa1Ss": ["이메일"], + "5Sa1Ss": ["E-mail"], "ePK91l": ["편집"], "mQpWAe": ["연락처 편집"], "iZLoa2": ["eg: X accounts, persona public keys, wallet addresses or ENS"], @@ -263,6 +287,7 @@ "w1ctdJ": ["Mask: 편집"], "MRIXE3": ["Encrypting your"], "zutir1": ["Encrypting your "], + "XB3tfc": ["Encrypting your **data**"], "Cz6Lx7": ["암호화 방식"], "N/fqDa": ["Ens 나 주소(0x)"], "mPxxVq": ["기스비 한도 입력"], @@ -282,9 +307,14 @@ "GS+Mus": ["내보내기"], "7Bj3x9": ["실패"], "SLEDBF": ["월렛 추가 실패, 다시 시도하기"], + "r92tNP": ["Failed to authorize Google Drive. Please try again."], "09vHB+": ["Failed to decrypt."], "jK7nvW": ["Failed to disconnect wallet"], + "9hzYBR": ["Failed to download and merge the backup: ", ["0"]], "0tkvsz": ["Failed to download and merge the backup."], + "etATpN": ["Failed to login: ", ["0"]], + "qDIxZ+": ["Failed to restore the backup from Google Drive to your browser. Please try again."], + "e3I0CA": ["Failed to restore the backup: ", ["0"]], "mrAv9J": ["네트워크 저장 실패"], "ZsjtYe": ["아바타 설정 실패"], "RWoEqV": ["Failed to transfer token: ", ["message"]], @@ -320,7 +350,9 @@ "fUn3xA": ["새로운 월렛 주소 생성"], "tdZPpe": ["Generating your"], "CiU2m/": ["Generating your "], + "RL5m+x": ["Generating your **accounts**"], "2p7WMm": ["Give permission to access <0/> your ", ["0"], "?"], + "w9Xmw/": ["Google Drive"], "76gPWk": ["알겠습니다"], "HqiAyF": ["Gwei"], "pu3rTn": ["GWEI"], @@ -339,7 +371,7 @@ "yx/fMc": ["높음"], "0caMy7": ["History"], "uip9JY": ["I wrote down those words in the correct order"], - "b5d759": ["아이덴티티"], + "b5d759": ["identity"], "RRw7LE": ["아이디"], "/WfDJy": [ "If you forget payment password, you can type 'RESET' to reset your wallet. <0>Remember, this action will erase all your previous wallets." @@ -352,6 +384,7 @@ "fza4cg": ["월렛 불러오기"], "HvDfH/": ["불러오기 완료됨"], "m3XvO+": ["월렛 불러오기"], + "ANk/Zy": ["Incorrect Backup Password"], "a23gJr": ["잘못된 비밀번호."], "bapItf": ["잘못된 백업 비밀번호."], "bassMa": ["잘못된 클라우드 백업 비밀번호입니다. 다시 시도하세요."], @@ -392,9 +425,11 @@ "jygqM9": ["Loading account information..."], "EBC6hj": ["로컬 백업"], "shPV5O": ["로컬 페르소나나 월렛만 가능합니다."], + "crVIc7": ["Locale Backup"], "KGHnSc": ["로컬 월렛"], "FgAxTj": ["로그아웃"], "kC3Q3d": ["Login to Mask Cloud"], + "nOhz3x": ["Logout"], "NkgvWN": ["로그아웃 실패"], "o4Iu2W": ["로그아웃 성공"], "nTWWCZ": ["낮음"], @@ -404,6 +439,7 @@ ], "lET9my": ["Mask가 아래 권한을 요청합니다."], "siroPf": ["Mask Network"], + "jhoAzY": ["Mask Network Cloud"], "lWOC+h": ["Mask Network requires you to authorize the following websites before using it."], "HsoakN": ["masknetwork"], "CK1KXz": ["최대치"], @@ -420,8 +456,10 @@ "sQJ3RN": ["네트워크 컨디션에 대한 최대 우선 가스비는 매우 낮습니다."], "ITBQO3": ["최대 우선 가스비는 0 GWEI보다 높아야 합니다"], "agPptk": ["보통"], + "lPsa94": ["Merge Completed"], "RH8jSA": ["데이터를 로컬 데이터베이스에 병합하기"], - "QTomF0": ["로컬로 합병하기"], + "E6YUtc": ["Merge to Browser"], + "QTomF0": ["Merge to local"], "xDAtGP": ["메시지"], "pGElS5": ["니모닉"], "yFrxQj": ["니모닉 단어"], @@ -483,8 +521,8 @@ "YKSmxE": [ "Other social networking platforms, such as <0>Instagram, <1>Facebook, and <2>Minds, do not have a verified relationship like X's Next.ID verified connection.<3/><4/>When connecting a persona with an account on these platforms, they only support sending encrypted posts." ], - "MXOdMY": ["백업 덮어쓰기"], - "p2xE4C": ["기존 백업 덮어쓰기"], + "MXOdMY": ["Overwrite Backup"], + "p2xE4C": ["Overwrite current backup"], "8ZsakT": ["비밀번호"], "9w2hgY": ["수동으로 붙여넣기"], "GAvnvl": ["결재 비밀번호"], @@ -547,9 +585,10 @@ "3AP6p1": ["Public Key: <0>", ["publicKey"], ""], "82+n6o": ["Quote Route"], "AV+9wg": ["다시 입력"], - "TZ0npN": ["준비 🚀"], + "TZ0npN": ["ready 🚀"], "nVT2pJ": ["realMaskNetwork"], "lDgVWA": ["받기"], + "OkofjH": ["Recover"], "XC7RGa": ["데어터 복구"], "UBzbea": ["월렛 복구"], "P9wzG/": ["복구"], @@ -571,8 +610,10 @@ "nvAt0H": ["Resource"], "yKu/3Y": ["복원하기"], "Z3+V9p": ["Restore backup failed."], + "nGl2Ng": ["Restore Completed"], "AKLbfQ": ["데이터베이스 복원"], "uM6jnS": ["복구 실패"], + "KFwID2": ["Restore Failed"], "/LkuGq": ["이전의 데이터베이스 백업에서 복원하기"], "KisOjk": ["등록 또는 로그인"], "6gRgw8": ["다시 시도"], @@ -590,7 +631,7 @@ "nTif4K": ["월렛 선택 및 연결"], "k/sb6z": ["언어 선택"], "LSwUJb": ["Select Liquidity"], - "RjF5dk": ["백업 내용을 선택하세요."], + "RjF5dk": ["Select the contents of the backup"], "PI/VCJ": ["Select the wallet(s) to use on this site. You should not connect to website you don't trust."], "a1SmQh": ["월렛 선택"], "JlFcis": ["보내기"], @@ -608,7 +649,7 @@ "iJLEZF": ["방법을 알려주세요."], "nOCyT5": ["잔액 $1 미만인 토큰 표시"], "c+Fnce": ["사인"], - "mErq7F": ["가입하기"], + "mErq7F": ["Sign Up"], "t3rUZr": ["Sign-in Request"], "py6hU8": ["시그너쳐 요청"], "9KKhJV": ["진행중..."], @@ -651,6 +692,9 @@ "VdhBp2": ["The chainID is not equal to the currently connected one."], "h3Vpnw": ["코드가 잘못되었습니다."], "7w1rTm": ["The download link is expired"], + "oYkran": [ + "The Mask Network Cloud Backup feature will be deactivated on April 30, 2025. Please use alternative cloud backup services or local backup solutions." + ], "o+zDNQ": ["The mnemonic word has been copied, please keep it in a safe place."], "yRuvmU": ["The mnemonic words has been copied, please keep it in a safe place."], "thX7xs": [ @@ -771,7 +815,7 @@ "vVEene": ["View your Tokens and NFTs"], "kbfp5m": ["공개 대상"], "PTXNyo": ["Waiting for ", ["providerType"]], - "6XyieG": ["월렛"], + "6XyieG": ["wallet"], "VECuJk": ["월렛 계정"], "KtMMzG": ["Wallet disconnected"], "Kl9gHp": ["월렛 그룹 #", ["0"]], @@ -789,6 +833,7 @@ "m74yjp": ["Welcome to Mask Cloud Services"], "hEpXzO": ["환영합니다"], "fFYJ8f": ["환영합니다"], + "OLUEnY": ["when you click Add Google Drive button,you will be forwarded to Google authorization pages."], "Qbo7Ev": ["니모닉 단어를 적어두세요"], "f5AidZ": ["Write down recovery phrase"], "yGyJ1l": [ @@ -798,6 +843,7 @@ "dyqtoj": ["You have recovered"], "V8x6o5": ["You have recovered "], "QU9aqK": ["You have signed with your wallet."], + "PeT3a5": ["You have successfully restored the backup from Google Drive to your browser."], "zkEW09": [ "You have verified your cloud password and recovered your backup. Do you want to let your cloud password and local backup password be the same?" ], @@ -806,12 +852,17 @@ "FnQek5": [ "Your connection to this site is not encrypted which can be modified by a hostile third party, we strongly suggest you reject this request." ], + "UDKbPj": ["Your file has been successfully merged into the browser data."], + "S2JNMm": ["Your file has been successfully restore into the browser data."], "Q68Nuc": [ "Your payment password encrypts wallet data and is needed to unlocking the wallet, transaction confirmations and signing. The password is never stored, and there is no way to recover it if you forget it." ], + "4EN5JL": ["Your Persona has been successfully created."], "N19nSk": ["Your Persona is on"], "WC7pDz": ["Your Persona is on "], + "PDW/HG": ["Your Persona is on **ready 🚀**"], "0kr+x1": ["Your Wallet is on"], - "v7OL2k": ["Your Wallet is on "] + "v7OL2k": ["Your Wallet is on "], + "wCtp6y": ["Your Wallet is on **ready 🚀**"] } } diff --git a/packages/mask/shared-ui/locale/ko-KR.po b/packages/mask/shared-ui/locale/ko-KR.po index 9def83f290ec..e9a56eee40b1 100644 --- a/packages/mask/shared-ui/locale/ko-KR.po +++ b/packages/mask/shared-ui/locale/ko-KR.po @@ -3,7 +3,7 @@ msgstr "" "Project-Id-Version: mask-network\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2025-01-08 06:53\n" +"PO-Revision-Date: 2025-04-10 05:53\n" "Last-Translator: \n" "Language: ko_KR\n" "Language-Team: Korean\n" @@ -46,7 +46,11 @@ msgid "{0} Pending" msgstr "" #: dashboard/pages/SetupPersona/Onboarding/index.tsx -msgid "{count, plural, one {# Wallet 🚀} other {# Wallets 🚀}}" +#~ msgid "{count, plural, one {# Wallet 🚀} other {# Wallets 🚀}}" +#~ msgstr "" + +#: dashboard/pages/SetupPersona/Onboarding/index.tsx +msgid "{count, plural, one {You have recovered **# Wallet 🚀**} other {You have recovered **# Wallets 🚀**}}" msgstr "" #: content-script/components/InjectedComponents/DecryptedPost/DecryptPostAwaiting.tsx @@ -132,8 +136,8 @@ msgstr "소결 미디어에서 웹3 앱을 탐색해 보세요." #: dashboard/pages/SetupPersona/Onboarding/index.tsx #: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx -msgid "accounts" -msgstr "계정" +#~ msgid "accounts" +#~ msgstr "" #: popups/pages/Wallet/components/WalletAssets/index.tsx msgid "Activities" @@ -162,6 +166,10 @@ msgstr "자산 추가" msgid "Add Contact" msgstr "연락처 추가" +#: dashboard/components/GoogleDriveLogin.tsx +msgid "Add google Drive" +msgstr "" + #: popups/pages/Wallet/NetworkManagement/index.tsx #: popups/pages/Wallet/EditNetwork/index.tsx msgid "Add Network" @@ -175,6 +183,10 @@ msgstr "현존 그룹에 새로운 주소 추가" msgid "Add Suggested Token" msgstr "" +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx +msgid "Add the file to Chrome's database" +msgstr "" + #: popups/pages/Wallet/components/StartUp/index.tsx #: popups/pages/Wallet/SwitchWallet/index.tsx #: popups/pages/Wallet/CreateWallet/index.tsx @@ -258,8 +270,8 @@ msgid "Approve amount" msgstr "금액 승인" #: dashboard/pages/SetupPersona/CloudBackupPreview/index.tsx -msgid "Are you sure to overwrite the backups stored on Mask Cloud Service?" -msgstr "" +#~ msgid "Are you sure to overwrite the backups stored on Mask Cloud Service?" +#~ msgstr "" #. placeholder {0}: formatEthereumAddress(wallet.identity, 4) #: popups/components/ConnectedWallet/index.tsx @@ -292,6 +304,10 @@ msgstr "관련 계정" msgid "At least 6 characters" msgstr "최소 8 글자 이상 이용하세요" +#: dashboard/components/GoogleDriveLogin.tsx +msgid "Authorization Failed" +msgstr "" + #: popups/pages/Wallet/WalletSettings/AutoLock.tsx msgid "Auto-lock" msgstr "" @@ -305,13 +321,24 @@ msgid "Avatar set successfully" msgstr "아바타 설정 성공" #: content-script/components/shared/SelectRecipients/SelectRecipientsDialog.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/Preview.tsx #: dashboard/pages/CreateMaskWallet/CreateMnemonic/index.tsx #: popups/pages/Personas/ExportPrivateKey/index.tsx #: popups/pages/Personas/AccountDetail/UI.tsx msgid "Back" msgstr "뒤로" -#: dashboard/pages/SetupPersona/CloudBackupPreview/index.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/GoogleDrive.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/GoogleDrive.tsx +#~ msgid "Back Up to Google Drive" +#~ msgstr "" + +#: dashboard/pages/SetupPersona/Backup/index.tsx +msgid "Back Up Your Data Your Way" +msgstr "" + +#: dashboard/pages/SetupPersona/Backup/Cloud/GoogleDrive.tsx +#: dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx #: popups/pages/Personas/Logout/index.tsx #: popups/modals/SwitchPersonaModal/index.tsx msgid "Backup" @@ -322,16 +349,16 @@ msgid "Backup & Recovery" msgstr "백업 맟 복구" #: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx -msgid "Backup downloaded and merged to local successfully." -msgstr "백업을 다운로드하여 로컬로 병합했습니다." +#~ msgid "Backup downloaded and merged to local successfully." +#~ msgstr "" #: dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx msgid "Backup Failed" msgstr "백업 실패" #: dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx -msgid "Backup is saved to Mask Cloud Service." -msgstr "" +#~ msgid "Backup is saved to Mask Cloud Service." +#~ msgstr "" #. placeholder {0}: user.localBackupAt #. placeholder {0}: user.cloudBackupAt @@ -340,13 +367,13 @@ msgstr "" msgid "Backup on {0}" msgstr "백업 시간 {0}" -#: dashboard/components/Restore/RestorePersonaFromLocal.tsx -#: dashboard/components/Restore/RestoreFromCloud/ConfirmBackupInfo.tsx +#: dashboard/pages/SetupPersona/Recovery/Local.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/ConfirmBackupInfo.tsx msgid "Backup password" msgstr "비밀번호 백업" -#: dashboard/pages/SetupPersona/LocalBackup/index.tsx -#: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx +#: dashboard/pages/SetupPersona/Backup/Local.tsx +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx #: dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx #: popups/pages/Settings/index.tsx #: popups/modals/SetBackupPasswordModal/index.tsx @@ -368,9 +395,18 @@ msgstr "백업 비밀번호가 설정되었습니다." msgid "Backup Persona" msgstr "페르소나 백업" +#: dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx +msgid "Backup Successful" +msgstr "" + +#: dashboard/pages/SetupPersona/Backup/Cloud/GoogleDrive.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/GoogleDrive.tsx +msgid "Backup to Google Drive" +msgstr "" + #: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx -msgid "Backup to Mask Cloud Service" -msgstr "Mask Cloud Service 백업" +#~ msgid "Backup to Mask Cloud Service" +#~ msgstr "" #: dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx msgid "Backup to the Cloud" @@ -437,7 +473,6 @@ msgstr "" #: content-script/components/InjectedComponents/SelectPeopleDialog.tsx #: dashboard/pages/SetupPersona/Welcome/index.tsx #: dashboard/pages/SetupPersona/Permissions/index.tsx -#: dashboard/pages/SetupPersona/CloudBackupPreview/index.tsx #: dashboard/modals/ConfirmModal/index.tsx #: dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx #: dashboard/components/Restore/ConfirmSynchronizePasswordDialog.tsx @@ -510,6 +545,10 @@ msgstr "결제 비밀번호 변경" msgid "Choose another wallet" msgstr "다른 월렛을 선택하세요" +#: dashboard/pages/SetupPersona/Backup/index.tsx +msgid "Choose from multiple backup options, now including encrypted storage via your authorized Google Drive for added security and flexibility." +msgstr "" + #: popups/modals/ChooseToken/index.tsx msgid "Choose Token" msgstr "토큰 선택" @@ -535,6 +574,7 @@ msgid "Close" msgstr "닫기" #: dashboard/pages/SetupPersona/Recovery/index.tsx +#: dashboard/pages/SetupPersona/Backup/index.tsx #: dashboard/components/Restore/ConfirmSynchronizePasswordDialog.tsx #: popups/pages/Settings/index.tsx msgid "Cloud Backup" @@ -548,12 +588,11 @@ msgstr "수집품" msgid "Coming soon" msgstr "" +#: dashboard/pages/SetupPersona/Recovery/Local.tsx #: dashboard/components/Restore/RestoreWalletFromLocal.tsx -#: dashboard/components/Restore/RestorePersonaFromLocal.tsx msgid "Completed" msgstr "완료됨" -#: dashboard/pages/SetupPersona/CloudBackupPreview/index.tsx #: dashboard/modals/ConfirmModal/index.tsx #: dashboard/components/Restore/ConfirmSynchronizePasswordDialog.tsx #: popups/pages/Wallet/components/DisconnectModal/index.tsx @@ -607,8 +646,6 @@ msgstr "" msgid "Confirm to hide {name}? You can redisplay it by re-adding this NFT at any time." msgstr "" -#: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx -#: dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx #: popups/pages/Personas/ConnectWallet/index.tsx msgid "Congratulations" msgstr "축하합니다" @@ -709,16 +746,18 @@ msgstr "연락처" #: dashboard/pages/SignUp/steps/PersonaNameUI.tsx #: dashboard/pages/SetupPersona/SignUp/index.tsx +#: dashboard/pages/SetupPersona/Recovery/PrivateKey.tsx +#: dashboard/pages/SetupPersona/Recovery/Phrase.tsx +#: dashboard/pages/SetupPersona/Recovery/Local.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/PhoneField.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/EmailField.tsx #: dashboard/pages/SetupPersona/Mnemonic/index.tsx -#: dashboard/pages/SetupPersona/CloudBackup/index.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/MaskNetwork.tsx #: dashboard/pages/CreateMaskWallet/CreateWalletForm/index.tsx #: dashboard/pages/CreateMaskWallet/AddDeriveWallet/index.tsx #: dashboard/components/Restore/RestoreWalletFromLocal.tsx -#: dashboard/components/Restore/RestorePersonaFromLocal.tsx #: dashboard/components/Restore/RestoreFromPrivateKey.tsx #: dashboard/components/Restore/RestoreFromMnemonic.tsx -#: dashboard/components/Restore/RestoreFromCloud/PhoneField.tsx -#: dashboard/components/Restore/RestoreFromCloud/EmailField.tsx msgid "Continue" msgstr "다음" @@ -774,6 +813,7 @@ msgstr "새로운 Mask 아이디 만들기" msgid "Create Password" msgstr "비밀번호 생성" +#: dashboard/pages/SetupPersona/Recovery/index.tsx #: popups/pages/Personas/Home/UI.tsx msgid "Create Persona" msgstr "페르소나 만들기" @@ -789,7 +829,19 @@ msgstr "이용하기 전에 페르소나 한번 만들어 보세요" #: dashboard/pages/SetupPersona/Onboarding/index.tsx #: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx -msgid "Creating your " +#~ msgid "Creating your " +#~ msgstr "" + +#: dashboard/pages/SetupPersona/Onboarding/index.tsx +msgid "Creating your **identity**" +msgstr "" + +#: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx +msgid "Creating your **wallet**" +msgstr "" + +#: dashboard/pages/SetupPersona/Onboarding/index.tsx +msgid "Creation Completed" msgstr "" #: popups/pages/Wallet/WalletSettings/ChangeCurrency.tsx @@ -830,23 +882,27 @@ msgstr "다크" #: dashboard/pages/SetupPersona/Onboarding/index.tsx #: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx -msgid "data" -msgstr "데이터" +#~ msgid "data" +#~ msgstr "" #: popups/pages/Wallet/Interaction/TransactionRequest.tsx msgid "Data" msgstr "데이터" +#: dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx +msgid "Data backed up successfully!" +msgstr "" + #: popups/pages/Settings/index.tsx msgid "Data correlation" msgstr "데이터 수정" #: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx -msgid "Data merged from Mask Cloud Service to local successfully. Re-enter your password to encrypt and upload the new backup to Mask Cloud Service." -msgstr "" +#~ msgid "Data merged from Mask Cloud Service to local successfully. Re-enter your password to encrypt and upload the new backup to Mask Cloud Service." +#~ msgstr "" -#: dashboard/components/Restore/RestoreFromCloud/ConfirmBackupInfo.tsx -#: dashboard/components/Restore/RestoreFromCloud/ConfirmBackupInfo.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/ConfirmBackupInfo.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/ConfirmBackupInfo.tsx msgid "Decrypt failed, please check password" msgstr "해독 실패, 비밀번호를 확인하세요" @@ -951,18 +1007,20 @@ msgid "Done" msgstr "완료" #: content-script/components/InjectedComponents/AutoPasteFailedDialog.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/Preview.tsx +#: dashboard/components/GoogleDriveFileTable.tsx msgid "Download" msgstr "다운로드" #: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx -msgid "Download backup" -msgstr "백업 다운로드" +#~ msgid "Download backup" +#~ msgstr "" -#: dashboard/pages/SetupPersona/LocalBackup/index.tsx +#: dashboard/pages/SetupPersona/Backup/Local.tsx msgid "Download Backup" msgstr "백업 다운로드" -#: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx msgid "Downloading" msgstr "다운로드 중" @@ -971,8 +1029,8 @@ msgid "Drag & Drop your file here" msgstr "파일을 끌어서 여기에 놓으세요" #: dashboard/pages/SetupPersona/CloudBackup/index.tsx -msgid "E-mail" -msgstr "이메일" +#~ msgid "E-mail" +#~ msgstr "" #: popups/pages/Wallet/ContactList/index.tsx msgid "Edit" @@ -987,13 +1045,14 @@ msgstr "연락처 편집" msgid "eg: X accounts, persona public keys, wallet addresses or ENS" msgstr "" -#: dashboard/pages/SetupPersona/CloudBackup/EmailForm.tsx -#: dashboard/components/Restore/RestoreFromCloud/EmailField.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/EmailField.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/MaskNetwork.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/EmailForm.tsx msgid "Email" msgstr "이메일" -#: dashboard/pages/SetupPersona/CloudBackup/EmailForm.tsx -#: dashboard/components/Restore/RestoreFromCloud/EmailField.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/EmailField.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/EmailForm.tsx msgid "Email verification code" msgstr "메일 인증번호" @@ -1024,7 +1083,12 @@ msgstr "Mask: 편집" #: dashboard/pages/SetupPersona/Onboarding/index.tsx #: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx -msgid "Encrypting your " +#~ msgid "Encrypting your " +#~ msgstr "" + +#: dashboard/pages/SetupPersona/Onboarding/index.tsx +#: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx +msgid "Encrypting your **data**" msgstr "" #: content-script/components/CompositionDialog/EncryptionMethodSelector.tsx @@ -1110,6 +1174,10 @@ msgstr "실패" msgid "Failed to add the wallet, please try again." msgstr "월렛 추가 실패, 다시 시도하기" +#: dashboard/components/GoogleDriveLogin.tsx +msgid "Failed to authorize Google Drive. Please try again." +msgstr "" + #: content-script/components/InjectedComponents/DecryptedPost/DecryptPostFailed.tsx msgid "Failed to decrypt." msgstr "" @@ -1118,8 +1186,26 @@ msgstr "" msgid "Failed to disconnect wallet" msgstr "" +#. placeholder {0}: (err as Error).message +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx +msgid "Failed to download and merge the backup: {0}" +msgstr "" + #: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx -msgid "Failed to download and merge the backup." +#~ msgid "Failed to download and merge the backup." +#~ msgstr "" + +#: dashboard/components/GoogleDriveLogin.tsx +#~ msgid "Failed to login: {0}" +#~ msgstr "" + +#: dashboard/pages/SetupPersona/Recovery/Cloud/GoogleDrive.tsx +msgid "Failed to restore the backup from Google Drive to your browser. Please try again." +msgstr "" + +#. placeholder {0}: (err as Error).message +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx +msgid "Failed to restore the backup: {0}" msgstr "" #: popups/pages/Wallet/EditNetwork/index.tsx @@ -1269,7 +1355,12 @@ msgstr "새로운 월렛 주소 생성" #: dashboard/pages/SetupPersona/Onboarding/index.tsx #: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx -msgid "Generating your " +#~ msgid "Generating your " +#~ msgstr "" + +#: dashboard/pages/SetupPersona/Onboarding/index.tsx +#: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx +msgid "Generating your **accounts**" msgstr "" #. placeholder {0}: contract?.symbol || '' @@ -1279,6 +1370,13 @@ msgstr "" msgid "Give permission to access <0/> your {0}?" msgstr "" +#: dashboard/pages/SetupPersona/Recovery/Cloud/index.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/GoogleDrive.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/index.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/GoogleDrive.tsx +msgid "Google Drive" +msgstr "" + #: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx msgid "Got it" msgstr "알겠습니다" @@ -1344,8 +1442,8 @@ msgid "I wrote down those words in the correct order" msgstr "" #: dashboard/pages/SetupPersona/Onboarding/index.tsx -msgid "identity" -msgstr "아이덴티티" +#~ msgid "identity" +#~ msgstr "" #: dashboard/pages/SetupPersona/Mnemonic/ComponentToPrint.tsx msgid "Identity ID" @@ -1389,17 +1487,21 @@ msgstr "불러오기 완료됨" msgid "Imported Wallets" msgstr "월렛 불러오기" +#: dashboard/hooks/useBackupFormState.ts +msgid "Incorrect Backup Password" +msgstr "" + #: popups/modals/VerifyBackupPasswordModal/index.tsx #: popups/modals/ChangeBackupPasswordModal/index.tsx msgid "Incorrect backup password." msgstr "잘못된 비밀번호." -#: dashboard/components/Restore/RestorePersonaFromLocal.tsx +#: dashboard/pages/SetupPersona/Recovery/Local.tsx msgid "Incorrect Backup Password." msgstr "잘못된 백업 비밀번호." -#: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx -#: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx msgid "Incorrect cloud backup password, please try again." msgstr "잘못된 클라우드 백업 비밀번호입니다. 다시 시도하세요." @@ -1417,7 +1519,7 @@ msgstr "" msgid "Incorrect password" msgstr "잘못된 비밀번호" -#: dashboard/pages/SetupPersona/LocalBackup/index.tsx +#: dashboard/pages/SetupPersona/Backup/Local.tsx #: dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx #: dashboard/hooks/useBackupFormState.ts #: dashboard/hooks/useBackupFormState.ts @@ -1425,7 +1527,6 @@ msgstr "잘못된 비밀번호" #: dashboard/hooks/useBackupFormState.ts #: dashboard/hooks/useBackupFormState.ts #: dashboard/hooks/useBackupFormState.ts -#: dashboard/hooks/useBackupFormState.ts msgid "Incorrect Password" msgstr "잘못된 비밀번호" @@ -1438,12 +1539,12 @@ msgstr "잘못된 결제 비밀번호" msgid "Incorrect Payment Password." msgstr "잘못된 결제 비밀번호" -#: dashboard/pages/SetupPersona/Recovery/index.tsx +#: dashboard/pages/SetupPersona/Recovery/PrivateKey.tsx #: dashboard/pages/CreateMaskWallet/Recovery/index.tsx msgid "Incorrect Private Key" msgstr "잘못된 아이디 코드" -#: dashboard/pages/SetupPersona/Recovery/index.tsx +#: dashboard/pages/SetupPersona/Recovery/Phrase.tsx msgid "Incorrect recovery phrase." msgstr "잘못된 복구 문구" @@ -1456,6 +1557,7 @@ msgstr "잘못된 월렛 주소." msgid "Incorrect words selected. Please try again!" msgstr "" +#: dashboard/pages/SetupPersona/Recovery/PrivateKey.tsx #: dashboard/components/Restore/RestoreFromPrivateKey.tsx msgid "Input your Private Key" msgstr "개인 키 입력하기" @@ -1473,12 +1575,13 @@ msgstr "자산이나 가스비가 부족합니다." msgid "Invalid Block Explorer URL." msgstr "무효한 Block Explorer URL." -#: dashboard/pages/SetupPersona/CloudBackup/EmailForm.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/EmailForm.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/CloudBackupFormContext.ts #: dashboard/contexts/CloudBackupFormContext.tsx msgid "Invalid email address format." msgstr "이메일 주소가 잘못되었습니다." -#: dashboard/components/Restore/RestoreFromCloud/EmailField.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/EmailField.tsx msgid "Invalid email address." msgstr "" @@ -1486,7 +1589,7 @@ msgstr "" msgid "Invalid number" msgstr "잘못된 번호" -#: dashboard/components/Restore/RestoreFromCloud/PhoneField.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/PhoneField.tsx msgid "Invalid phone number, please check and try again." msgstr "무효한 전화 번호입니다. 다시 시도해 보세요." @@ -1494,8 +1597,8 @@ msgstr "무효한 전화 번호입니다. 다시 시도해 보세요." msgid "Invalid RPC URL." msgstr "무효한 RPC URL" -#: dashboard/components/Restore/RestoreFromCloud/PhoneField.tsx -#: dashboard/components/Restore/RestoreFromCloud/EmailField.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/PhoneField.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/EmailField.tsx msgid "Invalid verification code." msgstr "유효하지 않은 인증 코드입니다." @@ -1576,6 +1679,10 @@ msgstr "로컬 백업" msgid "Local persona or wallet only" msgstr "로컬 페르소나나 월렛만 가능합니다." +#: dashboard/pages/SetupPersona/Backup/index.tsx +msgid "Locale Backup" +msgstr "" + #: popups/pages/Wallet/SwitchWallet/index.tsx msgid "Lock Wallet" msgstr "로컬 월렛" @@ -1587,7 +1694,13 @@ msgid "Log out" msgstr "로그아웃" #: dashboard/pages/SetupPersona/CloudBackup/index.tsx -msgid "Login to Mask Cloud" +#~ msgid "Login to Mask Cloud" +#~ msgstr "" + +#: dashboard/pages/SetupPersona/Recovery/Cloud/GoogleDrive.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/Preview.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/GoogleDrive.tsx +msgid "Logout" msgstr "" #: popups/pages/Personas/Logout/index.tsx @@ -1618,9 +1731,15 @@ msgstr "Mask가 아래 권한을 요청합니다." #: content-script/components/InjectedComponents/ToolboxUnstyled.tsx #: content-script/components/InjectedComponents/PostDialogHint.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/index.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/index.tsx msgid "Mask Network" msgstr "" +#: dashboard/pages/SetupPersona/Backup/Cloud/Preview.tsx +msgid "Mask Network Cloud" +msgstr "" + #: content-script/components/InjectedComponents/PermissionBoundary.tsx msgid "Mask Network requires you to authorize the following websites before using it." msgstr "" @@ -1692,15 +1811,23 @@ msgstr "최대 우선 가스비는 0 GWEI보다 높아야 합니다" msgid "Medium" msgstr "보통" -#: dashboard/pages/SetupPersona/CloudBackupPreview/index.tsx -#: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx -#: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx +msgid "Merge Completed" +msgstr "" + +#: dashboard/pages/SetupPersona/Backup/Cloud/Preview.tsx +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx msgid "Merge data to local database" msgstr "데이터를 로컬 데이터베이스에 병합하기" +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx +#: dashboard/components/GoogleDriveFileTable.tsx +msgid "Merge to Browser" +msgstr "" + #: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx -msgid "Merge to local" -msgstr "로컬로 합병하기" +#~ msgid "Merge to local" +#~ msgstr "" #: popups/components/SignRequestInfo/index.tsx msgid "Message" @@ -1715,15 +1842,15 @@ msgstr "니모닉" msgid "Mnemonic word" msgstr "니모닉 단어" -#: dashboard/pages/SetupPersona/CloudBackup/index.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/MaskNetwork.tsx msgid "Mobile" msgstr "모바일" -#: dashboard/pages/SetupPersona/CloudBackup/PhoneForm.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/PhoneForm.tsx msgid "Mobile number" msgstr "휴대폰 번호" -#: dashboard/components/Restore/RestoreFromCloud/PhoneField.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/PhoneField.tsx msgid "Mobile verification code" msgstr "모바일 인증번호" @@ -1836,7 +1963,8 @@ msgstr "" msgid "No back up" msgstr "백업 없음" -#: dashboard/pages/SetupPersona/CloudBackupPreview/index.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/Preview.tsx +#: dashboard/components/GoogleDriveFileTable.tsx msgid "No backups found" msgstr "백업 없음" @@ -1949,13 +2077,12 @@ msgid "Other social networking platforms, such as <0>Instagram, <1>Facebook, msgstr "" #: dashboard/pages/SetupPersona/CloudBackupPreview/index.tsx -#: dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx -msgid "Overwrite Backup" -msgstr "백업 덮어쓰기" +#~ msgid "Overwrite Backup" +#~ msgstr "" #: dashboard/pages/SetupPersona/CloudBackupPreview/index.tsx -msgid "Overwrite current backup" -msgstr "기존 백업 덮어쓰기" +#~ msgid "Overwrite current backup" +#~ msgstr "" #: popups/modals/VerifyBackupPasswordModal/index.tsx #: popups/modals/SetBackupPasswordModal/index.tsx @@ -1967,7 +2094,7 @@ msgstr "비밀번호" msgid "Paste manually" msgstr "수동으로 붙여넣기" -#: dashboard/pages/SetupPersona/LocalBackup/index.tsx +#: dashboard/pages/SetupPersona/Backup/Local.tsx #: dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx #: popups/pages/Wallet/SetPaymentPassword/index.tsx #: popups/modals/WalletRemoveModal/index.tsx @@ -2048,7 +2175,7 @@ msgstr "" msgid "Personas" msgstr "나의 페르소나" -#: dashboard/pages/SetupPersona/CloudBackup/PhoneForm.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/PhoneForm.tsx msgid "Phone verification code" msgstr "" @@ -2075,7 +2202,7 @@ msgstr "" msgid "Please enter backup password to export persona private key." msgstr "백업 비밀번호를 입력하고 페르소나 개인키를 내보낼 수 있습니다." -#: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx msgid "Please enter cloud backup password to download file." msgstr "파일을 다운로드하려면 클라우드 백업 암호를 입력하세요." @@ -2103,8 +2230,6 @@ msgid "Please note: This Persona {0} is the management account of above listed S msgstr "" #: dashboard/pages/SetupPersona/Recovery/index.tsx -#: dashboard/pages/SetupPersona/LocalBackup/index.tsx -#: dashboard/pages/SetupPersona/CloudBackupPreview/index.tsx msgid "Please select the appropriate method to restore your personal data." msgstr "12개 복구 문구로 페르소나 데어터를 복구할 수 있습니다." @@ -2134,8 +2259,8 @@ msgid "Please switch to <0>@{expectAccount} to continue the account verifica msgstr "" #: dashboard/pages/SetupPersona/CloudBackup/index.tsx -msgid "Please use your frequently used email or phone number for backup." -msgstr "" +#~ msgid "Please use your frequently used email or phone number for backup." +#~ msgstr "" #: dashboard/pages/CreateMaskWallet/CreateMnemonic/index.tsx msgid "Please write down or copy these words and save them in a secure place." @@ -2213,8 +2338,8 @@ msgstr "다시 입력" #: dashboard/pages/SetupPersona/Onboarding/index.tsx #: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx -msgid "ready 🚀" -msgstr "준비 🚀" +#~ msgid "ready 🚀" +#~ msgstr "" #: content-script/components/CompositionDialog/useSubmit.ts msgid "realMaskNetwork" @@ -2225,6 +2350,11 @@ msgstr "" msgid "Receive" msgstr "받기" +#: dashboard/pages/SetupPersona/Recovery/Cloud/GoogleDrive.tsx +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx +msgid "Recover" +msgstr "" + #: dashboard/pages/SetupPersona/Recovery/index.tsx msgid "Recover your data" msgstr "데어터 복구" @@ -2292,13 +2422,13 @@ msgstr "" msgid "Request Source" msgstr "소스 요청" -#: dashboard/components/Restore/RestorePersonaFromLocal.tsx +#: dashboard/pages/SetupPersona/Recovery/Local.tsx msgid "Reselect" msgstr "다시 선택" #: content-script/components/InjectedComponents/SetupGuide/VerifyNextID.tsx -#: dashboard/pages/SetupPersona/CloudBackup/PhoneForm.tsx -#: dashboard/pages/SetupPersona/CloudBackup/EmailForm.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/PhoneForm.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/EmailForm.tsx msgid "Resend" msgstr "다시 보내기" @@ -2310,24 +2440,32 @@ msgstr "월렛 리셋" msgid "Resource" msgstr "" -#: dashboard/components/Restore/RestorePersonaFromLocal.tsx -#: dashboard/components/Restore/RestoreFromCloud/index.tsx -#: dashboard/components/Restore/RestoreFromCloud/ConfirmBackupInfo.tsx +#: dashboard/pages/SetupPersona/Recovery/Local.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/MaskNetwork.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/ConfirmBackupInfo.tsx msgid "Restore" msgstr "복원하기" -#: dashboard/components/Restore/RestorePersonaFromLocal.tsx +#: dashboard/pages/SetupPersona/Recovery/Local.tsx msgid "Restore backup failed." msgstr "" +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx +msgid "Restore Completed" +msgstr "" + #: popups/pages/Settings/index.tsx msgid "Restore Database" msgstr "데이터베이스 복원" -#: dashboard/components/Restore/RestoreFromCloud/index.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/MaskNetwork.tsx msgid "Restore failed" msgstr "복구 실패" +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx +msgid "Restore Failed" +msgstr "" + #: popups/pages/Settings/index.tsx msgid "Restore from a previous database backup" msgstr "이전의 데이터베이스 백업에서 복원하기" @@ -2399,8 +2537,8 @@ msgid "Select Liquidity" msgstr "" #: dashboard/pages/SetupPersona/LocalBackup/index.tsx -msgid "Select the contents of the backup" -msgstr "백업 내용을 선택하세요." +#~ msgid "Select the contents of the backup" +#~ msgstr "" #: popups/pages/Wallet/Interaction/PermissionRequest.tsx msgid "Select the wallet(s) to use on this site. You should not connect to website you don't trust." @@ -2411,8 +2549,8 @@ msgid "Select Wallet" msgstr "월렛 선택" #: content-script/components/InjectedComponents/SetupGuide/VerifyNextID.tsx -#: dashboard/pages/SetupPersona/CloudBackup/PhoneForm.tsx -#: dashboard/pages/SetupPersona/CloudBackup/EmailForm.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/PhoneForm.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/EmailForm.tsx #: popups/pages/Wallet/components/ActivityList/ActivityItem.tsx #: popups/pages/Wallet/components/ActionGroup/index.tsx #: popups/pages/Wallet/Transfer/index.tsx @@ -2486,8 +2624,8 @@ msgid "Sign" msgstr "사인" #: dashboard/pages/SetupPersona/Recovery/index.tsx -msgid "Sign Up" -msgstr "가입하기" +#~ msgid "Sign Up" +#~ msgstr "" #: popups/components/SignRequestInfo/index.tsx msgid "Sign-in Request" @@ -2614,8 +2752,7 @@ msgstr "지원되는 사이트" msgid "Swap" msgstr "" -#: dashboard/pages/SetupPersona/CloudBackupPreview/index.tsx -#: dashboard/pages/SetupPersona/CloudBackupPreview/index.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/Preview.tsx msgid "Switch other account" msgstr "사용자 계정 전환" @@ -2623,7 +2760,7 @@ msgstr "사용자 계정 전환" msgid "Switch Persona" msgstr "페르소나 전환" -#: dashboard/components/Restore/RestoreFromCloud/ConfirmBackupInfo.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/ConfirmBackupInfo.tsx msgid "Switch to other accounts" msgstr "" @@ -2652,16 +2789,23 @@ msgstr "" msgid "The chainID is not equal to the currently connected one." msgstr "" -#: dashboard/pages/SetupPersona/CloudBackup/index.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/MaskNetwork.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/CloudBackupFormContext.ts +#: dashboard/pages/SetupPersona/Backup/Cloud/CloudBackupFormContext.ts #: dashboard/contexts/CloudBackupFormContext.tsx #: dashboard/contexts/CloudBackupFormContext.tsx msgid "The code is incorrect." msgstr "코드가 잘못되었습니다." -#: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx +#: dashboard/utils/api.ts msgid "The download link is expired" msgstr "" +#: dashboard/pages/SetupPersona/Recovery/Cloud/MaskNetwork.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/MaskNetwork.tsx +msgid "The Mask Network Cloud Backup feature will be deactivated on April 30, 2025. Please use alternative cloud backup services or local backup solutions." +msgstr "" + #: dashboard/pages/CreateMaskWallet/CreateMnemonic/index.tsx msgid "The mnemonic word has been copied, please keep it in a safe place." msgstr "" @@ -2700,6 +2844,7 @@ msgstr "" msgid "The persona name already exists." msgstr "이미 존재된 페르소나입니다" +#: dashboard/pages/SetupPersona/Backup/Cloud/CloudBackupFormContext.ts #: dashboard/contexts/CloudBackupFormContext.tsx msgid "The phone number is incorrect." msgstr "전화번호가 잘못되었습니다." @@ -2922,13 +3067,13 @@ msgstr "" msgid "Unlock" msgstr "언락" +#: dashboard/pages/SetupPersona/Recovery/Local.tsx #: dashboard/components/Restore/RestoreWalletFromLocal.tsx -#: dashboard/components/Restore/RestorePersonaFromLocal.tsx msgid "Unpacking" msgstr "" -#: dashboard/components/Restore/RestorePersonaFromLocal.tsx -#: dashboard/components/Restore/RestorePersonaFromLocal.tsx +#: dashboard/pages/SetupPersona/Recovery/Local.tsx +#: dashboard/pages/SetupPersona/Recovery/Local.tsx msgid "Unsupported data backup" msgstr "지원하지 않는 데이터 백업" @@ -2976,16 +3121,16 @@ msgstr "텍스 암호화 이용" msgid "value" msgstr "값" -#: dashboard/components/Restore/RestoreFromCloud/EmailField.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/EmailField.tsx msgid "Verification code has been sent to your email. Please check your mailbox." msgstr "" -#: dashboard/components/Restore/RestoreFromCloud/PhoneField.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/PhoneField.tsx msgid "Verification code has been sent to your phone." msgstr "" -#: dashboard/pages/SetupPersona/CloudBackup/PhoneForm.tsx -#: dashboard/pages/SetupPersona/CloudBackup/EmailForm.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/PhoneForm.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/EmailForm.tsx msgid "Verification code sent" msgstr "인증 코드가 발송되었습니다" @@ -3038,8 +3183,8 @@ msgid "Waiting for {providerType}" msgstr "" #: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx -msgid "wallet" -msgstr "월렛" +#~ msgid "wallet" +#~ msgstr "" #: popups/pages/Wallet/SwitchWallet/index.tsx #: popups/modals/WalletGroupModal/index.tsx @@ -3096,8 +3241,8 @@ msgid "Welcome Back" msgstr "환영합니다" #: dashboard/pages/SetupPersona/CloudBackupPreview/index.tsx -msgid "Welcome to Mask Cloud Services" -msgstr "" +#~ msgid "Welcome to Mask Cloud Services" +#~ msgstr "" #: popups/pages/Personas/Home/UI.tsx msgid "Welcome to Mask Network" @@ -3107,6 +3252,10 @@ msgstr "환영합니다" msgid "Welcome to use Mask Network" msgstr "환영합니다" +#: dashboard/components/GoogleDriveLogin.tsx +msgid "when you click Add Google Drive button,you will be forwarded to Google authorization pages." +msgstr "" + #: popups/pages/Wallet/ExportPrivateKey/index.tsx msgid "Write down mnemonic words" msgstr "니모닉 단어를 적어두세요" @@ -3120,21 +3269,25 @@ msgid "You could check the verification result on Mask Pop-up after few minutes. msgstr "" #: dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx -msgid "You have backed up your data." -msgstr "" +#~ msgid "You have backed up your data." +#~ msgstr "" #: dashboard/pages/SetupPersona/Onboarding/index.tsx #~ msgid "You have recovered" #~ msgstr "" #: dashboard/pages/SetupPersona/Onboarding/index.tsx -msgid "You have recovered " -msgstr "" +#~ msgid "You have recovered " +#~ msgstr "" #: popups/pages/Personas/ConnectWallet/index.tsx msgid "You have signed with your wallet." msgstr "" +#: dashboard/pages/SetupPersona/Recovery/Cloud/GoogleDrive.tsx +msgid "You have successfully restored the backup from Google Drive to your browser." +msgstr "" + #: dashboard/components/Restore/ConfirmSynchronizePasswordDialog.tsx msgid "You have verified your cloud password and recovered your backup. Do you want to let your cloud password and local backup password be the same?" msgstr "" @@ -3143,26 +3296,41 @@ msgstr "" msgid "You need to open the dApp to view the specific content." msgstr "" -#. placeholder {0}: user.email #: dashboard/pages/SetupPersona/CloudBackup/index.tsx #: dashboard/pages/SetupPersona/CloudBackup/index.tsx -msgid "You used <0>{0} for the last cloud backup." -msgstr "" +#~ msgid "You used <0>{0} for the last cloud backup." +#~ msgstr "" #: popups/components/SignRequestInfo/index.tsx msgid "Your connection to this site is not encrypted which can be modified by a hostile third party, we strongly suggest you reject this request." msgstr "" +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx +msgid "Your file has been successfully merged into the browser data." +msgstr "" + +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx +msgid "Your file has been successfully restore into the browser data." +msgstr "" + #: dashboard/pages/CreateMaskWallet/CreateWalletForm/index.tsx msgid "Your payment password encrypts wallet data and is needed to unlocking the wallet, transaction confirmations and signing. The password is never stored, and there is no way to recover it if you forget it." msgstr "" +#: dashboard/pages/SetupPersona/Onboarding/index.tsx +msgid "Your Persona has been successfully created." +msgstr "" + #: dashboard/pages/SetupPersona/Onboarding/index.tsx #~ msgid "Your Persona is on" #~ msgstr "" #: dashboard/pages/SetupPersona/Onboarding/index.tsx -msgid "Your Persona is on " +#~ msgid "Your Persona is on " +#~ msgstr "" + +#: dashboard/pages/SetupPersona/Onboarding/index.tsx +msgid "Your Persona is on **ready 🚀**" msgstr "" #: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx @@ -3170,5 +3338,9 @@ msgstr "" #~ msgstr "" #: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx -msgid "Your Wallet is on " +#~ msgid "Your Wallet is on " +#~ msgstr "" + +#: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx +msgid "Your Wallet is on **ready 🚀**" msgstr "" diff --git a/packages/mask/shared-ui/locale/qya-AA.po b/packages/mask/shared-ui/locale/qya-AA.po index bf1bb6be2c2a..b50b0ae13eb3 100644 --- a/packages/mask/shared-ui/locale/qya-AA.po +++ b/packages/mask/shared-ui/locale/qya-AA.po @@ -3,7 +3,7 @@ msgstr "" "Project-Id-Version: mask-network\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2025-01-08 06:53\n" +"PO-Revision-Date: 2025-04-10 05:53\n" "Last-Translator: \n" "Language: qya_AA\n" "Language-Team: Quenya\n" @@ -20,29 +20,38 @@ msgstr "" msgid "(the name is set by the web site)" msgstr "crwdns29840:0crwdne29840:0" +#. placeholder {0}: millisecondsToHours(value) #: popups/pages/Wallet/WalletSettings/AutoLock.tsx msgid "{0, plural, one {# Hour} other {# Hours}}" msgstr "crwdns32756:00={0}crwdne32756:0" +#. placeholder {0}: formatTokenBalance(tokenBalance, token?.decimals) #: popups/pages/Wallet/Transfer/FungibleTokenSection.tsx msgid "{0} available" msgstr "crwdns29842:0{0}crwdne29842:0" +#. placeholder {0}: wallet?.name || 'Your wallet' #: popups/pages/Wallet/ConnectedSites/index.tsx msgid "{0} is connected to these sites, they can view your account address." msgstr "crwdns35868:0{0}crwdne35868:0" +#. placeholder {0}: millisecondsToMinutes(value) #: popups/pages/Wallet/WalletSettings/AutoLock.tsx msgid "{0} Mins" msgstr "crwdns29844:0{0}crwdne29844:0" +#. placeholder {0}: pendingTransactions.length #: content-script/components/InjectedComponents/ToolboxUnstyled.tsx msgid "{0} Pending" msgstr "crwdns32758:0{0}crwdne32758:0" #: dashboard/pages/SetupPersona/Onboarding/index.tsx -msgid "{count, plural, one {# Wallet 🚀} other {# Wallets 🚀}}" -msgstr "crwdns32760:0count={count}crwdne32760:0" +#~ msgid "{count, plural, one {# Wallet 🚀} other {# Wallets 🚀}}" +#~ msgstr "" + +#: dashboard/pages/SetupPersona/Onboarding/index.tsx +msgid "{count, plural, one {You have recovered **# Wallet 🚀**} other {You have recovered **# Wallets 🚀**}}" +msgstr "crwdns37278:0count={count}crwdne37278:0" #: content-script/components/InjectedComponents/DecryptedPost/DecryptPostAwaiting.tsx msgid "{decryptProgress, select, finding_post_key {Mask is finding the key to decrypt this message. If this last for a long time, this post might not be shared to you.} finding_person_public_key {Mask is looking for the public key of the author...} other {Mask is decrypting...}}" @@ -64,10 +73,15 @@ msgstr "crwdns32766:0websiteCount={websiteCount}crwdnd32766:0websiteCount={websi msgid "<0>@{currentUserId} connected already." msgstr "crwdns32768:0{currentUserId}crwdne32768:0" +#. placeholder {0}: formatEthereumAddress(transaction.formattedTransaction.popup.spender, 4) #: popups/pages/Wallet/Interaction/TransactionRequest.tsx msgid "<0>Granted to <1>{0}" msgstr "crwdns31978:0{0}crwdne31978:0" +#: popups/pages/Wallet/WalletSettings/DisablePermit.tsx +msgid "<0>Permit allows users to authorize an address to access their ERC-20 tokens without requiring a separate approval transaction, providing a more efficient way to manage token permissions.<1>However, if the authorized limit is exceeded or the Permit expires, the authorization automatically becomes invalid. Despite this, security risks remain.<2>To prevent potential misuse, you can disable the Permit feature." +msgstr "crwdns36714:0crwdne36714:0" + #: content-script/components/InjectedComponents/ProfileTabContent.tsx msgid "<0>Powered by<1>Mask Network" msgstr "crwdns31980:0crwdne31980:0" @@ -108,6 +122,10 @@ msgstr "crwdns29850:0crwdne29850:0" msgid "About {collectionName}" msgstr "crwdns31984:0{collectionName}crwdne31984:0" +#: popups/pages/Wallet/WalletSettings/DisablePermit.tsx +msgid "About Permit" +msgstr "crwdns36716:0crwdne36716:0" + #: content-script/components/InjectedComponents/SetupGuide/VerifyNextID.tsx msgid "Account connected.<0/><1/>Try to explore more features powered by Mask Network." msgstr "crwdns31986:0crwdne31986:0" @@ -116,10 +134,10 @@ msgstr "crwdns31986:0crwdne31986:0" msgid "Account successfully connected to persona" msgstr "crwdns29854:0crwdne29854:0" -#: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx #: dashboard/pages/SetupPersona/Onboarding/index.tsx -msgid "accounts" -msgstr "crwdns29528:0crwdne29528:0" +#: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx +#~ msgid "accounts" +#~ msgstr "" #: popups/pages/Wallet/components/WalletAssets/index.tsx msgid "Activities" @@ -129,9 +147,9 @@ msgstr "crwdns29856:0crwdne29856:0" msgid "Activity Log" msgstr "crwdns29858:0crwdne29858:0" -#: popups/modals/SwitchPersonaModal/index.tsx -#: popups/pages/Friends/ContactCard/index.tsx #: popups/pages/Wallet/CreateWallet/Derive.tsx +#: popups/pages/Friends/ContactCard/index.tsx +#: popups/modals/SwitchPersonaModal/index.tsx msgid "Add" msgstr "crwdns29860:0crwdne29860:0" @@ -143,13 +161,17 @@ msgstr "crwdns31988:0crwdne31988:0" msgid "Add Assets" msgstr "crwdns29864:0crwdne29864:0" -#: popups/components/AddContactInputPanel/index.tsx #: popups/pages/Wallet/ContactList/index.tsx +#: popups/components/AddContactInputPanel/index.tsx msgid "Add Contact" msgstr "crwdns29866:0crwdne29866:0" -#: popups/pages/Wallet/EditNetwork/index.tsx +#: dashboard/components/GoogleDriveLogin.tsx +msgid "Add google Drive" +msgstr "crwdns37222:0crwdne37222:0" + #: popups/pages/Wallet/NetworkManagement/index.tsx +#: popups/pages/Wallet/EditNetwork/index.tsx msgid "Add Network" msgstr "crwdns29870:0crwdne29870:0" @@ -161,15 +183,19 @@ msgstr "crwdns29872:0crwdne29872:0" msgid "Add Suggested Token" msgstr "crwdns29874:0crwdne29874:0" +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx +msgid "Add the file to Chrome's database" +msgstr "crwdns37262:0crwdne37262:0" + #: popups/pages/Wallet/components/StartUp/index.tsx -#: popups/pages/Wallet/CreateWallet/Derive.tsx -#: popups/pages/Wallet/CreateWallet/index.tsx #: popups/pages/Wallet/SwitchWallet/index.tsx +#: popups/pages/Wallet/CreateWallet/index.tsx +#: popups/pages/Wallet/CreateWallet/Derive.tsx msgid "Add Wallet" msgstr "crwdns29876:0crwdne29876:0" -#: popups/components/TokenPicker/TokenItem.tsx #: popups/pages/Wallet/components/AssetsList/index.tsx +#: popups/components/TokenPicker/TokenItem.tsx msgid "Added by user" msgstr "crwdns29878:0crwdne29878:0" @@ -197,8 +223,8 @@ msgstr "crwdns29886:0crwdne29886:0" msgid "After logging out, your associated social accounts will no longer decrypt old encrypted messages. If you need to use your account again, you can recover your account with your identity, private key, local or cloud backup." msgstr "crwdns31992:0crwdne31992:0" -#: dashboard/pages/SetupPersona/Permissions/index.tsx #: dashboard/pages/SetupPersona/Welcome/index.tsx +#: dashboard/pages/SetupPersona/Permissions/index.tsx msgid "Agree" msgstr "crwdns29532:0crwdne29532:0" @@ -219,8 +245,8 @@ msgstr "crwdns29894:0crwdne29894:0" msgid "Allow us to collect your usage information to help us improve Mask." msgstr "crwdns31996:0crwdne31996:0" -#: popups/pages/Wallet/TransactionDetail/index.tsx #: popups/pages/Wallet/Transfer/FungibleTokenSection.tsx +#: popups/pages/Wallet/TransactionDetail/index.tsx msgid "Amount" msgstr "crwdns29896:0crwdne29896:0" @@ -228,14 +254,14 @@ msgstr "crwdns29896:0crwdne29896:0" msgid "an NFT" msgstr "crwdns29898:0crwdne29898:0" -#: popups/modals/SelectAppearanceModal/index.tsx #: popups/pages/Settings/index.tsx +#: popups/modals/SelectAppearanceModal/index.tsx msgid "Appearance" msgstr "crwdns29900:0crwdne29900:0" #: content-script/components/InjectedComponents/DisabledPluginSuggestion.tsx -#: popups/modals/UpdatePermissionModal/index.tsx #: popups/pages/RequestPermission/RequestPermission.tsx +#: popups/modals/UpdatePermissionModal/index.tsx msgid "Approve" msgstr "crwdns29902:0crwdne29902:0" @@ -244,9 +270,10 @@ msgid "Approve amount" msgstr "crwdns29904:0crwdne29904:0" #: dashboard/pages/SetupPersona/CloudBackupPreview/index.tsx -msgid "Are you sure to overwrite the backups stored on Mask Cloud Service?" -msgstr "crwdns31998:0crwdne31998:0" +#~ msgid "Are you sure to overwrite the backups stored on Mask Cloud Service?" +#~ msgstr "" +#. placeholder {0}: formatEthereumAddress(wallet.identity, 4) #: popups/components/ConnectedWallet/index.tsx msgid "Are you sure to remove the connected wallet <0>{0}?" msgstr "crwdns32774:0{0}crwdne32774:0" @@ -272,11 +299,15 @@ msgid "Associated Accounts" msgstr "crwdns29536:0crwdne29536:0" #: dashboard/pages/CreateMaskWallet/CreateWalletForm/index.tsx -#: popups/modals/ChangePaymentPasswordModal/index.tsx #: popups/pages/Wallet/SetPaymentPassword/index.tsx +#: popups/modals/ChangePaymentPasswordModal/index.tsx msgid "At least 6 characters" msgstr "crwdns29538:0crwdne29538:0" +#: dashboard/components/GoogleDriveLogin.tsx +msgid "Authorization Failed" +msgstr "crwdns37292:0crwdne37292:0" + #: popups/pages/Wallet/WalletSettings/AutoLock.tsx msgid "Auto-lock" msgstr "crwdns29916:0crwdne29916:0" @@ -290,15 +321,26 @@ msgid "Avatar set successfully" msgstr "crwdns29920:0crwdne29920:0" #: content-script/components/shared/SelectRecipients/SelectRecipientsDialog.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/Preview.tsx #: dashboard/pages/CreateMaskWallet/CreateMnemonic/index.tsx -#: popups/pages/Personas/AccountDetail/UI.tsx #: popups/pages/Personas/ExportPrivateKey/index.tsx +#: popups/pages/Personas/AccountDetail/UI.tsx msgid "Back" msgstr "crwdns29540:0crwdne29540:0" -#: dashboard/pages/SetupPersona/CloudBackupPreview/index.tsx -#: popups/modals/SwitchPersonaModal/index.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/GoogleDrive.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/GoogleDrive.tsx +#~ msgid "Back Up to Google Drive" +#~ msgstr "" + +#: dashboard/pages/SetupPersona/Backup/index.tsx +msgid "Back Up Your Data Your Way" +msgstr "crwdns37226:0crwdne37226:0" + +#: dashboard/pages/SetupPersona/Backup/Cloud/GoogleDrive.tsx +#: dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx #: popups/pages/Personas/Logout/index.tsx +#: popups/modals/SwitchPersonaModal/index.tsx msgid "Backup" msgstr "crwdns29542:0crwdne29542:0" @@ -307,53 +349,64 @@ msgid "Backup & Recovery" msgstr "crwdns29922:0crwdne29922:0" #: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx -msgid "Backup downloaded and merged to local successfully." -msgstr "crwdns29546:0crwdne29546:0" +#~ msgid "Backup downloaded and merged to local successfully." +#~ msgstr "" #: dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx msgid "Backup Failed" msgstr "crwdns29548:0crwdne29548:0" #: dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx -msgid "Backup is saved to Mask Cloud Service." -msgstr "crwdns32004:0crwdne32004:0" +#~ msgid "Backup is saved to Mask Cloud Service." +#~ msgstr "" +#. placeholder {0}: user.localBackupAt +#. placeholder {0}: user.cloudBackupAt #: popups/pages/Settings/index.tsx #: popups/pages/Settings/index.tsx msgid "Backup on {0}" msgstr "crwdns29924:0{0}crwdne29924:0" -#: dashboard/components/Restore/RestoreFromCloud/ConfirmBackupInfo.tsx -#: dashboard/components/Restore/RestorePersonaFromLocal.tsx +#: dashboard/pages/SetupPersona/Recovery/Local.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/ConfirmBackupInfo.tsx msgid "Backup password" msgstr "crwdns29550:0crwdne29550:0" +#: dashboard/pages/SetupPersona/Backup/Local.tsx +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx #: dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx -#: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx -#: dashboard/pages/SetupPersona/LocalBackup/index.tsx -#: popups/modals/SetBackupPasswordModal/index.tsx #: popups/pages/Settings/index.tsx +#: popups/modals/SetBackupPasswordModal/index.tsx msgid "Backup Password" msgstr "crwdns29552:0crwdne29552:0" -#: popups/modals/ChangeBackupPasswordModal/index.tsx #: popups/modals/SetBackupPasswordModal/index.tsx +#: popups/modals/ChangeBackupPasswordModal/index.tsx msgid "Backup password must be 8-20 characters, including uppercase, lowercase, special characters and numbers." msgstr "crwdns29926:0crwdne29926:0" -#: popups/modals/ChangeBackupPasswordModal/index.tsx #: popups/modals/SetBackupPasswordModal/index.tsx +#: popups/modals/ChangeBackupPasswordModal/index.tsx msgid "Backup password set successfully" msgstr "crwdns29928:0crwdne29928:0" -#: popups/modals/PersonaSettingModal/index.tsx #: popups/modals/VerifyBackupPasswordModal/index.tsx +#: popups/modals/PersonaSettingModal/index.tsx msgid "Backup Persona" msgstr "crwdns29930:0crwdne29930:0" +#: dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx +msgid "Backup Successful" +msgstr "crwdns37228:0crwdne37228:0" + +#: dashboard/pages/SetupPersona/Backup/Cloud/GoogleDrive.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/GoogleDrive.tsx +msgid "Backup to Google Drive" +msgstr "crwdns37294:0crwdne37294:0" + #: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx -msgid "Backup to Mask Cloud Service" -msgstr "crwdns29556:0crwdne29556:0" +#~ msgid "Backup to Mask Cloud Service" +#~ msgstr "" #: dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx msgid "Backup to the Cloud" @@ -396,8 +449,8 @@ msgstr "crwdns32008:0crwdne32008:0" msgid "Browser File" msgstr "crwdns29948:0crwdne29948:0" -#: dashboard/pages/SetupPersona/Permissions/index.tsx #: dashboard/pages/SetupPersona/Welcome/index.tsx +#: dashboard/pages/SetupPersona/Permissions/index.tsx msgid "By continuing to the app, you agree to these <0>Service Agreement and <1>Privacy Policy." msgstr "crwdns32776:0crwdne32776:0" @@ -418,30 +471,29 @@ msgid "Can't find a valid user address data source." msgstr "crwdns32010:0crwdne32010:0" #: content-script/components/InjectedComponents/SelectPeopleDialog.tsx -#: dashboard/components/Restore/ConfirmSynchronizePasswordDialog.tsx -#: dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx -#: dashboard/modals/ConfirmModal/index.tsx -#: dashboard/pages/SetupPersona/CloudBackupPreview/index.tsx -#: dashboard/pages/SetupPersona/Permissions/index.tsx #: dashboard/pages/SetupPersona/Welcome/index.tsx -#: popups/modals/AddContactModal/index.tsx -#: popups/modals/DeleteContactModal/index.tsx -#: popups/modals/EditContactModal/index.tsx -#: popups/modals/GasSettingModal/index.tsx -#: popups/pages/Personas/ConnectWallet/index.tsx -#: popups/pages/Personas/Logout/index.tsx -#: popups/pages/Personas/PersonaAvatarSetting/index.tsx -#: popups/pages/Personas/PersonaSignRequest/index.tsx -#: popups/pages/RequestPermission/RequestPermission.tsx -#: popups/pages/Wallet/ChangeOwner/index.tsx -#: popups/pages/Wallet/components/ActivityList/ActivityItem.tsx +#: dashboard/pages/SetupPersona/Permissions/index.tsx +#: dashboard/modals/ConfirmModal/index.tsx +#: dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx +#: dashboard/components/Restore/ConfirmSynchronizePasswordDialog.tsx #: popups/pages/Wallet/components/DisconnectModal/index.tsx -#: popups/pages/Wallet/EditNetwork/index.tsx -#: popups/pages/Wallet/Interaction/interaction.tsx -#: popups/pages/Wallet/ResetWallet/index.tsx -#: popups/pages/Wallet/SelectWallet/index.tsx -#: popups/pages/Wallet/TransactionDetail/index.tsx +#: popups/pages/Wallet/components/ActivityList/ActivityItem.tsx #: popups/pages/Wallet/Transfer/FungibleTokenSection.tsx +#: popups/pages/Wallet/TransactionDetail/index.tsx +#: popups/pages/Wallet/SelectWallet/index.tsx +#: popups/pages/Wallet/ResetWallet/index.tsx +#: popups/pages/Wallet/Interaction/interaction.tsx +#: popups/pages/Wallet/EditNetwork/index.tsx +#: popups/pages/Wallet/ChangeOwner/index.tsx +#: popups/pages/RequestPermission/RequestPermission.tsx +#: popups/pages/Personas/PersonaSignRequest/index.tsx +#: popups/pages/Personas/PersonaAvatarSetting/index.tsx +#: popups/pages/Personas/Logout/index.tsx +#: popups/pages/Personas/ConnectWallet/index.tsx +#: popups/modals/GasSettingModal/index.tsx +#: popups/modals/EditContactModal/index.tsx +#: popups/modals/DeleteContactModal/index.tsx +#: popups/modals/AddContactModal/index.tsx msgid "Cancel" msgstr "crwdns29558:0crwdne29558:0" @@ -449,18 +501,20 @@ msgstr "crwdns29558:0crwdne29558:0" msgid "Cannot switch to a unknown network." msgstr "crwdns29956:0crwdne29956:0" -#: popups/components/SignRequestInfo/index.tsx #: popups/pages/Wallet/EditNetwork/index.tsx +#: popups/components/SignRequestInfo/index.tsx msgid "Chain ID" msgstr "crwdns29958:0crwdne29958:0" +#. placeholder {0}: currentNetwork?.chainId ?? currentChainId +#. placeholder {0}: nextNetwork?.chainId ?? nextChainId #: popups/pages/Wallet/Interaction/SwitchChainRequest.tsx #: popups/pages/Wallet/Interaction/SwitchChainRequest.tsx msgid "Chain ID: {0}" msgstr "crwdns32012:0{0}crwdne32012:0" -#: popups/pages/Personas/ConnectWallet/index.tsx #: popups/pages/Wallet/ChangeOwner/index.tsx +#: popups/pages/Personas/ConnectWallet/index.tsx msgid "Change" msgstr "crwdns29960:0crwdne29960:0" @@ -468,8 +522,8 @@ msgstr "crwdns29960:0crwdne29960:0" msgid "Change another account and try again." msgstr "crwdns32014:0crwdne32014:0" -#: popups/modals/ChangeBackupPasswordModal/index.tsx #: popups/pages/Settings/index.tsx +#: popups/modals/ChangeBackupPasswordModal/index.tsx msgid "Change Backup Password" msgstr "crwdns29962:0crwdne29962:0" @@ -477,8 +531,8 @@ msgstr "crwdns29962:0crwdne29962:0" msgid "Change Network" msgstr "crwdns29964:0crwdne29964:0" -#: popups/pages/Wallet/ChangeOwner/index.tsx #: popups/pages/Wallet/WalletSettings/ChangeOwner.tsx +#: popups/pages/Wallet/ChangeOwner/index.tsx msgid "Change Owner" msgstr "crwdns29966:0crwdne29966:0" @@ -491,6 +545,10 @@ msgstr "crwdns29968:0crwdne29968:0" msgid "Choose another wallet" msgstr "crwdns29972:0crwdne29972:0" +#: dashboard/pages/SetupPersona/Backup/index.tsx +msgid "Choose from multiple backup options, now including encrypted storage via your authorized Google Drive for added security and flexibility." +msgstr "crwdns37230:0crwdne37230:0" + #: popups/modals/ChooseToken/index.tsx msgid "Choose Token" msgstr "crwdns29974:0crwdne29974:0" @@ -515,8 +573,9 @@ msgstr "crwdns32018:0crwdne32018:0" msgid "Close" msgstr "crwdns29982:0crwdne29982:0" -#: dashboard/components/Restore/ConfirmSynchronizePasswordDialog.tsx #: dashboard/pages/SetupPersona/Recovery/index.tsx +#: dashboard/pages/SetupPersona/Backup/index.tsx +#: dashboard/components/Restore/ConfirmSynchronizePasswordDialog.tsx #: popups/pages/Settings/index.tsx msgid "Cloud Backup" msgstr "crwdns29560:0crwdne29560:0" @@ -529,36 +588,35 @@ msgstr "crwdns29984:0crwdne29984:0" msgid "Coming soon" msgstr "crwdns29986:0crwdne29986:0" -#: dashboard/components/Restore/RestorePersonaFromLocal.tsx +#: dashboard/pages/SetupPersona/Recovery/Local.tsx #: dashboard/components/Restore/RestoreWalletFromLocal.tsx msgid "Completed" msgstr "crwdns29562:0crwdne29562:0" -#: dashboard/components/Restore/ConfirmSynchronizePasswordDialog.tsx #: dashboard/modals/ConfirmModal/index.tsx -#: dashboard/pages/SetupPersona/CloudBackupPreview/index.tsx -#: popups/components/NFTAvatarPicker/index.tsx -#: popups/modals/AddContactModal/index.tsx -#: popups/modals/ChangeBackupPasswordModal/index.tsx -#: popups/modals/ChangePaymentPasswordModal/index.tsx -#: popups/modals/ConfirmModal/index.tsx -#: popups/modals/EditContactModal/index.tsx -#: popups/modals/GasSettingModal/GasSettingDialog.tsx -#: popups/modals/PersonaRenameModal/index.tsx -#: popups/modals/SetBackupPasswordModal/index.tsx -#: popups/modals/ShowPrivateKeyModal/index.tsx -#: popups/modals/WalletAutoLockSettingModal/index.tsx -#: popups/modals/WalletRenameModal/index.tsx -#: popups/pages/Personas/PersonaAvatarSetting/index.tsx +#: dashboard/components/Restore/ConfirmSynchronizePasswordDialog.tsx #: popups/pages/Wallet/components/DisconnectModal/index.tsx -#: popups/pages/Wallet/EditNetwork/index.tsx -#: popups/pages/Wallet/GasSetting/GasSetting1559.tsx -#: popups/pages/Wallet/GasSetting/Prior1559GasSetting.tsx -#: popups/pages/Wallet/Interaction/interaction.tsx -#: popups/pages/Wallet/ResetWallet/index.tsx -#: popups/pages/Wallet/SelectWallet/index.tsx -#: popups/pages/Wallet/SetPaymentPassword/index.tsx #: popups/pages/Wallet/Transfer/NonFungibleTokenSection.tsx +#: popups/pages/Wallet/SetPaymentPassword/index.tsx +#: popups/pages/Wallet/SelectWallet/index.tsx +#: popups/pages/Wallet/ResetWallet/index.tsx +#: popups/pages/Wallet/Interaction/interaction.tsx +#: popups/pages/Wallet/GasSetting/Prior1559GasSetting.tsx +#: popups/pages/Wallet/GasSetting/GasSetting1559.tsx +#: popups/pages/Wallet/EditNetwork/index.tsx +#: popups/pages/Personas/PersonaAvatarSetting/index.tsx +#: popups/modals/WalletRenameModal/index.tsx +#: popups/modals/WalletAutoLockSettingModal/index.tsx +#: popups/modals/ShowPrivateKeyModal/index.tsx +#: popups/modals/SetBackupPasswordModal/index.tsx +#: popups/modals/PersonaRenameModal/index.tsx +#: popups/modals/GasSettingModal/GasSettingDialog.tsx +#: popups/modals/EditContactModal/index.tsx +#: popups/modals/ConfirmModal/index.tsx +#: popups/modals/ChangePaymentPasswordModal/index.tsx +#: popups/modals/ChangeBackupPasswordModal/index.tsx +#: popups/modals/AddContactModal/index.tsx +#: popups/components/NFTAvatarPicker/index.tsx msgid "Confirm" msgstr "crwdns29564:0crwdne29564:0" @@ -566,8 +624,8 @@ msgstr "crwdns29564:0crwdne29564:0" msgid "Confirm Bridge" msgstr "crwdns35396:0crwdne35396:0" -#: popups/modals/ChangePaymentPasswordModal/index.tsx #: popups/pages/Wallet/SetPaymentPassword/index.tsx +#: popups/modals/ChangePaymentPasswordModal/index.tsx msgid "Confirm Password" msgstr "crwdns29988:0crwdne29988:0" @@ -579,6 +637,7 @@ msgstr "crwdns29566:0crwdne29566:0" msgid "Confirm Swap" msgstr "crwdns35398:0crwdne35398:0" +#. placeholder {0}: asset.symbol #: popups/pages/Wallet/TokenDetail/index.tsx msgid "Confirm to hide {0}? You can redisplay it by re-adding this token at any time." msgstr "crwdns29992:0{0}crwdne29992:0" @@ -587,16 +646,14 @@ msgstr "crwdns29992:0{0}crwdne29992:0" msgid "Confirm to hide {name}? You can redisplay it by re-adding this NFT at any time." msgstr "crwdns32020:0{name}crwdne32020:0" -#: dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx -#: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx #: popups/pages/Personas/ConnectWallet/index.tsx msgid "Congratulations" msgstr "crwdns29568:0crwdne29568:0" #: content-script/components/CompositionDialog/EncryptionTargetSelector.tsx -#: popups/components/ConnectedWallet/index.tsx -#: popups/components/SocialAccounts/index.tsx #: popups/modals/SelectProviderModal/index.tsx +#: popups/components/SocialAccounts/index.tsx +#: popups/components/ConnectedWallet/index.tsx msgid "Connect" msgstr "crwdns29994:0crwdne29994:0" @@ -621,10 +678,10 @@ msgstr "crwdns30002:0crwdne30002:0" msgid "Connect Wallet" msgstr "crwdns30004:0crwdne30004:0" -#: popups/pages/Wallet/Interaction/AddChainRequest.tsx +#: popups/pages/Wallet/Interaction/SwitchChainRequest.tsx #: popups/pages/Wallet/Interaction/PermissionRequest.tsx #: popups/pages/Wallet/Interaction/PermissionRequest.tsx -#: popups/pages/Wallet/Interaction/SwitchChainRequest.tsx +#: popups/pages/Wallet/Interaction/AddChainRequest.tsx msgid "Connect with Mask Wallet" msgstr "crwdns30006:0crwdne30006:0" @@ -641,15 +698,20 @@ msgstr "crwdns30010:0crwdne30010:0" msgid "Connected" msgstr "crwdns32782:0crwdne32782:0" +#. placeholder {0}: currentPersona?.nickname #: popups/pages/Personas/ConnectWallet/index.tsx msgid "Connected {0} with {walletName}." msgstr "crwdns32022:0{0}crwdnd32022:0{walletName}crwdne32022:0" -#: popups/pages/Wallet/ConnectedSites/index.tsx #: popups/pages/Wallet/WalletSettings/ConnectedOrigins.tsx +#: popups/pages/Wallet/ConnectedSites/index.tsx msgid "Connected sites" msgstr "crwdns30012:0crwdne30012:0" +#: content-script/components/InjectedComponents/SetupGuide/AccountConnectStatus.tsx +msgid "Connected successfully." +msgstr "crwdns36875:0crwdne36875:0" + #: popups/pages/Personas/Home/UI.tsx msgid "Connected Wallet" msgstr "crwdns30014:0crwdne30014:0" @@ -675,30 +737,32 @@ msgid "Contact edited." msgstr "crwdns32030:0crwdne32030:0" #: dashboard/components/BackupPreview/index.tsx -#: popups/pages/Friends/Home/index.tsx +#: popups/pages/Wallet/WalletSettings/Contacts.tsx #: popups/pages/Wallet/ContactList/index.tsx #: popups/pages/Wallet/ContactList/index.tsx -#: popups/pages/Wallet/WalletSettings/Contacts.tsx +#: popups/pages/Friends/Home/index.tsx msgid "Contacts" msgstr "crwdns29570:0crwdne29570:0" -#: dashboard/components/Restore/RestoreFromCloud/EmailField.tsx -#: dashboard/components/Restore/RestoreFromCloud/PhoneField.tsx -#: dashboard/components/Restore/RestoreFromMnemonic.tsx -#: dashboard/components/Restore/RestoreFromPrivateKey.tsx -#: dashboard/components/Restore/RestorePersonaFromLocal.tsx -#: dashboard/components/Restore/RestoreWalletFromLocal.tsx -#: dashboard/pages/CreateMaskWallet/AddDeriveWallet/index.tsx -#: dashboard/pages/CreateMaskWallet/CreateWalletForm/index.tsx -#: dashboard/pages/SetupPersona/CloudBackup/index.tsx -#: dashboard/pages/SetupPersona/Mnemonic/index.tsx -#: dashboard/pages/SetupPersona/SignUp/index.tsx #: dashboard/pages/SignUp/steps/PersonaNameUI.tsx +#: dashboard/pages/SetupPersona/SignUp/index.tsx +#: dashboard/pages/SetupPersona/Recovery/PrivateKey.tsx +#: dashboard/pages/SetupPersona/Recovery/Phrase.tsx +#: dashboard/pages/SetupPersona/Recovery/Local.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/PhoneField.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/EmailField.tsx +#: dashboard/pages/SetupPersona/Mnemonic/index.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/MaskNetwork.tsx +#: dashboard/pages/CreateMaskWallet/CreateWalletForm/index.tsx +#: dashboard/pages/CreateMaskWallet/AddDeriveWallet/index.tsx +#: dashboard/components/Restore/RestoreWalletFromLocal.tsx +#: dashboard/components/Restore/RestoreFromPrivateKey.tsx +#: dashboard/components/Restore/RestoreFromMnemonic.tsx msgid "Continue" msgstr "crwdns29572:0crwdne29572:0" -#: popups/components/UnlockERC20Token/index.tsx #: popups/components/UnlockERC721Token/index.tsx +#: popups/components/UnlockERC20Token/index.tsx msgid "Contract" msgstr "crwdns30022:0crwdne30022:0" @@ -706,8 +770,8 @@ msgstr "crwdns30022:0crwdne30022:0" msgid "Contract Interaction" msgstr "crwdns30024:0crwdne30024:0" -#: popups/components/PrivateKeyDisplay/index.tsx #: popups/pages/Personas/ExportPrivateKey/index.tsx +#: popups/components/PrivateKeyDisplay/index.tsx msgid "Copied" msgstr "crwdns30026:0crwdne30026:0" @@ -732,8 +796,8 @@ msgid "Could not fetch chain ID. Is your RPC URL correct?" msgstr "crwdns30040:0crwdne30040:0" #: content-script/components/CompositionDialog/EncryptionTargetSelector.tsx -#: dashboard/pages/CreateMaskWallet/AddDeriveWallet/index.tsx #: dashboard/pages/CreateMaskWallet/Recovery/index.tsx +#: dashboard/pages/CreateMaskWallet/AddDeriveWallet/index.tsx msgid "Create" msgstr "crwdns29574:0crwdne29574:0" @@ -749,6 +813,7 @@ msgstr "crwdns29576:0crwdne29576:0" msgid "Create Password" msgstr "crwdns30044:0crwdne30044:0" +#: dashboard/pages/SetupPersona/Recovery/index.tsx #: popups/pages/Personas/Home/UI.tsx msgid "Create Persona" msgstr "crwdns30046:0crwdne30046:0" @@ -759,11 +824,28 @@ msgstr "crwdns29578:0crwdne29578:0" #: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx #: dashboard/pages/SetupPersona/Onboarding/index.tsx -msgid "Creating your" -msgstr "crwdns29580:0crwdne29580:0" +#~ msgid "Creating your" +#~ msgstr "" + +#: dashboard/pages/SetupPersona/Onboarding/index.tsx +#: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx +#~ msgid "Creating your " +#~ msgstr "" + +#: dashboard/pages/SetupPersona/Onboarding/index.tsx +msgid "Creating your **identity**" +msgstr "crwdns37280:0crwdne37280:0" + +#: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx +msgid "Creating your **wallet**" +msgstr "crwdns37282:0crwdne37282:0" + +#: dashboard/pages/SetupPersona/Onboarding/index.tsx +msgid "Creation Completed" +msgstr "crwdns37297:0crwdne37297:0" -#: popups/modals/ChooseCurrencyModal/index.tsx #: popups/pages/Wallet/WalletSettings/ChangeCurrency.tsx +#: popups/modals/ChooseCurrencyModal/index.tsx msgid "Currency" msgstr "crwdns30048:0crwdne30048:0" @@ -775,6 +857,7 @@ msgstr "crwdns30050:0crwdne30050:0" msgid "Current account is not the verifying account." msgstr "crwdns32032:0crwdne32032:0" +#. placeholder {0}: formatWeiToGwei(gasOptions.normal.baseFeePerGas).toFixed(2, BigNumber.ROUND_UP) #: popups/modals/GasSettingModal/GasSettingDialog.tsx msgid "Current base fee is {0} Gwei" msgstr "crwdns30052:0{0}crwdne30052:0" @@ -787,35 +870,39 @@ msgstr "crwdns30054:0crwdne30054:0" msgid "Current wallet (<0>{currentWallet}) is the management account of SmartPay wallet (<1>{other_wallets}).<2/>Deleting the current wallet will result in the deletion of the SmartPay wallet simultaneously." msgstr "crwdns32784:0{currentWallet}crwdnd32784:0{other_wallets}crwdne32784:0" -#: popups/components/GasSettingMenu/index.tsx #: popups/hooks/useGasOptionsMenu.tsx +#: popups/components/GasSettingMenu/index.tsx msgid "Custom" msgstr "crwdns30056:0crwdne30056:0" -#: popups/modals/SelectAppearanceModal/index.tsx #: popups/pages/Settings/index.tsx +#: popups/modals/SelectAppearanceModal/index.tsx msgid "Dark" msgstr "crwdns30058:0crwdne30058:0" -#: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx #: dashboard/pages/SetupPersona/Onboarding/index.tsx -msgid "data" -msgstr "crwdns29582:0crwdne29582:0" +#: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx +#~ msgid "data" +#~ msgstr "" #: popups/pages/Wallet/Interaction/TransactionRequest.tsx msgid "Data" msgstr "crwdns30060:0crwdne30060:0" +#: dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx +msgid "Data backed up successfully!" +msgstr "crwdns37232:0crwdne37232:0" + #: popups/pages/Settings/index.tsx msgid "Data correlation" msgstr "crwdns27972:0crwdne27972:0" #: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx -msgid "Data merged from Mask Cloud Service to local successfully. Re-enter your password to encrypt and upload the new backup to Mask Cloud Service." -msgstr "crwdns32034:0crwdne32034:0" +#~ msgid "Data merged from Mask Cloud Service to local successfully. Re-enter your password to encrypt and upload the new backup to Mask Cloud Service." +#~ msgstr "" -#: dashboard/components/Restore/RestoreFromCloud/ConfirmBackupInfo.tsx -#: dashboard/components/Restore/RestoreFromCloud/ConfirmBackupInfo.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/ConfirmBackupInfo.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/ConfirmBackupInfo.tsx msgid "Decrypt failed, please check password" msgstr "crwdns29586:0crwdne29586:0" @@ -831,8 +918,8 @@ msgstr "crwdns30062:0crwdne30062:0" msgid "Delete" msgstr "crwdns30066:0crwdne30066:0" -#: popups/modals/DeleteContactModal/index.tsx #: popups/pages/Wallet/ContactList/index.tsx +#: popups/modals/DeleteContactModal/index.tsx msgid "Delete Contact" msgstr "crwdns30068:0crwdne30068:0" @@ -848,6 +935,10 @@ msgstr "crwdns30074:0crwdne30074:0" msgid "Description" msgstr "crwdns30076:0crwdne30076:0" +#: popups/pages/Wallet/WalletSettings/DisablePermit.tsx +msgid "Disable Permit" +msgstr "crwdns36718:0crwdne36718:0" + #: popups/pages/Wallet/components/DisconnectModal/index.tsx msgid "Disconnect" msgstr "crwdns30078:0crwdne30078:0" @@ -887,6 +978,8 @@ msgstr "crwdns30090:0crwdne30090:0" msgid "Do you need to paste encrypted content manually?" msgstr "crwdns30092:0crwdne30092:0" +#. placeholder {0}: selectedAccount?.identifier.userId +#. placeholder {1}: currentPersona.nickname #: popups/pages/Personas/AccountDetail/index.tsx msgid "Do you want to remove the verified association between the X account @<0>{0} and {1}?" msgstr "crwdns32788:0{0}crwdnd32788:0{1}crwdne32788:0" @@ -903,29 +996,31 @@ msgstr "crwdns32038:0crwdne32038:0" msgid "Don't see your NFT?" msgstr "crwdns30098:0crwdne30098:0" -#: content-script/components/InjectedComponents/SelectPeopleDialog.tsx -#: content-script/components/InjectedComponents/SetupGuide/AccountConnectStatus.tsx #: content-script/components/shared/SelectRecipients/SelectRecipientsDialog.tsx #: content-script/components/shared/SelectRecipients/SelectRecipientsDialog.tsx #: content-script/components/shared/SelectRecipients/SelectRecipientsDialog.tsx +#: content-script/components/InjectedComponents/SelectPeopleDialog.tsx +#: content-script/components/InjectedComponents/SetupGuide/AccountConnectStatus.tsx #: dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx #: popups/pages/Personas/ConnectWallet/index.tsx msgid "Done" msgstr "crwdns29588:0crwdne29588:0" #: content-script/components/InjectedComponents/AutoPasteFailedDialog.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/Preview.tsx +#: dashboard/components/GoogleDriveFileTable.tsx msgid "Download" msgstr "crwdns30100:0crwdne30100:0" #: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx -msgid "Download backup" -msgstr "crwdns29590:0crwdne29590:0" +#~ msgid "Download backup" +#~ msgstr "" -#: dashboard/pages/SetupPersona/LocalBackup/index.tsx +#: dashboard/pages/SetupPersona/Backup/Local.tsx msgid "Download Backup" msgstr "crwdns29592:0crwdne29592:0" -#: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx msgid "Downloading" msgstr "crwdns29596:0crwdne29596:0" @@ -934,8 +1029,8 @@ msgid "Drag & Drop your file here" msgstr "crwdns30102:0crwdne30102:0" #: dashboard/pages/SetupPersona/CloudBackup/index.tsx -msgid "E-mail" -msgstr "crwdns29598:0crwdne29598:0" +#~ msgid "E-mail" +#~ msgstr "" #: popups/pages/Wallet/ContactList/index.tsx msgid "Edit" @@ -945,18 +1040,19 @@ msgstr "crwdns30104:0crwdne30104:0" msgid "Edit Contact" msgstr "crwdns30106:0crwdne30106:0" -#: content-script/components/shared/SelectProfileUI/SelectProfileUI.tsx #: content-script/components/shared/SelectRecipients/SelectRecipientsDialog.tsx +#: content-script/components/shared/SelectProfileUI/SelectProfileUI.tsx msgid "eg: X accounts, persona public keys, wallet addresses or ENS" msgstr "crwdns32040:0crwdne32040:0" -#: dashboard/components/Restore/RestoreFromCloud/EmailField.tsx -#: dashboard/pages/SetupPersona/CloudBackup/EmailForm.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/EmailField.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/MaskNetwork.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/EmailForm.tsx msgid "Email" msgstr "crwdns29600:0crwdne29600:0" -#: dashboard/components/Restore/RestoreFromCloud/EmailField.tsx -#: dashboard/pages/SetupPersona/CloudBackup/EmailForm.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/EmailField.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/EmailForm.tsx msgid "Email verification code" msgstr "crwdns29602:0crwdne29602:0" @@ -982,8 +1078,18 @@ msgstr "crwdns30120:0crwdne30120:0" #: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx #: dashboard/pages/SetupPersona/Onboarding/index.tsx -msgid "Encrypting your" -msgstr "crwdns29604:0crwdne29604:0" +#~ msgid "Encrypting your" +#~ msgstr "" + +#: dashboard/pages/SetupPersona/Onboarding/index.tsx +#: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx +#~ msgid "Encrypting your " +#~ msgstr "" + +#: dashboard/pages/SetupPersona/Onboarding/index.tsx +#: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx +msgid "Encrypting your **data**" +msgstr "crwdns37284:0crwdne37284:0" #: content-script/components/CompositionDialog/EncryptionMethodSelector.tsx msgid "Encryption Method" @@ -993,8 +1099,8 @@ msgstr "crwdns30122:0crwdne30122:0" msgid "Ens or Address(0x)" msgstr "crwdns30124:0crwdne30124:0" -#: popups/pages/Wallet/GasSetting/GasSetting1559.tsx #: popups/pages/Wallet/GasSetting/Prior1559GasSetting.tsx +#: popups/pages/Wallet/GasSetting/GasSetting1559.tsx msgid "Enter a gas limit" msgstr "crwdns30126:0crwdne30126:0" @@ -1022,6 +1128,7 @@ msgstr "crwdns30136:0crwdne30136:0" msgid "Entered passwords are inconsistent." msgstr "crwdns32046:0crwdne32046:0" +#. placeholder {0}: rejection.message #: content-script/components/InjectedComponents/SelectPeopleDialog.tsx msgid "Error: {0}" msgstr "crwdns32048:0{0}crwdne32048:0" @@ -1043,8 +1150,8 @@ msgstr "crwdns29608:0crwdne29608:0" msgid "Exchange" msgstr "crwdns35400:0crwdne35400:0" -#: dashboard/pages/SetupPersona/Onboarding/index.tsx #: dashboard/pages/SetupPersona/PermissionOnboarding/index.tsx +#: dashboard/pages/SetupPersona/Onboarding/index.tsx msgid "Experience in X" msgstr "crwdns29610:0crwdne29610:0" @@ -1052,8 +1159,8 @@ msgstr "crwdns29610:0crwdne29610:0" msgid "Explore multi-chain dApps." msgstr "crwdns30140:0crwdne30140:0" -#: popups/modals/VerifyBackupPasswordModal/index.tsx #: popups/pages/Wallet/ExportPrivateKey/index.tsx +#: popups/modals/VerifyBackupPasswordModal/index.tsx msgid "Export" msgstr "crwdns30142:0crwdne30142:0" @@ -1067,6 +1174,10 @@ msgstr "crwdns30144:0crwdne30144:0" msgid "Failed to add the wallet, please try again." msgstr "crwdns30146:0crwdne30146:0" +#: dashboard/components/GoogleDriveLogin.tsx +msgid "Failed to authorize Google Drive. Please try again." +msgstr "crwdns37296:0crwdne37296:0" + #: content-script/components/InjectedComponents/DecryptedPost/DecryptPostFailed.tsx msgid "Failed to decrypt." msgstr "crwdns32050:0crwdne32050:0" @@ -1075,9 +1186,27 @@ msgstr "crwdns32050:0crwdne32050:0" msgid "Failed to disconnect wallet" msgstr "crwdns32052:0crwdne32052:0" +#. placeholder {0}: (err as Error).message +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx +msgid "Failed to download and merge the backup: {0}" +msgstr "crwdns37234:0{0}crwdne37234:0" + #: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx -msgid "Failed to download and merge the backup." -msgstr "crwdns32054:0crwdne32054:0" +#~ msgid "Failed to download and merge the backup." +#~ msgstr "" + +#: dashboard/components/GoogleDriveLogin.tsx +#~ msgid "Failed to login: {0}" +#~ msgstr "" + +#: dashboard/pages/SetupPersona/Recovery/Cloud/GoogleDrive.tsx +msgid "Failed to restore the backup from Google Drive to your browser. Please try again." +msgstr "crwdns37264:0crwdne37264:0" + +#. placeholder {0}: (err as Error).message +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx +msgid "Failed to restore the backup: {0}" +msgstr "crwdns37266:0{0}crwdne37266:0" #: popups/pages/Wallet/EditNetwork/index.tsx msgid "Failed to save network" @@ -1120,10 +1249,10 @@ msgstr "crwdns35460:0{officialAccount}crwdne35460:0" msgid "Follow @realMaskNetwork to explore Web3." msgstr "crwdns32058:0crwdne32058:0" -#: popups/modals/SelectAppearanceModal/index.tsx -#: popups/modals/SelectLanguageModal/index.tsx #: popups/pages/Settings/index.tsx #: popups/pages/Settings/index.tsx +#: popups/modals/SelectLanguageModal/index.tsx +#: popups/modals/SelectAppearanceModal/index.tsx msgid "Follow System" msgstr "crwdns30164:0crwdne30164:0" @@ -1139,16 +1268,17 @@ msgstr "crwdns30168:0crwdne30168:0" msgid "from <0>{fromAddress}" msgstr "crwdns32790:0{fromAddress}crwdne32790:0" +#. placeholder {0}: transaction.formattedTransaction.popup.method #: popups/pages/Wallet/Interaction/TransactionRequest.tsx msgid "Function: {0}" msgstr "crwdns30170:0{0}crwdne30170:0" -#: popups/components/TransactionPreview/index.tsx -#: popups/components/UnlockERC20Token/index.tsx -#: popups/components/UnlockERC721Token/index.tsx -#: popups/modals/GasSettingModal/index.tsx -#: popups/pages/Wallet/ChangeOwner/index.tsx #: popups/pages/Wallet/Transfer/FungibleTokenSection.tsx +#: popups/pages/Wallet/ChangeOwner/index.tsx +#: popups/modals/GasSettingModal/index.tsx +#: popups/components/UnlockERC721Token/index.tsx +#: popups/components/UnlockERC20Token/index.tsx +#: popups/components/TransactionPreview/index.tsx msgid "Gas Fee" msgstr "crwdns30172:0crwdne30172:0" @@ -1161,9 +1291,9 @@ msgstr "crwdns30174:0crwdne30174:0" msgid "Gas fees are the fees for paying ethereum block builders. Block builders prefer to pack transactions with higher gas fees. Transactions with low gas fees might fail, and the paid gas fees won't be returned." msgstr "crwdns32060:0crwdne32060:0" -#: popups/modals/GasSettingModal/GasSettingDialog.tsx -#: popups/pages/Wallet/GasSetting/GasSetting1559.tsx #: popups/pages/Wallet/GasSetting/Prior1559GasSetting.tsx +#: popups/pages/Wallet/GasSetting/GasSetting1559.tsx +#: popups/modals/GasSettingModal/GasSettingDialog.tsx msgid "Gas Limit" msgstr "crwdns30178:0crwdne30178:0" @@ -1171,8 +1301,9 @@ msgstr "crwdns30178:0crwdne30178:0" msgid "Gas Limit (Units)" msgstr "crwdns30180:0crwdne30180:0" -#: popups/pages/Wallet/GasSetting/GasSetting1559.tsx +#. placeholder {0}: String(minGasLimit) #: popups/pages/Wallet/GasSetting/Prior1559GasSetting.tsx +#: popups/pages/Wallet/GasSetting/GasSetting1559.tsx msgid "Gas limit must be at least {0}" msgstr "crwdns30182:0{0}crwdne30182:0" @@ -1184,8 +1315,8 @@ msgstr "crwdns30184:0{minGas}crwdne30184:0" msgid "Gas limit must be smaller than {maxGas}." msgstr "crwdns30186:0{maxGas}crwdne30186:0" -#: popups/modals/GasSettingModal/GasSettingDialog.tsx #: popups/pages/Wallet/GasSetting/Prior1559GasSetting.tsx +#: popups/modals/GasSettingModal/GasSettingDialog.tsx msgid "Gas Price" msgstr "crwdns30188:0crwdne30188:0" @@ -1219,14 +1350,33 @@ msgstr "crwdns30202:0crwdne30202:0" #: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx #: dashboard/pages/SetupPersona/Onboarding/index.tsx -msgid "Generating your" -msgstr "crwdns29614:0crwdne29614:0" +#~ msgid "Generating your" +#~ msgstr "" -#: popups/components/UnlockERC20Token/index.tsx +#: dashboard/pages/SetupPersona/Onboarding/index.tsx +#: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx +#~ msgid "Generating your " +#~ msgstr "" + +#: dashboard/pages/SetupPersona/Onboarding/index.tsx +#: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx +msgid "Generating your **accounts**" +msgstr "crwdns37286:0crwdne37286:0" + +#. placeholder {0}: contract?.symbol || '' +#. placeholder {0}: token?.symbol || '' #: popups/components/UnlockERC721Token/index.tsx +#: popups/components/UnlockERC20Token/index.tsx msgid "Give permission to access <0/> your {0}?" msgstr "crwdns32792:0{0}crwdne32792:0" +#: dashboard/pages/SetupPersona/Recovery/Cloud/index.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/GoogleDrive.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/index.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/GoogleDrive.tsx +msgid "Google Drive" +msgstr "crwdns37238:0crwdne37238:0" + #: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx msgid "Got it" msgstr "crwdns29616:0crwdne29616:0" @@ -1255,6 +1405,7 @@ msgstr "crwdns32064:0crwdne32064:0" msgid "Hi friends, I just created {token} Lucky Drop. Download Mask.io to claim." msgstr "crwdns32794:0{token}crwdne32794:0" +#. placeholder {0}: asset.symbol #: popups/pages/Wallet/TokenDetail/index.tsx msgid "Hide {0}" msgstr "crwdns30212:0{0}crwdne30212:0" @@ -1275,10 +1426,10 @@ msgstr "crwdns30216:0crwdne30216:0" msgid "Hiding Scam Transactions" msgstr "crwdns30218:0crwdne30218:0" -#: popups/components/GasSettingMenu/index.tsx -#: popups/hooks/useGasOptionsMenu.tsx -#: popups/pages/Wallet/GasSetting/GasSetting1559.tsx #: popups/pages/Wallet/GasSetting/Prior1559GasSetting.tsx +#: popups/pages/Wallet/GasSetting/GasSetting1559.tsx +#: popups/hooks/useGasOptionsMenu.tsx +#: popups/components/GasSettingMenu/index.tsx msgid "High" msgstr "crwdns30220:0crwdne30220:0" @@ -1291,8 +1442,8 @@ msgid "I wrote down those words in the correct order" msgstr "crwdns32070:0crwdne32070:0" #: dashboard/pages/SetupPersona/Onboarding/index.tsx -msgid "identity" -msgstr "crwdns29620:0crwdne29620:0" +#~ msgid "identity" +#~ msgstr "" #: dashboard/pages/SetupPersona/Mnemonic/ComponentToPrint.tsx msgid "Identity ID" @@ -1336,17 +1487,21 @@ msgstr "crwdns30230:0crwdne30230:0" msgid "Imported Wallets" msgstr "crwdns30232:0crwdne30232:0" -#: popups/modals/ChangeBackupPasswordModal/index.tsx +#: dashboard/hooks/useBackupFormState.ts +msgid "Incorrect Backup Password" +msgstr "crwdns37240:0crwdne37240:0" + #: popups/modals/VerifyBackupPasswordModal/index.tsx +#: popups/modals/ChangeBackupPasswordModal/index.tsx msgid "Incorrect backup password." msgstr "crwdns30234:0crwdne30234:0" -#: dashboard/components/Restore/RestorePersonaFromLocal.tsx +#: dashboard/pages/SetupPersona/Recovery/Local.tsx msgid "Incorrect Backup Password." msgstr "crwdns29626:0crwdne29626:0" -#: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx -#: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx msgid "Incorrect cloud backup password, please try again." msgstr "crwdns29628:0crwdne29628:0" @@ -1358,21 +1513,20 @@ msgstr "crwdns29630:0crwdne29630:0" msgid "Incorrect Mnemonic Words." msgstr "crwdns32074:0crwdne32074:0" +#: popups/pages/Wallet/Unlock/index.tsx #: popups/pages/Personas/Logout/index.tsx #: popups/pages/Personas/Logout/index.tsx -#: popups/pages/Wallet/Unlock/index.tsx msgid "Incorrect password" msgstr "crwdns30236:0crwdne30236:0" +#: dashboard/pages/SetupPersona/Backup/Local.tsx +#: dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx #: dashboard/hooks/useBackupFormState.ts #: dashboard/hooks/useBackupFormState.ts #: dashboard/hooks/useBackupFormState.ts #: dashboard/hooks/useBackupFormState.ts #: dashboard/hooks/useBackupFormState.ts #: dashboard/hooks/useBackupFormState.ts -#: dashboard/hooks/useBackupFormState.ts -#: dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx -#: dashboard/pages/SetupPersona/LocalBackup/index.tsx msgid "Incorrect Password" msgstr "crwdns29634:0crwdne29634:0" @@ -1380,22 +1534,22 @@ msgstr "crwdns29634:0crwdne29634:0" msgid "Incorrect payment password." msgstr "crwdns30238:0crwdne30238:0" -#: popups/modals/ShowPrivateKeyModal/index.tsx #: popups/modals/WalletRemoveModal/index.tsx +#: popups/modals/ShowPrivateKeyModal/index.tsx msgid "Incorrect Payment Password." msgstr "crwdns30240:0crwdne30240:0" +#: dashboard/pages/SetupPersona/Recovery/PrivateKey.tsx #: dashboard/pages/CreateMaskWallet/Recovery/index.tsx -#: dashboard/pages/SetupPersona/Recovery/index.tsx msgid "Incorrect Private Key" msgstr "crwdns29636:0crwdne29636:0" -#: dashboard/pages/SetupPersona/Recovery/index.tsx +#: dashboard/pages/SetupPersona/Recovery/Phrase.tsx msgid "Incorrect recovery phrase." msgstr "crwdns29638:0crwdne29638:0" -#: popups/hooks/useContactsContext.ts #: popups/modals/AddContactModal/index.tsx +#: popups/hooks/useContactsContext.ts msgid "Incorrect wallet address." msgstr "crwdns30242:0crwdne30242:0" @@ -1403,12 +1557,13 @@ msgstr "crwdns30242:0crwdne30242:0" msgid "Incorrect words selected. Please try again!" msgstr "crwdns32076:0crwdne32076:0" +#: dashboard/pages/SetupPersona/Recovery/PrivateKey.tsx #: dashboard/components/Restore/RestoreFromPrivateKey.tsx msgid "Input your Private Key" msgstr "crwdns29640:0crwdne29640:0" -#: popups/components/GasSettingMenu/index.tsx #: popups/hooks/useGasOptionsMenu.tsx +#: popups/components/GasSettingMenu/index.tsx msgid "Instant" msgstr "crwdns30244:0crwdne30244:0" @@ -1420,12 +1575,13 @@ msgstr "crwdns30246:0crwdne30246:0" msgid "Invalid Block Explorer URL." msgstr "crwdns30248:0crwdne30248:0" +#: dashboard/pages/SetupPersona/Backup/Cloud/EmailForm.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/CloudBackupFormContext.ts #: dashboard/contexts/CloudBackupFormContext.tsx -#: dashboard/pages/SetupPersona/CloudBackup/EmailForm.tsx msgid "Invalid email address format." msgstr "crwdns29642:0crwdne29642:0" -#: dashboard/components/Restore/RestoreFromCloud/EmailField.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/EmailField.tsx msgid "Invalid email address." msgstr "crwdns32078:0crwdne32078:0" @@ -1433,7 +1589,7 @@ msgstr "crwdns32078:0crwdne32078:0" msgid "Invalid number" msgstr "crwdns30250:0crwdne30250:0" -#: dashboard/components/Restore/RestoreFromCloud/PhoneField.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/PhoneField.tsx msgid "Invalid phone number, please check and try again." msgstr "crwdns29644:0crwdne29644:0" @@ -1441,8 +1597,8 @@ msgstr "crwdns29644:0crwdne29644:0" msgid "Invalid RPC URL." msgstr "crwdns30252:0crwdne30252:0" -#: dashboard/components/Restore/RestoreFromCloud/EmailField.tsx -#: dashboard/components/Restore/RestoreFromCloud/PhoneField.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/PhoneField.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/EmailField.tsx msgid "Invalid verification code." msgstr "crwdns29646:0crwdne29646:0" @@ -1476,10 +1632,10 @@ msgstr "crwdns30262:0crwdne30262:0" msgid "Keystore password" msgstr "crwdns29650:0crwdne29650:0" +#: popups/modals/SetBackupPasswordModal/index.tsx #: popups/modals/ChangeBackupPasswordModal/index.tsx #: popups/modals/ChangeBackupPasswordModal/index.tsx #: popups/modals/ChangeBackupPasswordModal/index.tsx -#: popups/modals/SetBackupPasswordModal/index.tsx msgid "Lack of number, letter or special character." msgstr "crwdns30264:0crwdne30264:0" @@ -1487,8 +1643,8 @@ msgstr "crwdns30264:0crwdne30264:0" msgid "Language" msgstr "crwdns30266:0crwdne30266:0" -#: popups/modals/SelectAppearanceModal/index.tsx #: popups/pages/Settings/index.tsx +#: popups/modals/SelectAppearanceModal/index.tsx msgid "Light" msgstr "crwdns30268:0crwdne30268:0" @@ -1505,8 +1661,8 @@ msgid "Load failed" msgstr "crwdns30272:0crwdne30272:0" #: content-script/components/shared/SelectRecipients/SelectRecipientsDialog.tsx -#: popups/components/WalletSettingList/index.tsx #: popups/pages/Friends/Home/UI.tsx +#: popups/components/WalletSettingList/index.tsx msgid "Loading" msgstr "crwdns30274:0crwdne30274:0" @@ -1523,19 +1679,29 @@ msgstr "crwdns29652:0crwdne29652:0" msgid "Local persona or wallet only" msgstr "crwdns30276:0crwdne30276:0" +#: dashboard/pages/SetupPersona/Backup/index.tsx +msgid "Locale Backup" +msgstr "crwdns37242:0crwdne37242:0" + #: popups/pages/Wallet/SwitchWallet/index.tsx msgid "Lock Wallet" msgstr "crwdns30278:0crwdne30278:0" -#: popups/modals/PersonaSettingModal/index.tsx #: popups/pages/Personas/Logout/index.tsx #: popups/pages/Personas/Logout/index.tsx +#: popups/modals/PersonaSettingModal/index.tsx msgid "Log out" msgstr "crwdns30280:0crwdne30280:0" #: dashboard/pages/SetupPersona/CloudBackup/index.tsx -msgid "Login to Mask Cloud" -msgstr "crwdns32080:0crwdne32080:0" +#~ msgid "Login to Mask Cloud" +#~ msgstr "" + +#: dashboard/pages/SetupPersona/Recovery/Cloud/GoogleDrive.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/Preview.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/GoogleDrive.tsx +msgid "Logout" +msgstr "crwdns37244:0crwdne37244:0" #: popups/pages/Personas/Logout/index.tsx msgid "Logout failed" @@ -1545,13 +1711,13 @@ msgstr "crwdns30282:0crwdne30282:0" msgid "Logout successfully" msgstr "crwdns30284:0crwdne30284:0" -#: popups/pages/Wallet/GasSetting/GasSetting1559.tsx #: popups/pages/Wallet/GasSetting/Prior1559GasSetting.tsx +#: popups/pages/Wallet/GasSetting/GasSetting1559.tsx msgid "Low" msgstr "crwdns30286:0crwdne30286:0" -#: popups/modals/ChooseNetworkModal/index.tsx #: popups/pages/Wallet/NetworkManagement/index.tsx +#: popups/modals/ChooseNetworkModal/index.tsx msgid "Manage Network" msgstr "crwdns30288:0crwdne30288:0" @@ -1563,11 +1729,17 @@ msgstr "crwdns32082:0crwdne32082:0" msgid "Mask needs the following permissions" msgstr "crwdns30300:0crwdne30300:0" -#: content-script/components/InjectedComponents/PostDialogHint.tsx #: content-script/components/InjectedComponents/ToolboxUnstyled.tsx +#: content-script/components/InjectedComponents/PostDialogHint.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/index.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/index.tsx msgid "Mask Network" msgstr "crwdns30302:0crwdne30302:0" +#: dashboard/pages/SetupPersona/Backup/Cloud/Preview.tsx +msgid "Mask Network Cloud" +msgstr "crwdns37246:0crwdne37246:0" + #: content-script/components/InjectedComponents/PermissionBoundary.tsx msgid "Mask Network requires you to authorize the following websites before using it." msgstr "crwdns32800:0crwdne32800:0" @@ -1576,13 +1748,13 @@ msgstr "crwdns32800:0crwdne32800:0" msgid "masknetwork" msgstr "crwdns30304:0crwdne30304:0" -#: popups/components/UnlockERC20Token/index.tsx #: popups/pages/Wallet/Transfer/FungibleTokenSection.tsx +#: popups/components/UnlockERC20Token/index.tsx msgid "Max" msgstr "crwdns30306:0crwdne30306:0" -#: popups/modals/GasSettingModal/GasSettingDialog.tsx #: popups/pages/Wallet/GasSetting/GasSetting1559.tsx +#: popups/modals/GasSettingModal/GasSettingDialog.tsx msgid "Max Fee" msgstr "crwdns30308:0crwdne30308:0" @@ -1602,12 +1774,13 @@ msgstr "crwdns30314:0crwdne30314:0" msgid "Max fee is too low for network conditions." msgstr "crwdns30316:0crwdne30316:0" +#. placeholder {0}: formatWeiToGwei(miniumMaxFeePerGas).toFixed(2, BigNumber.ROUND_UP) #: popups/modals/GasSettingModal/GasSettingDialog.tsx msgid "Max fee should be greater than base fee of {0} Gwei." msgstr "crwdns30318:0{0}crwdne30318:0" -#: popups/modals/GasSettingModal/GasSettingDialog.tsx #: popups/pages/Wallet/GasSetting/GasSetting1559.tsx +#: popups/modals/GasSettingModal/GasSettingDialog.tsx msgid "Max Priority Fee" msgstr "crwdns30320:0crwdne30320:0" @@ -1631,22 +1804,30 @@ msgstr "crwdns30328:0crwdne30328:0" msgid "Max priority fee must be greater than 0 GWEI" msgstr "crwdns30330:0crwdne30330:0" -#: popups/components/GasSettingMenu/index.tsx -#: popups/hooks/useGasOptionsMenu.tsx -#: popups/pages/Wallet/GasSetting/GasSetting1559.tsx #: popups/pages/Wallet/GasSetting/Prior1559GasSetting.tsx +#: popups/pages/Wallet/GasSetting/GasSetting1559.tsx +#: popups/hooks/useGasOptionsMenu.tsx +#: popups/components/GasSettingMenu/index.tsx msgid "Medium" msgstr "crwdns30332:0crwdne30332:0" -#: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx -#: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx -#: dashboard/pages/SetupPersona/CloudBackupPreview/index.tsx +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx +msgid "Merge Completed" +msgstr "crwdns37248:0crwdne37248:0" + +#: dashboard/pages/SetupPersona/Backup/Cloud/Preview.tsx +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx msgid "Merge data to local database" msgstr "crwdns29656:0crwdne29656:0" +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx +#: dashboard/components/GoogleDriveFileTable.tsx +msgid "Merge to Browser" +msgstr "crwdns37250:0crwdne37250:0" + #: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx -msgid "Merge to local" -msgstr "crwdns29658:0crwdne29658:0" +#~ msgid "Merge to local" +#~ msgstr "" #: popups/components/SignRequestInfo/index.tsx msgid "Message" @@ -1661,18 +1842,20 @@ msgstr "crwdns30336:0crwdne30336:0" msgid "Mnemonic word" msgstr "crwdns29660:0crwdne29660:0" -#: dashboard/pages/SetupPersona/CloudBackup/index.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/MaskNetwork.tsx msgid "Mobile" msgstr "crwdns29662:0crwdne29662:0" -#: dashboard/pages/SetupPersona/CloudBackup/PhoneForm.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/PhoneForm.tsx msgid "Mobile number" msgstr "crwdns29664:0crwdne29664:0" -#: dashboard/components/Restore/RestoreFromCloud/PhoneField.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/PhoneField.tsx msgid "Mobile verification code" msgstr "crwdns29666:0crwdne29666:0" +#. placeholder {0}: String(currentMessageIndex + 1) +#. placeholder {1}: String(totalMessages) #: popups/pages/Wallet/Interaction/interaction.tsx msgid "Multiple transaction requests {0} / {1}" msgstr "crwdns30338:0{0}crwdnd30338:0{1}crwdne30338:0" @@ -1687,9 +1870,9 @@ msgstr "crwdns30340:0crwdne30340:0" msgid "N/A" msgstr "crwdns30342:0crwdne30342:0" -#: popups/modals/AddContactModal/index.tsx -#: popups/modals/EditContactModal/index.tsx #: popups/modals/PersonaSettingModal/index.tsx +#: popups/modals/EditContactModal/index.tsx +#: popups/modals/AddContactModal/index.tsx msgid "Name" msgstr "crwdns30344:0crwdne30344:0" @@ -1747,8 +1930,8 @@ msgstr "crwdns30358:0crwdne30358:0" #: content-script/components/GuideStep/index.tsx #: dashboard/pages/CreateMaskWallet/AddDeriveWallet/index.tsx -#: popups/pages/Wallet/ContactList/index.tsx #: popups/pages/Wallet/Transfer/FungibleTokenSection.tsx +#: popups/pages/Wallet/ContactList/index.tsx msgid "Next" msgstr "crwdns29670:0crwdne29670:0" @@ -1756,10 +1939,10 @@ msgstr "crwdns29670:0crwdne29670:0" msgid "Next.ID" msgstr "crwdns30360:0crwdne30360:0" -#: popups/pages/Personas/PersonaAvatarSetting/index.tsx -#: popups/pages/Wallet/AddToken/index.tsx #: popups/pages/Wallet/components/WalletAssets/index.tsx #: popups/pages/Wallet/Transfer/index.tsx +#: popups/pages/Wallet/AddToken/index.tsx +#: popups/pages/Personas/PersonaAvatarSetting/index.tsx msgid "NFTs" msgstr "crwdns30362:0crwdne30362:0" @@ -1780,7 +1963,8 @@ msgstr "crwdns32802:0crwdne32802:0" msgid "No back up" msgstr "crwdns30366:0crwdne30366:0" -#: dashboard/pages/SetupPersona/CloudBackupPreview/index.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/Preview.tsx +#: dashboard/components/GoogleDriveFileTable.tsx msgid "No backups found" msgstr "crwdns29672:0crwdne29672:0" @@ -1792,8 +1976,8 @@ msgstr "crwdns32096:0crwdne32096:0" msgid "No Data" msgstr "crwdns30368:0crwdne30368:0" -#: content-script/components/shared/SelectProfileUI/SelectProfileUI.tsx #: content-script/components/shared/SelectRecipients/SelectRecipientsDialog.tsx +#: content-script/components/shared/SelectProfileUI/SelectProfileUI.tsx msgid "No friends are stored locally, please try search one." msgstr "crwdns32098:0crwdne32098:0" @@ -1821,9 +2005,9 @@ msgstr "crwdns30380:0crwdne30380:0" msgid "No websites connected to this wallet" msgstr "crwdns35874:0crwdne35874:0" -#: popups/components/SignRequestInfo/index.tsx -#: popups/modals/GasSettingModal/GasSettingDialog.tsx #: popups/pages/Wallet/TransactionDetail/index.tsx +#: popups/modals/GasSettingModal/GasSettingDialog.tsx +#: popups/components/SignRequestInfo/index.tsx msgid "Nonce" msgstr "crwdns30382:0crwdne30382:0" @@ -1855,6 +2039,10 @@ msgstr "crwdns30394:0crwdne30394:0" msgid "OK" msgstr "crwdns30396:0crwdne30396:0" +#: popups/pages/Wallet/WalletSettings/DisablePermit.tsx +msgid "Okay" +msgstr "crwdns36720:0crwdne36720:0" + #: popups/modals/ChangePaymentPasswordModal/index.tsx msgid "Old Payment Password" msgstr "crwdns30398:0crwdne30398:0" @@ -1879,6 +2067,7 @@ msgstr "crwdns30404:0crwdne30404:0" msgid "Or create a new wallet group" msgstr "crwdns30406:0crwdne30406:0" +#. placeholder {0}: author.userId #: content-script/components/InjectedComponents/DecryptedPost/authorDifferentMessage.tsx msgid "Originally posted by {0}" msgstr "crwdns30408:0{0}crwdne30408:0" @@ -1887,18 +2076,17 @@ msgstr "crwdns30408:0{0}crwdne30408:0" msgid "Other social networking platforms, such as <0>Instagram, <1>Facebook, and <2>Minds, do not have a verified relationship like X's Next.ID verified connection.<3/><4/>When connecting a persona with an account on these platforms, they only support sending encrypted posts." msgstr "crwdns32806:0crwdne32806:0" -#: dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx #: dashboard/pages/SetupPersona/CloudBackupPreview/index.tsx -msgid "Overwrite Backup" -msgstr "crwdns29676:0crwdne29676:0" +#~ msgid "Overwrite Backup" +#~ msgstr "" #: dashboard/pages/SetupPersona/CloudBackupPreview/index.tsx -msgid "Overwrite current backup" -msgstr "crwdns29678:0crwdne29678:0" +#~ msgid "Overwrite current backup" +#~ msgstr "" -#: popups/modals/ChangeBackupPasswordModal/index.tsx -#: popups/modals/SetBackupPasswordModal/index.tsx #: popups/modals/VerifyBackupPasswordModal/index.tsx +#: popups/modals/SetBackupPasswordModal/index.tsx +#: popups/modals/ChangeBackupPasswordModal/index.tsx msgid "Password" msgstr "crwdns30410:0crwdne30410:0" @@ -1906,11 +2094,11 @@ msgstr "crwdns30410:0crwdne30410:0" msgid "Paste manually" msgstr "crwdns30412:0crwdne30412:0" +#: dashboard/pages/SetupPersona/Backup/Local.tsx #: dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx -#: dashboard/pages/SetupPersona/LocalBackup/index.tsx -#: popups/modals/ShowPrivateKeyModal/index.tsx -#: popups/modals/WalletRemoveModal/index.tsx #: popups/pages/Wallet/SetPaymentPassword/index.tsx +#: popups/modals/WalletRemoveModal/index.tsx +#: popups/modals/ShowPrivateKeyModal/index.tsx msgid "Payment Password" msgstr "crwdns29680:0crwdne29680:0" @@ -1920,9 +2108,9 @@ msgstr "crwdns32102:0crwdne32102:0" #: dashboard/pages/CreateMaskWallet/CreateWalletForm/index.tsx #: dashboard/pages/CreateMaskWallet/CreateWalletForm/index.tsx -#: popups/modals/ChangePaymentPasswordModal/index.tsx #: popups/pages/Wallet/hooks/usePasswordForm.ts #: popups/pages/Wallet/hooks/usePasswordForm.ts +#: popups/modals/ChangePaymentPasswordModal/index.tsx msgid "Payment password must be 6 to 20 characters." msgstr "crwdns32104:0crwdne32104:0" @@ -1962,8 +2150,8 @@ msgstr "crwdns29688:0crwdne29688:0" msgid "Persona created." msgstr "crwdns32112:0crwdne32112:0" -#: dashboard/pages/SetupPersona/SignUp/index.tsx #: dashboard/pages/SignUp/steps/PersonaNameUI.tsx +#: dashboard/pages/SetupPersona/SignUp/index.tsx msgid "Persona Name" msgstr "crwdns29692:0crwdne29692:0" @@ -1987,13 +2175,13 @@ msgstr "crwdns32114:0{personaName}crwdne32114:0" msgid "Personas" msgstr "crwdns29696:0crwdne29696:0" -#: dashboard/pages/SetupPersona/CloudBackup/PhoneForm.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/PhoneForm.tsx msgid "Phone verification code" msgstr "crwdns29698:0crwdne29698:0" -#: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx -#: dashboard/pages/SetupPersona/Onboarding/index.tsx #: dashboard/pages/SetupPersona/PermissionOnboarding/index.tsx +#: dashboard/pages/SetupPersona/Onboarding/index.tsx +#: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx msgid "Pin Mask Network to the toolbar for easier access:" msgstr "crwdns29700:0crwdne29700:0" @@ -2001,8 +2189,8 @@ msgstr "crwdns29700:0crwdne29700:0" msgid "Pinned successfully." msgstr "crwdns30424:0crwdne30424:0" -#: content-script/components/InjectedComponents/SetupGuide/index.tsx #: content-script/site-adaptors/facebook.com/injection/Composition.tsx +#: content-script/components/InjectedComponents/SetupGuide/index.tsx msgid "Please click the \"Post\" button to open the compose dialog." msgstr "crwdns32116:0crwdne32116:0" @@ -2014,7 +2202,7 @@ msgstr "crwdns32118:0crwdne32118:0" msgid "Please enter backup password to export persona private key." msgstr "crwdns30430:0crwdne30430:0" -#: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx msgid "Please enter cloud backup password to download file." msgstr "crwdns29702:0crwdne29702:0" @@ -2035,12 +2223,12 @@ msgstr "crwdns30434:0crwdne30434:0" msgid "Please install your metamask wallet and set up your first wallet." msgstr "crwdns30436:0crwdne30436:0" +#. placeholder {0}: currentPersona.nickname +#. placeholder {1}: manageWallets.length #: popups/pages/Personas/Logout/index.tsx msgid "Please note: This Persona {0} is the management account of above listed SmartPay {1, plural, one {wallet} other {wallets}}. You cannot use SmartPay wallet to interact with blockchain after logging out persona." msgstr "crwdns32808:00={0}crwdnd32808:01={1}crwdne32808:0" -#: dashboard/pages/SetupPersona/CloudBackupPreview/index.tsx -#: dashboard/pages/SetupPersona/LocalBackup/index.tsx #: dashboard/pages/SetupPersona/Recovery/index.tsx msgid "Please select the appropriate method to restore your personal data." msgstr "crwdns29706:0crwdne29706:0" @@ -2071,8 +2259,8 @@ msgid "Please switch to <0>@{expectAccount} to continue the account verifica msgstr "crwdns32810:0{expectAccount}crwdne32810:0" #: dashboard/pages/SetupPersona/CloudBackup/index.tsx -msgid "Please use your frequently used email or phone number for backup." -msgstr "crwdns32124:0crwdne32124:0" +#~ msgid "Please use your frequently used email or phone number for backup." +#~ msgstr "" #: dashboard/pages/CreateMaskWallet/CreateMnemonic/index.tsx msgid "Please write down or copy these words and save them in a secure place." @@ -2116,16 +2304,16 @@ msgstr "crwdns30458:0crwdne30458:0" msgid "Private" msgstr "crwdns30460:0crwdne30460:0" -#: dashboard/pages/CreateMaskWallet/Recovery/index.tsx #: dashboard/pages/SetupPersona/Recovery/index.tsx -#: popups/pages/Personas/ExportPrivateKey/index.tsx +#: dashboard/pages/CreateMaskWallet/Recovery/index.tsx #: popups/pages/Wallet/ExportPrivateKey/index.tsx #: popups/pages/Wallet/ExportPrivateKey/index.tsx +#: popups/pages/Personas/ExportPrivateKey/index.tsx msgid "Private Key" msgstr "crwdns29716:0crwdne29716:0" -#: popups/modals/PersonaSettingModal/index.tsx #: popups/pages/Personas/PersonaAvatarSetting/index.tsx +#: popups/modals/PersonaSettingModal/index.tsx msgid "Profile Photo" msgstr "crwdns30462:0crwdne30462:0" @@ -2143,15 +2331,15 @@ msgstr "crwdns32128:0{publicKey}crwdne32128:0" msgid "Quote Route" msgstr "crwdns35406:0crwdne35406:0" -#: popups/modals/ChangeBackupPasswordModal/index.tsx #: popups/modals/SetBackupPasswordModal/index.tsx +#: popups/modals/ChangeBackupPasswordModal/index.tsx msgid "Re-enter" msgstr "crwdns30466:0crwdne30466:0" -#: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx #: dashboard/pages/SetupPersona/Onboarding/index.tsx -msgid "ready 🚀" -msgstr "crwdns29720:0crwdne29720:0" +#: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx +#~ msgid "ready 🚀" +#~ msgstr "" #: content-script/components/CompositionDialog/useSubmit.ts msgid "realMaskNetwork" @@ -2162,6 +2350,11 @@ msgstr "crwdns30468:0crwdne30468:0" msgid "Receive" msgstr "crwdns30470:0crwdne30470:0" +#: dashboard/pages/SetupPersona/Recovery/Cloud/GoogleDrive.tsx +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx +msgid "Recover" +msgstr "crwdns37268:0crwdne37268:0" + #: dashboard/pages/SetupPersona/Recovery/index.tsx msgid "Recover your data" msgstr "crwdns29722:0crwdne29722:0" @@ -2170,8 +2363,8 @@ msgstr "crwdns29722:0crwdne29722:0" msgid "Recover your wallet" msgstr "crwdns29724:0crwdne29724:0" -#: dashboard/pages/SetupPersona/Mnemonic/index.tsx #: dashboard/pages/SetupPersona/SignUp/index.tsx +#: dashboard/pages/SetupPersona/Mnemonic/index.tsx #: popups/modals/SwitchPersonaModal/index.tsx msgid "Recovery" msgstr "crwdns29726:0crwdne29726:0" @@ -2180,8 +2373,8 @@ msgstr "crwdns29726:0crwdne29726:0" msgid "Recovery Phrase" msgstr "crwdns29728:0crwdne29728:0" -#: dashboard/pages/CreateMaskWallet/CreateMnemonic/index.tsx #: dashboard/pages/SetupPersona/Mnemonic/index.tsx +#: dashboard/pages/CreateMaskWallet/CreateMnemonic/index.tsx msgid "Refresh" msgstr "crwdns29730:0crwdne29730:0" @@ -2193,8 +2386,8 @@ msgstr "crwdns32130:0{totalMessages}crwdne32130:0" msgid "Reload" msgstr "crwdns30474:0crwdne30474:0" -#: popups/modals/WalletRemoveModal/index.tsx #: popups/pages/Wallet/WalletSettings/index.tsx +#: popups/modals/WalletRemoveModal/index.tsx msgid "Remove" msgstr "crwdns30476:0crwdne30476:0" @@ -2206,10 +2399,10 @@ msgstr "crwdns30478:0crwdne30478:0" msgid "Remove Wallet?" msgstr "crwdns30480:0crwdne30480:0" -#: popups/modals/PersonaRenameModal/index.tsx -#: popups/pages/Wallet/CreateWallet/Derive.tsx #: popups/pages/Wallet/WalletSettings/Rename.tsx #: popups/pages/Wallet/WalletSettings/Rename.tsx +#: popups/pages/Wallet/CreateWallet/Derive.tsx +#: popups/modals/PersonaRenameModal/index.tsx msgid "Rename" msgstr "crwdns30482:0crwdne30482:0" @@ -2229,12 +2422,13 @@ msgstr "crwdns30488:0crwdne30488:0" msgid "Request Source" msgstr "crwdns30490:0crwdne30490:0" -#: dashboard/components/Restore/RestorePersonaFromLocal.tsx +#: dashboard/pages/SetupPersona/Recovery/Local.tsx msgid "Reselect" msgstr "crwdns29732:0crwdne29732:0" -#: dashboard/pages/SetupPersona/CloudBackup/EmailForm.tsx -#: dashboard/pages/SetupPersona/CloudBackup/PhoneForm.tsx +#: content-script/components/InjectedComponents/SetupGuide/VerifyNextID.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/PhoneForm.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/EmailForm.tsx msgid "Resend" msgstr "crwdns29734:0crwdne29734:0" @@ -2246,24 +2440,32 @@ msgstr "crwdns30492:0crwdne30492:0" msgid "Resource" msgstr "crwdns30494:0crwdne30494:0" -#: dashboard/components/Restore/RestoreFromCloud/ConfirmBackupInfo.tsx -#: dashboard/components/Restore/RestoreFromCloud/index.tsx -#: dashboard/components/Restore/RestorePersonaFromLocal.tsx +#: dashboard/pages/SetupPersona/Recovery/Local.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/MaskNetwork.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/ConfirmBackupInfo.tsx msgid "Restore" msgstr "crwdns29736:0crwdne29736:0" -#: dashboard/components/Restore/RestorePersonaFromLocal.tsx +#: dashboard/pages/SetupPersona/Recovery/Local.tsx msgid "Restore backup failed." msgstr "crwdns32132:0crwdne32132:0" +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx +msgid "Restore Completed" +msgstr "crwdns37270:0crwdne37270:0" + #: popups/pages/Settings/index.tsx msgid "Restore Database" msgstr "crwdns30496:0crwdne30496:0" -#: dashboard/components/Restore/RestoreFromCloud/index.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/MaskNetwork.tsx msgid "Restore failed" msgstr "crwdns29740:0crwdne29740:0" +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx +msgid "Restore Failed" +msgstr "crwdns37272:0crwdne37272:0" + #: popups/pages/Settings/index.tsx msgid "Restore from a previous database backup" msgstr "crwdns30498:0crwdne30498:0" @@ -2280,8 +2482,8 @@ msgstr "crwdns30502:0crwdne30502:0" msgid "RPC URL" msgstr "crwdns30504:0crwdne30504:0" -#: popups/components/AddContactInputPanel/index.tsx #: popups/pages/Personas/AccountDetail/UI.tsx +#: popups/components/AddContactInputPanel/index.tsx msgid "Save" msgstr "crwdns30506:0crwdne30506:0" @@ -2317,8 +2519,8 @@ msgstr "crwdns35552:0crwdne35552:0" msgid "Select Address" msgstr "crwdns29742:0crwdne29742:0" -#: content-script/components/shared/SelectProfileUI/SelectProfileUI.tsx #: content-script/components/shared/SelectRecipients/SelectRecipientsDialog.tsx +#: content-script/components/shared/SelectProfileUI/SelectProfileUI.tsx msgid "Select All" msgstr "crwdns30528:0crwdne30528:0" @@ -2335,8 +2537,8 @@ msgid "Select Liquidity" msgstr "crwdns35408:0crwdne35408:0" #: dashboard/pages/SetupPersona/LocalBackup/index.tsx -msgid "Select the contents of the backup" -msgstr "crwdns29744:0crwdne29744:0" +#~ msgid "Select the contents of the backup" +#~ msgstr "" #: popups/pages/Wallet/Interaction/PermissionRequest.tsx msgid "Select the wallet(s) to use on this site. You should not connect to website you don't trust." @@ -2347,17 +2549,21 @@ msgid "Select Wallet" msgstr "crwdns30536:0crwdne30536:0" #: content-script/components/InjectedComponents/SetupGuide/VerifyNextID.tsx -#: dashboard/pages/SetupPersona/CloudBackup/EmailForm.tsx -#: dashboard/pages/SetupPersona/CloudBackup/PhoneForm.tsx -#: popups/components/TransactionPreview/index.tsx -#: popups/pages/Wallet/CollectibleDetail/index.tsx -#: popups/pages/Wallet/components/ActionGroup/index.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/PhoneForm.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/EmailForm.tsx #: popups/pages/Wallet/components/ActivityList/ActivityItem.tsx -#: popups/pages/Wallet/ContactList/index.tsx +#: popups/pages/Wallet/components/ActionGroup/index.tsx #: popups/pages/Wallet/Transfer/index.tsx +#: popups/pages/Wallet/ContactList/index.tsx +#: popups/pages/Wallet/CollectibleDetail/index.tsx +#: popups/components/TransactionPreview/index.tsx msgid "Send" msgstr "crwdns29746:0crwdne29746:0" +#: content-script/components/InjectedComponents/SetupGuide/AccountConnectStatus.tsx +msgid "Sent verification post successfully." +msgstr "crwdns36877:0crwdne36877:0" + #: popups/pages/Settings/index.tsx msgid "Service Agreement" msgstr "crwdns30538:0crwdne30538:0" @@ -2397,9 +2603,9 @@ msgstr "crwdns29756:0crwdne29756:0" msgid "Settings" msgstr "crwdns30544:0crwdne30544:0" -#: content-script/components/CompositionDialog/EncryptionTargetSelector.tsx -#: content-script/components/InjectedComponents/SelectPeopleDialog.tsx #: content-script/components/shared/SelectRecipients/SelectRecipientsDialog.tsx +#: content-script/components/InjectedComponents/SelectPeopleDialog.tsx +#: content-script/components/CompositionDialog/EncryptionTargetSelector.tsx msgid "Share with" msgstr "crwdns30546:0crwdne30546:0" @@ -2411,15 +2617,15 @@ msgstr "crwdns30548:0crwdne30548:0" msgid "Show tokens with value less than $1" msgstr "crwdns30550:0crwdne30550:0" -#: popups/pages/Personas/ConnectWallet/index.tsx -#: popups/pages/Personas/PersonaSignRequest/index.tsx #: popups/pages/Wallet/Interaction/WalletSignRequest.tsx +#: popups/pages/Personas/PersonaSignRequest/index.tsx +#: popups/pages/Personas/ConnectWallet/index.tsx msgid "Sign" msgstr "crwdns30552:0crwdne30552:0" #: dashboard/pages/SetupPersona/Recovery/index.tsx -msgid "Sign Up" -msgstr "crwdns29758:0crwdne29758:0" +#~ msgid "Sign Up" +#~ msgstr "" #: popups/components/SignRequestInfo/index.tsx msgid "Sign-in Request" @@ -2462,8 +2668,8 @@ msgstr "crwdns29760:0crwdne29760:0" msgid "Slippage" msgstr "crwdns35410:0crwdne35410:0" -#: popups/pages/Personas/AccountDetail/index.tsx #: popups/pages/Personas/Home/UI.tsx +#: popups/pages/Personas/AccountDetail/index.tsx msgid "Social Account" msgstr "crwdns30568:0crwdne30568:0" @@ -2471,14 +2677,14 @@ msgstr "crwdns30568:0crwdne30568:0" msgid "Sorry, signature failed! Please try signing again." msgstr "crwdns30570:0crwdne30570:0" -#: popups/modals/GasSettingModal/index.tsx #: popups/pages/Wallet/components/ActivityList/ActivityItem.tsx #: popups/pages/Wallet/TransactionDetail/index.tsx +#: popups/modals/GasSettingModal/index.tsx msgid "Speed Up" msgstr "crwdns30572:0crwdne30572:0" -#: popups/components/UnlockERC20Token/index.tsx #: popups/components/UnlockERC721Token/index.tsx +#: popups/components/UnlockERC20Token/index.tsx msgid "Spend limit requested by" msgstr "crwdns30574:0crwdne30574:0" @@ -2510,8 +2716,8 @@ msgstr "crwdns29766:0crwdne29766:0" msgid "Step 1/3" msgstr "crwdns29768:0crwdne29768:0" -#: dashboard/pages/CreateMaskWallet/AddDeriveWallet/index.tsx #: dashboard/pages/SetupPersona/Mnemonic/index.tsx +#: dashboard/pages/CreateMaskWallet/AddDeriveWallet/index.tsx msgid "Step 2/2" msgstr "crwdns29770:0crwdne29770:0" @@ -2536,18 +2742,17 @@ msgstr "crwdns30592:0crwdne30592:0" msgid "Support mnemonic phrase, private key or keystore file." msgstr "crwdns32140:0crwdne32140:0" -#: popups/modals/SupportedSitesModal/index.tsx #: popups/pages/Settings/index.tsx +#: popups/modals/SupportedSitesModal/index.tsx msgid "Supported Sites" msgstr "crwdns30596:0crwdne30596:0" -#: popups/pages/Trader/Header.tsx #: popups/pages/Wallet/components/ActionGroup/index.tsx +#: popups/pages/Trader/Header.tsx msgid "Swap" msgstr "crwdns35412:0crwdne35412:0" -#: dashboard/pages/SetupPersona/CloudBackupPreview/index.tsx -#: dashboard/pages/SetupPersona/CloudBackupPreview/index.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/Preview.tsx msgid "Switch other account" msgstr "crwdns29776:0crwdne29776:0" @@ -2555,7 +2760,7 @@ msgstr "crwdns29776:0crwdne29776:0" msgid "Switch Persona" msgstr "crwdns30600:0crwdne30600:0" -#: dashboard/components/Restore/RestoreFromCloud/ConfirmBackupInfo.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/ConfirmBackupInfo.tsx msgid "Switch to other accounts" msgstr "crwdns32142:0crwdne32142:0" @@ -2584,16 +2789,23 @@ msgstr "crwdns32146:0crwdne32146:0" msgid "The chainID is not equal to the currently connected one." msgstr "crwdns30606:0crwdne30606:0" +#: dashboard/pages/SetupPersona/Backup/Cloud/MaskNetwork.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/CloudBackupFormContext.ts +#: dashboard/pages/SetupPersona/Backup/Cloud/CloudBackupFormContext.ts #: dashboard/contexts/CloudBackupFormContext.tsx #: dashboard/contexts/CloudBackupFormContext.tsx -#: dashboard/pages/SetupPersona/CloudBackup/index.tsx msgid "The code is incorrect." msgstr "crwdns29780:0crwdne29780:0" -#: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx +#: dashboard/utils/api.ts msgid "The download link is expired" msgstr "crwdns32148:0crwdne32148:0" +#: dashboard/pages/SetupPersona/Recovery/Cloud/MaskNetwork.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/MaskNetwork.tsx +msgid "The Mask Network Cloud Backup feature will be deactivated on April 30, 2025. Please use alternative cloud backup services or local backup solutions." +msgstr "crwdns37252:0crwdne37252:0" + #: dashboard/pages/CreateMaskWallet/CreateMnemonic/index.tsx msgid "The mnemonic word has been copied, please keep it in a safe place." msgstr "crwdns32150:0crwdne32150:0" @@ -2603,13 +2815,19 @@ msgid "The mnemonic words has been copied, please keep it in a safe place." msgstr "crwdns32152:0crwdne32152:0" #: popups/pages/Wallet/EditNetwork/useWarnings.ts -msgid "The network with chain ID {formChainId} may use a different currency symbol ({0}) than the one you have entered. Please check." -msgstr "crwdns32154:0{formChainId}crwdnd32154:0{0}crwdne32154:0" +#~ msgid "The network with chain ID {formChainId} may use a different currency symbol ({0}) than the one you have entered. Please check." +#~ msgstr "" + +#. placeholder {1}: match.nativeCurrency.symbol +#: popups/pages/Wallet/EditNetwork/useWarnings.ts +msgid "The network with chain ID {formChainId} may use a different currency symbol ({1}) than the one you have entered. Please check." +msgstr "crwdns36382:0{formChainId}crwdnd36382:0{1}crwdne36382:0" #: popups/modals/ChangePaymentPasswordModal/index.tsx msgid "The new passwords don't match" msgstr "crwdns30610:0crwdne30610:0" +#. placeholder {0}: profile.identifier.userId #: content-script/components/shared/SelectRecipients/ProfileInList.tsx msgid "The Persona is connected to the account @${0}." msgstr "crwdns32818:0${0}crwdne32818:0" @@ -2626,6 +2844,7 @@ msgstr "crwdns32822:0crwdne32822:0" msgid "The persona name already exists." msgstr "crwdns30612:0crwdne30612:0" +#: dashboard/pages/SetupPersona/Backup/Cloud/CloudBackupFormContext.ts #: dashboard/contexts/CloudBackupFormContext.tsx msgid "The phone number is incorrect." msgstr "crwdns29784:0crwdne29784:0" @@ -2634,10 +2853,12 @@ msgstr "crwdns29784:0crwdne29784:0" msgid "The RPC URL you have entered returned a different chain ID ({rpcChainId}). Please update the Chain ID to match the RPC URL of the network you are trying to add." msgstr "crwdns32156:0{rpcChainId}crwdne32156:0" +#. placeholder {0}: format(localTransaction.updatedAt, "HH:mm 'on' M/dd/yyyy") #: popups/pages/Wallet/TransactionDetail/useTransactionLogs.ts msgid "The transaction was complete and has been recorded on blockchain at {0}" msgstr "crwdns30616:0{0}crwdne30616:0" +#. placeholder {0}: format(localTransaction.createdAt, "HH:mm 'on' M/dd/yyyy") #: popups/pages/Wallet/TransactionDetail/useTransactionLogs.ts msgid "The transaction was confirmed at {0}" msgstr "crwdns30618:0{0}crwdne30618:0" @@ -2650,9 +2871,9 @@ msgstr "crwdns32158:0crwdne32158:0" msgid "The wallet address already exists." msgstr "crwdns30620:0crwdne30620:0" -#: popups/modals/AddContactModal/index.tsx -#: popups/modals/EditContactModal/index.tsx #: popups/modals/WalletRenameModal/index.tsx +#: popups/modals/EditContactModal/index.tsx +#: popups/modals/AddContactModal/index.tsx msgid "The wallet name already exists." msgstr "crwdns30622:0crwdne30622:0" @@ -2660,6 +2881,7 @@ msgstr "crwdns30622:0crwdne30622:0" msgid "The web site can" msgstr "crwdns30624:0crwdne30624:0" +#. placeholder {0}: message.domain #: popups/components/SignRequestInfo/index.tsx msgid "The website ({messageOrigin}) is asking you to sign in to another domain ({0}). This may be a phishing attack." msgstr "crwdns30626:0{messageOrigin}crwdnd30626:0{0}crwdne30626:0" @@ -2676,6 +2898,7 @@ msgstr "crwdns30630:0crwdne30630:0" msgid "This address may be a scam address." msgstr "crwdns30632:0crwdne30632:0" +#. placeholder {0}: String(token?.symbol) #: popups/components/UnlockERC20Token/index.tsx msgid "This allows the third party to spend {value} {0} from your current balance." msgstr "crwdns30634:0{value}crwdnd30634:0{0}crwdne30634:0" @@ -2685,16 +2908,25 @@ msgid "This allows the third party to spend all your token balance until it reac msgstr "crwdns30636:0crwdne30636:0" #: popups/pages/Wallet/EditNetwork/useWarnings.ts -msgid "This Chain ID is currently used by the {0} network." -msgstr "crwdns30638:0{0}crwdne30638:0" +#~ msgid "This Chain ID is currently used by the {0} network." +#~ msgstr "" + +#. placeholder {0}: duplicated.name +#: popups/pages/Wallet/EditNetwork/useWarnings.ts +msgid "This Chain ID is currently used by the {0} network. " +msgstr "crwdns36384:0{0}crwdne36384:0" #: popups/hooks/useContactsContext.ts msgid "This ENS does not exist or not be resolved." msgstr "crwdns30640:0crwdne30640:0" #: popups/pages/Personas/ExportPrivateKey/index.tsx -msgid "This export is only for exporting private key. We do not export any other data. If you need more data, please go to Settings: <0>Global Backup " -msgstr "crwdns32824:0crwdne32824:0" +msgid "This export is only for exporting private key. We do not export any other data. If you need more data, please go to Settings: <0> Global Backup " +msgstr "crwdns36386:0crwdne36386:0" + +#: popups/pages/Personas/ExportPrivateKey/index.tsx +#~ msgid "This export is only for exporting private key. We do not export any other data. If you need more data, please go to Settings: <0>Global Backup " +#~ msgstr "" #: popups/pages/Wallet/ExportPrivateKey/index.tsx msgid "This JSON file is encrypted with your current payment password. The same password is required for decryption when importing this wallet." @@ -2728,6 +2960,7 @@ msgstr "crwdns30650:0crwdne30650:0" msgid "This request should only be sign in the future." msgstr "crwdns30652:0crwdne30652:0" +#. placeholder {0}: network.name #: popups/pages/Wallet/EditNetwork/network-schema.ts #: popups/pages/Wallet/EditNetwork/network-schema.ts msgid "This RPC URL is currently used by the {0} network" @@ -2737,6 +2970,7 @@ msgstr "crwdns30654:0{0}crwdne30654:0" msgid "This tweet is encrypted with #mask_io (@realMaskNetwork). 📪🔑" msgstr "crwdns35462:0crwdne35462:0" +#. placeholder {0}: String(currentPersona?.nickname) #: popups/pages/Personas/ConnectWallet/index.tsx msgid "This wallet is connected to current persona {0}." msgstr "crwdns30656:0{0}crwdne30656:0" @@ -2745,11 +2979,13 @@ msgstr "crwdns30656:0{0}crwdne30656:0" msgid "This will overwrite the existing cloud backup with the local data, this cannot be undo." msgstr "crwdns32164:0crwdne32164:0" -#: popups/components/AddContactInputPanel/index.tsx #: popups/pages/Wallet/TransactionDetail/index.tsx +#: popups/components/AddContactInputPanel/index.tsx msgid "To" msgstr "crwdns30658:0crwdne30658:0" +#. placeholder {0}: formatDomainName(domain) +#. placeholder {0}: formatEthereumAddress(toAddress, 4) #: popups/pages/Wallet/components/ActivityList/ActivityItem.tsx #: popups/pages/Wallet/components/ActivityList/ActivityItem.tsx msgid "to {0}" @@ -2784,9 +3020,9 @@ msgstr "crwdns32170:0crwdne32170:0" msgid "Token Value" msgstr "crwdns30666:0crwdne30666:0" -#: popups/pages/Wallet/AddToken/index.tsx #: popups/pages/Wallet/components/WalletAssets/index.tsx #: popups/pages/Wallet/Transfer/index.tsx +#: popups/pages/Wallet/AddToken/index.tsx msgid "Tokens" msgstr "crwdns30668:0crwdne30668:0" @@ -2810,12 +3046,16 @@ msgstr "crwdns30672:0crwdne30672:0" msgid "Try" msgstr "crwdns30674:0crwdne30674:0" +#: content-script/components/InjectedComponents/SetupGuide/AccountConnectStatus.tsx +msgid "Trying exploring more features powered by Mask Network." +msgstr "crwdns36879:0crwdne36879:0" + #: popups/modals/ChangeBackupPasswordModal/index.tsx msgid "Two entered passwords are different." msgstr "crwdns32172:0crwdne32172:0" -#: popups/modals/SetBackupPasswordModal/index.tsx #: popups/pages/Wallet/hooks/usePasswordForm.ts +#: popups/modals/SetBackupPasswordModal/index.tsx msgid "Two entered passwords are not the same." msgstr "crwdns32174:0crwdne32174:0" @@ -2827,13 +3067,13 @@ msgstr "crwdns30678:0crwdne30678:0" msgid "Unlock" msgstr "crwdns30680:0crwdne30680:0" -#: dashboard/components/Restore/RestorePersonaFromLocal.tsx +#: dashboard/pages/SetupPersona/Recovery/Local.tsx #: dashboard/components/Restore/RestoreWalletFromLocal.tsx msgid "Unpacking" msgstr "crwdns29794:0crwdne29794:0" -#: dashboard/components/Restore/RestorePersonaFromLocal.tsx -#: dashboard/components/Restore/RestorePersonaFromLocal.tsx +#: dashboard/pages/SetupPersona/Recovery/Local.tsx +#: dashboard/pages/SetupPersona/Recovery/Local.tsx msgid "Unsupported data backup" msgstr "crwdns29796:0crwdne29796:0" @@ -2881,16 +3121,16 @@ msgstr "crwdns30690:0crwdne30690:0" msgid "value" msgstr "crwdns30692:0crwdne30692:0" -#: dashboard/components/Restore/RestoreFromCloud/EmailField.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/EmailField.tsx msgid "Verification code has been sent to your email. Please check your mailbox." msgstr "crwdns32180:0crwdne32180:0" -#: dashboard/components/Restore/RestoreFromCloud/PhoneField.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/PhoneField.tsx msgid "Verification code has been sent to your phone." msgstr "crwdns32182:0crwdne32182:0" -#: dashboard/pages/SetupPersona/CloudBackup/EmailForm.tsx -#: dashboard/pages/SetupPersona/CloudBackup/PhoneForm.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/PhoneForm.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/EmailForm.tsx msgid "Verification code sent" msgstr "crwdns29808:0crwdne29808:0" @@ -2904,8 +3144,8 @@ msgstr "crwdns29812:0crwdne29812:0" msgid "Verify Account" msgstr "crwdns30694:0crwdne30694:0" -#: popups/components/SignRequestInfo/index.tsx #: popups/pages/Settings/index.tsx +#: popups/components/SignRequestInfo/index.tsx msgid "Version" msgstr "crwdns30696:0crwdne30696:0" @@ -2915,10 +3155,10 @@ msgstr "crwdns30698:0crwdne30698:0" #: content-script/components/InjectedComponents/ProfileCard/ProfileBar.tsx #: content-script/components/InjectedComponents/ProfileCard/ProfileBar.tsx -#: popups/pages/Personas/ConnectWallet/index.tsx +#: popups/pages/Wallet/TransactionDetail/index.tsx #: popups/pages/Wallet/ChangeOwner/index.tsx #: popups/pages/Wallet/ChangeOwner/index.tsx -#: popups/pages/Wallet/TransactionDetail/index.tsx +#: popups/pages/Personas/ConnectWallet/index.tsx msgid "View on Explorer" msgstr "crwdns30700:0crwdne30700:0" @@ -2943,11 +3183,11 @@ msgid "Waiting for {providerType}" msgstr "crwdns32190:0{providerType}crwdne32190:0" #: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx -msgid "wallet" -msgstr "crwdns29814:0crwdne29814:0" +#~ msgid "wallet" +#~ msgstr "" -#: popups/modals/WalletGroupModal/index.tsx #: popups/pages/Wallet/SwitchWallet/index.tsx +#: popups/modals/WalletGroupModal/index.tsx msgid "Wallet Account" msgstr "crwdns30706:0crwdne30706:0" @@ -2955,8 +3195,9 @@ msgstr "crwdns30706:0crwdne30706:0" msgid "Wallet disconnected" msgstr "crwdns32192:0crwdne32192:0" -#: popups/modals/WalletGroupModal/index.tsx +#. placeholder {0}: String(index + 1) #: popups/pages/Wallet/CreateWallet/index.tsx +#: popups/modals/WalletGroupModal/index.tsx msgid "Wallet Group #{0}" msgstr "crwdns30712:0#{0}crwdne30712:0" @@ -2973,8 +3214,8 @@ msgstr "crwdns30716:0crwdne30716:0" msgid "Wallet request timed out" msgstr "crwdns30718:0crwdne30718:0" -#: popups/pages/Wallet/SwitchWallet/index.tsx #: popups/pages/Wallet/WalletSettings/index.tsx +#: popups/pages/Wallet/SwitchWallet/index.tsx msgid "Wallet Settings" msgstr "crwdns30720:0crwdne30720:0" @@ -2990,8 +3231,8 @@ msgstr "crwdns32194:0crwdne32194:0" msgid "Web3 Profile Card" msgstr "crwdns30726:0crwdne30726:0" -#: popups/pages/Settings/index.tsx #: popups/pages/Wallet/components/OriginCard/index.tsx +#: popups/pages/Settings/index.tsx msgid "Website" msgstr "crwdns30728:0crwdne30728:0" @@ -3000,8 +3241,8 @@ msgid "Welcome Back" msgstr "crwdns30730:0crwdne30730:0" #: dashboard/pages/SetupPersona/CloudBackupPreview/index.tsx -msgid "Welcome to Mask Cloud Services" -msgstr "crwdns29820:0crwdne29820:0" +#~ msgid "Welcome to Mask Cloud Services" +#~ msgstr "" #: popups/pages/Personas/Home/UI.tsx msgid "Welcome to Mask Network" @@ -3011,6 +3252,10 @@ msgstr "crwdns30732:0crwdne30732:0" msgid "Welcome to use Mask Network" msgstr "crwdns29822:0crwdne29822:0" +#: dashboard/components/GoogleDriveLogin.tsx +msgid "when you click Add Google Drive button,you will be forwarded to Google authorization pages." +msgstr "crwdns37254:0crwdne37254:0" + #: popups/pages/Wallet/ExportPrivateKey/index.tsx msgid "Write down mnemonic words" msgstr "crwdns30734:0crwdne30734:0" @@ -3019,18 +3264,30 @@ msgstr "crwdns30734:0crwdne30734:0" msgid "Write down recovery phrase" msgstr "crwdns32196:0crwdne32196:0" +#: content-script/components/InjectedComponents/SetupGuide/AccountConnectStatus.tsx +msgid "You could check the verification result on Mask Pop-up after few minutes. If failed, try sending verification post again." +msgstr "crwdns36881:0crwdne36881:0" + #: dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx -msgid "You have backed up your data." -msgstr "crwdns32198:0crwdne32198:0" +#~ msgid "You have backed up your data." +#~ msgstr "" + +#: dashboard/pages/SetupPersona/Onboarding/index.tsx +#~ msgid "You have recovered" +#~ msgstr "" #: dashboard/pages/SetupPersona/Onboarding/index.tsx -msgid "You have recovered" -msgstr "crwdns32830:0crwdne32830:0" +#~ msgid "You have recovered " +#~ msgstr "" #: popups/pages/Personas/ConnectWallet/index.tsx msgid "You have signed with your wallet." msgstr "crwdns32200:0crwdne32200:0" +#: dashboard/pages/SetupPersona/Recovery/Cloud/GoogleDrive.tsx +msgid "You have successfully restored the backup from Google Drive to your browser." +msgstr "crwdns37274:0crwdne37274:0" + #: dashboard/components/Restore/ConfirmSynchronizePasswordDialog.tsx msgid "You have verified your cloud password and recovered your backup. Do you want to let your cloud password and local backup password be the same?" msgstr "crwdns32202:0crwdne32202:0" @@ -3041,22 +3298,50 @@ msgstr "crwdns32204:0crwdne32204:0" #: dashboard/pages/SetupPersona/CloudBackup/index.tsx #: dashboard/pages/SetupPersona/CloudBackup/index.tsx -msgid "You used <0>{0} for the last cloud backup." -msgstr "crwdns32832:0{0}crwdne32832:0" +#~ msgid "You used <0>{0} for the last cloud backup." +#~ msgstr "" #: popups/components/SignRequestInfo/index.tsx msgid "Your connection to this site is not encrypted which can be modified by a hostile third party, we strongly suggest you reject this request." msgstr "crwdns30740:0crwdne30740:0" +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx +msgid "Your file has been successfully merged into the browser data." +msgstr "crwdns37256:0crwdne37256:0" + +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx +msgid "Your file has been successfully restore into the browser data." +msgstr "crwdns37276:0crwdne37276:0" + #: dashboard/pages/CreateMaskWallet/CreateWalletForm/index.tsx msgid "Your payment password encrypts wallet data and is needed to unlocking the wallet, transaction confirmations and signing. The password is never stored, and there is no way to recover it if you forget it." msgstr "crwdns32206:0crwdne32206:0" #: dashboard/pages/SetupPersona/Onboarding/index.tsx -msgid "Your Persona is on" -msgstr "crwdns32834:0crwdne32834:0" +msgid "Your Persona has been successfully created." +msgstr "crwdns37299:0crwdne37299:0" + +#: dashboard/pages/SetupPersona/Onboarding/index.tsx +#~ msgid "Your Persona is on" +#~ msgstr "" + +#: dashboard/pages/SetupPersona/Onboarding/index.tsx +#~ msgid "Your Persona is on " +#~ msgstr "" + +#: dashboard/pages/SetupPersona/Onboarding/index.tsx +msgid "Your Persona is on **ready 🚀**" +msgstr "crwdns37288:0crwdne37288:0" + +#: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx +#~ msgid "Your Wallet is on" +#~ msgstr "" + +#: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx +#~ msgid "Your Wallet is on " +#~ msgstr "" #: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx -msgid "Your Wallet is on" -msgstr "crwdns29836:0crwdne29836:0" +msgid "Your Wallet is on **ready 🚀**" +msgstr "crwdns37290:0crwdne37290:0" diff --git a/packages/mask/shared-ui/locale/zh-CN.json b/packages/mask/shared-ui/locale/zh-CN.json index 7183669cfce1..d0ccc7c7d4ea 100644 --- a/packages/mask/shared-ui/locale/zh-CN.json +++ b/packages/mask/shared-ui/locale/zh-CN.json @@ -7,6 +7,16 @@ "y6VCOb": [["0"], " 分钟"], "MpnSqP": [["0"], " Pending"], "FKrzPv": [["count", "plural", { "one": ["#", " Wallet 🚀"], "other": ["#", " Wallets 🚀"] }]], + "5s6EhU": [ + [ + "count", + "plural", + { + "one": ["You have recovered **", "#", " Wallet 🚀**"], + "other": ["You have recovered **", "#", " Wallets 🚀**"] + } + ] + ], "yx3mb0": [ [ "decryptProgress", @@ -54,16 +64,18 @@ "pv5v6j": ["About Permit"], "k0USDt": ["Account connected.<0/><1/>Try to explore more features powered by Mask Network."], "R2K7XH": ["尝试探索社交媒体上的 Web3 dApps 功能。"], - "6c6xyD": ["账户"], + "6c6xyD": ["accounts"], "39ohdf": ["活动"], "I5kL4f": ["活动日志"], "m16xKo": ["添加"], "5YfW3S": ["Add an encrypted comment..."], "aTzTyw": ["添加资产"], "M0FgOk": ["添加联系人"], + "FAKSZG": ["Add google Drive"], "LP+1Z7": ["添加网络"], "68m9Nl": ["向现有组添加新地址"], "1LkMSp": ["Add Suggested Token"], + "O8PsYe": ["Add the file to Chrome's database"], "GtJJAj": ["添加钱包"], "uv94aG": ["由用户添加"], "8RF/Sx": ["添加成功"], @@ -94,13 +106,16 @@ "iTiwqa": ["Asset is hidden."], "2jQko7": ["关联账户"], "CEk7Nc": ["至少6个字符"], + "gp6A8z": ["Authorization Failed"], "Wvnsx1": ["自动锁定"], "7QptC5": ["自动锁定时间"], "nTFx7o": ["新头像设置成功"], "iH8pgl": ["返回"], + "npsHM5": ["Back Up to Google Drive"], + "V+1pjj": ["Back Up Your Data Your Way"], "rLgPvm": ["备份"], "h7+V7K": ["备份恢复"], - "QrHM/A": ["备份下载并成功合并到本地。"], + "QrHM/A": ["Backup downloaded and merged to local successfully."], "zp7Ha3": ["备份失败"], "5Cowlg": ["Backup is saved to Mask Cloud Service."], "qZ6p7p": ["Backup on ", ["0"]], @@ -109,7 +124,9 @@ "ERYJcj": ["备份密码必须是 8-20 个字符,包括大写、小写、特殊字符和数字。"], "hUF4dG": ["备份密码设置成功。"], "UtKGok": ["备份身份"], - "7Ry254": ["备份到 Mask 云服务"], + "+m7x4e": ["Backup Successful"], + "3iUAE7": ["Backup to Google Drive"], + "7Ry254": ["Backup to Mask Cloud Service"], "6IHgRq": ["Backup to the Cloud"], "QQPCqQ": ["备份钱包"], "fsBGk0": ["余额"], @@ -136,6 +153,9 @@ "tcHpvG": ["更改管理账户"], "fDP2k4": ["修改支付密码"], "IXbRbM": ["切换钱包"], + "lU6uRb": [ + "Choose from multiple backup options, now including encrypted storage via your authorized Google Drive for added security and flexibility." + ], "xH6cn+": ["选择代币"], "+adBn3": ["Chrome - external extension"], "EsKgLS": ["点击这里快速开始。"], @@ -191,6 +211,9 @@ "PjBWOL": ["创建您的身份以开始"], "WgawP2": ["Creating your"], "cEnmTp": ["Creating your "], + "L82H5Z": ["Creating your **identity**"], + "F7U8uz": ["Creating your **wallet**"], + "aF8kci": ["Creation Completed"], "Q2lUR2": ["货币"], "OgPkDe": ["货币符号(可选)"], "oOQfsI": ["Current account is not the verifying account."], @@ -205,8 +228,9 @@ ], "8Tg/JR": ["自定义"], "pvnfJD": ["深色"], - "Sp/me1": ["数据"], + "Sp/me1": ["data"], "HKH+W+": ["数据"], + "K8jCIB": ["Data backed up successfully!"], "3B4jmY": ["数据关联"], "rAcOY1": [ "Data merged from Mask Cloud Service to local successfully. Re-enter your password to encrypt and upload the new backup to Mask Cloud Service." @@ -244,11 +268,11 @@ "XZ/B+f": ["找不到您的NFT?"], "DPfwMq": ["完成"], "mzI/c+": ["下载"], - "1vSYsG": ["下载备份"], + "1vSYsG": ["Download backup"], "1+6BOG": ["下载备份"], "9hg9mc": ["正在下载"], "F8Wc3I": ["将您的文件拖放到此处"], - "5Sa1Ss": ["电子邮件"], + "5Sa1Ss": ["E-mail"], "ePK91l": ["编辑"], "mQpWAe": ["编辑联系人"], "iZLoa2": ["eg: X accounts, persona public keys, wallet addresses or ENS"], @@ -261,6 +285,7 @@ "w1ctdJ": ["加密贴文"], "MRIXE3": ["Encrypting your"], "zutir1": ["Encrypting your "], + "XB3tfc": ["Encrypting your **data**"], "Cz6Lx7": ["加密方式"], "N/fqDa": ["Ens或地址(0x)"], "mPxxVq": ["输入Gas Limit"], @@ -280,9 +305,14 @@ "GS+Mus": ["导出"], "7Bj3x9": ["失败"], "SLEDBF": ["添加钱包失败,请重试。"], + "r92tNP": ["Failed to authorize Google Drive. Please try again."], "09vHB+": ["Failed to decrypt."], "jK7nvW": ["Failed to disconnect wallet"], + "9hzYBR": ["Failed to download and merge the backup: ", ["0"]], "0tkvsz": ["Failed to download and merge the backup."], + "etATpN": ["Failed to login: ", ["0"]], + "qDIxZ+": ["Failed to restore the backup from Google Drive to your browser. Please try again."], + "e3I0CA": ["Failed to restore the backup: ", ["0"]], "mrAv9J": ["无法保存网络"], "ZsjtYe": ["加载头像失败。"], "RWoEqV": ["Failed to transfer token: ", ["message"]], @@ -318,7 +348,9 @@ "fUn3xA": ["生成一个新的钱包地址"], "tdZPpe": ["Generating your"], "CiU2m/": ["Generating your "], + "RL5m+x": ["Generating your **accounts**"], "2p7WMm": ["Give permission to access <0/> your ", ["0"], "?"], + "w9Xmw/": ["Google Drive"], "76gPWk": ["好的"], "HqiAyF": ["Gwei"], "pu3rTn": ["GWEI"], @@ -337,7 +369,7 @@ "yx/fMc": ["高速"], "0caMy7": ["History"], "uip9JY": ["I wrote down those words in the correct order"], - "b5d759": ["身份"], + "b5d759": ["identity"], "RRw7LE": ["身份助记词"], "/WfDJy": [ "If you forget payment password, you can type 'RESET' to reset your wallet. <0>Remember, this action will erase all your previous wallets." @@ -350,6 +382,7 @@ "fza4cg": ["导入钱包"], "HvDfH/": ["已导入"], "m3XvO+": ["导入钱包"], + "ANk/Zy": ["Incorrect Backup Password"], "a23gJr": ["密码不正确。"], "bapItf": ["备份密码错误。"], "bassMa": ["云备份密码不正确,请重试。"], @@ -390,9 +423,11 @@ "jygqM9": ["Loading account information..."], "EBC6hj": ["本地备份"], "shPV5O": ["仅限本地身份或钱包"], + "crVIc7": ["Locale Backup"], "KGHnSc": ["锁定钱包"], "FgAxTj": ["登出"], "kC3Q3d": ["Login to Mask Cloud"], + "nOhz3x": ["Logout"], "NkgvWN": ["登出失败"], "o4Iu2W": ["退出成功"], "nTWWCZ": ["低"], @@ -402,6 +437,7 @@ ], "lET9my": ["Mask Network需要以下权限"], "siroPf": ["Mask Network"], + "jhoAzY": ["Mask Network Cloud"], "lWOC+h": ["Mask Network requires you to authorize the following websites before using it."], "HsoakN": ["masknetwork"], "CK1KXz": ["最大"], @@ -418,8 +454,10 @@ "sQJ3RN": ["最大优先费用在当前网络环境下过低。"], "ITBQO3": ["Max priority fee必须大于 0 GWEI"], "agPptk": ["中等"], + "lPsa94": ["Merge Completed"], "RH8jSA": ["合并数据到本地数据库"], - "QTomF0": ["合并至本地数据"], + "E6YUtc": ["Merge to Browser"], + "QTomF0": ["Merge to local"], "xDAtGP": ["信息"], "pGElS5": ["助记词"], "yFrxQj": ["助记词"], @@ -479,8 +517,8 @@ "YKSmxE": [ "Other social networking platforms, such as <0>Instagram, <1>Facebook, and <2>Minds, do not have a verified relationship like X's Next.ID verified connection.<3/><4/>When connecting a persona with an account on these platforms, they only support sending encrypted posts." ], - "MXOdMY": ["覆盖备份"], - "p2xE4C": ["覆盖当前备份"], + "MXOdMY": ["Overwrite Backup"], + "p2xE4C": ["Overwrite current backup"], "8ZsakT": ["密码"], "9w2hgY": ["手动粘贴"], "GAvnvl": ["支付密码"], @@ -543,9 +581,10 @@ "3AP6p1": ["Public Key: <0>", ["publicKey"], ""], "82+n6o": ["Quote Route"], "AV+9wg": ["重新输入"], - "TZ0npN": ["准备🚀"], + "TZ0npN": ["ready 🚀"], "nVT2pJ": ["realMaskNetwork"], "lDgVWA": ["接收"], + "OkofjH": ["Recover"], "XC7RGa": ["恢复数据"], "UBzbea": ["恢复钱包"], "P9wzG/": ["恢复"], @@ -567,8 +606,10 @@ "nvAt0H": ["Resource"], "yKu/3Y": ["恢复"], "Z3+V9p": ["Restore backup failed."], + "nGl2Ng": ["Restore Completed"], "AKLbfQ": ["恢复数据库"], "uM6jnS": ["恢复失败"], + "KFwID2": ["Restore Failed"], "/LkuGq": ["从以前的数据库备份恢复"], "KisOjk": ["恢复身份"], "6gRgw8": ["重试"], @@ -586,7 +627,7 @@ "nTif4K": ["选择并连接到你的钱包"], "k/sb6z": ["选择语言"], "LSwUJb": ["Select Liquidity"], - "RjF5dk": ["选择备份的内容"], + "RjF5dk": ["Select the contents of the backup"], "PI/VCJ": ["Select the wallet(s) to use on this site. You should not connect to website you don't trust."], "a1SmQh": ["选择钱包"], "JlFcis": ["发送"], @@ -604,7 +645,7 @@ "iJLEZF": ["教我怎么做"], "nOCyT5": ["显示价值小于$1 的代币"], "c+Fnce": ["签名"], - "mErq7F": ["注册"], + "mErq7F": ["Sign Up"], "t3rUZr": ["Sign-in Request"], "py6hU8": ["签名请求"], "9KKhJV": ["正在签名..."], @@ -647,6 +688,9 @@ "VdhBp2": ["The chainID is not equal to the currently connected one."], "h3Vpnw": ["验证码不正确"], "7w1rTm": ["The download link is expired"], + "oYkran": [ + "The Mask Network Cloud Backup feature will be deactivated on April 30, 2025. Please use alternative cloud backup services or local backup solutions." + ], "o+zDNQ": ["The mnemonic word has been copied, please keep it in a safe place."], "yRuvmU": ["The mnemonic words has been copied, please keep it in a safe place."], "thX7xs": [ @@ -765,7 +809,7 @@ "vVEene": ["View your Tokens and NFTs"], "kbfp5m": ["可见范围"], "PTXNyo": ["Waiting for ", ["providerType"]], - "6XyieG": ["钱包"], + "6XyieG": ["wallet"], "VECuJk": ["钱包账户"], "KtMMzG": ["Wallet disconnected"], "Kl9gHp": ["钱包组 #", ["0"]], @@ -780,9 +824,10 @@ "EGWr+Q": ["Web3 名片"], "On0aF2": ["网站"], "CWsYB3": ["欢迎回来"], - "m74yjp": ["欢迎使用 Mask 云服务"], + "m74yjp": ["Welcome to Mask Cloud Services"], "hEpXzO": ["欢迎来到 Mask Network!"], "fFYJ8f": ["欢迎来到 Mask Network!"], + "OLUEnY": ["when you click Add Google Drive button,you will be forwarded to Google authorization pages."], "Qbo7Ev": ["写下助记词"], "f5AidZ": ["Write down recovery phrase"], "yGyJ1l": [ @@ -792,6 +837,7 @@ "dyqtoj": ["You have recovered"], "V8x6o5": ["You have recovered "], "QU9aqK": ["You have signed with your wallet."], + "PeT3a5": ["You have successfully restored the backup from Google Drive to your browser."], "zkEW09": [ "You have verified your cloud password and recovered your backup. Do you want to let your cloud password and local backup password be the same?" ], @@ -800,12 +846,17 @@ "FnQek5": [ "Your connection to this site is not encrypted which can be modified by a hostile third party, we strongly suggest you reject this request." ], + "UDKbPj": ["Your file has been successfully merged into the browser data."], + "S2JNMm": ["Your file has been successfully restore into the browser data."], "Q68Nuc": [ "Your payment password encrypts wallet data and is needed to unlocking the wallet, transaction confirmations and signing. The password is never stored, and there is no way to recover it if you forget it." ], + "4EN5JL": ["Your Persona has been successfully created."], "N19nSk": ["Your Persona is on"], "WC7pDz": ["Your Persona is on "], + "PDW/HG": ["Your Persona is on **ready 🚀**"], "0kr+x1": ["Your Wallet is on"], - "v7OL2k": ["Your Wallet is on "] + "v7OL2k": ["Your Wallet is on "], + "wCtp6y": ["Your Wallet is on **ready 🚀**"] } } diff --git a/packages/mask/shared-ui/locale/zh-CN.po b/packages/mask/shared-ui/locale/zh-CN.po index 61b4a085ad81..e67b13ff0a83 100644 --- a/packages/mask/shared-ui/locale/zh-CN.po +++ b/packages/mask/shared-ui/locale/zh-CN.po @@ -3,7 +3,7 @@ msgstr "" "Project-Id-Version: mask-network\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2025-01-08 06:53\n" +"PO-Revision-Date: 2025-04-10 05:53\n" "Last-Translator: \n" "Language: zh_CN\n" "Language-Team: Chinese Simplified\n" @@ -46,7 +46,11 @@ msgid "{0} Pending" msgstr "" #: dashboard/pages/SetupPersona/Onboarding/index.tsx -msgid "{count, plural, one {# Wallet 🚀} other {# Wallets 🚀}}" +#~ msgid "{count, plural, one {# Wallet 🚀} other {# Wallets 🚀}}" +#~ msgstr "" + +#: dashboard/pages/SetupPersona/Onboarding/index.tsx +msgid "{count, plural, one {You have recovered **# Wallet 🚀**} other {You have recovered **# Wallets 🚀**}}" msgstr "" #: content-script/components/InjectedComponents/DecryptedPost/DecryptPostAwaiting.tsx @@ -132,8 +136,8 @@ msgstr "尝试探索社交媒体上的 Web3 dApps 功能。" #: dashboard/pages/SetupPersona/Onboarding/index.tsx #: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx -msgid "accounts" -msgstr "账户" +#~ msgid "accounts" +#~ msgstr "" #: popups/pages/Wallet/components/WalletAssets/index.tsx msgid "Activities" @@ -162,6 +166,10 @@ msgstr "添加资产" msgid "Add Contact" msgstr "添加联系人" +#: dashboard/components/GoogleDriveLogin.tsx +msgid "Add google Drive" +msgstr "" + #: popups/pages/Wallet/NetworkManagement/index.tsx #: popups/pages/Wallet/EditNetwork/index.tsx msgid "Add Network" @@ -175,6 +183,10 @@ msgstr "向现有组添加新地址" msgid "Add Suggested Token" msgstr "" +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx +msgid "Add the file to Chrome's database" +msgstr "" + #: popups/pages/Wallet/components/StartUp/index.tsx #: popups/pages/Wallet/SwitchWallet/index.tsx #: popups/pages/Wallet/CreateWallet/index.tsx @@ -258,8 +270,8 @@ msgid "Approve amount" msgstr "已批准的金额" #: dashboard/pages/SetupPersona/CloudBackupPreview/index.tsx -msgid "Are you sure to overwrite the backups stored on Mask Cloud Service?" -msgstr "" +#~ msgid "Are you sure to overwrite the backups stored on Mask Cloud Service?" +#~ msgstr "" #. placeholder {0}: formatEthereumAddress(wallet.identity, 4) #: popups/components/ConnectedWallet/index.tsx @@ -292,6 +304,10 @@ msgstr "关联账户" msgid "At least 6 characters" msgstr "至少6个字符" +#: dashboard/components/GoogleDriveLogin.tsx +msgid "Authorization Failed" +msgstr "" + #: popups/pages/Wallet/WalletSettings/AutoLock.tsx msgid "Auto-lock" msgstr "自动锁定" @@ -305,13 +321,24 @@ msgid "Avatar set successfully" msgstr "新头像设置成功" #: content-script/components/shared/SelectRecipients/SelectRecipientsDialog.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/Preview.tsx #: dashboard/pages/CreateMaskWallet/CreateMnemonic/index.tsx #: popups/pages/Personas/ExportPrivateKey/index.tsx #: popups/pages/Personas/AccountDetail/UI.tsx msgid "Back" msgstr "返回" -#: dashboard/pages/SetupPersona/CloudBackupPreview/index.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/GoogleDrive.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/GoogleDrive.tsx +#~ msgid "Back Up to Google Drive" +#~ msgstr "" + +#: dashboard/pages/SetupPersona/Backup/index.tsx +msgid "Back Up Your Data Your Way" +msgstr "" + +#: dashboard/pages/SetupPersona/Backup/Cloud/GoogleDrive.tsx +#: dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx #: popups/pages/Personas/Logout/index.tsx #: popups/modals/SwitchPersonaModal/index.tsx msgid "Backup" @@ -322,16 +349,16 @@ msgid "Backup & Recovery" msgstr "备份恢复" #: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx -msgid "Backup downloaded and merged to local successfully." -msgstr "备份下载并成功合并到本地。" +#~ msgid "Backup downloaded and merged to local successfully." +#~ msgstr "" #: dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx msgid "Backup Failed" msgstr "备份失败" #: dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx -msgid "Backup is saved to Mask Cloud Service." -msgstr "" +#~ msgid "Backup is saved to Mask Cloud Service." +#~ msgstr "" #. placeholder {0}: user.localBackupAt #. placeholder {0}: user.cloudBackupAt @@ -340,13 +367,13 @@ msgstr "" msgid "Backup on {0}" msgstr "" -#: dashboard/components/Restore/RestorePersonaFromLocal.tsx -#: dashboard/components/Restore/RestoreFromCloud/ConfirmBackupInfo.tsx +#: dashboard/pages/SetupPersona/Recovery/Local.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/ConfirmBackupInfo.tsx msgid "Backup password" msgstr "备份密码" -#: dashboard/pages/SetupPersona/LocalBackup/index.tsx -#: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx +#: dashboard/pages/SetupPersona/Backup/Local.tsx +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx #: dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx #: popups/pages/Settings/index.tsx #: popups/modals/SetBackupPasswordModal/index.tsx @@ -368,9 +395,18 @@ msgstr "备份密码设置成功。" msgid "Backup Persona" msgstr "备份身份" +#: dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx +msgid "Backup Successful" +msgstr "" + +#: dashboard/pages/SetupPersona/Backup/Cloud/GoogleDrive.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/GoogleDrive.tsx +msgid "Backup to Google Drive" +msgstr "" + #: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx -msgid "Backup to Mask Cloud Service" -msgstr "备份到 Mask 云服务" +#~ msgid "Backup to Mask Cloud Service" +#~ msgstr "" #: dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx msgid "Backup to the Cloud" @@ -437,7 +473,6 @@ msgstr "" #: content-script/components/InjectedComponents/SelectPeopleDialog.tsx #: dashboard/pages/SetupPersona/Welcome/index.tsx #: dashboard/pages/SetupPersona/Permissions/index.tsx -#: dashboard/pages/SetupPersona/CloudBackupPreview/index.tsx #: dashboard/modals/ConfirmModal/index.tsx #: dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx #: dashboard/components/Restore/ConfirmSynchronizePasswordDialog.tsx @@ -510,6 +545,10 @@ msgstr "修改支付密码" msgid "Choose another wallet" msgstr "切换钱包" +#: dashboard/pages/SetupPersona/Backup/index.tsx +msgid "Choose from multiple backup options, now including encrypted storage via your authorized Google Drive for added security and flexibility." +msgstr "" + #: popups/modals/ChooseToken/index.tsx msgid "Choose Token" msgstr "选择代币" @@ -535,6 +574,7 @@ msgid "Close" msgstr "关闭" #: dashboard/pages/SetupPersona/Recovery/index.tsx +#: dashboard/pages/SetupPersona/Backup/index.tsx #: dashboard/components/Restore/ConfirmSynchronizePasswordDialog.tsx #: popups/pages/Settings/index.tsx msgid "Cloud Backup" @@ -548,12 +588,11 @@ msgstr "收藏品" msgid "Coming soon" msgstr "即将上线" +#: dashboard/pages/SetupPersona/Recovery/Local.tsx #: dashboard/components/Restore/RestoreWalletFromLocal.tsx -#: dashboard/components/Restore/RestorePersonaFromLocal.tsx msgid "Completed" msgstr "已完成" -#: dashboard/pages/SetupPersona/CloudBackupPreview/index.tsx #: dashboard/modals/ConfirmModal/index.tsx #: dashboard/components/Restore/ConfirmSynchronizePasswordDialog.tsx #: popups/pages/Wallet/components/DisconnectModal/index.tsx @@ -607,8 +646,6 @@ msgstr "" msgid "Confirm to hide {name}? You can redisplay it by re-adding this NFT at any time." msgstr "" -#: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx -#: dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx #: popups/pages/Personas/ConnectWallet/index.tsx msgid "Congratulations" msgstr "恭喜您!" @@ -709,16 +746,18 @@ msgstr "联系人" #: dashboard/pages/SignUp/steps/PersonaNameUI.tsx #: dashboard/pages/SetupPersona/SignUp/index.tsx +#: dashboard/pages/SetupPersona/Recovery/PrivateKey.tsx +#: dashboard/pages/SetupPersona/Recovery/Phrase.tsx +#: dashboard/pages/SetupPersona/Recovery/Local.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/PhoneField.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/EmailField.tsx #: dashboard/pages/SetupPersona/Mnemonic/index.tsx -#: dashboard/pages/SetupPersona/CloudBackup/index.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/MaskNetwork.tsx #: dashboard/pages/CreateMaskWallet/CreateWalletForm/index.tsx #: dashboard/pages/CreateMaskWallet/AddDeriveWallet/index.tsx #: dashboard/components/Restore/RestoreWalletFromLocal.tsx -#: dashboard/components/Restore/RestorePersonaFromLocal.tsx #: dashboard/components/Restore/RestoreFromPrivateKey.tsx #: dashboard/components/Restore/RestoreFromMnemonic.tsx -#: dashboard/components/Restore/RestoreFromCloud/PhoneField.tsx -#: dashboard/components/Restore/RestoreFromCloud/EmailField.tsx msgid "Continue" msgstr "继续" @@ -774,6 +813,7 @@ msgstr "创建新的 MASK 身份" msgid "Create Password" msgstr "设置密码" +#: dashboard/pages/SetupPersona/Recovery/index.tsx #: popups/pages/Personas/Home/UI.tsx msgid "Create Persona" msgstr "创建身份" @@ -789,7 +829,19 @@ msgstr "创建您的身份以开始" #: dashboard/pages/SetupPersona/Onboarding/index.tsx #: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx -msgid "Creating your " +#~ msgid "Creating your " +#~ msgstr "" + +#: dashboard/pages/SetupPersona/Onboarding/index.tsx +msgid "Creating your **identity**" +msgstr "" + +#: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx +msgid "Creating your **wallet**" +msgstr "" + +#: dashboard/pages/SetupPersona/Onboarding/index.tsx +msgid "Creation Completed" msgstr "" #: popups/pages/Wallet/WalletSettings/ChangeCurrency.tsx @@ -830,23 +882,27 @@ msgstr "深色" #: dashboard/pages/SetupPersona/Onboarding/index.tsx #: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx -msgid "data" -msgstr "数据" +#~ msgid "data" +#~ msgstr "" #: popups/pages/Wallet/Interaction/TransactionRequest.tsx msgid "Data" msgstr "数据" +#: dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx +msgid "Data backed up successfully!" +msgstr "" + #: popups/pages/Settings/index.tsx msgid "Data correlation" msgstr "数据关联" #: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx -msgid "Data merged from Mask Cloud Service to local successfully. Re-enter your password to encrypt and upload the new backup to Mask Cloud Service." -msgstr "" +#~ msgid "Data merged from Mask Cloud Service to local successfully. Re-enter your password to encrypt and upload the new backup to Mask Cloud Service." +#~ msgstr "" -#: dashboard/components/Restore/RestoreFromCloud/ConfirmBackupInfo.tsx -#: dashboard/components/Restore/RestoreFromCloud/ConfirmBackupInfo.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/ConfirmBackupInfo.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/ConfirmBackupInfo.tsx msgid "Decrypt failed, please check password" msgstr "备份解密失败,请检查密码" @@ -951,18 +1007,20 @@ msgid "Done" msgstr "完成" #: content-script/components/InjectedComponents/AutoPasteFailedDialog.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/Preview.tsx +#: dashboard/components/GoogleDriveFileTable.tsx msgid "Download" msgstr "下载" #: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx -msgid "Download backup" -msgstr "下载备份" +#~ msgid "Download backup" +#~ msgstr "" -#: dashboard/pages/SetupPersona/LocalBackup/index.tsx +#: dashboard/pages/SetupPersona/Backup/Local.tsx msgid "Download Backup" msgstr "下载备份" -#: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx msgid "Downloading" msgstr "正在下载" @@ -971,8 +1029,8 @@ msgid "Drag & Drop your file here" msgstr "将您的文件拖放到此处" #: dashboard/pages/SetupPersona/CloudBackup/index.tsx -msgid "E-mail" -msgstr "电子邮件" +#~ msgid "E-mail" +#~ msgstr "" #: popups/pages/Wallet/ContactList/index.tsx msgid "Edit" @@ -987,13 +1045,14 @@ msgstr "编辑联系人" msgid "eg: X accounts, persona public keys, wallet addresses or ENS" msgstr "" -#: dashboard/pages/SetupPersona/CloudBackup/EmailForm.tsx -#: dashboard/components/Restore/RestoreFromCloud/EmailField.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/EmailField.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/MaskNetwork.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/EmailForm.tsx msgid "Email" msgstr "电子邮箱" -#: dashboard/pages/SetupPersona/CloudBackup/EmailForm.tsx -#: dashboard/components/Restore/RestoreFromCloud/EmailField.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/EmailField.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/EmailForm.tsx msgid "Email verification code" msgstr "邮箱验证码" @@ -1024,7 +1083,12 @@ msgstr "加密贴文" #: dashboard/pages/SetupPersona/Onboarding/index.tsx #: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx -msgid "Encrypting your " +#~ msgid "Encrypting your " +#~ msgstr "" + +#: dashboard/pages/SetupPersona/Onboarding/index.tsx +#: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx +msgid "Encrypting your **data**" msgstr "" #: content-script/components/CompositionDialog/EncryptionMethodSelector.tsx @@ -1110,6 +1174,10 @@ msgstr "失败" msgid "Failed to add the wallet, please try again." msgstr "添加钱包失败,请重试。" +#: dashboard/components/GoogleDriveLogin.tsx +msgid "Failed to authorize Google Drive. Please try again." +msgstr "" + #: content-script/components/InjectedComponents/DecryptedPost/DecryptPostFailed.tsx msgid "Failed to decrypt." msgstr "" @@ -1118,8 +1186,26 @@ msgstr "" msgid "Failed to disconnect wallet" msgstr "" +#. placeholder {0}: (err as Error).message +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx +msgid "Failed to download and merge the backup: {0}" +msgstr "" + #: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx -msgid "Failed to download and merge the backup." +#~ msgid "Failed to download and merge the backup." +#~ msgstr "" + +#: dashboard/components/GoogleDriveLogin.tsx +#~ msgid "Failed to login: {0}" +#~ msgstr "" + +#: dashboard/pages/SetupPersona/Recovery/Cloud/GoogleDrive.tsx +msgid "Failed to restore the backup from Google Drive to your browser. Please try again." +msgstr "" + +#. placeholder {0}: (err as Error).message +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx +msgid "Failed to restore the backup: {0}" msgstr "" #: popups/pages/Wallet/EditNetwork/index.tsx @@ -1269,7 +1355,12 @@ msgstr "生成一个新的钱包地址" #: dashboard/pages/SetupPersona/Onboarding/index.tsx #: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx -msgid "Generating your " +#~ msgid "Generating your " +#~ msgstr "" + +#: dashboard/pages/SetupPersona/Onboarding/index.tsx +#: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx +msgid "Generating your **accounts**" msgstr "" #. placeholder {0}: contract?.symbol || '' @@ -1279,6 +1370,13 @@ msgstr "" msgid "Give permission to access <0/> your {0}?" msgstr "" +#: dashboard/pages/SetupPersona/Recovery/Cloud/index.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/GoogleDrive.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/index.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/GoogleDrive.tsx +msgid "Google Drive" +msgstr "" + #: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx msgid "Got it" msgstr "好的" @@ -1344,8 +1442,8 @@ msgid "I wrote down those words in the correct order" msgstr "" #: dashboard/pages/SetupPersona/Onboarding/index.tsx -msgid "identity" -msgstr "身份" +#~ msgid "identity" +#~ msgstr "" #: dashboard/pages/SetupPersona/Mnemonic/ComponentToPrint.tsx msgid "Identity ID" @@ -1389,17 +1487,21 @@ msgstr "已导入" msgid "Imported Wallets" msgstr "导入钱包" +#: dashboard/hooks/useBackupFormState.ts +msgid "Incorrect Backup Password" +msgstr "" + #: popups/modals/VerifyBackupPasswordModal/index.tsx #: popups/modals/ChangeBackupPasswordModal/index.tsx msgid "Incorrect backup password." msgstr "密码不正确。" -#: dashboard/components/Restore/RestorePersonaFromLocal.tsx +#: dashboard/pages/SetupPersona/Recovery/Local.tsx msgid "Incorrect Backup Password." msgstr "备份密码错误。" -#: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx -#: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx msgid "Incorrect cloud backup password, please try again." msgstr "云备份密码不正确,请重试。" @@ -1417,7 +1519,7 @@ msgstr "" msgid "Incorrect password" msgstr "密码不正确" -#: dashboard/pages/SetupPersona/LocalBackup/index.tsx +#: dashboard/pages/SetupPersona/Backup/Local.tsx #: dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx #: dashboard/hooks/useBackupFormState.ts #: dashboard/hooks/useBackupFormState.ts @@ -1425,7 +1527,6 @@ msgstr "密码不正确" #: dashboard/hooks/useBackupFormState.ts #: dashboard/hooks/useBackupFormState.ts #: dashboard/hooks/useBackupFormState.ts -#: dashboard/hooks/useBackupFormState.ts msgid "Incorrect Password" msgstr "密码不正确" @@ -1438,12 +1539,12 @@ msgstr "支付密码错误。" msgid "Incorrect Payment Password." msgstr "支付密码错误。" -#: dashboard/pages/SetupPersona/Recovery/index.tsx +#: dashboard/pages/SetupPersona/Recovery/PrivateKey.tsx #: dashboard/pages/CreateMaskWallet/Recovery/index.tsx msgid "Incorrect Private Key" msgstr "私钥不正确" -#: dashboard/pages/SetupPersona/Recovery/index.tsx +#: dashboard/pages/SetupPersona/Recovery/Phrase.tsx msgid "Incorrect recovery phrase." msgstr "助记词不正确。" @@ -1456,6 +1557,7 @@ msgstr "无效钱包地址。" msgid "Incorrect words selected. Please try again!" msgstr "" +#: dashboard/pages/SetupPersona/Recovery/PrivateKey.tsx #: dashboard/components/Restore/RestoreFromPrivateKey.tsx msgid "Input your Private Key" msgstr "输入您的私钥" @@ -1473,12 +1575,13 @@ msgstr "Gas 不足。" msgid "Invalid Block Explorer URL." msgstr "无效的块浏览器URL。" -#: dashboard/pages/SetupPersona/CloudBackup/EmailForm.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/EmailForm.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/CloudBackupFormContext.ts #: dashboard/contexts/CloudBackupFormContext.tsx msgid "Invalid email address format." msgstr "邮箱地址不正确。" -#: dashboard/components/Restore/RestoreFromCloud/EmailField.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/EmailField.tsx msgid "Invalid email address." msgstr "" @@ -1486,7 +1589,7 @@ msgstr "" msgid "Invalid number" msgstr "数字无效" -#: dashboard/components/Restore/RestoreFromCloud/PhoneField.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/PhoneField.tsx msgid "Invalid phone number, please check and try again." msgstr "无效的电话号码,请检查并重试。" @@ -1494,8 +1597,8 @@ msgstr "无效的电话号码,请检查并重试。" msgid "Invalid RPC URL." msgstr "无效 RPC URL 。" -#: dashboard/components/Restore/RestoreFromCloud/PhoneField.tsx -#: dashboard/components/Restore/RestoreFromCloud/EmailField.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/PhoneField.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/EmailField.tsx msgid "Invalid verification code." msgstr "验证码错误。" @@ -1576,6 +1679,10 @@ msgstr "本地备份" msgid "Local persona or wallet only" msgstr "仅限本地身份或钱包" +#: dashboard/pages/SetupPersona/Backup/index.tsx +msgid "Locale Backup" +msgstr "" + #: popups/pages/Wallet/SwitchWallet/index.tsx msgid "Lock Wallet" msgstr "锁定钱包" @@ -1587,7 +1694,13 @@ msgid "Log out" msgstr "登出" #: dashboard/pages/SetupPersona/CloudBackup/index.tsx -msgid "Login to Mask Cloud" +#~ msgid "Login to Mask Cloud" +#~ msgstr "" + +#: dashboard/pages/SetupPersona/Recovery/Cloud/GoogleDrive.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/Preview.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/GoogleDrive.tsx +msgid "Logout" msgstr "" #: popups/pages/Personas/Logout/index.tsx @@ -1618,9 +1731,15 @@ msgstr "Mask Network需要以下权限" #: content-script/components/InjectedComponents/ToolboxUnstyled.tsx #: content-script/components/InjectedComponents/PostDialogHint.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/index.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/index.tsx msgid "Mask Network" msgstr "" +#: dashboard/pages/SetupPersona/Backup/Cloud/Preview.tsx +msgid "Mask Network Cloud" +msgstr "" + #: content-script/components/InjectedComponents/PermissionBoundary.tsx msgid "Mask Network requires you to authorize the following websites before using it." msgstr "" @@ -1692,15 +1811,23 @@ msgstr "Max priority fee必须大于 0 GWEI" msgid "Medium" msgstr "中等" -#: dashboard/pages/SetupPersona/CloudBackupPreview/index.tsx -#: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx -#: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx +msgid "Merge Completed" +msgstr "" + +#: dashboard/pages/SetupPersona/Backup/Cloud/Preview.tsx +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx msgid "Merge data to local database" msgstr "合并数据到本地数据库" +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx +#: dashboard/components/GoogleDriveFileTable.tsx +msgid "Merge to Browser" +msgstr "" + #: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx -msgid "Merge to local" -msgstr "合并至本地数据" +#~ msgid "Merge to local" +#~ msgstr "" #: popups/components/SignRequestInfo/index.tsx msgid "Message" @@ -1715,15 +1842,15 @@ msgstr "助记词" msgid "Mnemonic word" msgstr "助记词" -#: dashboard/pages/SetupPersona/CloudBackup/index.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/MaskNetwork.tsx msgid "Mobile" msgstr "手机" -#: dashboard/pages/SetupPersona/CloudBackup/PhoneForm.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/PhoneForm.tsx msgid "Mobile number" msgstr "手机号码" -#: dashboard/components/Restore/RestoreFromCloud/PhoneField.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/PhoneField.tsx msgid "Mobile verification code" msgstr "手机验证码" @@ -1836,7 +1963,8 @@ msgstr "" msgid "No back up" msgstr "没有备份" -#: dashboard/pages/SetupPersona/CloudBackupPreview/index.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/Preview.tsx +#: dashboard/components/GoogleDriveFileTable.tsx msgid "No backups found" msgstr "没有发现备份" @@ -1949,13 +2077,12 @@ msgid "Other social networking platforms, such as <0>Instagram, <1>Facebook, msgstr "" #: dashboard/pages/SetupPersona/CloudBackupPreview/index.tsx -#: dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx -msgid "Overwrite Backup" -msgstr "覆盖备份" +#~ msgid "Overwrite Backup" +#~ msgstr "" #: dashboard/pages/SetupPersona/CloudBackupPreview/index.tsx -msgid "Overwrite current backup" -msgstr "覆盖当前备份" +#~ msgid "Overwrite current backup" +#~ msgstr "" #: popups/modals/VerifyBackupPasswordModal/index.tsx #: popups/modals/SetBackupPasswordModal/index.tsx @@ -1967,7 +2094,7 @@ msgstr "密码" msgid "Paste manually" msgstr "手动粘贴" -#: dashboard/pages/SetupPersona/LocalBackup/index.tsx +#: dashboard/pages/SetupPersona/Backup/Local.tsx #: dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx #: popups/pages/Wallet/SetPaymentPassword/index.tsx #: popups/modals/WalletRemoveModal/index.tsx @@ -2048,7 +2175,7 @@ msgstr "" msgid "Personas" msgstr "身份" -#: dashboard/pages/SetupPersona/CloudBackup/PhoneForm.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/PhoneForm.tsx msgid "Phone verification code" msgstr "验证码" @@ -2075,7 +2202,7 @@ msgstr "" msgid "Please enter backup password to export persona private key." msgstr "请输入导出个人私钥的备份密码。" -#: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx msgid "Please enter cloud backup password to download file." msgstr "请输入云备份密码以下载文件。" @@ -2103,8 +2230,6 @@ msgid "Please note: This Persona {0} is the management account of above listed S msgstr "" #: dashboard/pages/SetupPersona/Recovery/index.tsx -#: dashboard/pages/SetupPersona/LocalBackup/index.tsx -#: dashboard/pages/SetupPersona/CloudBackupPreview/index.tsx msgid "Please select the appropriate method to restore your personal data." msgstr "请选择合适的方法来恢复个人数据。" @@ -2134,8 +2259,8 @@ msgid "Please switch to <0>@{expectAccount} to continue the account verifica msgstr "" #: dashboard/pages/SetupPersona/CloudBackup/index.tsx -msgid "Please use your frequently used email or phone number for backup." -msgstr "" +#~ msgid "Please use your frequently used email or phone number for backup." +#~ msgstr "" #: dashboard/pages/CreateMaskWallet/CreateMnemonic/index.tsx msgid "Please write down or copy these words and save them in a secure place." @@ -2213,8 +2338,8 @@ msgstr "重新输入" #: dashboard/pages/SetupPersona/Onboarding/index.tsx #: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx -msgid "ready 🚀" -msgstr "准备🚀" +#~ msgid "ready 🚀" +#~ msgstr "" #: content-script/components/CompositionDialog/useSubmit.ts msgid "realMaskNetwork" @@ -2225,6 +2350,11 @@ msgstr "" msgid "Receive" msgstr "接收" +#: dashboard/pages/SetupPersona/Recovery/Cloud/GoogleDrive.tsx +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx +msgid "Recover" +msgstr "" + #: dashboard/pages/SetupPersona/Recovery/index.tsx msgid "Recover your data" msgstr "恢复数据" @@ -2292,13 +2422,13 @@ msgstr "" msgid "Request Source" msgstr "请求源" -#: dashboard/components/Restore/RestorePersonaFromLocal.tsx +#: dashboard/pages/SetupPersona/Recovery/Local.tsx msgid "Reselect" msgstr "重新选择" #: content-script/components/InjectedComponents/SetupGuide/VerifyNextID.tsx -#: dashboard/pages/SetupPersona/CloudBackup/PhoneForm.tsx -#: dashboard/pages/SetupPersona/CloudBackup/EmailForm.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/PhoneForm.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/EmailForm.tsx msgid "Resend" msgstr "重新发送" @@ -2310,24 +2440,32 @@ msgstr "重置钱包" msgid "Resource" msgstr "" -#: dashboard/components/Restore/RestorePersonaFromLocal.tsx -#: dashboard/components/Restore/RestoreFromCloud/index.tsx -#: dashboard/components/Restore/RestoreFromCloud/ConfirmBackupInfo.tsx +#: dashboard/pages/SetupPersona/Recovery/Local.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/MaskNetwork.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/ConfirmBackupInfo.tsx msgid "Restore" msgstr "恢复" -#: dashboard/components/Restore/RestorePersonaFromLocal.tsx +#: dashboard/pages/SetupPersona/Recovery/Local.tsx msgid "Restore backup failed." msgstr "" +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx +msgid "Restore Completed" +msgstr "" + #: popups/pages/Settings/index.tsx msgid "Restore Database" msgstr "恢复数据库" -#: dashboard/components/Restore/RestoreFromCloud/index.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/MaskNetwork.tsx msgid "Restore failed" msgstr "恢复失败" +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx +msgid "Restore Failed" +msgstr "" + #: popups/pages/Settings/index.tsx msgid "Restore from a previous database backup" msgstr "从以前的数据库备份恢复" @@ -2399,8 +2537,8 @@ msgid "Select Liquidity" msgstr "" #: dashboard/pages/SetupPersona/LocalBackup/index.tsx -msgid "Select the contents of the backup" -msgstr "选择备份的内容" +#~ msgid "Select the contents of the backup" +#~ msgstr "" #: popups/pages/Wallet/Interaction/PermissionRequest.tsx msgid "Select the wallet(s) to use on this site. You should not connect to website you don't trust." @@ -2411,8 +2549,8 @@ msgid "Select Wallet" msgstr "选择钱包" #: content-script/components/InjectedComponents/SetupGuide/VerifyNextID.tsx -#: dashboard/pages/SetupPersona/CloudBackup/PhoneForm.tsx -#: dashboard/pages/SetupPersona/CloudBackup/EmailForm.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/PhoneForm.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/EmailForm.tsx #: popups/pages/Wallet/components/ActivityList/ActivityItem.tsx #: popups/pages/Wallet/components/ActionGroup/index.tsx #: popups/pages/Wallet/Transfer/index.tsx @@ -2486,8 +2624,8 @@ msgid "Sign" msgstr "签名" #: dashboard/pages/SetupPersona/Recovery/index.tsx -msgid "Sign Up" -msgstr "注册" +#~ msgid "Sign Up" +#~ msgstr "" #: popups/components/SignRequestInfo/index.tsx msgid "Sign-in Request" @@ -2614,8 +2752,7 @@ msgstr "所支持的网站" msgid "Swap" msgstr "" -#: dashboard/pages/SetupPersona/CloudBackupPreview/index.tsx -#: dashboard/pages/SetupPersona/CloudBackupPreview/index.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/Preview.tsx msgid "Switch other account" msgstr "切换帐号" @@ -2623,7 +2760,7 @@ msgstr "切换帐号" msgid "Switch Persona" msgstr "切换 Persona" -#: dashboard/components/Restore/RestoreFromCloud/ConfirmBackupInfo.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/ConfirmBackupInfo.tsx msgid "Switch to other accounts" msgstr "" @@ -2652,16 +2789,23 @@ msgstr "" msgid "The chainID is not equal to the currently connected one." msgstr "" -#: dashboard/pages/SetupPersona/CloudBackup/index.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/MaskNetwork.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/CloudBackupFormContext.ts +#: dashboard/pages/SetupPersona/Backup/Cloud/CloudBackupFormContext.ts #: dashboard/contexts/CloudBackupFormContext.tsx #: dashboard/contexts/CloudBackupFormContext.tsx msgid "The code is incorrect." msgstr "验证码不正确" -#: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx +#: dashboard/utils/api.ts msgid "The download link is expired" msgstr "" +#: dashboard/pages/SetupPersona/Recovery/Cloud/MaskNetwork.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/MaskNetwork.tsx +msgid "The Mask Network Cloud Backup feature will be deactivated on April 30, 2025. Please use alternative cloud backup services or local backup solutions." +msgstr "" + #: dashboard/pages/CreateMaskWallet/CreateMnemonic/index.tsx msgid "The mnemonic word has been copied, please keep it in a safe place." msgstr "" @@ -2700,6 +2844,7 @@ msgstr "" msgid "The persona name already exists." msgstr "此身份名称已存在" +#: dashboard/pages/SetupPersona/Backup/Cloud/CloudBackupFormContext.ts #: dashboard/contexts/CloudBackupFormContext.tsx msgid "The phone number is incorrect." msgstr "此手机号码不正确。" @@ -2922,13 +3067,13 @@ msgstr "" msgid "Unlock" msgstr "解锁" +#: dashboard/pages/SetupPersona/Recovery/Local.tsx #: dashboard/components/Restore/RestoreWalletFromLocal.tsx -#: dashboard/components/Restore/RestorePersonaFromLocal.tsx msgid "Unpacking" msgstr "" -#: dashboard/components/Restore/RestorePersonaFromLocal.tsx -#: dashboard/components/Restore/RestorePersonaFromLocal.tsx +#: dashboard/pages/SetupPersona/Recovery/Local.tsx +#: dashboard/pages/SetupPersona/Recovery/Local.tsx msgid "Unsupported data backup" msgstr "不支持的数据备份格式" @@ -2976,16 +3121,16 @@ msgstr "使用文本加密" msgid "value" msgstr "价值" -#: dashboard/components/Restore/RestoreFromCloud/EmailField.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/EmailField.tsx msgid "Verification code has been sent to your email. Please check your mailbox." msgstr "" -#: dashboard/components/Restore/RestoreFromCloud/PhoneField.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/PhoneField.tsx msgid "Verification code has been sent to your phone." msgstr "" -#: dashboard/pages/SetupPersona/CloudBackup/PhoneForm.tsx -#: dashboard/pages/SetupPersona/CloudBackup/EmailForm.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/PhoneForm.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/EmailForm.tsx msgid "Verification code sent" msgstr "验证码已发送" @@ -3038,8 +3183,8 @@ msgid "Waiting for {providerType}" msgstr "" #: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx -msgid "wallet" -msgstr "钱包" +#~ msgid "wallet" +#~ msgstr "" #: popups/pages/Wallet/SwitchWallet/index.tsx #: popups/modals/WalletGroupModal/index.tsx @@ -3096,8 +3241,8 @@ msgid "Welcome Back" msgstr "欢迎回来" #: dashboard/pages/SetupPersona/CloudBackupPreview/index.tsx -msgid "Welcome to Mask Cloud Services" -msgstr "欢迎使用 Mask 云服务" +#~ msgid "Welcome to Mask Cloud Services" +#~ msgstr "" #: popups/pages/Personas/Home/UI.tsx msgid "Welcome to Mask Network" @@ -3107,6 +3252,10 @@ msgstr "欢迎来到 Mask Network!" msgid "Welcome to use Mask Network" msgstr "欢迎来到 Mask Network!" +#: dashboard/components/GoogleDriveLogin.tsx +msgid "when you click Add Google Drive button,you will be forwarded to Google authorization pages." +msgstr "" + #: popups/pages/Wallet/ExportPrivateKey/index.tsx msgid "Write down mnemonic words" msgstr "写下助记词" @@ -3120,21 +3269,25 @@ msgid "You could check the verification result on Mask Pop-up after few minutes. msgstr "" #: dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx -msgid "You have backed up your data." -msgstr "" +#~ msgid "You have backed up your data." +#~ msgstr "" #: dashboard/pages/SetupPersona/Onboarding/index.tsx #~ msgid "You have recovered" #~ msgstr "" #: dashboard/pages/SetupPersona/Onboarding/index.tsx -msgid "You have recovered " -msgstr "" +#~ msgid "You have recovered " +#~ msgstr "" #: popups/pages/Personas/ConnectWallet/index.tsx msgid "You have signed with your wallet." msgstr "" +#: dashboard/pages/SetupPersona/Recovery/Cloud/GoogleDrive.tsx +msgid "You have successfully restored the backup from Google Drive to your browser." +msgstr "" + #: dashboard/components/Restore/ConfirmSynchronizePasswordDialog.tsx msgid "You have verified your cloud password and recovered your backup. Do you want to let your cloud password and local backup password be the same?" msgstr "" @@ -3143,26 +3296,41 @@ msgstr "" msgid "You need to open the dApp to view the specific content." msgstr "" -#. placeholder {0}: user.email #: dashboard/pages/SetupPersona/CloudBackup/index.tsx #: dashboard/pages/SetupPersona/CloudBackup/index.tsx -msgid "You used <0>{0} for the last cloud backup." -msgstr "" +#~ msgid "You used <0>{0} for the last cloud backup." +#~ msgstr "" #: popups/components/SignRequestInfo/index.tsx msgid "Your connection to this site is not encrypted which can be modified by a hostile third party, we strongly suggest you reject this request." msgstr "" +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx +msgid "Your file has been successfully merged into the browser data." +msgstr "" + +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx +msgid "Your file has been successfully restore into the browser data." +msgstr "" + #: dashboard/pages/CreateMaskWallet/CreateWalletForm/index.tsx msgid "Your payment password encrypts wallet data and is needed to unlocking the wallet, transaction confirmations and signing. The password is never stored, and there is no way to recover it if you forget it." msgstr "" +#: dashboard/pages/SetupPersona/Onboarding/index.tsx +msgid "Your Persona has been successfully created." +msgstr "" + #: dashboard/pages/SetupPersona/Onboarding/index.tsx #~ msgid "Your Persona is on" #~ msgstr "" #: dashboard/pages/SetupPersona/Onboarding/index.tsx -msgid "Your Persona is on " +#~ msgid "Your Persona is on " +#~ msgstr "" + +#: dashboard/pages/SetupPersona/Onboarding/index.tsx +msgid "Your Persona is on **ready 🚀**" msgstr "" #: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx @@ -3170,5 +3338,9 @@ msgstr "" #~ msgstr "" #: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx -msgid "Your Wallet is on " +#~ msgid "Your Wallet is on " +#~ msgstr "" + +#: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx +msgid "Your Wallet is on **ready 🚀**" msgstr "" diff --git a/packages/mask/shared-ui/locale/zh-TW.json b/packages/mask/shared-ui/locale/zh-TW.json index 0944ff73d188..0cfa4492b17d 100644 --- a/packages/mask/shared-ui/locale/zh-TW.json +++ b/packages/mask/shared-ui/locale/zh-TW.json @@ -7,6 +7,16 @@ "y6VCOb": [["0"], " 分钟"], "MpnSqP": [["0"], " Pending"], "FKrzPv": [["count", "plural", { "one": ["#", " Wallet 🚀"], "other": ["#", " Wallets 🚀"] }]], + "5s6EhU": [ + [ + "count", + "plural", + { + "one": ["You have recovered **", "#", " Wallet 🚀**"], + "other": ["You have recovered **", "#", " Wallets 🚀**"] + } + ] + ], "yx3mb0": [ [ "decryptProgress", @@ -54,16 +64,18 @@ "pv5v6j": ["About Permit"], "k0USDt": ["Account connected.<0/><1/>Try to explore more features powered by Mask Network."], "R2K7XH": ["尝试探索社交媒体上的 Web3 dApps 功能。"], - "6c6xyD": ["账户"], + "6c6xyD": ["accounts"], "39ohdf": ["活动"], "I5kL4f": ["活动日志"], "m16xKo": ["添加"], "5YfW3S": ["Add an encrypted comment..."], "aTzTyw": ["添加资产"], "M0FgOk": ["添加联系人"], + "FAKSZG": ["Add google Drive"], "LP+1Z7": ["添加网络"], "68m9Nl": ["向现有组添加新地址"], "1LkMSp": ["Add Suggested Token"], + "O8PsYe": ["Add the file to Chrome's database"], "GtJJAj": ["添加钱包"], "uv94aG": ["由用户添加"], "8RF/Sx": ["添加成功"], @@ -94,13 +106,16 @@ "iTiwqa": ["Asset is hidden."], "2jQko7": ["关联账户"], "CEk7Nc": ["至少6个字符"], + "gp6A8z": ["Authorization Failed"], "Wvnsx1": ["自动锁定"], "7QptC5": ["自动锁定时间"], "nTFx7o": ["新头像设置成功"], "iH8pgl": ["返回"], + "npsHM5": ["Back Up to Google Drive"], + "V+1pjj": ["Back Up Your Data Your Way"], "rLgPvm": ["备份"], "h7+V7K": ["备份恢复"], - "QrHM/A": ["备份下载并成功合并到本地。"], + "QrHM/A": ["Backup downloaded and merged to local successfully."], "zp7Ha3": ["備份失敗"], "5Cowlg": ["Backup is saved to Mask Cloud Service."], "qZ6p7p": ["Backup on ", ["0"]], @@ -109,7 +124,9 @@ "ERYJcj": ["备份密码必须是 8-20 个字符,包括大写、小写、特殊字符和数字。"], "hUF4dG": ["备份密码设置成功。"], "UtKGok": ["备份身份"], - "7Ry254": ["备份到 Mask 云服务"], + "+m7x4e": ["Backup Successful"], + "3iUAE7": ["Backup to Google Drive"], + "7Ry254": ["Backup to Mask Cloud Service"], "6IHgRq": ["Backup to the Cloud"], "QQPCqQ": ["备份钱包"], "fsBGk0": ["余额"], @@ -136,6 +153,9 @@ "tcHpvG": ["更改管理账户"], "fDP2k4": ["修改支付密码"], "IXbRbM": ["切换钱包"], + "lU6uRb": [ + "Choose from multiple backup options, now including encrypted storage via your authorized Google Drive for added security and flexibility." + ], "xH6cn+": ["选择代币"], "+adBn3": ["Chrome - external extension"], "EsKgLS": ["点击这里快速开始。"], @@ -191,6 +211,9 @@ "PjBWOL": ["创建您的身份以开始"], "WgawP2": ["Creating your"], "cEnmTp": ["Creating your "], + "L82H5Z": ["Creating your **identity**"], + "F7U8uz": ["Creating your **wallet**"], + "aF8kci": ["Creation Completed"], "Q2lUR2": ["货币"], "OgPkDe": ["货币符号(可选)"], "oOQfsI": ["Current account is not the verifying account."], @@ -205,8 +228,9 @@ ], "8Tg/JR": ["自定义"], "pvnfJD": ["深色"], - "Sp/me1": ["数据"], + "Sp/me1": ["data"], "HKH+W+": ["数据"], + "K8jCIB": ["Data backed up successfully!"], "3B4jmY": ["数据关联"], "rAcOY1": [ "Data merged from Mask Cloud Service to local successfully. Re-enter your password to encrypt and upload the new backup to Mask Cloud Service." @@ -244,11 +268,11 @@ "XZ/B+f": ["找不到您的NFT?"], "DPfwMq": ["完成!"], "mzI/c+": ["下載"], - "1vSYsG": ["下载备份"], + "1vSYsG": ["Download backup"], "1+6BOG": ["下载备份"], "9hg9mc": ["正在下载"], "F8Wc3I": ["将您的文件拖放到此处"], - "5Sa1Ss": ["电子邮件"], + "5Sa1Ss": ["E-mail"], "ePK91l": ["編輯"], "mQpWAe": ["编辑联系人"], "iZLoa2": ["eg: X accounts, persona public keys, wallet addresses or ENS"], @@ -261,6 +285,7 @@ "w1ctdJ": ["Mask: 發表貼文"], "MRIXE3": ["Encrypting your"], "zutir1": ["Encrypting your "], + "XB3tfc": ["Encrypting your **data**"], "Cz6Lx7": ["加密方式"], "N/fqDa": ["Ens或地址(0x)"], "mPxxVq": ["輸入礦工費上限"], @@ -280,9 +305,14 @@ "GS+Mus": ["導出"], "7Bj3x9": ["失敗"], "SLEDBF": ["添加钱包失败,请重试。"], + "r92tNP": ["Failed to authorize Google Drive. Please try again."], "09vHB+": ["Failed to decrypt."], "jK7nvW": ["Failed to disconnect wallet"], + "9hzYBR": ["Failed to download and merge the backup: ", ["0"]], "0tkvsz": ["Failed to download and merge the backup."], + "etATpN": ["Failed to login: ", ["0"]], + "qDIxZ+": ["Failed to restore the backup from Google Drive to your browser. Please try again."], + "e3I0CA": ["Failed to restore the backup: ", ["0"]], "mrAv9J": ["无法保存网络"], "ZsjtYe": ["加载头像失败。"], "RWoEqV": ["Failed to transfer token: ", ["message"]], @@ -318,7 +348,9 @@ "fUn3xA": ["生成一个新的钱包地址"], "tdZPpe": ["Generating your"], "CiU2m/": ["Generating your "], + "RL5m+x": ["Generating your **accounts**"], "2p7WMm": ["Give permission to access <0/> your ", ["0"], "?"], + "w9Xmw/": ["Google Drive"], "76gPWk": ["好的"], "HqiAyF": ["Gwei"], "pu3rTn": ["GWEI"], @@ -337,7 +369,7 @@ "yx/fMc": ["高速"], "0caMy7": ["History"], "uip9JY": ["I wrote down those words in the correct order"], - "b5d759": ["身份"], + "b5d759": ["identity"], "RRw7LE": ["身份助记词"], "/WfDJy": [ "If you forget payment password, you can type 'RESET' to reset your wallet. <0>Remember, this action will erase all your previous wallets." @@ -350,6 +382,7 @@ "fza4cg": ["导入钱包"], "HvDfH/": ["已导入"], "m3XvO+": ["导入钱包"], + "ANk/Zy": ["Incorrect Backup Password"], "a23gJr": ["密码不正确。"], "bapItf": ["备份密码错误。"], "bassMa": ["云备份密码不正确,请重试。"], @@ -390,9 +423,11 @@ "jygqM9": ["Loading account information..."], "EBC6hj": ["本地备份"], "shPV5O": ["仅限本地身份或钱包"], + "crVIc7": ["Locale Backup"], "KGHnSc": ["锁定钱包"], "FgAxTj": ["登出"], "kC3Q3d": ["Login to Mask Cloud"], + "nOhz3x": ["Logout"], "NkgvWN": ["登出失败"], "o4Iu2W": ["退出成功"], "nTWWCZ": ["低"], @@ -402,6 +437,7 @@ ], "lET9my": ["Mask Network需要以下权限"], "siroPf": ["Mask Network"], + "jhoAzY": ["Mask Network Cloud"], "lWOC+h": ["Mask Network requires you to authorize the following websites before using it."], "HsoakN": ["masknetwork"], "CK1KXz": ["最大"], @@ -418,8 +454,10 @@ "sQJ3RN": ["最大优先费用在当前网络环境下过低。"], "ITBQO3": ["Max priority fee必须大于 0 GWEI"], "agPptk": ["中等"], + "lPsa94": ["Merge Completed"], "RH8jSA": ["合并数据到本地数据库"], - "QTomF0": ["合并至本地数据"], + "E6YUtc": ["Merge to Browser"], + "QTomF0": ["Merge to local"], "xDAtGP": ["信息"], "pGElS5": ["助记词"], "yFrxQj": ["助记词"], @@ -479,8 +517,8 @@ "YKSmxE": [ "Other social networking platforms, such as <0>Instagram, <1>Facebook, and <2>Minds, do not have a verified relationship like X's Next.ID verified connection.<3/><4/>When connecting a persona with an account on these platforms, they only support sending encrypted posts." ], - "MXOdMY": ["覆盖备份"], - "p2xE4C": ["覆盖当前备份"], + "MXOdMY": ["Overwrite Backup"], + "p2xE4C": ["Overwrite current backup"], "8ZsakT": ["密码"], "9w2hgY": ["手動貼上"], "GAvnvl": ["支付密碼"], @@ -543,9 +581,10 @@ "3AP6p1": ["Public Key: <0>", ["publicKey"], ""], "82+n6o": ["Quote Route"], "AV+9wg": ["重新输入"], - "TZ0npN": ["准备🚀"], + "TZ0npN": ["ready 🚀"], "nVT2pJ": ["realMaskNetwork"], "lDgVWA": ["接收"], + "OkofjH": ["Recover"], "XC7RGa": ["恢复数据"], "UBzbea": ["恢复钱包"], "P9wzG/": ["恢復"], @@ -567,8 +606,10 @@ "nvAt0H": ["Resource"], "yKu/3Y": ["恢復"], "Z3+V9p": ["Restore backup failed."], + "nGl2Ng": ["Restore Completed"], "AKLbfQ": ["恢复数据库"], "uM6jnS": ["恢復失敗"], + "KFwID2": ["Restore Failed"], "/LkuGq": ["从以前的数据库备份恢复"], "KisOjk": ["恢复身份"], "6gRgw8": ["重試"], @@ -586,7 +627,7 @@ "nTif4K": ["选择并连接到你的钱包"], "k/sb6z": ["选择语言"], "LSwUJb": ["Select Liquidity"], - "RjF5dk": ["选择备份的内容"], + "RjF5dk": ["Select the contents of the backup"], "PI/VCJ": ["Select the wallet(s) to use on this site. You should not connect to website you don't trust."], "a1SmQh": ["选择钱包"], "JlFcis": ["發送"], @@ -604,7 +645,7 @@ "iJLEZF": ["告訴我怎麼做"], "nOCyT5": ["显示价值小于$1 的代币"], "c+Fnce": ["簽署"], - "mErq7F": ["注册"], + "mErq7F": ["Sign Up"], "t3rUZr": ["Sign-in Request"], "py6hU8": ["签名请求"], "9KKhJV": ["正在签名..."], @@ -647,6 +688,9 @@ "VdhBp2": ["The chainID is not equal to the currently connected one."], "h3Vpnw": ["验证码不正确"], "7w1rTm": ["The download link is expired"], + "oYkran": [ + "The Mask Network Cloud Backup feature will be deactivated on April 30, 2025. Please use alternative cloud backup services or local backup solutions." + ], "o+zDNQ": ["The mnemonic word has been copied, please keep it in a safe place."], "yRuvmU": ["The mnemonic words has been copied, please keep it in a safe place."], "thX7xs": [ @@ -765,7 +809,7 @@ "vVEene": ["View your Tokens and NFTs"], "kbfp5m": ["可见范围"], "PTXNyo": ["Waiting for ", ["providerType"]], - "6XyieG": ["钱包"], + "6XyieG": ["wallet"], "VECuJk": ["钱包账户"], "KtMMzG": ["Wallet disconnected"], "Kl9gHp": ["钱包组 #", ["0"]], @@ -780,9 +824,10 @@ "EGWr+Q": ["Web3 名片"], "On0aF2": ["网站"], "CWsYB3": ["欢迎回来"], - "m74yjp": ["欢迎使用 Mask 云服务"], + "m74yjp": ["Welcome to Mask Cloud Services"], "hEpXzO": ["欢迎来到 Mask Network!"], "fFYJ8f": ["欢迎来到 Mask Network!"], + "OLUEnY": ["when you click Add Google Drive button,you will be forwarded to Google authorization pages."], "Qbo7Ev": ["写下助记词"], "f5AidZ": ["Write down recovery phrase"], "yGyJ1l": [ @@ -792,6 +837,7 @@ "dyqtoj": ["You have recovered"], "V8x6o5": ["You have recovered "], "QU9aqK": ["You have signed with your wallet."], + "PeT3a5": ["You have successfully restored the backup from Google Drive to your browser."], "zkEW09": [ "You have verified your cloud password and recovered your backup. Do you want to let your cloud password and local backup password be the same?" ], @@ -800,12 +846,17 @@ "FnQek5": [ "Your connection to this site is not encrypted which can be modified by a hostile third party, we strongly suggest you reject this request." ], + "UDKbPj": ["Your file has been successfully merged into the browser data."], + "S2JNMm": ["Your file has been successfully restore into the browser data."], "Q68Nuc": [ "Your payment password encrypts wallet data and is needed to unlocking the wallet, transaction confirmations and signing. The password is never stored, and there is no way to recover it if you forget it." ], + "4EN5JL": ["Your Persona has been successfully created."], "N19nSk": ["Your Persona is on"], "WC7pDz": ["Your Persona is on "], + "PDW/HG": ["Your Persona is on **ready 🚀**"], "0kr+x1": ["Your Wallet is on"], - "v7OL2k": ["Your Wallet is on "] + "v7OL2k": ["Your Wallet is on "], + "wCtp6y": ["Your Wallet is on **ready 🚀**"] } } diff --git a/packages/mask/shared-ui/locale/zh-TW.po b/packages/mask/shared-ui/locale/zh-TW.po index 8cbe7a8af2ed..dee9c16e679d 100644 --- a/packages/mask/shared-ui/locale/zh-TW.po +++ b/packages/mask/shared-ui/locale/zh-TW.po @@ -3,7 +3,7 @@ msgstr "" "Project-Id-Version: mask-network\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2025-01-08 06:53\n" +"PO-Revision-Date: 2025-04-10 05:53\n" "Last-Translator: \n" "Language: zh_TW\n" "Language-Team: Chinese Traditional\n" @@ -46,7 +46,11 @@ msgid "{0} Pending" msgstr "" #: dashboard/pages/SetupPersona/Onboarding/index.tsx -msgid "{count, plural, one {# Wallet 🚀} other {# Wallets 🚀}}" +#~ msgid "{count, plural, one {# Wallet 🚀} other {# Wallets 🚀}}" +#~ msgstr "" + +#: dashboard/pages/SetupPersona/Onboarding/index.tsx +msgid "{count, plural, one {You have recovered **# Wallet 🚀**} other {You have recovered **# Wallets 🚀**}}" msgstr "" #: content-script/components/InjectedComponents/DecryptedPost/DecryptPostAwaiting.tsx @@ -132,8 +136,8 @@ msgstr "" #: dashboard/pages/SetupPersona/Onboarding/index.tsx #: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx -msgid "accounts" -msgstr "" +#~ msgid "accounts" +#~ msgstr "" #: popups/pages/Wallet/components/WalletAssets/index.tsx msgid "Activities" @@ -162,6 +166,10 @@ msgstr "" msgid "Add Contact" msgstr "" +#: dashboard/components/GoogleDriveLogin.tsx +msgid "Add google Drive" +msgstr "" + #: popups/pages/Wallet/NetworkManagement/index.tsx #: popups/pages/Wallet/EditNetwork/index.tsx msgid "Add Network" @@ -175,6 +183,10 @@ msgstr "" msgid "Add Suggested Token" msgstr "" +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx +msgid "Add the file to Chrome's database" +msgstr "" + #: popups/pages/Wallet/components/StartUp/index.tsx #: popups/pages/Wallet/SwitchWallet/index.tsx #: popups/pages/Wallet/CreateWallet/index.tsx @@ -258,8 +270,8 @@ msgid "Approve amount" msgstr "" #: dashboard/pages/SetupPersona/CloudBackupPreview/index.tsx -msgid "Are you sure to overwrite the backups stored on Mask Cloud Service?" -msgstr "" +#~ msgid "Are you sure to overwrite the backups stored on Mask Cloud Service?" +#~ msgstr "" #. placeholder {0}: formatEthereumAddress(wallet.identity, 4) #: popups/components/ConnectedWallet/index.tsx @@ -292,6 +304,10 @@ msgstr "" msgid "At least 6 characters" msgstr "" +#: dashboard/components/GoogleDriveLogin.tsx +msgid "Authorization Failed" +msgstr "" + #: popups/pages/Wallet/WalletSettings/AutoLock.tsx msgid "Auto-lock" msgstr "" @@ -305,13 +321,24 @@ msgid "Avatar set successfully" msgstr "" #: content-script/components/shared/SelectRecipients/SelectRecipientsDialog.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/Preview.tsx #: dashboard/pages/CreateMaskWallet/CreateMnemonic/index.tsx #: popups/pages/Personas/ExportPrivateKey/index.tsx #: popups/pages/Personas/AccountDetail/UI.tsx msgid "Back" msgstr "返回" -#: dashboard/pages/SetupPersona/CloudBackupPreview/index.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/GoogleDrive.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/GoogleDrive.tsx +#~ msgid "Back Up to Google Drive" +#~ msgstr "" + +#: dashboard/pages/SetupPersona/Backup/index.tsx +msgid "Back Up Your Data Your Way" +msgstr "" + +#: dashboard/pages/SetupPersona/Backup/Cloud/GoogleDrive.tsx +#: dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx #: popups/pages/Personas/Logout/index.tsx #: popups/modals/SwitchPersonaModal/index.tsx msgid "Backup" @@ -322,16 +349,16 @@ msgid "Backup & Recovery" msgstr "" #: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx -msgid "Backup downloaded and merged to local successfully." -msgstr "" +#~ msgid "Backup downloaded and merged to local successfully." +#~ msgstr "" #: dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx msgid "Backup Failed" msgstr "備份失敗" #: dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx -msgid "Backup is saved to Mask Cloud Service." -msgstr "" +#~ msgid "Backup is saved to Mask Cloud Service." +#~ msgstr "" #. placeholder {0}: user.localBackupAt #. placeholder {0}: user.cloudBackupAt @@ -340,13 +367,13 @@ msgstr "" msgid "Backup on {0}" msgstr "" -#: dashboard/components/Restore/RestorePersonaFromLocal.tsx -#: dashboard/components/Restore/RestoreFromCloud/ConfirmBackupInfo.tsx +#: dashboard/pages/SetupPersona/Recovery/Local.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/ConfirmBackupInfo.tsx msgid "Backup password" msgstr "備份密碼" -#: dashboard/pages/SetupPersona/LocalBackup/index.tsx -#: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx +#: dashboard/pages/SetupPersona/Backup/Local.tsx +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx #: dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx #: popups/pages/Settings/index.tsx #: popups/modals/SetBackupPasswordModal/index.tsx @@ -368,10 +395,19 @@ msgstr "" msgid "Backup Persona" msgstr "" -#: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx -msgid "Backup to Mask Cloud Service" +#: dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx +msgid "Backup Successful" msgstr "" +#: dashboard/pages/SetupPersona/Backup/Cloud/GoogleDrive.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/GoogleDrive.tsx +msgid "Backup to Google Drive" +msgstr "" + +#: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx +#~ msgid "Backup to Mask Cloud Service" +#~ msgstr "" + #: dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx msgid "Backup to the Cloud" msgstr "" @@ -437,7 +473,6 @@ msgstr "" #: content-script/components/InjectedComponents/SelectPeopleDialog.tsx #: dashboard/pages/SetupPersona/Welcome/index.tsx #: dashboard/pages/SetupPersona/Permissions/index.tsx -#: dashboard/pages/SetupPersona/CloudBackupPreview/index.tsx #: dashboard/modals/ConfirmModal/index.tsx #: dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx #: dashboard/components/Restore/ConfirmSynchronizePasswordDialog.tsx @@ -510,6 +545,10 @@ msgstr "" msgid "Choose another wallet" msgstr "" +#: dashboard/pages/SetupPersona/Backup/index.tsx +msgid "Choose from multiple backup options, now including encrypted storage via your authorized Google Drive for added security and flexibility." +msgstr "" + #: popups/modals/ChooseToken/index.tsx msgid "Choose Token" msgstr "" @@ -535,6 +574,7 @@ msgid "Close" msgstr "關閉" #: dashboard/pages/SetupPersona/Recovery/index.tsx +#: dashboard/pages/SetupPersona/Backup/index.tsx #: dashboard/components/Restore/ConfirmSynchronizePasswordDialog.tsx #: popups/pages/Settings/index.tsx msgid "Cloud Backup" @@ -548,12 +588,11 @@ msgstr "" msgid "Coming soon" msgstr "" +#: dashboard/pages/SetupPersona/Recovery/Local.tsx #: dashboard/components/Restore/RestoreWalletFromLocal.tsx -#: dashboard/components/Restore/RestorePersonaFromLocal.tsx msgid "Completed" msgstr "" -#: dashboard/pages/SetupPersona/CloudBackupPreview/index.tsx #: dashboard/modals/ConfirmModal/index.tsx #: dashboard/components/Restore/ConfirmSynchronizePasswordDialog.tsx #: popups/pages/Wallet/components/DisconnectModal/index.tsx @@ -607,8 +646,6 @@ msgstr "" msgid "Confirm to hide {name}? You can redisplay it by re-adding this NFT at any time." msgstr "" -#: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx -#: dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx #: popups/pages/Personas/ConnectWallet/index.tsx msgid "Congratulations" msgstr "" @@ -709,16 +746,18 @@ msgstr "聯繫人" #: dashboard/pages/SignUp/steps/PersonaNameUI.tsx #: dashboard/pages/SetupPersona/SignUp/index.tsx +#: dashboard/pages/SetupPersona/Recovery/PrivateKey.tsx +#: dashboard/pages/SetupPersona/Recovery/Phrase.tsx +#: dashboard/pages/SetupPersona/Recovery/Local.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/PhoneField.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/EmailField.tsx #: dashboard/pages/SetupPersona/Mnemonic/index.tsx -#: dashboard/pages/SetupPersona/CloudBackup/index.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/MaskNetwork.tsx #: dashboard/pages/CreateMaskWallet/CreateWalletForm/index.tsx #: dashboard/pages/CreateMaskWallet/AddDeriveWallet/index.tsx #: dashboard/components/Restore/RestoreWalletFromLocal.tsx -#: dashboard/components/Restore/RestorePersonaFromLocal.tsx #: dashboard/components/Restore/RestoreFromPrivateKey.tsx #: dashboard/components/Restore/RestoreFromMnemonic.tsx -#: dashboard/components/Restore/RestoreFromCloud/PhoneField.tsx -#: dashboard/components/Restore/RestoreFromCloud/EmailField.tsx msgid "Continue" msgstr "" @@ -774,6 +813,7 @@ msgstr "" msgid "Create Password" msgstr "" +#: dashboard/pages/SetupPersona/Recovery/index.tsx #: popups/pages/Personas/Home/UI.tsx msgid "Create Persona" msgstr "" @@ -789,7 +829,19 @@ msgstr "" #: dashboard/pages/SetupPersona/Onboarding/index.tsx #: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx -msgid "Creating your " +#~ msgid "Creating your " +#~ msgstr "" + +#: dashboard/pages/SetupPersona/Onboarding/index.tsx +msgid "Creating your **identity**" +msgstr "" + +#: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx +msgid "Creating your **wallet**" +msgstr "" + +#: dashboard/pages/SetupPersona/Onboarding/index.tsx +msgid "Creation Completed" msgstr "" #: popups/pages/Wallet/WalletSettings/ChangeCurrency.tsx @@ -830,23 +882,27 @@ msgstr "" #: dashboard/pages/SetupPersona/Onboarding/index.tsx #: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx -msgid "data" -msgstr "" +#~ msgid "data" +#~ msgstr "" #: popups/pages/Wallet/Interaction/TransactionRequest.tsx msgid "Data" msgstr "" +#: dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx +msgid "Data backed up successfully!" +msgstr "" + #: popups/pages/Settings/index.tsx msgid "Data correlation" msgstr "" #: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx -msgid "Data merged from Mask Cloud Service to local successfully. Re-enter your password to encrypt and upload the new backup to Mask Cloud Service." -msgstr "" +#~ msgid "Data merged from Mask Cloud Service to local successfully. Re-enter your password to encrypt and upload the new backup to Mask Cloud Service." +#~ msgstr "" -#: dashboard/components/Restore/RestoreFromCloud/ConfirmBackupInfo.tsx -#: dashboard/components/Restore/RestoreFromCloud/ConfirmBackupInfo.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/ConfirmBackupInfo.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/ConfirmBackupInfo.tsx msgid "Decrypt failed, please check password" msgstr "備份解密失敗,請檢查密碼" @@ -951,18 +1007,20 @@ msgid "Done" msgstr "完成!" #: content-script/components/InjectedComponents/AutoPasteFailedDialog.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/Preview.tsx +#: dashboard/components/GoogleDriveFileTable.tsx msgid "Download" msgstr "下載" #: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx -msgid "Download backup" -msgstr "" +#~ msgid "Download backup" +#~ msgstr "" -#: dashboard/pages/SetupPersona/LocalBackup/index.tsx +#: dashboard/pages/SetupPersona/Backup/Local.tsx msgid "Download Backup" msgstr "" -#: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx msgid "Downloading" msgstr "" @@ -971,8 +1029,8 @@ msgid "Drag & Drop your file here" msgstr "" #: dashboard/pages/SetupPersona/CloudBackup/index.tsx -msgid "E-mail" -msgstr "" +#~ msgid "E-mail" +#~ msgstr "" #: popups/pages/Wallet/ContactList/index.tsx msgid "Edit" @@ -987,13 +1045,14 @@ msgstr "" msgid "eg: X accounts, persona public keys, wallet addresses or ENS" msgstr "" -#: dashboard/pages/SetupPersona/CloudBackup/EmailForm.tsx -#: dashboard/components/Restore/RestoreFromCloud/EmailField.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/EmailField.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/MaskNetwork.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/EmailForm.tsx msgid "Email" msgstr "" -#: dashboard/pages/SetupPersona/CloudBackup/EmailForm.tsx -#: dashboard/components/Restore/RestoreFromCloud/EmailField.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/EmailField.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/EmailForm.tsx msgid "Email verification code" msgstr "" @@ -1024,7 +1083,12 @@ msgstr "Mask: 發表貼文" #: dashboard/pages/SetupPersona/Onboarding/index.tsx #: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx -msgid "Encrypting your " +#~ msgid "Encrypting your " +#~ msgstr "" + +#: dashboard/pages/SetupPersona/Onboarding/index.tsx +#: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx +msgid "Encrypting your **data**" msgstr "" #: content-script/components/CompositionDialog/EncryptionMethodSelector.tsx @@ -1110,6 +1174,10 @@ msgstr "失敗" msgid "Failed to add the wallet, please try again." msgstr "" +#: dashboard/components/GoogleDriveLogin.tsx +msgid "Failed to authorize Google Drive. Please try again." +msgstr "" + #: content-script/components/InjectedComponents/DecryptedPost/DecryptPostFailed.tsx msgid "Failed to decrypt." msgstr "" @@ -1118,8 +1186,26 @@ msgstr "" msgid "Failed to disconnect wallet" msgstr "" +#. placeholder {0}: (err as Error).message +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx +msgid "Failed to download and merge the backup: {0}" +msgstr "" + #: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx -msgid "Failed to download and merge the backup." +#~ msgid "Failed to download and merge the backup." +#~ msgstr "" + +#: dashboard/components/GoogleDriveLogin.tsx +#~ msgid "Failed to login: {0}" +#~ msgstr "" + +#: dashboard/pages/SetupPersona/Recovery/Cloud/GoogleDrive.tsx +msgid "Failed to restore the backup from Google Drive to your browser. Please try again." +msgstr "" + +#. placeholder {0}: (err as Error).message +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx +msgid "Failed to restore the backup: {0}" msgstr "" #: popups/pages/Wallet/EditNetwork/index.tsx @@ -1269,7 +1355,12 @@ msgstr "" #: dashboard/pages/SetupPersona/Onboarding/index.tsx #: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx -msgid "Generating your " +#~ msgid "Generating your " +#~ msgstr "" + +#: dashboard/pages/SetupPersona/Onboarding/index.tsx +#: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx +msgid "Generating your **accounts**" msgstr "" #. placeholder {0}: contract?.symbol || '' @@ -1279,6 +1370,13 @@ msgstr "" msgid "Give permission to access <0/> your {0}?" msgstr "" +#: dashboard/pages/SetupPersona/Recovery/Cloud/index.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/GoogleDrive.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/index.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/GoogleDrive.tsx +msgid "Google Drive" +msgstr "" + #: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx msgid "Got it" msgstr "" @@ -1344,8 +1442,8 @@ msgid "I wrote down those words in the correct order" msgstr "" #: dashboard/pages/SetupPersona/Onboarding/index.tsx -msgid "identity" -msgstr "" +#~ msgid "identity" +#~ msgstr "" #: dashboard/pages/SetupPersona/Mnemonic/ComponentToPrint.tsx msgid "Identity ID" @@ -1389,17 +1487,21 @@ msgstr "" msgid "Imported Wallets" msgstr "" +#: dashboard/hooks/useBackupFormState.ts +msgid "Incorrect Backup Password" +msgstr "" + #: popups/modals/VerifyBackupPasswordModal/index.tsx #: popups/modals/ChangeBackupPasswordModal/index.tsx msgid "Incorrect backup password." msgstr "" -#: dashboard/components/Restore/RestorePersonaFromLocal.tsx +#: dashboard/pages/SetupPersona/Recovery/Local.tsx msgid "Incorrect Backup Password." msgstr "" -#: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx -#: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx msgid "Incorrect cloud backup password, please try again." msgstr "" @@ -1417,7 +1519,7 @@ msgstr "" msgid "Incorrect password" msgstr "" -#: dashboard/pages/SetupPersona/LocalBackup/index.tsx +#: dashboard/pages/SetupPersona/Backup/Local.tsx #: dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx #: dashboard/hooks/useBackupFormState.ts #: dashboard/hooks/useBackupFormState.ts @@ -1425,7 +1527,6 @@ msgstr "" #: dashboard/hooks/useBackupFormState.ts #: dashboard/hooks/useBackupFormState.ts #: dashboard/hooks/useBackupFormState.ts -#: dashboard/hooks/useBackupFormState.ts msgid "Incorrect Password" msgstr "" @@ -1438,12 +1539,12 @@ msgstr "" msgid "Incorrect Payment Password." msgstr "" -#: dashboard/pages/SetupPersona/Recovery/index.tsx +#: dashboard/pages/SetupPersona/Recovery/PrivateKey.tsx #: dashboard/pages/CreateMaskWallet/Recovery/index.tsx msgid "Incorrect Private Key" msgstr "私钥不正确" -#: dashboard/pages/SetupPersona/Recovery/index.tsx +#: dashboard/pages/SetupPersona/Recovery/Phrase.tsx msgid "Incorrect recovery phrase." msgstr "" @@ -1456,6 +1557,7 @@ msgstr "" msgid "Incorrect words selected. Please try again!" msgstr "" +#: dashboard/pages/SetupPersona/Recovery/PrivateKey.tsx #: dashboard/components/Restore/RestoreFromPrivateKey.tsx msgid "Input your Private Key" msgstr "請輸入你的私鑰" @@ -1473,12 +1575,13 @@ msgstr "" msgid "Invalid Block Explorer URL." msgstr "" -#: dashboard/pages/SetupPersona/CloudBackup/EmailForm.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/EmailForm.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/CloudBackupFormContext.ts #: dashboard/contexts/CloudBackupFormContext.tsx msgid "Invalid email address format." msgstr "" -#: dashboard/components/Restore/RestoreFromCloud/EmailField.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/EmailField.tsx msgid "Invalid email address." msgstr "" @@ -1486,7 +1589,7 @@ msgstr "" msgid "Invalid number" msgstr "" -#: dashboard/components/Restore/RestoreFromCloud/PhoneField.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/PhoneField.tsx msgid "Invalid phone number, please check and try again." msgstr "" @@ -1494,8 +1597,8 @@ msgstr "" msgid "Invalid RPC URL." msgstr "" -#: dashboard/components/Restore/RestoreFromCloud/PhoneField.tsx -#: dashboard/components/Restore/RestoreFromCloud/EmailField.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/PhoneField.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/EmailField.tsx msgid "Invalid verification code." msgstr "" @@ -1576,6 +1679,10 @@ msgstr "" msgid "Local persona or wallet only" msgstr "" +#: dashboard/pages/SetupPersona/Backup/index.tsx +msgid "Locale Backup" +msgstr "" + #: popups/pages/Wallet/SwitchWallet/index.tsx msgid "Lock Wallet" msgstr "" @@ -1587,7 +1694,13 @@ msgid "Log out" msgstr "" #: dashboard/pages/SetupPersona/CloudBackup/index.tsx -msgid "Login to Mask Cloud" +#~ msgid "Login to Mask Cloud" +#~ msgstr "" + +#: dashboard/pages/SetupPersona/Recovery/Cloud/GoogleDrive.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/Preview.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/GoogleDrive.tsx +msgid "Logout" msgstr "" #: popups/pages/Personas/Logout/index.tsx @@ -1618,9 +1731,15 @@ msgstr "" #: content-script/components/InjectedComponents/ToolboxUnstyled.tsx #: content-script/components/InjectedComponents/PostDialogHint.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/index.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/index.tsx msgid "Mask Network" msgstr "" +#: dashboard/pages/SetupPersona/Backup/Cloud/Preview.tsx +msgid "Mask Network Cloud" +msgstr "" + #: content-script/components/InjectedComponents/PermissionBoundary.tsx msgid "Mask Network requires you to authorize the following websites before using it." msgstr "" @@ -1692,16 +1811,24 @@ msgstr "" msgid "Medium" msgstr "" -#: dashboard/pages/SetupPersona/CloudBackupPreview/index.tsx -#: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx -#: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx +msgid "Merge Completed" +msgstr "" + +#: dashboard/pages/SetupPersona/Backup/Cloud/Preview.tsx +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx msgid "Merge data to local database" msgstr "" -#: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx -msgid "Merge to local" +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx +#: dashboard/components/GoogleDriveFileTable.tsx +msgid "Merge to Browser" msgstr "" +#: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx +#~ msgid "Merge to local" +#~ msgstr "" + #: popups/components/SignRequestInfo/index.tsx msgid "Message" msgstr "" @@ -1715,15 +1842,15 @@ msgstr "" msgid "Mnemonic word" msgstr "" -#: dashboard/pages/SetupPersona/CloudBackup/index.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/MaskNetwork.tsx msgid "Mobile" msgstr "" -#: dashboard/pages/SetupPersona/CloudBackup/PhoneForm.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/PhoneForm.tsx msgid "Mobile number" msgstr "" -#: dashboard/components/Restore/RestoreFromCloud/PhoneField.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/PhoneField.tsx msgid "Mobile verification code" msgstr "" @@ -1836,7 +1963,8 @@ msgstr "" msgid "No back up" msgstr "" -#: dashboard/pages/SetupPersona/CloudBackupPreview/index.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/Preview.tsx +#: dashboard/components/GoogleDriveFileTable.tsx msgid "No backups found" msgstr "" @@ -1949,13 +2077,12 @@ msgid "Other social networking platforms, such as <0>Instagram, <1>Facebook, msgstr "" #: dashboard/pages/SetupPersona/CloudBackupPreview/index.tsx -#: dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx -msgid "Overwrite Backup" -msgstr "" +#~ msgid "Overwrite Backup" +#~ msgstr "" #: dashboard/pages/SetupPersona/CloudBackupPreview/index.tsx -msgid "Overwrite current backup" -msgstr "" +#~ msgid "Overwrite current backup" +#~ msgstr "" #: popups/modals/VerifyBackupPasswordModal/index.tsx #: popups/modals/SetBackupPasswordModal/index.tsx @@ -1967,7 +2094,7 @@ msgstr "" msgid "Paste manually" msgstr "手動貼上" -#: dashboard/pages/SetupPersona/LocalBackup/index.tsx +#: dashboard/pages/SetupPersona/Backup/Local.tsx #: dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx #: popups/pages/Wallet/SetPaymentPassword/index.tsx #: popups/modals/WalletRemoveModal/index.tsx @@ -2048,7 +2175,7 @@ msgstr "" msgid "Personas" msgstr "角色" -#: dashboard/pages/SetupPersona/CloudBackup/PhoneForm.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/PhoneForm.tsx msgid "Phone verification code" msgstr "" @@ -2075,7 +2202,7 @@ msgstr "" msgid "Please enter backup password to export persona private key." msgstr "" -#: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx msgid "Please enter cloud backup password to download file." msgstr "" @@ -2103,8 +2230,6 @@ msgid "Please note: This Persona {0} is the management account of above listed S msgstr "" #: dashboard/pages/SetupPersona/Recovery/index.tsx -#: dashboard/pages/SetupPersona/LocalBackup/index.tsx -#: dashboard/pages/SetupPersona/CloudBackupPreview/index.tsx msgid "Please select the appropriate method to restore your personal data." msgstr "" @@ -2134,8 +2259,8 @@ msgid "Please switch to <0>@{expectAccount} to continue the account verifica msgstr "" #: dashboard/pages/SetupPersona/CloudBackup/index.tsx -msgid "Please use your frequently used email or phone number for backup." -msgstr "" +#~ msgid "Please use your frequently used email or phone number for backup." +#~ msgstr "" #: dashboard/pages/CreateMaskWallet/CreateMnemonic/index.tsx msgid "Please write down or copy these words and save them in a secure place." @@ -2213,8 +2338,8 @@ msgstr "" #: dashboard/pages/SetupPersona/Onboarding/index.tsx #: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx -msgid "ready 🚀" -msgstr "" +#~ msgid "ready 🚀" +#~ msgstr "" #: content-script/components/CompositionDialog/useSubmit.ts msgid "realMaskNetwork" @@ -2225,6 +2350,11 @@ msgstr "" msgid "Receive" msgstr "" +#: dashboard/pages/SetupPersona/Recovery/Cloud/GoogleDrive.tsx +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx +msgid "Recover" +msgstr "" + #: dashboard/pages/SetupPersona/Recovery/index.tsx msgid "Recover your data" msgstr "" @@ -2292,13 +2422,13 @@ msgstr "" msgid "Request Source" msgstr "" -#: dashboard/components/Restore/RestorePersonaFromLocal.tsx +#: dashboard/pages/SetupPersona/Recovery/Local.tsx msgid "Reselect" msgstr "" #: content-script/components/InjectedComponents/SetupGuide/VerifyNextID.tsx -#: dashboard/pages/SetupPersona/CloudBackup/PhoneForm.tsx -#: dashboard/pages/SetupPersona/CloudBackup/EmailForm.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/PhoneForm.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/EmailForm.tsx msgid "Resend" msgstr "重新傳送" @@ -2310,24 +2440,32 @@ msgstr "" msgid "Resource" msgstr "" -#: dashboard/components/Restore/RestorePersonaFromLocal.tsx -#: dashboard/components/Restore/RestoreFromCloud/index.tsx -#: dashboard/components/Restore/RestoreFromCloud/ConfirmBackupInfo.tsx +#: dashboard/pages/SetupPersona/Recovery/Local.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/MaskNetwork.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/ConfirmBackupInfo.tsx msgid "Restore" msgstr "恢復" -#: dashboard/components/Restore/RestorePersonaFromLocal.tsx +#: dashboard/pages/SetupPersona/Recovery/Local.tsx msgid "Restore backup failed." msgstr "" +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx +msgid "Restore Completed" +msgstr "" + #: popups/pages/Settings/index.tsx msgid "Restore Database" msgstr "" -#: dashboard/components/Restore/RestoreFromCloud/index.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/MaskNetwork.tsx msgid "Restore failed" msgstr "恢復失敗" +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx +msgid "Restore Failed" +msgstr "" + #: popups/pages/Settings/index.tsx msgid "Restore from a previous database backup" msgstr "" @@ -2399,8 +2537,8 @@ msgid "Select Liquidity" msgstr "" #: dashboard/pages/SetupPersona/LocalBackup/index.tsx -msgid "Select the contents of the backup" -msgstr "" +#~ msgid "Select the contents of the backup" +#~ msgstr "" #: popups/pages/Wallet/Interaction/PermissionRequest.tsx msgid "Select the wallet(s) to use on this site. You should not connect to website you don't trust." @@ -2411,8 +2549,8 @@ msgid "Select Wallet" msgstr "" #: content-script/components/InjectedComponents/SetupGuide/VerifyNextID.tsx -#: dashboard/pages/SetupPersona/CloudBackup/PhoneForm.tsx -#: dashboard/pages/SetupPersona/CloudBackup/EmailForm.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/PhoneForm.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/EmailForm.tsx #: popups/pages/Wallet/components/ActivityList/ActivityItem.tsx #: popups/pages/Wallet/components/ActionGroup/index.tsx #: popups/pages/Wallet/Transfer/index.tsx @@ -2486,8 +2624,8 @@ msgid "Sign" msgstr "簽署" #: dashboard/pages/SetupPersona/Recovery/index.tsx -msgid "Sign Up" -msgstr "" +#~ msgid "Sign Up" +#~ msgstr "" #: popups/components/SignRequestInfo/index.tsx msgid "Sign-in Request" @@ -2614,8 +2752,7 @@ msgstr "" msgid "Swap" msgstr "" -#: dashboard/pages/SetupPersona/CloudBackupPreview/index.tsx -#: dashboard/pages/SetupPersona/CloudBackupPreview/index.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/Preview.tsx msgid "Switch other account" msgstr "" @@ -2623,7 +2760,7 @@ msgstr "" msgid "Switch Persona" msgstr "" -#: dashboard/components/Restore/RestoreFromCloud/ConfirmBackupInfo.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/ConfirmBackupInfo.tsx msgid "Switch to other accounts" msgstr "" @@ -2652,16 +2789,23 @@ msgstr "" msgid "The chainID is not equal to the currently connected one." msgstr "" -#: dashboard/pages/SetupPersona/CloudBackup/index.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/MaskNetwork.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/CloudBackupFormContext.ts +#: dashboard/pages/SetupPersona/Backup/Cloud/CloudBackupFormContext.ts #: dashboard/contexts/CloudBackupFormContext.tsx #: dashboard/contexts/CloudBackupFormContext.tsx msgid "The code is incorrect." msgstr "" -#: dashboard/modals/MergeBackupModal/MergeBackupDialog.tsx +#: dashboard/utils/api.ts msgid "The download link is expired" msgstr "" +#: dashboard/pages/SetupPersona/Recovery/Cloud/MaskNetwork.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/MaskNetwork.tsx +msgid "The Mask Network Cloud Backup feature will be deactivated on April 30, 2025. Please use alternative cloud backup services or local backup solutions." +msgstr "" + #: dashboard/pages/CreateMaskWallet/CreateMnemonic/index.tsx msgid "The mnemonic word has been copied, please keep it in a safe place." msgstr "" @@ -2700,6 +2844,7 @@ msgstr "" msgid "The persona name already exists." msgstr "" +#: dashboard/pages/SetupPersona/Backup/Cloud/CloudBackupFormContext.ts #: dashboard/contexts/CloudBackupFormContext.tsx msgid "The phone number is incorrect." msgstr "通訊號碼錯誤" @@ -2922,13 +3067,13 @@ msgstr "" msgid "Unlock" msgstr "解鎖" +#: dashboard/pages/SetupPersona/Recovery/Local.tsx #: dashboard/components/Restore/RestoreWalletFromLocal.tsx -#: dashboard/components/Restore/RestorePersonaFromLocal.tsx msgid "Unpacking" msgstr "" -#: dashboard/components/Restore/RestorePersonaFromLocal.tsx -#: dashboard/components/Restore/RestorePersonaFromLocal.tsx +#: dashboard/pages/SetupPersona/Recovery/Local.tsx +#: dashboard/pages/SetupPersona/Recovery/Local.tsx msgid "Unsupported data backup" msgstr "不支持數據備份格式" @@ -2976,16 +3121,16 @@ msgstr "" msgid "value" msgstr "" -#: dashboard/components/Restore/RestoreFromCloud/EmailField.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/EmailField.tsx msgid "Verification code has been sent to your email. Please check your mailbox." msgstr "" -#: dashboard/components/Restore/RestoreFromCloud/PhoneField.tsx +#: dashboard/pages/SetupPersona/Recovery/Cloud/PhoneField.tsx msgid "Verification code has been sent to your phone." msgstr "" -#: dashboard/pages/SetupPersona/CloudBackup/PhoneForm.tsx -#: dashboard/pages/SetupPersona/CloudBackup/EmailForm.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/PhoneForm.tsx +#: dashboard/pages/SetupPersona/Backup/Cloud/EmailForm.tsx msgid "Verification code sent" msgstr "驗證碼已傳送" @@ -3038,8 +3183,8 @@ msgid "Waiting for {providerType}" msgstr "" #: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx -msgid "wallet" -msgstr "" +#~ msgid "wallet" +#~ msgstr "" #: popups/pages/Wallet/SwitchWallet/index.tsx #: popups/modals/WalletGroupModal/index.tsx @@ -3096,8 +3241,8 @@ msgid "Welcome Back" msgstr "" #: dashboard/pages/SetupPersona/CloudBackupPreview/index.tsx -msgid "Welcome to Mask Cloud Services" -msgstr "" +#~ msgid "Welcome to Mask Cloud Services" +#~ msgstr "" #: popups/pages/Personas/Home/UI.tsx msgid "Welcome to Mask Network" @@ -3107,6 +3252,10 @@ msgstr "" msgid "Welcome to use Mask Network" msgstr "" +#: dashboard/components/GoogleDriveLogin.tsx +msgid "when you click Add Google Drive button,you will be forwarded to Google authorization pages." +msgstr "" + #: popups/pages/Wallet/ExportPrivateKey/index.tsx msgid "Write down mnemonic words" msgstr "" @@ -3120,21 +3269,25 @@ msgid "You could check the verification result on Mask Pop-up after few minutes. msgstr "" #: dashboard/modals/BackupPreviewModal/BackupPreviewDialog.tsx -msgid "You have backed up your data." -msgstr "" +#~ msgid "You have backed up your data." +#~ msgstr "" #: dashboard/pages/SetupPersona/Onboarding/index.tsx #~ msgid "You have recovered" #~ msgstr "" #: dashboard/pages/SetupPersona/Onboarding/index.tsx -msgid "You have recovered " -msgstr "" +#~ msgid "You have recovered " +#~ msgstr "" #: popups/pages/Personas/ConnectWallet/index.tsx msgid "You have signed with your wallet." msgstr "" +#: dashboard/pages/SetupPersona/Recovery/Cloud/GoogleDrive.tsx +msgid "You have successfully restored the backup from Google Drive to your browser." +msgstr "" + #: dashboard/components/Restore/ConfirmSynchronizePasswordDialog.tsx msgid "You have verified your cloud password and recovered your backup. Do you want to let your cloud password and local backup password be the same?" msgstr "" @@ -3143,26 +3296,41 @@ msgstr "" msgid "You need to open the dApp to view the specific content." msgstr "" -#. placeholder {0}: user.email #: dashboard/pages/SetupPersona/CloudBackup/index.tsx #: dashboard/pages/SetupPersona/CloudBackup/index.tsx -msgid "You used <0>{0} for the last cloud backup." -msgstr "" +#~ msgid "You used <0>{0} for the last cloud backup." +#~ msgstr "" #: popups/components/SignRequestInfo/index.tsx msgid "Your connection to this site is not encrypted which can be modified by a hostile third party, we strongly suggest you reject this request." msgstr "" +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx +msgid "Your file has been successfully merged into the browser data." +msgstr "" + +#: dashboard/modals/RestoreBackupModal/RestoreBackupDialog.tsx +msgid "Your file has been successfully restore into the browser data." +msgstr "" + #: dashboard/pages/CreateMaskWallet/CreateWalletForm/index.tsx msgid "Your payment password encrypts wallet data and is needed to unlocking the wallet, transaction confirmations and signing. The password is never stored, and there is no way to recover it if you forget it." msgstr "" +#: dashboard/pages/SetupPersona/Onboarding/index.tsx +msgid "Your Persona has been successfully created." +msgstr "" + #: dashboard/pages/SetupPersona/Onboarding/index.tsx #~ msgid "Your Persona is on" #~ msgstr "" #: dashboard/pages/SetupPersona/Onboarding/index.tsx -msgid "Your Persona is on " +#~ msgid "Your Persona is on " +#~ msgstr "" + +#: dashboard/pages/SetupPersona/Onboarding/index.tsx +msgid "Your Persona is on **ready 🚀**" msgstr "" #: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx @@ -3170,5 +3338,9 @@ msgstr "" #~ msgstr "" #: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx -msgid "Your Wallet is on " +#~ msgid "Your Wallet is on " +#~ msgstr "" + +#: dashboard/pages/CreateMaskWallet/Onboarding/index.tsx +msgid "Your Wallet is on **ready 🚀**" msgstr "" diff --git a/packages/mask/shared/helpers/checkAndRequestIdentityPermission.ts b/packages/mask/shared/helpers/checkAndRequestIdentityPermission.ts new file mode 100644 index 000000000000..dcd4dafe1067 --- /dev/null +++ b/packages/mask/shared/helpers/checkAndRequestIdentityPermission.ts @@ -0,0 +1,17 @@ +import { Environment, isEnvironment } from '@dimensiondev/holoflows-kit' +import type { Manifest } from 'webextension-polyfill' + +export async function checkAndRequestPermission() { + if (!isEnvironment(Environment.ExtensionProtocol) && !isEnvironment(Environment.ManifestBackground)) { + // The User Activation limitation is from Firefox + throw new Error( + 'browser.permissions.request can only be called after a User Activation and from a chrome-extension:// protocol.', + ) + } + const contained = await browser.permissions.contains({ permissions: ['identity'] }) + if (!contained) { + const granted = await browser.permissions.request({ permissions: ['identity' as Manifest.OptionalPermission] }) + if (!granted) return + } + return true +} diff --git a/packages/mask/shared/helpers/index.ts b/packages/mask/shared/helpers/index.ts index 483d4de6435d..0865dabd302d 100644 --- a/packages/mask/shared/helpers/index.ts +++ b/packages/mask/shared/helpers/index.ts @@ -1,2 +1,4 @@ export * from './download.js' export * from './formatTokenBalance.js' +export * from './checkAndRequestIdentityPermission.js' +export * from './requestDriveAccessToken.js' diff --git a/packages/mask/shared/helpers/requestDriveAccessToken.ts b/packages/mask/shared/helpers/requestDriveAccessToken.ts new file mode 100644 index 000000000000..b66f6f0122b0 --- /dev/null +++ b/packages/mask/shared/helpers/requestDriveAccessToken.ts @@ -0,0 +1,29 @@ +/* eslint-disable @typescript-eslint/ban-ts-comment */ +import { Environment, isEnvironment } from '@dimensiondev/holoflows-kit' + +export async function requestDriveAccessToken(interactive = false) { + if (!isEnvironment(Environment.ExtensionProtocol) && !isEnvironment(Environment.ManifestBackground)) { + // The User Activation limitation is from Firefox + throw new Error( + 'browser.permissions.request can only be called after a User Activation and from a chrome-extension:// protocol.', + ) + } + return new Promise((resolve, reject) => { + // @ts-expect-error + chrome.identity.getAuthToken( + { + interactive, + scopes: ['https://www.googleapis.com/auth/drive.file', 'email'], + }, + (token: string) => { + // @ts-expect-error + if (chrome.runtime.lastError) { + // @ts-expect-error + reject(new Error(chrome.runtime.lastError.message)) + return + } + resolve(token) + }, + ) + }) +} diff --git a/packages/plugins/Collectible/src/SiteAdaptor/Card/CollectibleCard.tsx b/packages/plugins/Collectible/src/SiteAdaptor/Card/CollectibleCard.tsx index 43610b46cdbc..b2cbcfe0175d 100644 --- a/packages/plugins/Collectible/src/SiteAdaptor/Card/CollectibleCard.tsx +++ b/packages/plugins/Collectible/src/SiteAdaptor/Card/CollectibleCard.tsx @@ -9,6 +9,7 @@ const useStyles = makeStyles()((theme) => { height: '100%', borderRadius: 0, overflow: 'auto', + scrollbarWidth: 'none', '::-webkit-scrollbar': { display: 'none', }, diff --git a/packages/plugins/Collectible/src/SiteAdaptor/Shared/DetailsCard.tsx b/packages/plugins/Collectible/src/SiteAdaptor/Shared/DetailsCard.tsx index 6704c442184e..841da07d6fda 100644 --- a/packages/plugins/Collectible/src/SiteAdaptor/Shared/DetailsCard.tsx +++ b/packages/plugins/Collectible/src/SiteAdaptor/Shared/DetailsCard.tsx @@ -11,7 +11,6 @@ const PLATFORM_COSTS: { [k in SourceType]?: number } = { [SourceType.OpenSea]: 2.5, - [SourceType.X2Y2]: 0.5, [SourceType.LooksRare]: 2, } diff --git a/packages/plugins/Collectible/src/helpers/url.ts b/packages/plugins/Collectible/src/helpers/url.ts index 74a2078cef2e..5761abe073c6 100644 --- a/packages/plugins/Collectible/src/helpers/url.ts +++ b/packages/plugins/Collectible/src/helpers/url.ts @@ -93,15 +93,6 @@ const RULES = [ address: (matched: string) => matched.replace('zora', ZORA_COLLECTION_ADDRESS), }, - // x2y2 - { - hosts: ['x2y2.io'], - pathname: /^\/eth\/(0x[\dA-Fa-f]{40})\/(\d+)/, - pluginID: NetworkPluginID.PLUGIN_EVM, - chainId: ChainIdEVM.Mainnet, - provider: SourceType.X2Y2, - }, - // looksrare { hosts: ['looksrare.org'], diff --git a/packages/plugins/Collectible/tests/helpers.ts b/packages/plugins/Collectible/tests/helpers.ts index 150fdb8218b6..ae44b56a5817 100644 --- a/packages/plugins/Collectible/tests/helpers.ts +++ b/packages/plugins/Collectible/tests/helpers.ts @@ -85,18 +85,6 @@ describe('getPayloadFromURL', () => { }, }, - // x2y2 - { - give: 'https://x2y2.io/eth/0x6d19568A959FCB4211852F6472d3df7b67C6Cd54/332', - expected: { - pluginID: NetworkPluginID.PLUGIN_EVM, - chainId: ChainIdEVM.Mainnet, - address: '0x6d19568A959FCB4211852F6472d3df7b67C6Cd54', - tokenId: '332', - provider: SourceType.X2Y2, - }, - }, - // loosrare { give: 'https://looksrare.org/collections/0x60E4d786628Fea6478F785A6d7e704777c86a7c6/28850', diff --git a/packages/plugins/RSS3/src/SiteAdaptor/SocialFeeds/useSocialFeeds.ts b/packages/plugins/RSS3/src/SiteAdaptor/SocialFeeds/useSocialFeeds.ts index cb965022d7ea..cf423f86dde7 100644 --- a/packages/plugins/RSS3/src/SiteAdaptor/SocialFeeds/useSocialFeeds.ts +++ b/packages/plugins/RSS3/src/SiteAdaptor/SocialFeeds/useSocialFeeds.ts @@ -1,8 +1,9 @@ import { t } from '@lingui/core/macro' import { timeout } from '@masknet/kit' +import { useLensClient } from '@masknet/shared' import { EMPTY_LIST, type PageIndicator } from '@masknet/shared-base' import { useFireflyFarcasterAccounts, useFireflyLensAccounts } from '@masknet/web3-hooks-base' -import { FireflyConfig, FireflyFarcaster, Lens } from '@masknet/web3-providers' +import { FireflyConfig, FireflyFarcaster } from '@masknet/web3-providers' import { skipToken, useInfiniteQuery, useQuery } from '@tanstack/react-query' import { sortBy, uniq } from 'lodash-es' import { useCallback } from 'react' @@ -48,12 +49,14 @@ export function useSocialFeeds({ userId, address }: Options) { }, }) + const lensClient = useLensClient() const lensHandles = uniq(lensAccounts.map((x) => x.handle).concat(profiles?.lensHandles || [])) - const { data: lensIds = EMPTY_LIST } = useQuery({ - queryKey: ['lens', 'popup-list', lensHandles], + const { data: accounts = EMPTY_LIST } = useQuery({ + queryKey: ['lens', 'popup-list', lensHandles, !lensClient], queryFn: async () => { - const profiles = await Lens.getProfilesByHandles(lensHandles) - return profiles.map((x) => x.id) + if (!lensClient) return + const profiles = await lensClient.getAccountsByHandles(lensHandles) + return profiles?.map((x) => x.address) || EMPTY_LIST }, }) const { @@ -65,9 +68,10 @@ export function useSocialFeeds({ userId, address }: Options) { hasNextPage: hasNextLensPage, isLoading: isLoadingLens, } = useInfiniteQuery({ - queryKey: ['social-feeds', 'lens', lensIds], + enabled: !!lensClient, + queryKey: ['social-feeds', 'lens', accounts, !lensClient], queryFn: async ({ pageParam }) => { - return timeout(Lens.getPostsByProfileId(lensIds, pageParam), 30_000, t`Request timed out`) + return timeout(lensClient!.getPostsByAccounts(accounts, pageParam), 30_000, t`Request timed out`) }, initialPageParam: undefined as PageIndicator | undefined, getNextPageParam: (lastPage) => lastPage?.nextIndicator, diff --git a/packages/plugins/RSS3/src/SiteAdaptor/hooks/index.ts b/packages/plugins/RSS3/src/SiteAdaptor/hooks/index.ts index a337083261f2..118c5d6955b5 100644 --- a/packages/plugins/RSS3/src/SiteAdaptor/hooks/index.ts +++ b/packages/plugins/RSS3/src/SiteAdaptor/hooks/index.ts @@ -1,4 +1,3 @@ export * from './useAddressLabel.js' export * from './useFeeds.js' -export * from './usePublicationId.js' export * from './useMarkdownStyles.js' diff --git a/packages/plugins/RSS3/src/SiteAdaptor/hooks/usePublicationId.ts b/packages/plugins/RSS3/src/SiteAdaptor/hooks/usePublicationId.ts deleted file mode 100644 index 9c1d42a5b44d..000000000000 --- a/packages/plugins/RSS3/src/SiteAdaptor/hooks/usePublicationId.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Lens } from '@masknet/web3-providers' -import { useQuery } from '@tanstack/react-query' - -export function usePublicationId(txId: string | null) { - return useQuery({ - queryKey: ['lens', 'transaction-publication-id', txId], - queryFn: async () => { - if (!txId) return null - return Lens.queryTransactionPublicationId(txId) - }, - }) -} diff --git a/packages/plugins/ScamWarning/src/SiteAdaptor/components/LinkModifier.tsx b/packages/plugins/ScamWarning/src/SiteAdaptor/components/LinkModifier.tsx index 1675a7657bf3..dd4a0b0ae433 100644 --- a/packages/plugins/ScamWarning/src/SiteAdaptor/components/LinkModifier.tsx +++ b/packages/plugins/ScamWarning/src/SiteAdaptor/components/LinkModifier.tsx @@ -3,11 +3,11 @@ import type { Plugin } from '@masknet/plugin-infra' import { makeStyles, ShadowRootPopper } from '@masknet/theme' import { Link } from '@mui/material' import { memo } from 'react' -import { usePopoverControl } from './usePopoverControl.js' -import { WarningCard } from './WarningCard.js' +import { useCheckLink } from '../hooks/useCheckLink.js' import { useDetectAddress } from '../hooks/useDetectAddress.js' import { AddressTag } from './TextModifier.js' -import { useCheckLink } from '../hooks/useCheckLink.js' +import { usePopoverControl } from './usePopoverControl.js' +import { WarningCard } from './WarningCard.js' const useStyles = makeStyles()((theme) => ({ link: { diff --git a/packages/plugins/Web3Profile/package.json b/packages/plugins/Web3Profile/package.json index bb068991ab85..dd66b224ab09 100644 --- a/packages/plugins/Web3Profile/package.json +++ b/packages/plugins/Web3Profile/package.json @@ -16,6 +16,7 @@ } }, "dependencies": { + "@lens-protocol/client": "0.0.0-canary-20250408064617", "@masknet/icons": "workspace:^", "@masknet/plugin-infra": "workspace:^", "@masknet/shared": "workspace:^", diff --git a/packages/plugins/Web3Profile/src/SiteAdaptor/Web3ProfileGlobalInjection.tsx b/packages/plugins/Web3Profile/src/SiteAdaptor/Web3ProfileGlobalInjection.tsx index b0e9c517ee58..a0274fccf878 100644 --- a/packages/plugins/Web3Profile/src/SiteAdaptor/Web3ProfileGlobalInjection.tsx +++ b/packages/plugins/Web3Profile/src/SiteAdaptor/Web3ProfileGlobalInjection.tsx @@ -19,10 +19,7 @@ export const Web3ProfileGlobalInjection = memo(function Web3ProfileGlobalInjecti const { open: lensOpen, closeDialog: closeLensDialog } = useRemoteControlledDialog( CrossIsolationMessages.events.followLensDialogEvent, (ev) => { - if (!ev.open) { - setHandle('') - } - setHandle(ev.handle) + setHandle(ev.open ? ev.handle : '') }, ) diff --git a/packages/plugins/Web3Profile/src/SiteAdaptor/components/Lens/FollowLensDialog.tsx b/packages/plugins/Web3Profile/src/SiteAdaptor/components/Lens/FollowLensDialog.tsx index a85004debdb9..f042f99dbb8c 100644 --- a/packages/plugins/Web3Profile/src/SiteAdaptor/components/Lens/FollowLensDialog.tsx +++ b/packages/plugins/Web3Profile/src/SiteAdaptor/components/Lens/FollowLensDialog.tsx @@ -1,24 +1,25 @@ +import { type Account, type EvmAddress } from '@lens-protocol/client' import { Trans } from '@lingui/react/macro' import { Icons } from '@masknet/icons' import { ChainBoundary, - EthereumERC20TokenApprovedBoundary, InjectedDialog, + setMyLensAccountAddress, + useAvailableLensAccounts, + useLensClient, + useMyLensAccountAddress, WalletConnectedBoundary, } from '@masknet/shared' -import { NetworkPluginID, PersistentStorages } from '@masknet/shared-base' +import { NetworkPluginID } from '@masknet/shared-base' import { ActionButton, makeStyles, useCustomSnackbar } from '@masknet/theme' -import { useChainContext, useFungibleTokenBalance, useNetworkContext, useWallet } from '@masknet/web3-hooks-base' -import { Lens } from '@masknet/web3-providers' -import { FollowModuleType, type LensBaseAPI } from '@masknet/web3-providers/types' -import { ZERO, formatBalance, isLessThan, isSameAddress } from '@masknet/web3-shared-base' -import { ChainId, createERC20Token, formatAmount } from '@masknet/web3-shared-evm' -import { Avatar, Box, Button, CircularProgress, DialogContent, Typography, buttonClasses } from '@mui/material' +import { useChainContext, useNetworkContext, useWallet } from '@masknet/web3-hooks-base' +import { isSameAddress } from '@masknet/web3-shared-base' +import { ChainId } from '@masknet/web3-shared-evm' +import { Avatar, Box, Button, buttonClasses, CircularProgress, DialogContent, Typography } from '@mui/material' import { useQuery } from '@tanstack/react-query' import { first } from 'lodash-es' -import { useCallback, useMemo, useState, type MouseEvent } from 'react' -import { useAsyncRetry } from 'react-use' -import { getFireflyLensProfileLink, getProfileAvatar } from '../../../utils.js' +import { useCallback, useMemo, useState } from 'react' +import { getFireflyLensProfileLink } from '../../../utils.js' import { useConfettiExplosion } from '../../hooks/ConfettiExplosion/index.js' import { useFollow } from '../../hooks/Lens/useFollow.js' import { useUnfollow } from '../../hooks/Lens/useUnfollow.js' @@ -111,123 +112,61 @@ let task: Promise | undefined export function FollowLensDialog({ handle, onClose }: Props) { const wallet = useWallet() - const [currentProfile, setCurrentProfile] = useState() const [isHovering, setIsHovering] = useState(false) const { classes } = useStyles({ account: !!wallet }) - const { account, chainId, providerType } = useChainContext() + const { account: walletAccount } = useChainContext() const { pluginID } = useNetworkContext() const { showSnackbar } = useCustomSnackbar() + const lensClient = useLensClient() + const myLensAccount = useMyLensAccountAddress(true) - // #region profile information - const { value, loading } = useAsyncRetry(async () => { - if (!handle || !open || !open) return - const profile = await Lens.getProfileByHandle(handle) - - if (!profile) return - - const defaultProfile = await Lens.queryDefaultProfileByAddress(account) - - const profiles = await Lens.queryProfilesByAddress(account) - - const latestProfile = PersistentStorages.Settings.storage.latestLensProfile?.value - setCurrentProfile((prev) => { - const profile = defaultProfile ?? profiles.find((x) => x.id === latestProfile) ?? first(profiles) - if (!prev && profile) { - if (latestProfile) PersistentStorages.Settings.storage.latestLensProfile.setValue(profile.id) - return profile - } - return prev - }) - return { - profile, - isSelf: isSameAddress(profile.ownedBy.address, account), - profiles, - defaultProfile: defaultProfile || first(profiles), - } - }, [handle, open, account]) - - const { profile, defaultProfile, isSelf, profiles } = value || {} + const { data: lensAccount, isLoading } = useQuery({ + enabled: !!handle && !!open, + queryKey: ['lens', 'profile-info', !lensClient, handle], + queryFn: async () => { + if (!handle || !lensClient) return + const lensAccount = await lensClient.getAccountByHandle(handle) + return lensAccount + }, + }) + const { data: accounts } = useAvailableLensAccounts() + const isSelf = isSameAddress(lensAccount?.username?.ownedBy as string, walletAccount) - const currentProfileId = currentProfile?.id - const targetProfileId = value?.profile.id + const currentAccount = accounts?.find((p) => isSameAddress(p.account.address, myLensAccount)) || first(accounts) + const targetAccountAddress: EvmAddress | undefined = lensAccount?.address const { isPending, data: isFollowing } = useQuery({ - queryKey: ['lens', 'following-status', currentProfileId, handle, targetProfileId], + queryKey: ['lens', 'following-status', myLensAccount, targetAccountAddress, !lensClient], queryFn: async () => { - if (!targetProfileId || !currentProfileId) return false - const result = await Lens.queryFollowStatus(currentProfileId, targetProfileId) - return result + if (!targetAccountAddress || !myLensAccount || !lensClient) return false + const res = await lensClient.getFollowStatus([{ account: targetAccountAddress, follower: myLensAccount }]) + const status = res[0].isFollowing + return status.onChain }, refetchOnWindowFocus: false, staleTime: 0, }) const updateFollowingStatus = useUpdateFollowingStatus() - const followModule = useMemo(() => { - if (profile?.followModule?.type === FollowModuleType.ProfileFollowModule && defaultProfile) { - return { - profileFollowModule: { - profileId: defaultProfile.id, - }, - } - } else if (profile?.followModule?.type === FollowModuleType.FeeFollowModule && profile.followModule.amount) { - return { - feeFollowModule: { - currency: profile.followModule.amount.asset.contract.address, - value: profile.followModule.amount.value, - }, - } - } - return - }, [profile, defaultProfile]) - // #endregion - - const approved = useMemo(() => { - if (!profile?.followModule?.amount?.asset) return { amount: ZERO.toFixed() } - const { - contract: { address }, - name, - symbol, - decimals, - } = profile.followModule.amount.asset - const token = createERC20Token(chainId, address, name, symbol, decimals) - const amount = formatAmount(profile.followModule.amount.value, decimals) - - return { - token, - amount, - } - }, [profile?.followModule?.amount, chainId]) - // #region follow and unfollow event handler const { showConfettiExplosion, canvasRef } = useConfettiExplosion() - const { loading: followLoading, handleFollow } = useFollow( - profile?.id, - currentProfile?.id, - followModule, - currentProfile?.signless, - (event: MouseEvent) => { - showConfettiExplosion(event.currentTarget.offsetWidth, event.currentTarget.offsetHeight) - updateFollowingStatus(currentProfileId, handle, true) + const { loading: followLoading, handleFollow } = useFollow({ + accountAddress: lensAccount?.address, + onSuccess: (width: number, height: number) => { + showConfettiExplosion(width, height) + updateFollowingStatus(myLensAccount, targetAccountAddress, true) }, - () => updateFollowingStatus(currentProfileId, handle, false), - ) - const { loading: unfollowLoading, handleUnfollow } = useUnfollow( - profile?.id, - currentProfile?.id, - currentProfile?.signless, - () => updateFollowingStatus(currentProfileId, handle, false), - () => updateFollowingStatus(currentProfileId, handle, true), - ) + onFailed: () => updateFollowingStatus(myLensAccount, targetAccountAddress, false), + }) + const { loading: unfollowLoading, handleUnfollow } = useUnfollow({ + accountAddress: lensAccount?.address as string, + onSuccess: () => updateFollowingStatus(myLensAccount, targetAccountAddress, false), + onFailed: () => updateFollowingStatus(myLensAccount, targetAccountAddress, true), + }) // #endregion - const { data: feeTokenBalance, isPending: getBalanceLoading } = useFungibleTokenBalance( - NetworkPluginID.PLUGIN_EVM, - profile?.followModule?.amount?.asset.contract.address ?? '', - ) - const handleClick = useCallback( - (event: MouseEvent) => { + (event: React.MouseEvent) => { if (task) { showSnackbar(isFollowing ? Lens Unfollow : Lens Follow, { processing: true, @@ -239,91 +178,51 @@ export function FollowLensDialog({ handle, onClose }: Props) { }) return } - task = (isFollowing ? handleUnfollow(event) : handleFollow(event)).finally(() => (task = undefined)) + task = (isFollowing ? handleUnfollow() : handleFollow(event)).finally(() => (task = undefined)) }, - [handleFollow, handleUnfollow, isFollowing], + [handleFollow, handleUnfollow, isFollowing, showSnackbar], ) - const disabled = useMemo(() => { - if ( - !account || - !currentProfile || - !!wallet?.owner || - pluginID !== NetworkPluginID.PLUGIN_EVM || - followLoading || - unfollowLoading || - profile?.followModule?.type === FollowModuleType.UnknownFollowModule || - (profile?.followModule?.type === FollowModuleType.ProfileFollowModule && !defaultProfile) || - (profile?.followModule?.type === FollowModuleType.FeeFollowModule && - profile.followModule.amount && - (!feeTokenBalance || - isLessThan( - formatBalance(feeTokenBalance, profile.followModule.amount.asset.decimals), - profile.followModule.amount.value, - ))) || - profile?.followModule?.type === FollowModuleType.RevertFollowModule - ) - return true - - return false - }, [ - currentProfile, - account, - wallet?.owner, - chainId, - followLoading, - unfollowLoading, - feeTokenBalance, - profile?.followModule, - pluginID, - ]) + const accountConditions = + !walletAccount || !currentAccount || !!wallet?.owner || pluginID !== NetworkPluginID.PLUGIN_EVM + const operationConditions = followLoading || unfollowLoading + const disabled = accountConditions || operationConditions const buttonText = useMemo(() => { if (isFollowing) { return isHovering ? Unfollow : Following - } else if (profile?.followModule?.type === FollowModuleType.UnknownFollowModule) { - return This profile can not be followed. - } else if (profile?.followModule?.type === FollowModuleType.FeeFollowModule && profile.followModule.amount) { - return ( - - Follow for {profile.followModule.amount.value} {profile.followModule.amount.asset.symbol} - - ) + } + switch (lensAccount?.operations?.canFollow.__typename) { + case 'AccountFollowOperationValidationPassed': + return Follow + case 'AccountFollowOperationValidationUnknown': + return This profile can not be followed. + case 'AccountFollowOperationValidationFailed': + return This profile can not be followed: {lensAccount.operations.canFollow.reason} } return Follow - }, [isFollowing, isHovering, profile]) + }, [isFollowing, isHovering, lensAccount]) const tips = useMemo(() => { if (wallet?.owner || pluginID !== NetworkPluginID.PLUGIN_EVM) return Current wallet does not support to interact with Lens protocol. - else if (profile?.followModule?.type === FollowModuleType.ProfileFollowModule && !defaultProfile) - return Only holding lens handle can follow. - else if ( - profile?.followModule?.type === FollowModuleType.FeeFollowModule && - profile.followModule.amount && - (!feeTokenBalance || - isLessThan( - formatBalance(feeTokenBalance, profile.followModule.amount.asset.decimals), - profile.followModule.amount.value, - )) - ) - return No enough balance to complete follow process. - else if (profile?.followModule?.type === FollowModuleType.RevertFollowModule) - return This user has banned follow function. - else if (!currentProfile) { + else if (lensAccount?.operations?.canFollow.__typename === 'AccountFollowOperationValidationFailed') + return Can not follow: {lensAccount.operations.canFollow.reason} + else if (!currentAccount) { return The current wallet does not hold a lens and cannot follow/unfollow } return - }, [wallet?.owner, chainId, profile, feeTokenBalance, pluginID, providerType, isSelf, currentProfile]) + }, [wallet?.owner, lensAccount, pluginID, currentAccount]) - const avatar = useMemo(() => getProfileAvatar(profile), [profile]) + const avatar = lensAccount?.metadata?.picture - const handleProfileChange = useCallback((profile: LensBaseAPI.Profile) => { - setCurrentProfile(profile) - PersistentStorages.Settings.storage.latestLensProfile.setValue(profile.id) + const handleProfileChange = useCallback((profile: Account) => { + setMyLensAccountAddress(profile.address) }, []) + const loading = followLoading || unfollowLoading || isLoading || isPending + return ( Lens} classes={{ dialogTitle: classes.dialogTitle, paper: classes.dialogContent }}> - {!value && (loading || getBalanceLoading) ? + {!lensAccount && isLoading ? @@ -341,13 +240,12 @@ export function FollowLensDialog({ handle, onClose }: Props) { sx={{ width: 64, height: 64 }} /> - {profile?.metadata?.displayName ?? profile?.handle.localName} + {lensAccount?.metadata?.name ?? lensAccount?.username?.localName} - @{profile?.handle.localName} + @{handle || '--'} - {profile?.stats.followers ?? '0'} Followers{' '} - {profile?.stats.following ?? '0'} Following + 0 Followers 0 Following @@ -355,7 +253,7 @@ export function FollowLensDialog({ handle, onClose }: Props) { : <> - - Unlock {value?.profile.followModule?.amount?.value ?? ZERO.toFixed()}{' '} - {approved.token?.symbol ?? ''} and follow - - } - failedContent={ - - Unlock {value?.profile.followModule?.amount?.value ?? ZERO.toFixed()}{' '} - {approved.token?.symbol ?? ''} and follow - - }> - Switch to Polygon and Follow}> - setIsHovering(true)} - onMouseOut={() => setIsHovering(false)}> - {buttonText} - - - + switchText={Switch to Polygon and Follow}> + setIsHovering(true)} + onMouseOut={() => setIsHovering(false)}> + {buttonText} + +