diff --git a/src/_locales/en/messages.json b/src/_locales/en/messages.json index 7abe82470ef..44f12b9c4dc 100644 --- a/src/_locales/en/messages.json +++ b/src/_locales/en/messages.json @@ -90,13 +90,13 @@ "message": "Welcome to Maskbook" }, "welcome_0_description": { - "message": "You can post on Facebook without allowing Facebook to stalk, analyze, or spy on you." + "message": "You can post on social networks without allowing them to stalk, analyze, or spy on you." }, "welcome_0_new_user": { "message": "New user?" }, - "welcome_0_connect_facebook": { - "message": "Connect Facebook" + "welcome_0_connect_maskbook": { + "message": "Setup Maskbook" }, "welcome_0_old_user": { "message": "Returning user?" @@ -107,6 +107,15 @@ "welcome_0_caption": { "message": "Lost your keypair backup? No worry. Simply start as a new user." }, + "welcome_1a1_title": { + "message": "Setup which account?" + }, + "welcome_1a1_next": { + "message": "Next" + }, + "welcome_1a1_didntfind": { + "message": "Didn't find your account?" + }, "welcome_1a2_title": { "message": "Encrypt message in a Maskbook postbox" }, @@ -162,7 +171,7 @@ "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." + "message": "This allows your friends to verify the connection between your social network account and your keypair." }, "welcome_1a4_type_auto_switch": { "message": "Prefer doing it manually?" @@ -171,7 +180,7 @@ "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." + "message": "This allows your friends to verify the connection between your social network account and your keypair." }, "welcome_1a4_type_manual_goto": { "message": "Copy & Go to Profile" diff --git a/src/_locales/zh/messages.json b/src/_locales/zh/messages.json index e170ca819c4..415c19963a9 100644 --- a/src/_locales/zh/messages.json +++ b/src/_locales/zh/messages.json @@ -91,13 +91,13 @@ "message": "歡迎使用 Maskbook" }, "welcome_0_description": { - "message": "從此無需擔心 Facebook 追蹤、分析、窺視你的數字生活" + "message": "從此無需擔心社交網路追蹤、分析、窺視你的數字生活" }, "welcome_0_new_user": { "message": "新用戶?" }, - "welcome_0_connect_facebook": { - "message": "連接 Facebook 賬號" + "welcome_0_connect_maskbook": { + "message": "設置 Maskbook 賬號" }, "welcome_0_old_user": { "message": "老用戶?" @@ -108,6 +108,15 @@ "welcome_0_caption": { "message": "弄丟了備份檔案?不用擔心,當作自己是新用戶即可。" }, + "welcome_1a1_title": { + "message": "你希望為哪個賬戶設定 Maskbook?" + }, + "welcome_1a1_next": { + "message": "確認" + }, + "welcome_1a1_didntfind": { + "message": "沒有找到你的賬戶?" + }, "welcome_1a2_title": { "message": "使用 Maskbook 的輸入框來加密" }, @@ -163,7 +172,7 @@ "message": "避免好友感到迷惑" }, "welcome_1a4_type_auto_subtitle2": { - "message": "這使得你的好友能夠驗證你的 Facebook 賬號與你的 Maskbook 公鑰都屬於你。" + "message": "這使得你的好友能夠驗證你的社交網路賬號與你的 Maskbook 公鑰都屬於你。" }, "welcome_1a4_type_auto_switch": { "message": "更願意手動操作?" @@ -172,7 +181,7 @@ "message": "將這串文本添加到個人簡介或分享到時間線,在發佈第一條加密訊息之前。" }, "welcome_1a4_type_manual_subtitle2": { - "message": "這使得你的好友能夠驗證你的 Facebook 賬號與你的 Maskbook 公鑰都屬於你。" + "message": "這使得你的好友能夠驗證你的社交網路賬號與你的 Maskbook 公鑰都屬於你。" }, "welcome_1a4_type_manual_goto": { "message": "拷貝並跳轉到個人簡介" diff --git a/src/components/InjectedComponents/SelectPeople.tsx b/src/components/InjectedComponents/SelectPeople.tsx index 6f797861c0b..ff6e537ed3b 100644 --- a/src/components/InjectedComponents/SelectPeople.tsx +++ b/src/components/InjectedComponents/SelectPeople.tsx @@ -20,27 +20,38 @@ interface PeopleInListProps { person: Person onClick(): void disabled?: boolean + showAtNetwork?: boolean } -const usePeopleInListStyle = makeStyles({ +const usePeopleInListStyle = makeStyles(theme => ({ overflow: { textOverflow: 'ellipsis', whiteSpace: 'nowrap', overflow: 'hidden', }, -}) + networkHint: { + color: theme.palette.grey[500], + }, +})) /** * Item in the list */ -function PersonInList({ person, onClick, disabled }: PeopleInListProps) { +function PersonInList({ person, onClick, disabled, showAtNetwork }: PeopleInListProps) { const classes = usePeopleInListStyle() + const name = person.nickname || person.identifier.userId + const withNetwork = ( + <> + {name} + @ {person.identifier.network} + + ) return ( - + @@ -63,13 +74,18 @@ function PersonInChip({ disabled, onDelete, person }: PersonInChipProps) { /> ) } -interface SelectPeopleUI { +interface SelectPeopleUIProps { ignoreMyself?: boolean people: Person[] selected: Person[] frozenSelected: Person[] onSetSelected: (selected: Person[]) => void disabled?: boolean + hideSelectAll?: boolean + hideSelectNone?: boolean + showAtNetwork?: boolean + maxSelection?: number + classes?: Partial> } const useStyles = makeStyles({ paper: { maxWidth: 500 }, @@ -82,8 +98,9 @@ const useStyles = makeStyles({ input: { flex: 1 }, button: { marginLeft: 8, padding: '2px 6px' }, }) -export function SelectPeopleUI(props: SelectPeopleUI) { +export function SelectPeopleUI(props: SelectPeopleUIProps) { const { people, frozenSelected, onSetSelected, selected, disabled, ignoreMyself } = props + const { hideSelectAll, hideSelectNone, showAtNetwork, maxSelection, classes: classesProp = {} } = props const classes = useStyles() const myself = useContext(CurrentUsingIdentityContext) @@ -113,8 +130,12 @@ export function SelectPeopleUI(props: SelectPeopleUI) { {geti18nString('select_none')} ) + + const showSelectAll = !hideSelectAll && listAfterSearch.length > 0 && typeof maxSelection === 'undefined' + const showSelectNone = !hideSelectNone && selected.length > 0 + return ( - <> +
{frozenSelected.map(FrozenChip)} {selected.map(RemovableChip)} @@ -131,38 +152,39 @@ export function SelectPeopleUI(props: SelectPeopleUI) { disabled={disabled} /> - {disabled ? ( - undefined - ) : ( - <> - - {listAfterSearch.length > 0 && SelectAllButton} - {selected.length > 0 && SelectNoneButton} - - - - {listBeforeSearch.length > 0 && listBeforeSearch.length === 0 && ( - - - - )} - {listAfterSearch.map(PeopleListItem)} - - - - )} - + + {showSelectAll && SelectAllButton} + {showSelectNone && SelectNoneButton} + + + + {listBeforeSearch.length > 0 && listBeforeSearch.length === 0 && ( + + + + )} + {listAfterSearch.map(PeopleListItem)} + + +
) function PeopleListItem(person: Person) { if (ignoreMyself && myself && person.identifier.equals(myself.identifier)) return null return ( = 2 && + frozenSelected.length + selected.length >= maxSelection) + } onClick={() => { - onSetSelected(selected.concat(person)) + if (maxSelection === 1) onSetSelected([person]) + else onSetSelected(selected.concat(person)) setSearch('') }} /> diff --git a/src/components/InjectedComponents/SelectPeopleDialog.tsx b/src/components/InjectedComponents/SelectPeopleDialog.tsx index d1b7af8272c..88f848e8a94 100644 --- a/src/components/InjectedComponents/SelectPeopleDialog.tsx +++ b/src/components/InjectedComponents/SelectPeopleDialog.tsx @@ -25,7 +25,7 @@ const useStyles = makeStyles({ content: { padding: '0 12px' }, progress: { marginRight: 6 }, }) -const ResponsiveDialog = withMobileDialog()(Dialog) +const ResponsiveDialog = withMobileDialog({ breakpoint: 'xs' })(Dialog) export function SelectPeopleDialog(props: Props) { const classes = useStyles() const [people, select] = useState([] as Person[]) diff --git a/src/components/Welcomes/0.tsx b/src/components/Welcomes/0.tsx index 0820f0ab62c..a42575cee21 100644 --- a/src/components/Welcomes/0.tsx +++ b/src/components/Welcomes/0.tsx @@ -86,7 +86,7 @@ export default function Welcome({ create, restore, close }: Props) { {geti18nString('welcome_0_new_user')} - {geti18nString('welcome_0_connect_facebook')} + {geti18nString('welcome_0_connect_maskbook')} diff --git a/src/components/Welcomes/1a1.tsx b/src/components/Welcomes/1a1.tsx new file mode 100644 index 00000000000..498de4d8125 --- /dev/null +++ b/src/components/Welcomes/1a1.tsx @@ -0,0 +1,61 @@ +import * as React from 'react' +import { getUrl } from '../../utils/utils' +import { geti18nString } from '../../utils/i18n' +import { Typography, Button, makeStyles } from '@material-ui/core' +import WelcomeContainer from './WelcomeContainer' +import { SelectPeopleUI } from '../InjectedComponents/SelectPeople' +import { useState } from 'react' +import { Person } from '../../database' + +interface Props { + next(person: Person): void + didntFindAccount(): void + identities: Person[] +} +const useStyles = makeStyles(theme => ({ + paper: { + padding: '2rem 1rem 1rem 1rem', + textAlign: 'center', + '& > *': { + marginBottom: theme.spacing(3), + }, + }, + button: { + minWidth: 180, + }, + select: { + padding: '0 4em', + }, +})) +export default function Welcome({ next, identities, didntFindAccount }: Props) { + const classes = useStyles() + const [selected, setSelect] = useState([]) + return ( + + {geti18nString('welcome_1a1_title')} + + +
+ +
+ ) +} diff --git a/src/extension/options-page/Welcome/index.tsx b/src/extension/options-page/Welcome/index.tsx index 90f3c55af8a..55d9063623a 100644 --- a/src/extension/options-page/Welcome/index.tsx +++ b/src/extension/options-page/Welcome/index.tsx @@ -127,7 +127,7 @@ function Welcome(props: Welcome) { return } } -const ResponsiveDialog = withMobileDialog()(Dialog) +const ResponsiveDialog = withMobileDialog({ breakpoint: 'xs' })(Dialog) const ProvePostRef = new ValueRef('') const IdentifierRef = new ValueRef(PersonIdentifier.unknown) const getMyProveBio = async () => { diff --git a/src/stories/Welcome.tsx b/src/stories/Welcome.tsx index a2fdced2a85..3c9fb3c0ba2 100644 --- a/src/stories/Welcome.tsx +++ b/src/stories/Welcome.tsx @@ -1,6 +1,7 @@ import React from 'react' import { storiesOf } from '@storybook/react' import Welcome0 from '../components/Welcomes/0' +import Welcome1a1 from '../components/Welcomes/1a1' import Welcome1a2 from '../components/Welcomes/1a2' import Welcome1a3 from '../components/Welcomes/1a3' import Welcome1a4v2 from '../components/Welcomes/1a4.v2' @@ -12,8 +13,9 @@ import { action } from '@storybook/addon-actions' import { BannerUI } from '../components/Welcomes/Banner' import { withMobileDialog, Dialog } from '@material-ui/core' import QRScanner from '../components/Welcomes/QRScanner' +import { demoPeople } from './demoPeople' -const ResponsiveDialog = withMobileDialog()(Dialog) +const ResponsiveDialog = withMobileDialog({ breakpoint: 'xs' })(Dialog) storiesOf('Welcome', module) .add('Banner', () => ( @@ -22,11 +24,20 @@ storiesOf('Welcome', module) )) + .add('Step 1a-1', () => ( + + to('Welcome', 'Step 1a-2')} + identities={demoPeople} + didntFindAccount={action('didntFindAccount')} + /> + + )) .add('Step 1a-2', () => ( diff --git a/src/stories/demoPeople.tsx b/src/stories/demoPeople.tsx index d6de4de5dce..4c1e02eaff0 100644 --- a/src/stories/demoPeople.tsx +++ b/src/stories/demoPeople.tsx @@ -4,8 +4,8 @@ export const demoPeople: Person[] = [ { fingerprint: 'FDFE333CE20ED446AD88F3C8BA3AD1AA5ECAF521', avatar: 'https://avatars3.githubusercontent.com/u/5390719?s=460&v=4', - nickname: 'Jack Works', - identifier: new PersonIdentifier('localhost', 'test'), + nickname: '雨宮響也', + identifier: new PersonIdentifier('facebook.com', 'test'), groups: [], }, { @@ -14,20 +14,20 @@ export const demoPeople: Person[] = [ .reverse() .join(''), avatar: 'https://avatars1.githubusercontent.com/u/3343358?s=460&v=4', - nickname: 'Robot of the century', - identifier: new PersonIdentifier('localhost', 'test'), + nickname: '赫胥黎', + identifier: new PersonIdentifier('twitter.com', 'test2'), groups: [], }, { fingerprint: 'a2f7643cd1aed446ad88f3c8ba13843dfa2f321d', - nickname: 'Material Design', - identifier: new PersonIdentifier('localhost', 'test'), + nickname: '小樱茉莉', + identifier: new PersonIdentifier('mastodon@example.org', 'test3'), groups: [], }, { fingerprint: 'a2f7643cd1aed446ad88f3c8ba13843dfa2f321d', - nickname: 'コノハ', - identifier: new PersonIdentifier('localhost', 'test'), + nickname: '温斯顿·史密斯', + identifier: new PersonIdentifier('gnu-social@example.org', 'test4'), groups: [], }, ]