From a74ae9be7669a854974aecd28858fa97813cb5a4 Mon Sep 17 00:00:00 2001 From: Jack Works Date: Wed, 22 May 2019 22:32:07 +0800 Subject: [PATCH 1/3] Ready for i18n #40 Signed-off-by: Jack Works --- .vscode/i18n.code-snippets | 24 ++ public/_locales/en/messages.json | 251 ++++++++++++++++++ public/_locales/zh/messages.json | 251 ++++++++++++++++++ public/manifest.json | 3 +- .../InjectedComponents/AddToKeyStore.tsx | 10 +- .../InjectedComponents/AdditionalPostBox.tsx | 19 +- .../InjectedComponents/DecryptedPost.tsx | 18 +- .../InjectedComponents/SelectPeople.tsx | 9 +- .../InjectedComponents/SelectPeopleDialog.tsx | 5 +- src/components/Welcomes/0.tsx | 21 +- src/components/Welcomes/1a2.tsx | 11 +- src/components/Welcomes/1a3.tsx | 9 +- src/components/Welcomes/1a4.auto.tsx | 15 +- src/components/Welcomes/1a4.tsx | 100 ------- src/components/Welcomes/1a4.v2.tsx | 23 +- src/components/Welcomes/1b1.tsx | 13 +- src/components/Welcomes/2.tsx | 5 +- src/components/Welcomes/Banner.tsx | 7 +- .../background-script/CryptoService.ts | 16 +- .../background-script/WelcomeService.ts | 6 +- src/extension/content-script/tasks.ts | 7 +- src/extension/options-page/Welcome/index.tsx | 6 +- src/index.tsx | 7 +- src/key-management/people-gun.ts | 3 +- src/stories/index.tsx | 7 - src/utils/i18n.ts | 21 ++ src/utils/type-transform/Payload.ts | 14 +- src/utils/type-transform/Username.ts | 6 +- tsconfig.json | 2 +- 29 files changed, 678 insertions(+), 211 deletions(-) create mode 100644 .vscode/i18n.code-snippets create mode 100644 public/_locales/en/messages.json create mode 100644 public/_locales/zh/messages.json delete mode 100644 src/components/Welcomes/1a4.tsx create mode 100644 src/utils/i18n.ts diff --git a/.vscode/i18n.code-snippets b/.vscode/i18n.code-snippets new file mode 100644 index 000000000000..ab6f5432e06a --- /dev/null +++ b/.vscode/i18n.code-snippets @@ -0,0 +1,24 @@ +{ + "Add an i18n message": { + "scope": "json,jsonc", + "prefix": "i18", + "body": ["\"$1\": {", "\"message\": \"$2\"", "},"], + "description": "Add a new message" + } + // Place your maskbook workspace snippets here. Each snippet is defined under a snippet name and has a scope, prefix, body and + // description. Add comma separated ids of the languages where the snippet is applicable in the scope field. If scope + // is left empty or omitted, the snippet gets applied to all languages. The prefix is what is + // used to trigger the snippet and the body will be expanded and inserted. Possible variables are: + // $1, $2 for tab stops, $0 for the final cursor position, and ${1:label}, ${2:another} for placeholders. + // Placeholders with the same ids are connected. + // Example: + // "Print to console": { + // "scope": "javascript,typescript", + // "prefix": "log", + // "body": [ + // "console.log('$1');", + // "$2" + // ], + // "description": "Log output to console" + // } +} diff --git a/public/_locales/en/messages.json b/public/_locales/en/messages.json new file mode 100644 index 000000000000..660c060ab6bc --- /dev/null +++ b/public/_locales/en/messages.json @@ -0,0 +1,251 @@ +{ + "additional-post-box--placeholder-w-name": { + "message": "Hey $1, what's your mind? Encrypt with Maskbook" + }, + "additional-post-box--placeholder-wo-name": { + "message": "What's your mind? Encrypt with Maskbook" + }, + "additional-post-box--post-button": { + "message": "📫 Post it!" + }, + "additional-post-box--encrypted-post-pre": { + "message": "Decrypt this post with $1" + }, + "additional-post-box--encrypted-failed": { + "message": "Encrypted text has been copied into the clipboard!\nHowever, you need to paste it to the post box by yourself." + }, + "add-to-key-store-success": { + "message": "Maskbook public key added to keystore ✔" + }, + "add-to-key-store-verifying": { + "message": "Maskbook public key found, verifying..." + }, + "add-to-key-store-failed-title": { + "message": "Maskbook public key NOT verified ❌" + }, + "add-to-key-store-failed-text": { + "message": "$1\nThis public key won't be saved." + }, + "decrypted-postbox-title": { + "message": "Maskbook decrypted content:" + }, + "decrypted-postbox-add-decryptor": { + "message": "Add decryptor" + }, + "decrypted-postbox-verified": { + "message": "Signature verified ✔" + }, + "decrypted-postbox-not-verified": { + "message": "Signature NOT verified ❌" + }, + "decrypted-postbox-decrypting": { + "message": "Maskbook decrypting..." + }, + "decrypted-postbox-failed": { + "message": "Maskbook decryption failed" + }, + "search-box-placeholder": { + "message": "Type here to search" + }, + "select-all": { + "message": "Select All" + }, + "select-none": { + "message": "Select None" + }, + "not-found": { + "message": "Not found" + }, + "cancel": { + "message": "Cancel" + }, + "sharing": { + "message": "Sharing" + }, + "share": { + "message": "Share" + }, + "restore": { + "message": "Restore" + }, + "back": { + "message": "Back" + }, + "finish": { + "message": "Finish" + }, + "welcome-0-close-button": { + "message": "I'll do it later" + }, + "welcome-0-title": { + "message": "Welcome to Maskbook" + }, + "welcome-0-description": { + "message": "You can post on Facebook without allowing Facebook to stalk, analyze, and peep into you." + }, + "welcome-0-new-user": { + "message": "New user?" + }, + "welcome-0-connect-facebook": { + "message": "Connect Facebook" + }, + "welcome-0-old-user": { + "message": "Returning user?" + }, + "welcome-0-restore-key": { + "message": "Restore Keypair" + }, + "welcome-0-caption": { + "message": "Lost your keypair backup? No worry. Simply start as a new user." + }, + "welcome-1a2-title": { + "message": "Encrypt message use this postbox" + }, + "welcome-1a2-imgalt": { + "message": "Screenshot of how to encrypt message with Maskbook" + }, + "welcome-1a2-description": { + "message": "Then only people you selected with Maskbook can see the post content" + }, + "welcome-1a2-done-button": { + "message": "Nice!" + }, + "welcome-1a3-title": { + "message": "Keep your backups carefully" + }, + "welcome-1a3-description1": { + "message": "The first backup has been put in your Downloads folder." + }, + "welcome-1a3-description2": { + "message": "And export backups frequently!" + }, + "welcome-1a3-done-button": { + "message": "Got it!" + }, + "welcome-1a4-auto-radio-aria": { + "message": "Choose how to verify your account" + }, + "welcome-1a4-auto-profile-title": { + "message": "Add public key to profile" + }, + "welcome-1a4-auto-profile-description1": { + "message": "Easy and lightweight." + }, + "welcome-1a4-auto-profile-description2": { + "message": "Never disturb anyone." + }, + "welcome-1a4-auto-post-title": { + "message": "Create a verification post" + }, + "welcome-1a4-auto-post-description1": { + "message": "We appreciate your valor!" + }, + "welcome-1a4-auto-post-description2": { + "message": "Editable after posting." + }, + "welcome-1a4-title": { + "message": "Verify Account Ownership" + }, + "welcome-1a4-bio-disabled": { + "message": "Sorry, automatically verify your account through bio is not available now." + }, + "welcome-1a4-type-auto-subtitle1": { + "message": "Avoid any confusion before your first encrypted post." + }, + "welcome-1a4-type-auto-subtitle2": { + "message": "This allows your friends to verify the connection between your Facebook account and your keypair." + }, + "welcome-1a4-type-auto-switch": { + "message": "Prefer doing it manually?" + }, + "welcome-1a4-type-manual-subtitle1": { + "message": "Add this to bio, or post on timeline, before your first encrypted post." + }, + "welcome-1a4-type-manual-subtitle2": { + "message": "This allows your friends to verify the connection between your Facebook account and your keypair." + }, + "welcome-1a4-type-manual-goto": { + "message": "Copy & Go to Profile" + }, + "welcome-1a4-type-manual-switch": { + "message": "Prefer automating the steps?" + }, + "welcome-1b-title": { + "message": "Restore your keypair" + }, + "welcome-1b-dragging": { + "message": "Drag your key backup into this dialog" + }, + "welcome-1b-no-file-selected": { + "message": "Select your exported key backup" + }, + "welcome-1b-file-selected": { + "message": "Selected exported key backup: $1" + }, + "welcome-2-title": { + "message": "You're done!" + }, + "welcome-2-greeting": { + "message": "You can use Maskbook now!" + }, + "banner-title": { + "message": "Welcome to Maskbook" + }, + "banner-get-started": { + "message": "Get started" + }, + "banner-dismiss-aria": { + "message": "Dismiss the banner" + }, + "service-others-key-not-found": { + "message": "$1's public key not found!" + }, + "service-publish-post-aes-key-failed": { + "message": "Publish AES key failed!" + }, + "service-not-share-target": { + "message": "Maskbook does not find the key used to decrypt this post. Maybe this post is not intended to share with you?" + }, + "service-decryption-failed": { + "message": "Decryption failed." + }, + "service-unknown-payload": { + "message": "Unknown post version, maybe you should update Maskbook?" + }, + "service-key-parse-failed": { + "message": "Key parse failed" + }, + "service-have-no-own-key-yet": { + "message": "You have no private key yet" + }, + "service-username-invalid": { + "message": "Username not valid" + }, + "automation-request-click-post-box": { + "message": "Click the post box please!" + }, + "automation-request-click-edit-bio-button": { + "message": "Please click the \"Edit bio\" button or the pencil on the bio box." + }, + "automation-request-paste-into-bio-box": { + "message": "Your prove content is write to your clipboard. Please paste into the bio input!" + }, + "automation-request-paste-into-post-box": { + "message": "Prove content has been copied into the clipboard!\nHowever, you need to paste it to the post box by yourself." + }, + "payload-not-found": { + "message": "Doesn't find payload" + }, + "payload-incomplete": { + "message": "This post is not complete, you need to view the full post." + }, + "payload-bad": { + "message": "This post seemed to be corrupted. Maskbook cannot decrypt it." + }, + "payload-throw-in-alpha41": { + "message": "Support for Alpha41 is dropped. Tell your friends to upgrade Maskbook!" + }, + "options-index-welcome": { + "message": "First to Maskbook?" + } +} diff --git a/public/_locales/zh/messages.json b/public/_locales/zh/messages.json new file mode 100644 index 000000000000..660c060ab6bc --- /dev/null +++ b/public/_locales/zh/messages.json @@ -0,0 +1,251 @@ +{ + "additional-post-box--placeholder-w-name": { + "message": "Hey $1, what's your mind? Encrypt with Maskbook" + }, + "additional-post-box--placeholder-wo-name": { + "message": "What's your mind? Encrypt with Maskbook" + }, + "additional-post-box--post-button": { + "message": "📫 Post it!" + }, + "additional-post-box--encrypted-post-pre": { + "message": "Decrypt this post with $1" + }, + "additional-post-box--encrypted-failed": { + "message": "Encrypted text has been copied into the clipboard!\nHowever, you need to paste it to the post box by yourself." + }, + "add-to-key-store-success": { + "message": "Maskbook public key added to keystore ✔" + }, + "add-to-key-store-verifying": { + "message": "Maskbook public key found, verifying..." + }, + "add-to-key-store-failed-title": { + "message": "Maskbook public key NOT verified ❌" + }, + "add-to-key-store-failed-text": { + "message": "$1\nThis public key won't be saved." + }, + "decrypted-postbox-title": { + "message": "Maskbook decrypted content:" + }, + "decrypted-postbox-add-decryptor": { + "message": "Add decryptor" + }, + "decrypted-postbox-verified": { + "message": "Signature verified ✔" + }, + "decrypted-postbox-not-verified": { + "message": "Signature NOT verified ❌" + }, + "decrypted-postbox-decrypting": { + "message": "Maskbook decrypting..." + }, + "decrypted-postbox-failed": { + "message": "Maskbook decryption failed" + }, + "search-box-placeholder": { + "message": "Type here to search" + }, + "select-all": { + "message": "Select All" + }, + "select-none": { + "message": "Select None" + }, + "not-found": { + "message": "Not found" + }, + "cancel": { + "message": "Cancel" + }, + "sharing": { + "message": "Sharing" + }, + "share": { + "message": "Share" + }, + "restore": { + "message": "Restore" + }, + "back": { + "message": "Back" + }, + "finish": { + "message": "Finish" + }, + "welcome-0-close-button": { + "message": "I'll do it later" + }, + "welcome-0-title": { + "message": "Welcome to Maskbook" + }, + "welcome-0-description": { + "message": "You can post on Facebook without allowing Facebook to stalk, analyze, and peep into you." + }, + "welcome-0-new-user": { + "message": "New user?" + }, + "welcome-0-connect-facebook": { + "message": "Connect Facebook" + }, + "welcome-0-old-user": { + "message": "Returning user?" + }, + "welcome-0-restore-key": { + "message": "Restore Keypair" + }, + "welcome-0-caption": { + "message": "Lost your keypair backup? No worry. Simply start as a new user." + }, + "welcome-1a2-title": { + "message": "Encrypt message use this postbox" + }, + "welcome-1a2-imgalt": { + "message": "Screenshot of how to encrypt message with Maskbook" + }, + "welcome-1a2-description": { + "message": "Then only people you selected with Maskbook can see the post content" + }, + "welcome-1a2-done-button": { + "message": "Nice!" + }, + "welcome-1a3-title": { + "message": "Keep your backups carefully" + }, + "welcome-1a3-description1": { + "message": "The first backup has been put in your Downloads folder." + }, + "welcome-1a3-description2": { + "message": "And export backups frequently!" + }, + "welcome-1a3-done-button": { + "message": "Got it!" + }, + "welcome-1a4-auto-radio-aria": { + "message": "Choose how to verify your account" + }, + "welcome-1a4-auto-profile-title": { + "message": "Add public key to profile" + }, + "welcome-1a4-auto-profile-description1": { + "message": "Easy and lightweight." + }, + "welcome-1a4-auto-profile-description2": { + "message": "Never disturb anyone." + }, + "welcome-1a4-auto-post-title": { + "message": "Create a verification post" + }, + "welcome-1a4-auto-post-description1": { + "message": "We appreciate your valor!" + }, + "welcome-1a4-auto-post-description2": { + "message": "Editable after posting." + }, + "welcome-1a4-title": { + "message": "Verify Account Ownership" + }, + "welcome-1a4-bio-disabled": { + "message": "Sorry, automatically verify your account through bio is not available now." + }, + "welcome-1a4-type-auto-subtitle1": { + "message": "Avoid any confusion before your first encrypted post." + }, + "welcome-1a4-type-auto-subtitle2": { + "message": "This allows your friends to verify the connection between your Facebook account and your keypair." + }, + "welcome-1a4-type-auto-switch": { + "message": "Prefer doing it manually?" + }, + "welcome-1a4-type-manual-subtitle1": { + "message": "Add this to bio, or post on timeline, before your first encrypted post." + }, + "welcome-1a4-type-manual-subtitle2": { + "message": "This allows your friends to verify the connection between your Facebook account and your keypair." + }, + "welcome-1a4-type-manual-goto": { + "message": "Copy & Go to Profile" + }, + "welcome-1a4-type-manual-switch": { + "message": "Prefer automating the steps?" + }, + "welcome-1b-title": { + "message": "Restore your keypair" + }, + "welcome-1b-dragging": { + "message": "Drag your key backup into this dialog" + }, + "welcome-1b-no-file-selected": { + "message": "Select your exported key backup" + }, + "welcome-1b-file-selected": { + "message": "Selected exported key backup: $1" + }, + "welcome-2-title": { + "message": "You're done!" + }, + "welcome-2-greeting": { + "message": "You can use Maskbook now!" + }, + "banner-title": { + "message": "Welcome to Maskbook" + }, + "banner-get-started": { + "message": "Get started" + }, + "banner-dismiss-aria": { + "message": "Dismiss the banner" + }, + "service-others-key-not-found": { + "message": "$1's public key not found!" + }, + "service-publish-post-aes-key-failed": { + "message": "Publish AES key failed!" + }, + "service-not-share-target": { + "message": "Maskbook does not find the key used to decrypt this post. Maybe this post is not intended to share with you?" + }, + "service-decryption-failed": { + "message": "Decryption failed." + }, + "service-unknown-payload": { + "message": "Unknown post version, maybe you should update Maskbook?" + }, + "service-key-parse-failed": { + "message": "Key parse failed" + }, + "service-have-no-own-key-yet": { + "message": "You have no private key yet" + }, + "service-username-invalid": { + "message": "Username not valid" + }, + "automation-request-click-post-box": { + "message": "Click the post box please!" + }, + "automation-request-click-edit-bio-button": { + "message": "Please click the \"Edit bio\" button or the pencil on the bio box." + }, + "automation-request-paste-into-bio-box": { + "message": "Your prove content is write to your clipboard. Please paste into the bio input!" + }, + "automation-request-paste-into-post-box": { + "message": "Prove content has been copied into the clipboard!\nHowever, you need to paste it to the post box by yourself." + }, + "payload-not-found": { + "message": "Doesn't find payload" + }, + "payload-incomplete": { + "message": "This post is not complete, you need to view the full post." + }, + "payload-bad": { + "message": "This post seemed to be corrupted. Maskbook cannot decrypt it." + }, + "payload-throw-in-alpha41": { + "message": "Support for Alpha41 is dropped. Tell your friends to upgrade Maskbook!" + }, + "options-index-welcome": { + "message": "First to Maskbook?" + } +} diff --git a/public/manifest.json b/public/manifest.json index d66370320493..45df411059f1 100644 --- a/public/manifest.json +++ b/public/manifest.json @@ -27,5 +27,6 @@ "256": "256x256.png" }, "homepage_url": "https://maskbook.io", - "description": "Encrypt your posts & chats on You-Know-Where. Allow only your friends to decrypt." + "description": "Encrypt your posts & chats on You-Know-Where. Allow only your friends to decrypt.", + "default_locale": "en" } diff --git a/src/components/InjectedComponents/AddToKeyStore.tsx b/src/components/InjectedComponents/AddToKeyStore.tsx index b26ae8d560de..d4ef6b964787 100644 --- a/src/components/InjectedComponents/AddToKeyStore.tsx +++ b/src/components/InjectedComponents/AddToKeyStore.tsx @@ -2,6 +2,7 @@ import React from 'react' import AsyncComponent from '../../utils/components/AsyncComponent' import { AdditionalContent } from './AdditionalPostContent' import Services from '../../extension/service' +import { geti18nString } from '../../utils/i18n' interface Props { provePost: string @@ -19,11 +20,12 @@ export function AddToKeyStore({ provePost, postBy }: Props) { ) } export const AddToKeyStoreUI = { - success: , - awaiting: , + success: , + awaiting: , failed: (props: { error: Error }) => ( - - {props.error.message} This public key won't be saved.{console.error(props.error)} + + {geti18nString('add-to-key-store-failed-text', props.error.message)} + {console.error(props.error)} ), } diff --git a/src/components/InjectedComponents/AdditionalPostBox.tsx b/src/components/InjectedComponents/AdditionalPostBox.tsx index 6f0d2d911d7f..bab27675733e 100644 --- a/src/components/InjectedComponents/AdditionalPostBox.tsx +++ b/src/components/InjectedComponents/AdditionalPostBox.tsx @@ -18,6 +18,7 @@ import { useCapturedInput } from '../../utils/hooks/useCapturedEvents' import { Avatar } from '../../utils/components/Avatar' import Services from '../../extension/service' import { pasteIntoPostBox } from '../../extension/content-script/tasks' +import { geti18nString } from '../../utils/i18n' interface Props { people: Person[] @@ -58,9 +59,12 @@ export const AdditionalPostBoxUI = withStylesTyped({ inputRef={inputRef} fullWidth multiline - placeholder={`${ - myself.nickname ? `Hey ${myself.nickname}, w` : 'W' - }hat's your mind? Encrypt with Maskbook`} + placeholder={geti18nString( + myself.nickname + ? 'additional-post-box--placeholder-w-name' + : 'additional-post-box--placeholder-wo-name', + myself.nickname, + )} /> @@ -79,7 +83,7 @@ export const AdditionalPostBoxUI = withStylesTyped({ color="primary" className={classes.button} disabled={!(selectedPeople.length && text)}> - 📫 Post it! + {geti18nString('additional-post-box--post-button')} @@ -97,11 +101,8 @@ export function AdditionalPostBox() { useAsync(() => Services.People.queryAvatar(username || ''), []).then(setAvatar) const onRequestPost = React.useCallback(async (people, text) => { const [encrypted, token] = await Services.Crypto.encryptTo(text, people) - const fullPost = 'Decrypt this post with ' + encrypted - pasteIntoPostBox( - fullPost, - 'Encrypted text has been copied into the clipboard!\nHowever, you need to paste it to the post box by yourself.', - ) + const fullPost = geti18nString('additional-post-box--encrypted-post-pre', encrypted) + pasteIntoPostBox(fullPost, geti18nString('additional-post-box--encrypted-failed')) Services.Crypto.publishPostAESKey(token) }, []) if (!username) { diff --git a/src/components/InjectedComponents/DecryptedPost.tsx b/src/components/InjectedComponents/DecryptedPost.tsx index 3e1bdb4f462b..6f277635bc32 100644 --- a/src/components/InjectedComponents/DecryptedPost.tsx +++ b/src/components/InjectedComponents/DecryptedPost.tsx @@ -8,6 +8,7 @@ import Link from '@material-ui/core/Link' import { withStylesTyped } from '../../utils/theme' import { sleep } from '../../utils/utils' import Services from '../../extension/service' +import { geti18nString } from '../../utils/i18n' interface DecryptPostSuccessProps { data: { signatureVerifyResult: boolean; content: string } @@ -27,16 +28,17 @@ const DecryptPostSuccess = withStylesTyped({ title={ <> {ShareMenu} - Maskbook decrypted content: + {geti18nString('decrypted-postbox-title')} + {props.displayAppendDecryptor ? ( - Add decryptor + {geti18nString('decrypted-postbox-add-decryptor')} ) : null} {data.signatureVerifyResult ? ( - Signature verified ✔ + {geti18nString('decrypted-postbox-verified')} ) : ( - Signature NOT verified ❌ + {geti18nString('decrypted-postbox-not-verified')} )} } @@ -51,9 +53,13 @@ const DecryptPostSuccess = withStylesTyped({ ) }) -const DecryptPostAwaiting = +const DecryptPostAwaiting = function DecryptPostFailed({ error }: { error: Error }) { - return {error && error.message} + return ( + + {error && error.message} + + ) } interface DecryptPostProps { diff --git a/src/components/InjectedComponents/SelectPeople.tsx b/src/components/InjectedComponents/SelectPeople.tsx index 5d0f9fee20a9..cd1b2368b1e2 100644 --- a/src/components/InjectedComponents/SelectPeople.tsx +++ b/src/components/InjectedComponents/SelectPeople.tsx @@ -10,6 +10,7 @@ import Button from '@material-ui/core/Button/Button' import { withStylesTyped } from '../../utils/theme' import ListItemAvatar from '@material-ui/core/ListItemAvatar/ListItemAvatar' import { Avatar } from '../../utils/components/Avatar' +import { geti18nString } from '../../utils/i18n' interface PeopleInListProps { person: Person @@ -101,7 +102,7 @@ export const SelectPeopleUI = withStylesTyped({ onSetSelected(selected.slice(0, selected.length - 1)) } }} - placeholder={disabled ? '' : 'Type here to search'} + placeholder={disabled ? '' : geti18nString('search-box-placeholder')} disabled={disabled} /> @@ -114,12 +115,12 @@ export const SelectPeopleUI = withStylesTyped({ className={classes.button} color="primary" onClick={() => onSetSelected([...selected, ...listAfterSearch])}> - Select All + {geti18nString('select-all')} )} {selected.length > 0 && ( )} @@ -132,7 +133,7 @@ export const SelectPeopleUI = withStylesTyped({ {listBeforeSearch.length > 0 && listBeforeSearch.length === 0 && ( - + )} {listAfterSearch.map(p => ( diff --git a/src/components/InjectedComponents/SelectPeopleDialog.tsx b/src/components/InjectedComponents/SelectPeopleDialog.tsx index cba4099a5d35..a259529e9313 100644 --- a/src/components/InjectedComponents/SelectPeopleDialog.tsx +++ b/src/components/InjectedComponents/SelectPeopleDialog.tsx @@ -8,6 +8,7 @@ import DialogTitle from '@material-ui/core/DialogTitle/DialogTitle' import DialogActions from '@material-ui/core/DialogActions/DialogActions' import DialogContent from '@material-ui/core/DialogContent/DialogContent' import { withStylesTyped } from '../../utils/theme' +import { geti18nString } from '../../utils/i18n' interface Props { open: boolean people: Person[] @@ -54,13 +55,13 @@ export const SelectPeopleDialog = withStylesTyped({ )} diff --git a/src/components/Welcomes/0.tsx b/src/components/Welcomes/0.tsx index f47711f71861..7f5e5b5f9b3f 100644 --- a/src/components/Welcomes/0.tsx +++ b/src/components/Welcomes/0.tsx @@ -7,6 +7,7 @@ import Button from '@material-ui/core/Button/Button' import { VerticalCenter, FullWidth, createBox } from '../../utils/components/Flex' import Close from '@material-ui/icons/Close' +import { geti18nString } from '../../utils/i18n' const LinedBox = createBox(theme => ({ border: '1px solid #ddd', @@ -62,41 +63,41 @@ export default withStylesTyped(theme =>
- Welcome to Maskbook + {geti18nString('welcome-0-title')} - You can post on Facebook without allowing Facebook to stalk, analyze, and peep into you. + {geti18nString('welcome-0-description')} - New user? - Connect Facebook Account + {geti18nString('welcome-0-new-user')} + {geti18nString('welcome-0-connect-facebook')} - Returning user? - Restore Keyparis + {geti18nString('welcome-0-old-user')} + {geti18nString('welcome-0-restore-key')} - Lost your keystore backup? No worry. Simply start as a new user. + {geti18nString('welcome-0-caption')}
diff --git a/src/components/Welcomes/1a2.tsx b/src/components/Welcomes/1a2.tsx index 0540b1dedb40..8ebcbb6961b5 100644 --- a/src/components/Welcomes/1a2.tsx +++ b/src/components/Welcomes/1a2.tsx @@ -5,6 +5,7 @@ import { withStylesTyped } from '../../utils/theme' import createStyles from '@material-ui/core/styles/createStyles' import Button from '@material-ui/core/Button/Button' import { getUrl } from '../../utils/utils' +import { geti18nString } from '../../utils/i18n' interface Props { next(): void @@ -31,18 +32,16 @@ export default withStylesTyped(theme => )(function Welcome({ classes, next }) { return ( - Encrypt message use this postbox + {geti18nString('welcome-1a2-title')} Screenshot of how to encrypt message with Maskbook - - Then only people you selected with Maskbook can see the post content - + {geti18nString('welcome-1a2-description')} ) diff --git a/src/components/Welcomes/1a3.tsx b/src/components/Welcomes/1a3.tsx index dfadc63c5098..d34f52a6f6df 100644 --- a/src/components/Welcomes/1a3.tsx +++ b/src/components/Welcomes/1a3.tsx @@ -5,6 +5,7 @@ import { withStylesTyped } from '../../utils/theme' import createStyles from '@material-ui/core/styles/createStyles' import Button from '@material-ui/core/Button/Button' import { getUrl } from '../../utils/utils' +import { geti18nString } from '../../utils/i18n' interface Props { next(): void @@ -30,16 +31,16 @@ export default withStylesTyped(theme => const filename = `maskbook-keystore-backup-${today}.json` return ( - Keep your backups carefully + {geti18nString('welcome-1a3-title')} {filename} - The first backup has been put in your Downloads folder. + {geti18nString('welcome-1a3-description1')}
- And export backups frequently! + {geti18nString('welcome-1a3-description2')}
) diff --git a/src/components/Welcomes/1a4.auto.tsx b/src/components/Welcomes/1a4.auto.tsx index 90b29ce6c027..b17fa179fc20 100644 --- a/src/components/Welcomes/1a4.auto.tsx +++ b/src/components/Welcomes/1a4.auto.tsx @@ -7,6 +7,7 @@ import Radio from '@material-ui/core/Radio/Radio' import FormControl from '@material-ui/core/FormControl/FormControl' import RadioGroup from '@material-ui/core/RadioGroup/RadioGroup' import FormControlLabel from '@material-ui/core/FormControlLabel/FormControlLabel' +import { geti18nString } from '../../utils/i18n' const Option = withStylesTyped(theme => ({ root: { @@ -61,7 +62,7 @@ export default withStylesTyped(theme => setType(v as any)}> label={ } @@ -89,12 +90,12 @@ export default withStylesTyped(theme => label={ } diff --git a/src/components/Welcomes/1a4.tsx b/src/components/Welcomes/1a4.tsx deleted file mode 100644 index f66206aee999..000000000000 --- a/src/components/Welcomes/1a4.tsx +++ /dev/null @@ -1,100 +0,0 @@ -import * as React from 'react' -import Paper from '@material-ui/core/Paper/Paper' -import Typography from '@material-ui/core/Typography/Typography' -import { withStylesTyped } from '../../utils/theme' -import createStyles from '@material-ui/core/styles/createStyles' -import Button from '@material-ui/core/Button/Button' -import { createBox } from '../../utils/components/Flex' - -const TextField = createBox( - theme => ({ - background: theme.palette.background.default, - color: theme.palette.text.hint, - padding: `${theme.spacing.unit * 2}px`, - border: `1px solid ${theme.palette.divider}`, - textAlign: 'start', - whiteSpace: 'pre-line', - borderRadius: theme.shape.borderRadius, - fontSize: '1.15rem', - wordBreak: 'break-all', - display: 'block', - resize: 'none', - width: '100%', - boxSizing: 'border-box', - }), - 'textarea', -) -interface Props { - copyToClipboard(text: string, gotoBio: boolean): void - provePost: string -} -export default withStylesTyped(theme => - createStyles({ - paper: { - padding: '2rem 2rem 1rem 2rem', - textAlign: 'center', - width: 600, - boxSizing: 'border-box', - '& > *': { - marginBottom: theme.spacing.unit * 3, - }, - }, - button: { - minWidth: 180, - }, - textFieldShort: { - minHeight: '10em', - }, - textFieldLong: { - minHeight: '11em', - }, - }), -)(function Welcome({ classes, copyToClipboard, provePost }) { - const full = `I'm using https://maskbook.io/ to encrypt my posts to prevent Facebook from peeping into them. -Install Maskbook as well, so that you may read my encrypted posts, and prevent Facebook from imposing surveillance on our communication. -Privacy, enforced. -${provePost}` - const [showShort, setShort] = React.useState(false) - const ref = React.createRef() - function onFocus() { - setTimeout(() => { - if (!ref.current) return - ref.current.select() - }, 20) - } - const onBlur = React.useCallback(() => { - const selection = getSelection() - if (!selection) return - selection.removeAllRanges() - }, []) - return ( - - Let your friends join Maskbook - - - {showShort - ? 'Paste this into your profile bio, then your friends can verify the connection between your Maskbook and your Facebook account.' - : 'Avoid any confusion before your first encrypted post.'} - - -
- -
- ) -}) diff --git a/src/components/Welcomes/1a4.v2.tsx b/src/components/Welcomes/1a4.v2.tsx index dadbafd7c2e2..241cdaac8dc2 100644 --- a/src/components/Welcomes/1a4.v2.tsx +++ b/src/components/Welcomes/1a4.v2.tsx @@ -7,6 +7,7 @@ import Button from '@material-ui/core/Button/Button' import Auto from './1a4.auto' import Manual from './1a4.manual' +import { geti18nString } from '../../utils/i18n' interface Props { bioDisabled?: boolean @@ -41,47 +42,45 @@ export default withStylesTyped(theme => const auto = ( <> - Avoid any confusion before your first encrypted post. + {geti18nString('welcome-1a4-type-auto-subtitle1')}
- This allows your friends to verify the connection between your Facebook account and your keypair. + {geti18nString('welcome-1a4-type-auto-subtitle2')}

) const manual = ( <> - Add this to bio, or post on timeline, before your first encrypted post. + {geti18nString('welcome-1a4-type-manual-subtitle1')}
- This allows your friends to verify the connection between your Facebook account and your keypair. + {geti18nString('welcome-1a4-type-manual-subtitle2')}

) return ( - Verify Account Ownership + {geti18nString('welcome-1a4-title')} {actionType === 'auto' ? ( ) : ( )} {actionType === 'auto' && bioDisabled && ( - - Sorry, automatically verify your account through bio is not available now. - + {geti18nString('welcome-1a4-bio-disabled')} )} {actionType === 'auto' ? auto : manual} diff --git a/src/components/Welcomes/1b1.tsx b/src/components/Welcomes/1b1.tsx index 44f6e21fb0d1..3a6ef9febca5 100644 --- a/src/components/Welcomes/1b1.tsx +++ b/src/components/Welcomes/1b1.tsx @@ -8,6 +8,7 @@ import { createBox } from '../../utils/components/Flex' import ArrowBack from '@material-ui/icons/ArrowBack' import { useDragAndDrop } from '../../utils/hooks/useDragAndDrop' +import { geti18nString } from '../../utils/i18n' const RestoreBox = createBox(theme => ({ color: theme.palette.text.hint, @@ -73,11 +74,11 @@ export default withStylesTyped(theme =>
- Restore your keypair + {geti18nString('welcome-1b-title')}
data-active={dragStatus === 'drag-enter'} onClick={() => ref.current && ref.current.click()}> {dragStatus === 'drag-enter' - ? 'Drag your key backup into this dialog' + ? geti18nString('welcome-1b-dragging') : fileRef.current - ? `Selected exported key backup: ${fileRef.current.name}` - : 'Select your exported key backup'} + ? geti18nString('welcome-1b-file-selected', fileRef.current.name) + : geti18nString('welcome-1b-no-file-selected')}
diff --git a/src/components/Welcomes/2.tsx b/src/components/Welcomes/2.tsx index 6b9ffb1b7f43..8bc866a0c3eb 100644 --- a/src/components/Welcomes/2.tsx +++ b/src/components/Welcomes/2.tsx @@ -3,6 +3,7 @@ import Paper from '@material-ui/core/Paper/Paper' import Typography from '@material-ui/core/Typography/Typography' import { withStylesTyped } from '../../utils/theme' import createStyles from '@material-ui/core/styles/createStyles' +import { geti18nString } from '../../utils/i18n' interface Props {} export default withStylesTyped(theme => @@ -20,8 +21,8 @@ export default withStylesTyped(theme => )(function Welcome({ classes }) { return ( - You're done! - You can use Maskbook now! + {geti18nString('welcome-2-title')} + {geti18nString('welcome-2-greeting')} ) }) diff --git a/src/components/Welcomes/Banner.tsx b/src/components/Welcomes/Banner.tsx index 0fd732f5bd70..cd3e4c0656c9 100644 --- a/src/components/Welcomes/Banner.tsx +++ b/src/components/Welcomes/Banner.tsx @@ -7,6 +7,7 @@ import { FullWidth } from '../../utils/components/Flex' import IconButton from '@material-ui/core/IconButton/IconButton' import CloseIcon from '@material-ui/icons/Close' import { withStylesTyped } from '../../utils/theme' +import { geti18nString } from '../../utils/i18n' interface Props { getStarted(): void @@ -35,7 +36,7 @@ export const Banner = withStylesTyped({ - Welcome to Maskbook + {geti18nString('banner-title')} diff --git a/src/extension/background-script/CryptoService.ts b/src/extension/background-script/CryptoService.ts index 131928f3feb9..e39f7f29cd11 100644 --- a/src/extension/background-script/CryptoService.ts +++ b/src/extension/background-script/CryptoService.ts @@ -15,6 +15,7 @@ import { } from '../../utils/type-transform/EncodeDecode' import { gun } from '../../key-management/gun' import { constructAlpha40, deconstructPayload } from '../../utils/type-transform/Payload' +import { geti18nString } from '../../utils/i18n' OnlyRunInContext('background', 'EncryptService') //#region Encrypt & Decrypt @@ -28,7 +29,7 @@ async function prepareOthersKeyForEncryption(to: Person[]) { to.map(async person => ({ name: person.username, key: await queryPersonCryptoKey(person.username) })), )).map(person => ({ name: person.name, key: (person.key === null ? null : person.key.key.publicKey)! })) toKey.forEach(x => { - if (x.key === null) throw new Error(`${x.name}'s public key not found!`) + if (x.key === null) throw new Error(geti18nString('service-others-key-not-found', x.name)) }) return toKey } @@ -97,7 +98,7 @@ export async function encryptTo(content: string, to: Person[]): Promise<[Encrypt * @param token Token that returns in the encryptTo */ export async function publishPostAESKey(token: string) { - if (!OthersAESKeyEncryptedMap.has(token)) throw new Error('Publish AES key failed!') + if (!OthersAESKeyEncryptedMap.has(token)) throw new Error(geti18nString('service-publish-post-aes-key-failed')) return publishPostAESKey_Service(token, OthersAESKeyEncryptedMap.get(token)!) } @@ -132,7 +133,7 @@ export async function decryptFrom( return key } const byKey = await getKey(by) - if (!byKey) return { error: `${name}'s public key not found.` } + if (!byKey) return { error: geti18nString('service-others-key-not-found', by) } const mine = (await getMyPrivateKey())! try { const unverified = ['2/4', ownersAESKeyEncrypted, salt, encryptedText].join('|') @@ -161,8 +162,7 @@ export async function decryptFrom( // ? after the auto-share with friends is done. if (aesKeyEncrypted === undefined) { return { - error: - 'Maskbook does not find the key used to decrypt this post. Maybe this post is not intended to share with you?', + error: geti18nString('service-not-share-target'), } } const content = decodeText( @@ -186,11 +186,11 @@ export async function decryptFrom( } catch (e) { if (e instanceof DOMException) { console.error(e) - return { error: 'Decryption failed.' } + return { error: geti18nString('service-decryption-failed') } } else throw e } } - return { error: 'Unknown post version, maybe you should update Maskbook?' } + return { error: geti18nString('service-unknown-payload') } } //#endregion @@ -220,7 +220,7 @@ export async function verifyOthersProve(bio: string, othersName: string) { 'deriveKey', ]) } catch { - throw new Error('Key parse failed') + throw new Error(geti18nString('service-key-parse-failed')) } storeKey({ username: othersName, key: { publicKey: publicKey } }) return publicKey diff --git a/src/extension/background-script/WelcomeService.ts b/src/extension/background-script/WelcomeService.ts index dec59622b20e..d2dd6aa8cf65 100644 --- a/src/extension/background-script/WelcomeService.ts +++ b/src/extension/background-script/WelcomeService.ts @@ -4,6 +4,7 @@ import { encodeText } from '../../utils/type-transform/EncodeDecode' import { getMyLocalKey } from '../../key-management/local-db' import { sleep } from '../../utils/utils' import { regularUsername } from '../../utils/type-transform/Username' +import { geti18nString } from '../../utils/i18n' OnlyRunInContext('background', 'WelcomeService') export async function backupMyKeyPair() { @@ -11,7 +12,7 @@ export async function backupMyKeyPair() { await sleep(1000) const key = await getMyPrivateKey() const localKey = await crypto.subtle.exportKey('jwk', (await getMyLocalKey()).key) - if (!key) throw new TypeError('You have no private key yet') + if (!key) throw new TypeError(geti18nString('service-have-no-own-key-yet')) const keyRecord: CryptoKeyRecord = await toStoreCryptoKey(key) const string = JSON.stringify({ key: keyRecord, local: localKey }) const buffer = encodeText(string) @@ -31,6 +32,7 @@ export async function backupMyKeyPair() { } export async function openWelcomePage(username: string) { - if (!regularUsername(username)) throw new TypeError('Username not valid') + if (!regularUsername(username)) throw new TypeError(geti18nString('service-username-invalid')) + // TODO: move to .open options page api return browser.tabs.create({ url: browser.runtime.getURL('index.html#/welcome?username=' + username) }) } diff --git a/src/extension/content-script/tasks.ts b/src/extension/content-script/tasks.ts index 609a472de3cb..98ae177c986a 100644 --- a/src/extension/content-script/tasks.ts +++ b/src/extension/content-script/tasks.ts @@ -1,5 +1,6 @@ import { AutomatedTabTask, LiveSelector, MutationObserverWatcher, IntervalWatcher } from '@holoflows/kit' import { sleep, dispatchCustomEvents, timeout, untilDocumentReady } from '../../utils/utils' +import { geti18nString } from '../../utils/i18n' const bioCard = new LiveSelector().querySelector('#profile_timeline_intro_card') /** @@ -31,7 +32,7 @@ export async function pasteIntoPostBox(text: string, warningText: string) { if (!dialog.evaluateOnce()[0]) throw new Error('Click not working') } catch (e) { console.warn(e) - if (!dialog.evaluateOnce()[0]) alert('Click the post box please!') + if (!dialog.evaluateOnce()[0]) alert(geti18nString('automation-request-click-post-box')) } console.log('Awaiting dialog') } @@ -97,7 +98,7 @@ export default AutomatedTabTask( await sleep(200) bioEditButton.click() } catch { - alert('Please click the "Edit bio" button or the pencil on the bio box.') + alert(geti18nString('automation-request-click-edit-bio-button')) } await sleep(400) @@ -113,7 +114,7 @@ export default AutomatedTabTask( } catch { console.warn('Text not pasted to the text area') navigator.clipboard.writeText(text) - alert('Your prove content is write to your clipboard. Please paste into the bio input!') + alert(geti18nString('automation-request-paste-into-bio-box')) } }, pasteIntoPostBox, diff --git a/src/extension/options-page/Welcome/index.tsx b/src/extension/options-page/Welcome/index.tsx index 94fe17cc2832..08e77be30fae 100644 --- a/src/extension/options-page/Welcome/index.tsx +++ b/src/extension/options-page/Welcome/index.tsx @@ -12,6 +12,7 @@ import tasks from '../../content-script/tasks' import { RouteComponentProps, withRouter } from 'react-router' import { getProfilePageUrl } from '../../../utils/type-transform/Username' import { setStorage, LATEST_WELCOME_VERSION } from '../../../components/Welcomes/WelcomeVersion' +import { geti18nString } from '../../../utils/i18n' //#region Welcome enum WelcomeState { @@ -54,10 +55,7 @@ const WelcomeActions = { memorable: false, pinned: false, timeout: Infinity, - }).pasteIntoPostBox( - prove, - 'Prove content has been copied into the clipboard!\nHowever, you need to paste it to the post box by yourself.', - ) + }).pasteIntoPostBox(prove, geti18nString('automation-request-paste-into-post-box')) }, manualVerifyBio(userId: string, prove: string) { this.autoVerifyBio(userId, prove) diff --git a/src/index.tsx b/src/index.tsx index 325adda134ef..8a0a8d13d22e 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -6,13 +6,18 @@ import ReactDOM from 'react-dom' import Welcome from './extension/options-page/Welcome' import { MuiThemeProvider } from '@material-ui/core' import { MaskbookLightTheme } from './utils/theme' +import { geti18nString } from './utils/i18n' uiSetup() function App() { return ( - -> Welcome} /> + {geti18nString('options-index-welcome')}} + /> diff --git a/src/key-management/people-gun.ts b/src/key-management/people-gun.ts index 88786d702583..2cf901d4f393 100644 --- a/src/key-management/people-gun.ts +++ b/src/key-management/people-gun.ts @@ -4,6 +4,7 @@ import tasks from '../extension/content-script/tasks' import { verifyOthersProve } from '../extension/background-script/CryptoService' import { sleep } from '../utils/utils' import { getProfilePageUrl, getPostUrl } from '../utils/type-transform/Username' +import { geti18nString } from '../utils/i18n' export async function queryPersonFromGun(username: string) { return gun @@ -44,7 +45,7 @@ export async function addPersonPublicKey(username: string): Promise ) .add('Step 1a-2', () => ) .add('Step 1a-3', () => ) - .add('Step 1a-4', () => ( - - )) .add('New Step 1a-4', () => ( = { + en: getUrl('/_locales/en/messages.json') as any, + zh: getUrl('/_locales/zh/messages.json') as any, + } + const lang = langs[navigator.language.split('-')[0] as any] || langs.en + const string = lang[key] || langs.en[key] + // tslint:disable-next-line: no-parameter-reassignment + if (typeof substitutions === 'string') substitutions = [substitutions] + if (substitutions.length > 2) console.error('Implement this please') + return string.message.replace('$1', substitutions[0]).replace('$2', substitutions[1]) + } +} diff --git a/src/utils/type-transform/Payload.ts b/src/utils/type-transform/Payload.ts index 294e0e5bb1e5..44f17cb82974 100644 --- a/src/utils/type-transform/Payload.ts +++ b/src/utils/type-transform/Payload.ts @@ -1,3 +1,5 @@ +import { geti18nString } from '../i18n' + export interface PayloadAlpha40 { version: -40 ownersAESKeyEncrypted: string @@ -12,15 +14,15 @@ function deconstructAlpha40(str: string, throws = false): PayloadAlpha40 | null // 🎼2/4|ownersAESKeyEncrypted|iv|encryptedText|signature:|| const [_, payloadStart] = str.split('🎼2/4|') if (!payloadStart) - if (throws) throw new Error("Doesn't find payload") + if (throws) throw new Error(geti18nString('payload-not-found')) else return null const [payload, rest] = payloadStart.split(':||') if (rest === undefined) - if (throws) throw new Error('This post is not complete, you need to view the full post.') + if (throws) throw new Error(geti18nString('payload-incomplete')) else return null const [ownersAESKeyEncrypted, iv, encryptedText, signature, ...extra] = payload.split('|') if (!(ownersAESKeyEncrypted && iv && encryptedText)) - if (throws) throw new Error('This post seemed to be corrupted. Maskbook cannot decrypt it') + if (throws) throw new Error(geti18nString('payload-bad')) else return null if (extra.length) console.warn('Found extra payload', extra) return { @@ -34,7 +36,7 @@ function deconstructAlpha40(str: string, throws = false): PayloadAlpha40 | null function deconstructAlpha41(str: string, throws = false): null | never { // 🎼1/4|ownersAESKeyEncrypted|iv|encryptedText|signature:|| if (str.match('🎼1/4') && str.match(':||')) - if (throws) throw new Error('Support for Alpha41 is dropped. Tell your friends to upgrade Maskbook!') + if (throws) throw new Error(geti18nString('payload-throw-in-alpha41')) else return null return null } @@ -50,9 +52,9 @@ export function deconstructPayload(str: string, throws = false): PayloadAlpha40 return ver(str, true) } if (str.match('🎼') && str.match(':||')) - if (throws) throw new TypeError('Unknown post version, maybe you should update Maskbook?') + if (throws) throw new TypeError(geti18nString('service-unknown-payload')) else return null - if (throws) throw new TypeError('Payload not found') + if (throws) throw new TypeError(geti18nString('payload-not-found')) else return null } diff --git a/src/utils/type-transform/Username.ts b/src/utils/type-transform/Username.ts index c8becf6ae41c..baac516c5e8f 100644 --- a/src/utils/type-transform/Username.ts +++ b/src/utils/type-transform/Username.ts @@ -1,3 +1,5 @@ +import { geti18nString } from '../i18n' + /** * @see https://www.facebook.com/help/105399436216001#What-are-the-guidelines-around-creating-a-custom-username? * @unstable @@ -16,7 +18,7 @@ export function regularUsername(name: string) { * Normalize post url */ export function getPostUrl(username: string, postId: string | number) { - if (!regularUsername(username)) throw new TypeError('Username is invalid') + if (!regularUsername(username)) throw new TypeError(geti18nString('service-username-invalid')) if (parseFloat(username)) return `https://www.facebook.com/permalink.php?story_fbid=${postId}&id=${username}` return `https://www.facebook.com/${username}/posts/${postId}` } @@ -24,7 +26,7 @@ export function getPostUrl(username: string, postId: string | number) { * Normalize profile url */ export function getProfilePageUrl(username: string) { - if (!regularUsername(username)) throw new TypeError('Username is invalid!') + if (!regularUsername(username)) throw new TypeError(geti18nString('service-username-invalid')) if (parseFloat(username)) return `https://www.facebook.com/profile.php?id=${username}` return `https://www.facebook.com/${username}?fref=pymk` } diff --git a/tsconfig.json b/tsconfig.json index da17cdd3cdbc..896d9b3328da 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -18,5 +18,5 @@ "incremental": true, "tsBuildInfoFile": "./.tscache/" }, - "include": ["src"] + "include": ["src", "./public/_locales"] } From dec289943986718eb9c1ab3ffff91192ae481a1e Mon Sep 17 00:00:00 2001 From: Jack Works Date: Thu, 23 May 2019 10:47:28 +0800 Subject: [PATCH 2/3] Fix string seperator Signed-off-by: Jack Works --- config-overrides.js | 2 +- public/_locales/en/messages.json | 157 +++++++++--------- public/_locales/zh/messages.json | 157 +++++++++--------- public/manifest.json | 2 +- .../InjectedComponents/AddToKeyStore.tsx | 8 +- .../InjectedComponents/AdditionalPostBox.tsx | 10 +- .../InjectedComponents/DecryptedPost.tsx | 12 +- .../InjectedComponents/SelectPeople.tsx | 8 +- src/components/Welcomes/0.tsx | 18 +- src/components/Welcomes/1a2.tsx | 8 +- src/components/Welcomes/1a3.tsx | 8 +- src/components/Welcomes/1a4.auto.tsx | 14 +- src/components/Welcomes/1a4.v2.tsx | 18 +- src/components/Welcomes/1b1.tsx | 8 +- src/components/Welcomes/2.tsx | 4 +- src/components/Welcomes/Banner.tsx | 6 +- .../background-script/CryptoService.ts | 14 +- .../background-script/WelcomeService.ts | 4 +- src/extension/content-script/tasks.ts | 6 +- src/extension/options-page/Welcome/index.tsx | 2 +- src/index.tsx | 2 +- src/key-management/people-gun.ts | 2 +- src/utils/type-transform/Payload.ts | 12 +- src/utils/type-transform/Username.ts | 4 +- 24 files changed, 246 insertions(+), 240 deletions(-) diff --git a/config-overrides.js b/config-overrides.js index d3e5954ba961..761240892344 100644 --- a/config-overrides.js +++ b/config-overrides.js @@ -25,7 +25,7 @@ module.exports = function override(/** @type{import("webpack").Configuration} */ config.plugins.push( new (require('write-file-webpack-plugin'))({ - test: /(webp|jpg|png|shim|polyfill|js\/.*|index\.html|manifest\.json)/, + test: /(webp|jpg|png|shim|polyfill|js\/.*|index\.html|manifest\.json|_locales)/, }), ) // Write files to /public diff --git a/public/_locales/en/messages.json b/public/_locales/en/messages.json index 660c060ab6bc..d933d325fbae 100644 --- a/public/_locales/en/messages.json +++ b/public/_locales/en/messages.json @@ -1,59 +1,62 @@ { - "additional-post-box--placeholder-w-name": { + "manifest_description": { + "message": "Encrypt your posts & chats on You-Know-Where. Allow only your friends to decrypt." + }, + "additional_post_box__placeholder_w_name": { "message": "Hey $1, what's your mind? Encrypt with Maskbook" }, - "additional-post-box--placeholder-wo-name": { + "additional_post_box__placeholder_wo_name": { "message": "What's your mind? Encrypt with Maskbook" }, - "additional-post-box--post-button": { + "additional_post_box__post_button": { "message": "📫 Post it!" }, - "additional-post-box--encrypted-post-pre": { + "additional_post_box__encrypted_post_pre": { "message": "Decrypt this post with $1" }, - "additional-post-box--encrypted-failed": { + "additional_post_box__encrypted_failed": { "message": "Encrypted text has been copied into the clipboard!\nHowever, you need to paste it to the post box by yourself." }, - "add-to-key-store-success": { + "add_to_key_store_success": { "message": "Maskbook public key added to keystore ✔" }, - "add-to-key-store-verifying": { + "add_to_key_store_verifying": { "message": "Maskbook public key found, verifying..." }, - "add-to-key-store-failed-title": { + "add_to_key_store_failed_title": { "message": "Maskbook public key NOT verified ❌" }, - "add-to-key-store-failed-text": { + "add_to_key_store_failed_text": { "message": "$1\nThis public key won't be saved." }, - "decrypted-postbox-title": { + "decrypted_postbox_title": { "message": "Maskbook decrypted content:" }, - "decrypted-postbox-add-decryptor": { + "decrypted_postbox_add_decryptor": { "message": "Add decryptor" }, - "decrypted-postbox-verified": { + "decrypted_postbox_verified": { "message": "Signature verified ✔" }, - "decrypted-postbox-not-verified": { + "decrypted_postbox_not_verified": { "message": "Signature NOT verified ❌" }, - "decrypted-postbox-decrypting": { + "decrypted_postbox_decrypting": { "message": "Maskbook decrypting..." }, - "decrypted-postbox-failed": { + "decrypted_postbox_failed": { "message": "Maskbook decryption failed" }, - "search-box-placeholder": { + "search_box_placeholder": { "message": "Type here to search" }, - "select-all": { + "select_all": { "message": "Select All" }, - "select-none": { + "select_none": { "message": "Select None" }, - "not-found": { + "not_found": { "message": "Not found" }, "cancel": { @@ -74,178 +77,178 @@ "finish": { "message": "Finish" }, - "welcome-0-close-button": { + "welcome_0_close_button": { "message": "I'll do it later" }, - "welcome-0-title": { + "welcome_0_title": { "message": "Welcome to Maskbook" }, - "welcome-0-description": { + "welcome_0_description": { "message": "You can post on Facebook without allowing Facebook to stalk, analyze, and peep into you." }, - "welcome-0-new-user": { + "welcome_0_new_user": { "message": "New user?" }, - "welcome-0-connect-facebook": { + "welcome_0_connect_facebook": { "message": "Connect Facebook" }, - "welcome-0-old-user": { + "welcome_0_old_user": { "message": "Returning user?" }, - "welcome-0-restore-key": { + "welcome_0_restore_key": { "message": "Restore Keypair" }, - "welcome-0-caption": { + "welcome_0_caption": { "message": "Lost your keypair backup? No worry. Simply start as a new user." }, - "welcome-1a2-title": { + "welcome_1a2_title": { "message": "Encrypt message use this postbox" }, - "welcome-1a2-imgalt": { + "welcome_1a2_imgalt": { "message": "Screenshot of how to encrypt message with Maskbook" }, - "welcome-1a2-description": { + "welcome_1a2_description": { "message": "Then only people you selected with Maskbook can see the post content" }, - "welcome-1a2-done-button": { + "welcome_1a2_done_button": { "message": "Nice!" }, - "welcome-1a3-title": { + "welcome_1a3_title": { "message": "Keep your backups carefully" }, - "welcome-1a3-description1": { + "welcome_1a3_description1": { "message": "The first backup has been put in your Downloads folder." }, - "welcome-1a3-description2": { + "welcome_1a3_description2": { "message": "And export backups frequently!" }, - "welcome-1a3-done-button": { + "welcome_1a3_done_button": { "message": "Got it!" }, - "welcome-1a4-auto-radio-aria": { + "welcome_1a4_auto_radio_aria": { "message": "Choose how to verify your account" }, - "welcome-1a4-auto-profile-title": { + "welcome_1a4_auto_profile_title": { "message": "Add public key to profile" }, - "welcome-1a4-auto-profile-description1": { + "welcome_1a4_auto_profile_description1": { "message": "Easy and lightweight." }, - "welcome-1a4-auto-profile-description2": { + "welcome_1a4_auto_profile_description2": { "message": "Never disturb anyone." }, - "welcome-1a4-auto-post-title": { + "welcome_1a4_auto_post_title": { "message": "Create a verification post" }, - "welcome-1a4-auto-post-description1": { + "welcome_1a4_auto_post_description1": { "message": "We appreciate your valor!" }, - "welcome-1a4-auto-post-description2": { + "welcome_1a4_auto_post_description2": { "message": "Editable after posting." }, - "welcome-1a4-title": { + "welcome_1a4_title": { "message": "Verify Account Ownership" }, - "welcome-1a4-bio-disabled": { + "welcome_1a4_bio_disabled": { "message": "Sorry, automatically verify your account through bio is not available now." }, - "welcome-1a4-type-auto-subtitle1": { + "welcome_1a4_type_auto_subtitle1": { "message": "Avoid any confusion before your first encrypted post." }, - "welcome-1a4-type-auto-subtitle2": { + "welcome_1a4_type_auto_subtitle2": { "message": "This allows your friends to verify the connection between your Facebook account and your keypair." }, - "welcome-1a4-type-auto-switch": { + "welcome_1a4_type_auto_switch": { "message": "Prefer doing it manually?" }, - "welcome-1a4-type-manual-subtitle1": { + "welcome_1a4_type_manual_subtitle1": { "message": "Add this to bio, or post on timeline, before your first encrypted post." }, - "welcome-1a4-type-manual-subtitle2": { + "welcome_1a4_type_manual_subtitle2": { "message": "This allows your friends to verify the connection between your Facebook account and your keypair." }, - "welcome-1a4-type-manual-goto": { + "welcome_1a4_type_manual_goto": { "message": "Copy & Go to Profile" }, - "welcome-1a4-type-manual-switch": { + "welcome_1a4_type_manual_switch": { "message": "Prefer automating the steps?" }, - "welcome-1b-title": { + "welcome_1b_title": { "message": "Restore your keypair" }, - "welcome-1b-dragging": { + "welcome_1b_dragging": { "message": "Drag your key backup into this dialog" }, - "welcome-1b-no-file-selected": { + "welcome_1b_no_file_selected": { "message": "Select your exported key backup" }, - "welcome-1b-file-selected": { + "welcome_1b_file_selected": { "message": "Selected exported key backup: $1" }, - "welcome-2-title": { + "welcome_2_title": { "message": "You're done!" }, - "welcome-2-greeting": { + "welcome_2_greeting": { "message": "You can use Maskbook now!" }, - "banner-title": { + "banner_title": { "message": "Welcome to Maskbook" }, - "banner-get-started": { + "banner_get_started": { "message": "Get started" }, - "banner-dismiss-aria": { + "banner_dismiss_aria": { "message": "Dismiss the banner" }, - "service-others-key-not-found": { + "service_others_key_not_found": { "message": "$1's public key not found!" }, - "service-publish-post-aes-key-failed": { + "service_publish_post_aes_key_failed": { "message": "Publish AES key failed!" }, - "service-not-share-target": { + "service_not_share_target": { "message": "Maskbook does not find the key used to decrypt this post. Maybe this post is not intended to share with you?" }, - "service-decryption-failed": { + "service_decryption_failed": { "message": "Decryption failed." }, - "service-unknown-payload": { + "service_unknown_payload": { "message": "Unknown post version, maybe you should update Maskbook?" }, - "service-key-parse-failed": { + "service_key_parse_failed": { "message": "Key parse failed" }, - "service-have-no-own-key-yet": { + "service_have_no_own_key_yet": { "message": "You have no private key yet" }, - "service-username-invalid": { + "service_username_invalid": { "message": "Username not valid" }, - "automation-request-click-post-box": { + "automation_request_click_post_box": { "message": "Click the post box please!" }, - "automation-request-click-edit-bio-button": { + "automation_request_click_edit_bio_button": { "message": "Please click the \"Edit bio\" button or the pencil on the bio box." }, - "automation-request-paste-into-bio-box": { + "automation_request_paste_into_bio_box": { "message": "Your prove content is write to your clipboard. Please paste into the bio input!" }, - "automation-request-paste-into-post-box": { + "automation_request_paste_into_post_box": { "message": "Prove content has been copied into the clipboard!\nHowever, you need to paste it to the post box by yourself." }, - "payload-not-found": { + "payload_not_found": { "message": "Doesn't find payload" }, - "payload-incomplete": { + "payload_incomplete": { "message": "This post is not complete, you need to view the full post." }, - "payload-bad": { + "payload_bad": { "message": "This post seemed to be corrupted. Maskbook cannot decrypt it." }, - "payload-throw-in-alpha41": { + "payload_throw_in_alpha41": { "message": "Support for Alpha41 is dropped. Tell your friends to upgrade Maskbook!" }, - "options-index-welcome": { + "options_index_welcome": { "message": "First to Maskbook?" } } diff --git a/public/_locales/zh/messages.json b/public/_locales/zh/messages.json index 660c060ab6bc..d933d325fbae 100644 --- a/public/_locales/zh/messages.json +++ b/public/_locales/zh/messages.json @@ -1,59 +1,62 @@ { - "additional-post-box--placeholder-w-name": { + "manifest_description": { + "message": "Encrypt your posts & chats on You-Know-Where. Allow only your friends to decrypt." + }, + "additional_post_box__placeholder_w_name": { "message": "Hey $1, what's your mind? Encrypt with Maskbook" }, - "additional-post-box--placeholder-wo-name": { + "additional_post_box__placeholder_wo_name": { "message": "What's your mind? Encrypt with Maskbook" }, - "additional-post-box--post-button": { + "additional_post_box__post_button": { "message": "📫 Post it!" }, - "additional-post-box--encrypted-post-pre": { + "additional_post_box__encrypted_post_pre": { "message": "Decrypt this post with $1" }, - "additional-post-box--encrypted-failed": { + "additional_post_box__encrypted_failed": { "message": "Encrypted text has been copied into the clipboard!\nHowever, you need to paste it to the post box by yourself." }, - "add-to-key-store-success": { + "add_to_key_store_success": { "message": "Maskbook public key added to keystore ✔" }, - "add-to-key-store-verifying": { + "add_to_key_store_verifying": { "message": "Maskbook public key found, verifying..." }, - "add-to-key-store-failed-title": { + "add_to_key_store_failed_title": { "message": "Maskbook public key NOT verified ❌" }, - "add-to-key-store-failed-text": { + "add_to_key_store_failed_text": { "message": "$1\nThis public key won't be saved." }, - "decrypted-postbox-title": { + "decrypted_postbox_title": { "message": "Maskbook decrypted content:" }, - "decrypted-postbox-add-decryptor": { + "decrypted_postbox_add_decryptor": { "message": "Add decryptor" }, - "decrypted-postbox-verified": { + "decrypted_postbox_verified": { "message": "Signature verified ✔" }, - "decrypted-postbox-not-verified": { + "decrypted_postbox_not_verified": { "message": "Signature NOT verified ❌" }, - "decrypted-postbox-decrypting": { + "decrypted_postbox_decrypting": { "message": "Maskbook decrypting..." }, - "decrypted-postbox-failed": { + "decrypted_postbox_failed": { "message": "Maskbook decryption failed" }, - "search-box-placeholder": { + "search_box_placeholder": { "message": "Type here to search" }, - "select-all": { + "select_all": { "message": "Select All" }, - "select-none": { + "select_none": { "message": "Select None" }, - "not-found": { + "not_found": { "message": "Not found" }, "cancel": { @@ -74,178 +77,178 @@ "finish": { "message": "Finish" }, - "welcome-0-close-button": { + "welcome_0_close_button": { "message": "I'll do it later" }, - "welcome-0-title": { + "welcome_0_title": { "message": "Welcome to Maskbook" }, - "welcome-0-description": { + "welcome_0_description": { "message": "You can post on Facebook without allowing Facebook to stalk, analyze, and peep into you." }, - "welcome-0-new-user": { + "welcome_0_new_user": { "message": "New user?" }, - "welcome-0-connect-facebook": { + "welcome_0_connect_facebook": { "message": "Connect Facebook" }, - "welcome-0-old-user": { + "welcome_0_old_user": { "message": "Returning user?" }, - "welcome-0-restore-key": { + "welcome_0_restore_key": { "message": "Restore Keypair" }, - "welcome-0-caption": { + "welcome_0_caption": { "message": "Lost your keypair backup? No worry. Simply start as a new user." }, - "welcome-1a2-title": { + "welcome_1a2_title": { "message": "Encrypt message use this postbox" }, - "welcome-1a2-imgalt": { + "welcome_1a2_imgalt": { "message": "Screenshot of how to encrypt message with Maskbook" }, - "welcome-1a2-description": { + "welcome_1a2_description": { "message": "Then only people you selected with Maskbook can see the post content" }, - "welcome-1a2-done-button": { + "welcome_1a2_done_button": { "message": "Nice!" }, - "welcome-1a3-title": { + "welcome_1a3_title": { "message": "Keep your backups carefully" }, - "welcome-1a3-description1": { + "welcome_1a3_description1": { "message": "The first backup has been put in your Downloads folder." }, - "welcome-1a3-description2": { + "welcome_1a3_description2": { "message": "And export backups frequently!" }, - "welcome-1a3-done-button": { + "welcome_1a3_done_button": { "message": "Got it!" }, - "welcome-1a4-auto-radio-aria": { + "welcome_1a4_auto_radio_aria": { "message": "Choose how to verify your account" }, - "welcome-1a4-auto-profile-title": { + "welcome_1a4_auto_profile_title": { "message": "Add public key to profile" }, - "welcome-1a4-auto-profile-description1": { + "welcome_1a4_auto_profile_description1": { "message": "Easy and lightweight." }, - "welcome-1a4-auto-profile-description2": { + "welcome_1a4_auto_profile_description2": { "message": "Never disturb anyone." }, - "welcome-1a4-auto-post-title": { + "welcome_1a4_auto_post_title": { "message": "Create a verification post" }, - "welcome-1a4-auto-post-description1": { + "welcome_1a4_auto_post_description1": { "message": "We appreciate your valor!" }, - "welcome-1a4-auto-post-description2": { + "welcome_1a4_auto_post_description2": { "message": "Editable after posting." }, - "welcome-1a4-title": { + "welcome_1a4_title": { "message": "Verify Account Ownership" }, - "welcome-1a4-bio-disabled": { + "welcome_1a4_bio_disabled": { "message": "Sorry, automatically verify your account through bio is not available now." }, - "welcome-1a4-type-auto-subtitle1": { + "welcome_1a4_type_auto_subtitle1": { "message": "Avoid any confusion before your first encrypted post." }, - "welcome-1a4-type-auto-subtitle2": { + "welcome_1a4_type_auto_subtitle2": { "message": "This allows your friends to verify the connection between your Facebook account and your keypair." }, - "welcome-1a4-type-auto-switch": { + "welcome_1a4_type_auto_switch": { "message": "Prefer doing it manually?" }, - "welcome-1a4-type-manual-subtitle1": { + "welcome_1a4_type_manual_subtitle1": { "message": "Add this to bio, or post on timeline, before your first encrypted post." }, - "welcome-1a4-type-manual-subtitle2": { + "welcome_1a4_type_manual_subtitle2": { "message": "This allows your friends to verify the connection between your Facebook account and your keypair." }, - "welcome-1a4-type-manual-goto": { + "welcome_1a4_type_manual_goto": { "message": "Copy & Go to Profile" }, - "welcome-1a4-type-manual-switch": { + "welcome_1a4_type_manual_switch": { "message": "Prefer automating the steps?" }, - "welcome-1b-title": { + "welcome_1b_title": { "message": "Restore your keypair" }, - "welcome-1b-dragging": { + "welcome_1b_dragging": { "message": "Drag your key backup into this dialog" }, - "welcome-1b-no-file-selected": { + "welcome_1b_no_file_selected": { "message": "Select your exported key backup" }, - "welcome-1b-file-selected": { + "welcome_1b_file_selected": { "message": "Selected exported key backup: $1" }, - "welcome-2-title": { + "welcome_2_title": { "message": "You're done!" }, - "welcome-2-greeting": { + "welcome_2_greeting": { "message": "You can use Maskbook now!" }, - "banner-title": { + "banner_title": { "message": "Welcome to Maskbook" }, - "banner-get-started": { + "banner_get_started": { "message": "Get started" }, - "banner-dismiss-aria": { + "banner_dismiss_aria": { "message": "Dismiss the banner" }, - "service-others-key-not-found": { + "service_others_key_not_found": { "message": "$1's public key not found!" }, - "service-publish-post-aes-key-failed": { + "service_publish_post_aes_key_failed": { "message": "Publish AES key failed!" }, - "service-not-share-target": { + "service_not_share_target": { "message": "Maskbook does not find the key used to decrypt this post. Maybe this post is not intended to share with you?" }, - "service-decryption-failed": { + "service_decryption_failed": { "message": "Decryption failed." }, - "service-unknown-payload": { + "service_unknown_payload": { "message": "Unknown post version, maybe you should update Maskbook?" }, - "service-key-parse-failed": { + "service_key_parse_failed": { "message": "Key parse failed" }, - "service-have-no-own-key-yet": { + "service_have_no_own_key_yet": { "message": "You have no private key yet" }, - "service-username-invalid": { + "service_username_invalid": { "message": "Username not valid" }, - "automation-request-click-post-box": { + "automation_request_click_post_box": { "message": "Click the post box please!" }, - "automation-request-click-edit-bio-button": { + "automation_request_click_edit_bio_button": { "message": "Please click the \"Edit bio\" button or the pencil on the bio box." }, - "automation-request-paste-into-bio-box": { + "automation_request_paste_into_bio_box": { "message": "Your prove content is write to your clipboard. Please paste into the bio input!" }, - "automation-request-paste-into-post-box": { + "automation_request_paste_into_post_box": { "message": "Prove content has been copied into the clipboard!\nHowever, you need to paste it to the post box by yourself." }, - "payload-not-found": { + "payload_not_found": { "message": "Doesn't find payload" }, - "payload-incomplete": { + "payload_incomplete": { "message": "This post is not complete, you need to view the full post." }, - "payload-bad": { + "payload_bad": { "message": "This post seemed to be corrupted. Maskbook cannot decrypt it." }, - "payload-throw-in-alpha41": { + "payload_throw_in_alpha41": { "message": "Support for Alpha41 is dropped. Tell your friends to upgrade Maskbook!" }, - "options-index-welcome": { + "options_index_welcome": { "message": "First to Maskbook?" } } diff --git a/public/manifest.json b/public/manifest.json index 45df411059f1..ed0c1203832b 100644 --- a/public/manifest.json +++ b/public/manifest.json @@ -27,6 +27,6 @@ "256": "256x256.png" }, "homepage_url": "https://maskbook.io", - "description": "Encrypt your posts & chats on You-Know-Where. Allow only your friends to decrypt.", + "description": "__MSG_manifest_description__", "default_locale": "en" } diff --git a/src/components/InjectedComponents/AddToKeyStore.tsx b/src/components/InjectedComponents/AddToKeyStore.tsx index d4ef6b964787..9eafda423540 100644 --- a/src/components/InjectedComponents/AddToKeyStore.tsx +++ b/src/components/InjectedComponents/AddToKeyStore.tsx @@ -20,11 +20,11 @@ export function AddToKeyStore({ provePost, postBy }: Props) { ) } export const AddToKeyStoreUI = { - success: , - awaiting: , + success: , + awaiting: , failed: (props: { error: Error }) => ( - - {geti18nString('add-to-key-store-failed-text', props.error.message)} + + {geti18nString('add_to_key_store_failed_text', props.error.message)} {console.error(props.error)} ), diff --git a/src/components/InjectedComponents/AdditionalPostBox.tsx b/src/components/InjectedComponents/AdditionalPostBox.tsx index bab27675733e..a0d4d88ebfce 100644 --- a/src/components/InjectedComponents/AdditionalPostBox.tsx +++ b/src/components/InjectedComponents/AdditionalPostBox.tsx @@ -61,8 +61,8 @@ export const AdditionalPostBoxUI = withStylesTyped({ multiline placeholder={geti18nString( myself.nickname - ? 'additional-post-box--placeholder-w-name' - : 'additional-post-box--placeholder-wo-name', + ? 'additional_post_box__placeholder_w_name' + : 'additional_post_box__placeholder_wo_name', myself.nickname, )} /> @@ -83,7 +83,7 @@ export const AdditionalPostBoxUI = withStylesTyped({ color="primary" className={classes.button} disabled={!(selectedPeople.length && text)}> - {geti18nString('additional-post-box--post-button')} + {geti18nString('additional_post_box__post_button')} @@ -101,8 +101,8 @@ export function AdditionalPostBox() { useAsync(() => Services.People.queryAvatar(username || ''), []).then(setAvatar) const onRequestPost = React.useCallback(async (people, text) => { const [encrypted, token] = await Services.Crypto.encryptTo(text, people) - const fullPost = geti18nString('additional-post-box--encrypted-post-pre', encrypted) - pasteIntoPostBox(fullPost, geti18nString('additional-post-box--encrypted-failed')) + const fullPost = geti18nString('additional_post_box__encrypted_post_pre', encrypted) + pasteIntoPostBox(fullPost, geti18nString('additional_post_box__encrypted_failed')) Services.Crypto.publishPostAESKey(token) }, []) if (!username) { diff --git a/src/components/InjectedComponents/DecryptedPost.tsx b/src/components/InjectedComponents/DecryptedPost.tsx index 6f277635bc32..4c1654316830 100644 --- a/src/components/InjectedComponents/DecryptedPost.tsx +++ b/src/components/InjectedComponents/DecryptedPost.tsx @@ -28,17 +28,17 @@ const DecryptPostSuccess = withStylesTyped({ title={ <> {ShareMenu} - {geti18nString('decrypted-postbox-title')} + {geti18nString('decrypted_postbox_title')} {props.displayAppendDecryptor ? ( - {geti18nString('decrypted-postbox-add-decryptor')} + {geti18nString('decrypted_postbox_add_decryptor')} ) : null} {data.signatureVerifyResult ? ( - {geti18nString('decrypted-postbox-verified')} + {geti18nString('decrypted_postbox_verified')} ) : ( - {geti18nString('decrypted-postbox-not-verified')} + {geti18nString('decrypted_postbox_not_verified')} )} } @@ -53,10 +53,10 @@ const DecryptPostSuccess = withStylesTyped({ ) }) -const DecryptPostAwaiting = +const DecryptPostAwaiting = function DecryptPostFailed({ error }: { error: Error }) { return ( - + {error && error.message} ) diff --git a/src/components/InjectedComponents/SelectPeople.tsx b/src/components/InjectedComponents/SelectPeople.tsx index cd1b2368b1e2..6b5b1012d3a9 100644 --- a/src/components/InjectedComponents/SelectPeople.tsx +++ b/src/components/InjectedComponents/SelectPeople.tsx @@ -102,7 +102,7 @@ export const SelectPeopleUI = withStylesTyped({ onSetSelected(selected.slice(0, selected.length - 1)) } }} - placeholder={disabled ? '' : geti18nString('search-box-placeholder')} + placeholder={disabled ? '' : geti18nString('search_box_placeholder')} disabled={disabled} /> @@ -115,12 +115,12 @@ export const SelectPeopleUI = withStylesTyped({ className={classes.button} color="primary" onClick={() => onSetSelected([...selected, ...listAfterSearch])}> - {geti18nString('select-all')} + {geti18nString('select_all')} )} {selected.length > 0 && ( )} @@ -133,7 +133,7 @@ export const SelectPeopleUI = withStylesTyped({ {listBeforeSearch.length > 0 && listBeforeSearch.length === 0 && ( - + )} {listAfterSearch.map(p => ( diff --git a/src/components/Welcomes/0.tsx b/src/components/Welcomes/0.tsx index 7f5e5b5f9b3f..7735e76e53b6 100644 --- a/src/components/Welcomes/0.tsx +++ b/src/components/Welcomes/0.tsx @@ -63,32 +63,32 @@ export default withStylesTyped(theme =>
- {geti18nString('welcome-0-title')} + {geti18nString('welcome_0_title')} - {geti18nString('welcome-0-description')} + {geti18nString('welcome_0_description')} - {geti18nString('welcome-0-new-user')} - {geti18nString('welcome-0-connect-facebook')} + {geti18nString('welcome_0_new_user')} + {geti18nString('welcome_0_connect_facebook')} - {geti18nString('welcome-0-old-user')} - {geti18nString('welcome-0-restore-key')} + {geti18nString('welcome_0_old_user')} + {geti18nString('welcome_0_restore_key')}
diff --git a/src/components/Welcomes/1a2.tsx b/src/components/Welcomes/1a2.tsx index 8ebcbb6961b5..ba79fddeecc3 100644 --- a/src/components/Welcomes/1a2.tsx +++ b/src/components/Welcomes/1a2.tsx @@ -32,16 +32,16 @@ export default withStylesTyped(theme => )(function Welcome({ classes, next }) { return ( - {geti18nString('welcome-1a2-title')} + {geti18nString('welcome_1a2_title')} {geti18nString('welcome-1a2-imgalt')} - {geti18nString('welcome-1a2-description')} + {geti18nString('welcome_1a2_description')} ) diff --git a/src/components/Welcomes/1a3.tsx b/src/components/Welcomes/1a3.tsx index d34f52a6f6df..67b0f388ba51 100644 --- a/src/components/Welcomes/1a3.tsx +++ b/src/components/Welcomes/1a3.tsx @@ -31,16 +31,16 @@ export default withStylesTyped(theme => const filename = `maskbook-keystore-backup-${today}.json` return ( - {geti18nString('welcome-1a3-title')} + {geti18nString('welcome_1a3_title')} {filename} - {geti18nString('welcome-1a3-description1')} + {geti18nString('welcome_1a3_description1')}
- {geti18nString('welcome-1a3-description2')} + {geti18nString('welcome_1a3_description2')}
) diff --git a/src/components/Welcomes/1a4.auto.tsx b/src/components/Welcomes/1a4.auto.tsx index b17fa179fc20..b29277003822 100644 --- a/src/components/Welcomes/1a4.auto.tsx +++ b/src/components/Welcomes/1a4.auto.tsx @@ -62,7 +62,7 @@ export default withStylesTyped(theme => setType(v as any)}> label={ } @@ -90,12 +90,12 @@ export default withStylesTyped(theme => label={ } diff --git a/src/components/Welcomes/1a4.v2.tsx b/src/components/Welcomes/1a4.v2.tsx index 241cdaac8dc2..493eca62c971 100644 --- a/src/components/Welcomes/1a4.v2.tsx +++ b/src/components/Welcomes/1a4.v2.tsx @@ -42,45 +42,45 @@ export default withStylesTyped(theme => const auto = ( <> - {geti18nString('welcome-1a4-type-auto-subtitle1')} + {geti18nString('welcome_1a4_type_auto_subtitle1')}
- {geti18nString('welcome-1a4-type-auto-subtitle2')} + {geti18nString('welcome_1a4_type_auto_subtitle2')}

) const manual = ( <> - {geti18nString('welcome-1a4-type-manual-subtitle1')} + {geti18nString('welcome_1a4_type_manual_subtitle1')}
- {geti18nString('welcome-1a4-type-manual-subtitle2')} + {geti18nString('welcome_1a4_type_manual_subtitle2')}

) return ( - {geti18nString('welcome-1a4-title')} + {geti18nString('welcome_1a4_title')} {actionType === 'auto' ? ( ) : ( )} {actionType === 'auto' && bioDisabled && ( - {geti18nString('welcome-1a4-bio-disabled')} + {geti18nString('welcome_1a4_bio_disabled')} )} {actionType === 'auto' ? auto : manual} diff --git a/src/components/Welcomes/1b1.tsx b/src/components/Welcomes/1b1.tsx index 3a6ef9febca5..dd5def77c081 100644 --- a/src/components/Welcomes/1b1.tsx +++ b/src/components/Welcomes/1b1.tsx @@ -78,7 +78,7 @@ export default withStylesTyped(theme =>
- {geti18nString('welcome-1b-title')} + {geti18nString('welcome_1b_title')}
data-active={dragStatus === 'drag-enter'} onClick={() => ref.current && ref.current.click()}> {dragStatus === 'drag-enter' - ? geti18nString('welcome-1b-dragging') + ? geti18nString('welcome_1b_dragging') : fileRef.current - ? geti18nString('welcome-1b-file-selected', fileRef.current.name) - : geti18nString('welcome-1b-no-file-selected')} + ? geti18nString('welcome_1b_file_selected', fileRef.current.name) + : geti18nString('welcome_1b_no_file_selected')}
diff --git a/src/extension/background-script/CryptoService.ts b/src/extension/background-script/CryptoService.ts index e39f7f29cd11..de76f2f0c58f 100644 --- a/src/extension/background-script/CryptoService.ts +++ b/src/extension/background-script/CryptoService.ts @@ -29,7 +29,7 @@ async function prepareOthersKeyForEncryption(to: Person[]) { to.map(async person => ({ name: person.username, key: await queryPersonCryptoKey(person.username) })), )).map(person => ({ name: person.name, key: (person.key === null ? null : person.key.key.publicKey)! })) toKey.forEach(x => { - if (x.key === null) throw new Error(geti18nString('service-others-key-not-found', x.name)) + if (x.key === null) throw new Error(geti18nString('service_others_key_not_found', x.name)) }) return toKey } @@ -98,7 +98,7 @@ export async function encryptTo(content: string, to: Person[]): Promise<[Encrypt * @param token Token that returns in the encryptTo */ export async function publishPostAESKey(token: string) { - if (!OthersAESKeyEncryptedMap.has(token)) throw new Error(geti18nString('service-publish-post-aes-key-failed')) + if (!OthersAESKeyEncryptedMap.has(token)) throw new Error(geti18nString('service_publish_post_aes_key_failed')) return publishPostAESKey_Service(token, OthersAESKeyEncryptedMap.get(token)!) } @@ -133,7 +133,7 @@ export async function decryptFrom( return key } const byKey = await getKey(by) - if (!byKey) return { error: geti18nString('service-others-key-not-found', by) } + if (!byKey) return { error: geti18nString('service_others_key_not_found', by) } const mine = (await getMyPrivateKey())! try { const unverified = ['2/4', ownersAESKeyEncrypted, salt, encryptedText].join('|') @@ -162,7 +162,7 @@ export async function decryptFrom( // ? after the auto-share with friends is done. if (aesKeyEncrypted === undefined) { return { - error: geti18nString('service-not-share-target'), + error: geti18nString('service_not_share_target'), } } const content = decodeText( @@ -186,11 +186,11 @@ export async function decryptFrom( } catch (e) { if (e instanceof DOMException) { console.error(e) - return { error: geti18nString('service-decryption-failed') } + return { error: geti18nString('service_decryption_failed') } } else throw e } } - return { error: geti18nString('service-unknown-payload') } + return { error: geti18nString('service_unknown_payload') } } //#endregion @@ -220,7 +220,7 @@ export async function verifyOthersProve(bio: string, othersName: string) { 'deriveKey', ]) } catch { - throw new Error(geti18nString('service-key-parse-failed')) + throw new Error(geti18nString('service_key_parse_failed')) } storeKey({ username: othersName, key: { publicKey: publicKey } }) return publicKey diff --git a/src/extension/background-script/WelcomeService.ts b/src/extension/background-script/WelcomeService.ts index d2dd6aa8cf65..840d1aafa815 100644 --- a/src/extension/background-script/WelcomeService.ts +++ b/src/extension/background-script/WelcomeService.ts @@ -12,7 +12,7 @@ export async function backupMyKeyPair() { await sleep(1000) const key = await getMyPrivateKey() const localKey = await crypto.subtle.exportKey('jwk', (await getMyLocalKey()).key) - if (!key) throw new TypeError(geti18nString('service-have-no-own-key-yet')) + if (!key) throw new TypeError(geti18nString('service_have_no_own_key_yet')) const keyRecord: CryptoKeyRecord = await toStoreCryptoKey(key) const string = JSON.stringify({ key: keyRecord, local: localKey }) const buffer = encodeText(string) @@ -32,7 +32,7 @@ export async function backupMyKeyPair() { } export async function openWelcomePage(username: string) { - if (!regularUsername(username)) throw new TypeError(geti18nString('service-username-invalid')) + if (!regularUsername(username)) throw new TypeError(geti18nString('service_username_invalid')) // TODO: move to .open options page api return browser.tabs.create({ url: browser.runtime.getURL('index.html#/welcome?username=' + username) }) } diff --git a/src/extension/content-script/tasks.ts b/src/extension/content-script/tasks.ts index 98ae177c986a..7235dcca86bf 100644 --- a/src/extension/content-script/tasks.ts +++ b/src/extension/content-script/tasks.ts @@ -32,7 +32,7 @@ export async function pasteIntoPostBox(text: string, warningText: string) { if (!dialog.evaluateOnce()[0]) throw new Error('Click not working') } catch (e) { console.warn(e) - if (!dialog.evaluateOnce()[0]) alert(geti18nString('automation-request-click-post-box')) + if (!dialog.evaluateOnce()[0]) alert(geti18nString('automation_request_click_post_box')) } console.log('Awaiting dialog') } @@ -98,7 +98,7 @@ export default AutomatedTabTask( await sleep(200) bioEditButton.click() } catch { - alert(geti18nString('automation-request-click-edit-bio-button')) + alert(geti18nString('automation_request_click_edit_bio_button')) } await sleep(400) @@ -114,7 +114,7 @@ export default AutomatedTabTask( } catch { console.warn('Text not pasted to the text area') navigator.clipboard.writeText(text) - alert(geti18nString('automation-request-paste-into-bio-box')) + alert(geti18nString('automation_request_paste_into_bio_box')) } }, pasteIntoPostBox, diff --git a/src/extension/options-page/Welcome/index.tsx b/src/extension/options-page/Welcome/index.tsx index 08e77be30fae..9745544428ae 100644 --- a/src/extension/options-page/Welcome/index.tsx +++ b/src/extension/options-page/Welcome/index.tsx @@ -55,7 +55,7 @@ const WelcomeActions = { memorable: false, pinned: false, timeout: Infinity, - }).pasteIntoPostBox(prove, geti18nString('automation-request-paste-into-post-box')) + }).pasteIntoPostBox(prove, geti18nString('automation_request_paste_into_post_box')) }, manualVerifyBio(userId: string, prove: string) { this.autoVerifyBio(userId, prove) diff --git a/src/index.tsx b/src/index.tsx index 8a0a8d13d22e..7960e2fbe79c 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -16,7 +16,7 @@ function App() { {geti18nString('options-index-welcome')}} + component={() => {geti18nString('options_index_welcome')}} /> diff --git a/src/key-management/people-gun.ts b/src/key-management/people-gun.ts index 2cf901d4f393..254b9dbf60ca 100644 --- a/src/key-management/people-gun.ts +++ b/src/key-management/people-gun.ts @@ -45,7 +45,7 @@ export async function addPersonPublicKey(username: string): Promise Date: Thu, 23 May 2019 08:06:53 +0000 Subject: [PATCH 3/3] added zh-hant translation --- public/_locales/zh/messages.json | 166 +++++++++++++++---------------- 1 file changed, 83 insertions(+), 83 deletions(-) diff --git a/public/_locales/zh/messages.json b/public/_locales/zh/messages.json index d933d325fbae..b1a840556ed4 100644 --- a/public/_locales/zh/messages.json +++ b/public/_locales/zh/messages.json @@ -1,254 +1,254 @@ { "manifest_description": { - "message": "Encrypt your posts & chats on You-Know-Where. Allow only your friends to decrypt." + "message": "在臉書發佈加密訊息,只讓你的朋友閱讀。" }, "additional_post_box__placeholder_w_name": { - "message": "Hey $1, what's your mind? Encrypt with Maskbook" + "message": "Hey $1, 有何所思?用 Maskbook 加密分享。" }, "additional_post_box__placeholder_wo_name": { - "message": "What's your mind? Encrypt with Maskbook" + "message": "有何所思?用 Maskbook 加密分享。" }, "additional_post_box__post_button": { - "message": "📫 Post it!" + "message": "現在發佈!" }, "additional_post_box__encrypted_post_pre": { - "message": "Decrypt this post with $1" + "message": "使用 $1 來解密這個訊息" }, "additional_post_box__encrypted_failed": { - "message": "Encrypted text has been copied into the clipboard!\nHowever, you need to paste it to the post box by yourself." + "message": "加密文本已經拷貝至剪貼板!\n不過,你需要手動粘貼到發佈框。" }, "add_to_key_store_success": { - "message": "Maskbook public key added to keystore ✔" + "message": "Maskbook 已獲取此公鑰並添加至本地 ✔" }, "add_to_key_store_verifying": { - "message": "Maskbook public key found, verifying..." + "message": "Maskbook 公鑰已獲取,驗證中…" }, "add_to_key_store_failed_title": { - "message": "Maskbook public key NOT verified ❌" + "message": "Maskbook 公鑰驗證失敗 ❌" }, "add_to_key_store_failed_text": { - "message": "$1\nThis public key won't be saved." + "message": "$1\n這個公鑰不會被相信。" }, "decrypted_postbox_title": { - "message": "Maskbook decrypted content:" + "message": "Maskbook 解密出的文本:" }, "decrypted_postbox_add_decryptor": { - "message": "Add decryptor" + "message": "添加解密權限者:" }, "decrypted_postbox_verified": { - "message": "Signature verified ✔" + "message": "數字簽名驗證成功 ✔" }, "decrypted_postbox_not_verified": { - "message": "Signature NOT verified ❌" + "message": "數字簽名驗證失敗,對方可能被駭了 ❌" }, "decrypted_postbox_decrypting": { - "message": "Maskbook decrypting..." + "message": "Maskbook 解密中…" }, "decrypted_postbox_failed": { - "message": "Maskbook decryption failed" + "message": "Maskbook 解密失敗" }, "search_box_placeholder": { - "message": "Type here to search" + "message": "鍵入以搜尋" }, "select_all": { - "message": "Select All" + "message": "選取全部" }, "select_none": { - "message": "Select None" + "message": "全部取消選取" }, "not_found": { - "message": "Not found" + "message": "找不到" }, "cancel": { - "message": "Cancel" + "message": "取消" }, "sharing": { - "message": "Sharing" + "message": "分享" }, "share": { - "message": "Share" + "message": "分享" }, "restore": { - "message": "Restore" + "message": "恢復" }, "back": { - "message": "Back" + "message": "返回" }, "finish": { - "message": "Finish" + "message": "完成" }, "welcome_0_close_button": { - "message": "I'll do it later" + "message": "我想以後再做" }, "welcome_0_title": { - "message": "Welcome to Maskbook" + "message": "歡迎使用 Maskbook" }, "welcome_0_description": { - "message": "You can post on Facebook without allowing Facebook to stalk, analyze, and peep into you." + "message": "從此無需擔心 Facebook 追蹤、分析、窺視你的數字生活" }, "welcome_0_new_user": { - "message": "New user?" + "message": "新用戶?" }, "welcome_0_connect_facebook": { - "message": "Connect Facebook" + "message": "連接 Facebook 賬號" }, "welcome_0_old_user": { - "message": "Returning user?" + "message": "老用戶?" }, "welcome_0_restore_key": { - "message": "Restore Keypair" + "message": "導入備份檔案" }, "welcome_0_caption": { - "message": "Lost your keypair backup? No worry. Simply start as a new user." + "message": "弄丟了備份檔案?不用擔心,當作自己是新用戶即可。" }, "welcome_1a2_title": { - "message": "Encrypt message use this postbox" + "message": "使用這個輸入框來加密" }, "welcome_1a2_imgalt": { - "message": "Screenshot of how to encrypt message with Maskbook" + "message": "關於如何使用 Maskbook 加密的截圖" }, "welcome_1a2_description": { - "message": "Then only people you selected with Maskbook can see the post content" + "message": "這樣,只有你選中的好友才能解密這條訊息" }, "welcome_1a2_done_button": { - "message": "Nice!" + "message": "棒耶!" }, "welcome_1a3_title": { - "message": "Keep your backups carefully" + "message": "請妥善保管備份檔案" }, "welcome_1a3_description1": { - "message": "The first backup has been put in your Downloads folder." + "message": "第一個備份檔案已經放在「下載」文件夾。" }, "welcome_1a3_description2": { - "message": "And export backups frequently!" + "message": "記得經常創建新備份!" }, "welcome_1a3_done_button": { - "message": "Got it!" + "message": "瞭解!" }, "welcome_1a4_auto_radio_aria": { - "message": "Choose how to verify your account" + "message": "選擇賬號歸屬權驗證手段" }, "welcome_1a4_auto_profile_title": { - "message": "Add public key to profile" + "message": "添加公鑰到個人簡介" }, "welcome_1a4_auto_profile_description1": { - "message": "Easy and lightweight." + "message": "簡潔高效" }, "welcome_1a4_auto_profile_description2": { - "message": "Never disturb anyone." + "message": "不會打擾到任何人" }, "welcome_1a4_auto_post_title": { - "message": "Create a verification post" + "message": "發佈一個聲明訊息" }, "welcome_1a4_auto_post_description1": { - "message": "We appreciate your valor!" + "message": "我們感謝你的支持" }, "welcome_1a4_auto_post_description2": { - "message": "Editable after posting." + "message": "你可以調整文本措辭" }, "welcome_1a4_title": { - "message": "Verify Account Ownership" + "message": "驗證賬號歸屬權" }, "welcome_1a4_bio_disabled": { - "message": "Sorry, automatically verify your account through bio is not available now." + "message": "由於技術問題,此驗證方式暫時不可用。" }, "welcome_1a4_type_auto_subtitle1": { - "message": "Avoid any confusion before your first encrypted post." + "message": "避免好友感到迷惑" }, "welcome_1a4_type_auto_subtitle2": { - "message": "This allows your friends to verify the connection between your Facebook account and your keypair." + "message": "這使得你的好友能夠驗證你的 Facebook 賬號與你的 Maskbook 公鑰都屬於你。" }, "welcome_1a4_type_auto_switch": { - "message": "Prefer doing it manually?" + "message": "更願意手動操作?" }, "welcome_1a4_type_manual_subtitle1": { - "message": "Add this to bio, or post on timeline, before your first encrypted post." + "message": "將這串文本添加到個人簡介或分享到時間線,在發佈第一條加密訊息之前。" }, "welcome_1a4_type_manual_subtitle2": { - "message": "This allows your friends to verify the connection between your Facebook account and your keypair." + "message": "這使得你的好友能夠驗證你的 Facebook 賬號與你的 Maskbook 公鑰都屬於你。" }, "welcome_1a4_type_manual_goto": { - "message": "Copy & Go to Profile" + "message": "拷貝並跳轉到個人簡介" }, "welcome_1a4_type_manual_switch": { - "message": "Prefer automating the steps?" + "message": "更願意讓 Maskbook 代勞?" }, "welcome_1b_title": { - "message": "Restore your keypair" + "message": "導入備份檔案" }, "welcome_1b_dragging": { - "message": "Drag your key backup into this dialog" + "message": "將備份檔案拖拽到此處" }, "welcome_1b_no_file_selected": { - "message": "Select your exported key backup" + "message": "選取備份檔案" }, "welcome_1b_file_selected": { - "message": "Selected exported key backup: $1" + "message": "已選取備份檔案:$1" }, "welcome_2_title": { - "message": "You're done!" + "message": "完畢!" }, "welcome_2_greeting": { - "message": "You can use Maskbook now!" + "message": "你現在可以使用 Maskbook 了!" }, "banner_title": { - "message": "Welcome to Maskbook" + "message": "歡迎使用 Maskbook" }, "banner_get_started": { - "message": "Get started" + "message": "開始使用" }, "banner_dismiss_aria": { - "message": "Dismiss the banner" + "message": "關閉消息" }, "service_others_key_not_found": { - "message": "$1's public key not found!" + "message": "$1 的公鑰無法找到!" }, "service_publish_post_aes_key_failed": { - "message": "Publish AES key failed!" + "message": "未能發佈 AES 密鑰。" }, "service_not_share_target": { - "message": "Maskbook does not find the key used to decrypt this post. Maybe this post is not intended to share with you?" + "message": "找不到 AES 密鑰。或許這條訊息不是分享給你的?" }, "service_decryption_failed": { - "message": "Decryption failed." + "message": "解密失敗。" }, "service_unknown_payload": { - "message": "Unknown post version, maybe you should update Maskbook?" + "message": "不支持的訊息構造。或許你需要更新 Maskbook 版本了?" }, "service_key_parse_failed": { "message": "Key parse failed" }, "service_have_no_own_key_yet": { - "message": "You have no private key yet" + "message": "你還沒有私鑰" }, "service_username_invalid": { - "message": "Username not valid" + "message": "無效用戶名" }, "automation_request_click_post_box": { - "message": "Click the post box please!" + "message": "請點擊發佈框" }, "automation_request_click_edit_bio_button": { - "message": "Please click the \"Edit bio\" button or the pencil on the bio box." + "message": "請點擊「編輯簡介」按鈕或簡介旁的鉛筆圖標" }, "automation_request_paste_into_bio_box": { - "message": "Your prove content is write to your clipboard. Please paste into the bio input!" + "message": "已將公鑰拷貝至剪貼板,可以直接粘貼到輸入框。" }, "automation_request_paste_into_post_box": { - "message": "Prove content has been copied into the clipboard!\nHowever, you need to paste it to the post box by yourself." + "message": "已將公鑰拷貝至剪貼板,可以直接粘貼到輸入框。" }, "payload_not_found": { - "message": "Doesn't find payload" + "message": "找不到 payload" }, "payload_incomplete": { - "message": "This post is not complete, you need to view the full post." + "message": "不完整的 payload。請點擊「查看全文」。" }, "payload_bad": { - "message": "This post seemed to be corrupted. Maskbook cannot decrypt it." + "message": "Payload 可能遭到了篡改。" }, "payload_throw_in_alpha41": { - "message": "Support for Alpha41 is dropped. Tell your friends to upgrade Maskbook!" + "message": "已經不再支持 Alpha41。請提醒對方安裝新版 Maskbook。" }, "options_index_welcome": { - "message": "First to Maskbook?" + "message": "首次來到 Maskbook?" } }