Skip to content

Commit

Permalink
wot-author stories (keybase#23333)
Browse files Browse the repository at this point in the history
* wot-author stories

* x

* mobile fixes

* yarn test -u Storyshots

* sort keys

* sort-keys affects stories

* feedback

* yarn test -u Storyshots
  • Loading branch information
mlsteele authored Apr 1, 2020
1 parent 192f356 commit 3bba810
Show file tree
Hide file tree
Showing 16 changed files with 3,237 additions and 9 deletions.
6 changes: 4 additions & 2 deletions go/protocol/keybase1/extras.go
Original file line number Diff line number Diff line change
Expand Up @@ -3953,12 +3953,14 @@ func (e TeamSearchExport) Hash() string {

// web-of-trust
// In order of descending quality.
// Keep in sync with server: helpers/wot.ts
// Keep in sync with:
// - server helpers/wot.ts
// - gui WebOfTrustVerificationType
const (
UsernameVerificationType_IN_PERSON = "in_person"
UsernameVerificationType_PROOFS = "proofs"
UsernameVerificationType_VIDEO = "video"
UsernameVerificationType_AUDIO = "audio"
UsernameVerificationType_PROOFS = "proofs"
UsernameVerificationType_OTHER_CHAT = "other_chat"
UsernameVerificationType_FAMILIAR = "familiar"
UsernameVerificationType_OTHER = "other"
Expand Down
9 changes: 9 additions & 0 deletions shared/common-adapters/icon.constants-gen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -536,6 +536,7 @@ export type IconType =
| 'icon-illustration-teams-feature-profile-460-64'
| 'icon-illustration-teams-subteams-460-96'
| 'icon-illustration-welcome-96'
| 'icon-illustration-wot-460-96'
| 'icon-illustration-zen-240-180'
| 'icon-invite-link-48'
| 'icon-keybase-logo-128'
Expand Down Expand Up @@ -5803,6 +5804,14 @@ export const iconMeta: {[k in IconType]: IconMeta} = {
return require('../images/icons/icon-illustration-welcome-96.png')
},
},
'icon-illustration-wot-460-96': {
extension: 'png',
imagesDir: 'icons',
isFont: false,
get require() {
return require('../images/icons/icon-illustration-wot-460-96.png')
},
},
'icon-illustration-zen-240-180': {
extension: 'png',
imagesDir: 'icons',
Expand Down
1 change: 1 addition & 0 deletions shared/common-adapters/radio-button.desktop.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const StyledRadio: any = Styles.styled.div(
() => ({
...Styles.transition('background'),
borderRadius: '100%',
flex: 'none',
height: RADIOBUTTON_SIZE,
marginRight: RADIOBUTTON_MARGIN,
position: 'relative',
Expand Down
11 changes: 11 additions & 0 deletions shared/constants/profile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,14 @@ export const SEARCH_CONTAINER_ZINDEX = BACK_ZINDEX + 1
export const ADD_TO_TEAM_ZINDEX = SEARCH_CONTAINER_ZINDEX + 1
export const ROLE_PICKER_ZINDEX = ADD_TO_TEAM_ZINDEX + 1
export const EDIT_AVATAR_ZINDEX = SEARCH_CONTAINER_ZINDEX + 1

// In order of quality.
export const webOfTrustVerificationTypes: Types.WebOfTrustVerificationType[] = [
'in_person',
'video',
'audio',
'proofs',
'other_chat',
'familiar',
'other',
]
10 changes: 9 additions & 1 deletion shared/constants/types/profile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,15 @@ import * as RPCTypes from './rpc-gen'
import {PlatformsExpandedType} from './more'
import {SiteIconSet} from './tracker2'

export type WebOfTrustVerificationType = 'none' | 'audio' | 'video' | 'email' | 'other_chat' | 'in_person'
// Keep in sync with keybase1 extras.go UsernameVerificationType
export type WebOfTrustVerificationType =
| 'in_person'
| 'video'
| 'audio'
| 'proofs'
| 'other_chat'
| 'familiar'
| 'other'

export type ProveGenericParams = {
readonly logoBlack: SiteIconSet
Expand Down
Binary file modified shared/fonts/kb.ttf
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added shared/images/icons/[email protected]
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added shared/images/icons/[email protected]
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions shared/profile/index.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import proveWebsite from './prove-website-choice/index.stories'
import revoke from './revoke/index.stories'
import profile from './profile.stories'
import teamInfo from './user/teams/teaminfo.stories'
import wotAuthor from './wot-author/index.stories'

const load = () => {
;[
Expand All @@ -21,6 +22,7 @@ const load = () => {
proveWebsite,
revoke,
teamInfo,
wotAuthor,
].forEach(load => load())
}

Expand Down
2 changes: 1 addition & 1 deletion shared/profile/user/container.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ const connected = Container.namedConnect(
onAddIdentity,
onBack: dispatchProps.onBack,
onEditAvatar: stateProps.userIsYou ? dispatchProps._onEditAvatar : undefined,
onIKnowThem: () => {},
onIKnowThem: () => {}, // PICNIC-847 open the modal
onReload: () => dispatchProps._onReload(stateProps.username, stateProps.userIsYou, stateProps.state),
reason: stateProps.reason,
sbsAvatarUrl: stateProps.sbsAvatarUrl,
Expand Down
Empty file.
23 changes: 23 additions & 0 deletions shared/profile/wot-author/index.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import * as React from 'react'
import * as Sb from '../../stories/storybook'
import {Question1, Question2} from '.'

const props = {
onSubmit: Sb.action('onSubmit'),
voucheeUsername: 'weijiekohyalenus',
}

const errorProps = {
error: 'You are offline.',
}

const load = () => {
Sb.storiesOf('Profile/WotAuthor', module)
.addDecorator(Sb.createPropProviderWithCommon())
.add('Question1', () => <Question1 {...props} />)
.add('Question2', () => <Question2 {...props} />)
.add('Question1 error', () => <Question1 {...props} {...errorProps} />)
.add('Question2 error', () => <Question2 {...props} {...errorProps} />)
}

export default load
213 changes: 213 additions & 0 deletions shared/profile/wot-author/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
import * as React from 'react'
import * as Types from '../../constants/types/profile'
import * as Constants from '../../constants/profile'
import * as Kb from '../../common-adapters'
import * as Styles from '../../styles'

type Props = {
error?: string
onSubmit: () => void
voucheeUsername: string
}

type WotModalProps = {
error?: string
submitLabel: string
onSubmit: () => void
children: React.ReactNode
}

// PICNIC-1059 Keep in sync with server limit (yet to be implemented)
const statementLimit = 700

const WotModal = (props: WotModalProps) => {
return (
<Kb.Modal
header={{title: 'Web of Trust'}}
mode="DefaultFullHeight"
banners={[
!!props.error && (
<Kb.Banner color="red">
<Kb.BannerParagraph bannerColor="red" content={props.error} />
</Kb.Banner>
),
]}
footer={{
content: (
<Kb.ButtonBar align="center" direction="row" fullWidth={true} style={styles.buttonBar}>
<Kb.Button fullWidth={true} label={props.submitLabel} onClick={props.onSubmit} />
</Kb.ButtonBar>
),
}}
>
<Kb.Box2
direction="vertical"
alignSelf="stretch"
alignItems="stretch"
style={{backgroundColor: Styles.globalColors.green}}
>
<Kb.Icon type="icon-illustration-wot-460-96" />
</Kb.Box2>
{props.children}
</Kb.Modal>
)
}

export const Question1 = (props: Props) => {
return (
<WotModal error={props.error} submitLabel="Continue" onSubmit={props.onSubmit}>
<Kb.Box2
direction="horizontal"
alignSelf="stretch"
alignItems="center"
style={Styles.collapseStyles([styles.sidePadding, styles.id])}
>
<Kb.Avatar username={props.voucheeUsername} size={48} />
<Kb.Text type="BodySemibold" style={styles.idInner}>
How do you know{' '}
<Kb.ConnectedUsernames
usernames={props.voucheeUsername}
type="BodySemibold"
inline={true}
colorFollowing={true}
colorBroken={true}
/>{' '}
is the person you think they are?
</Kb.Text>
</Kb.Box2>
{Constants.webOfTrustVerificationTypes.map(vt => (
<VerificationChoice
key={vt}
voucheeUsername={props.voucheeUsername}
verificationType={vt}
selected={false}
onSelect={() => {}}
/>
))}
</WotModal>
)
}

export const Question2 = (props: Props) => {
return (
<WotModal error={props.error} submitLabel="Submit" onSubmit={props.onSubmit}>
<Kb.Box2
direction="vertical"
alignSelf="stretch"
alignItems="stretch"
style={Styles.collapseStyles([styles.sidePadding, styles.outside])}
>
<Kb.Box2 direction="horizontal" alignItems="center" style={styles.outsideBox}>
<Kb.Avatar username={props.voucheeUsername} size={48} />
<Kb.Text type="BodySemibold" style={styles.idInner}>
How do you know{' '}
<Kb.ConnectedUsernames
usernames={props.voucheeUsername}
type="BodySemibold"
inline={true}
colorFollowing={true}
colorBroken={true}
/>{' '}
outside of Keybase?
</Kb.Text>
</Kb.Box2>
<Kb.LabeledInput
placeholder="Your claim"
hoverPlaceholder={'Write how you met them and what experiences you shared with them.'}
multiline={true}
rowsMin={9}
autoFocus={true}
maxLength={statementLimit}
/>
<Kb.Text type="BodySmall" style={styles.approveNote}>
{props.voucheeUsername} will be able to approve or suggest edits to what you’ve written.
</Kb.Text>
</Kb.Box2>
</WotModal>
)
}

const VerificationChoice = (props: {
voucheeUsername: string
verificationType: Types.WebOfTrustVerificationType
selected: boolean
onSelect: () => void
}) => {
let text: React.ReactNode = 'Do not choose this option'
let color: string = Styles.globalColors.white
switch (props.verificationType) {
case 'in_person':
text = (
<>
{props.voucheeUsername} told me their username <Kb.Text type="BodyBold">in person</Kb.Text>
</>
)
color = Styles.globalColors.greenDark
break
case 'video':
text = `${props.voucheeUsername} told me their username over video`
color = '#56fff5'
break
case 'audio':
text = `${props.voucheeUsername} told me their username over audio`
color = Styles.globalColors.blueLight
break
case 'proofs':
text = `I know one of ${props.voucheeUsername}'s proofs`
color = Styles.globalColors.blueLight
break
case 'other_chat':
text = `${props.voucheeUsername} texted me their username`
color = Styles.globalColors.yellow
break
case 'familiar':
text = 'We are longtime Keybase friends'
color = Styles.globalColors.yellow
break
case 'other':
text = 'Other'
color = Styles.globalColors.yellowDark
break
}
return (
<Kb.Box2 direction="horizontal" alignSelf="stretch" alignItems="center">
<Kb.Box2
direction="vertical"
alignSelf="stretch"
style={{backgroundColor: color, flexShrink: 0, width: 6}}
/>
<Kb.RadioButton
label={
<Kb.Text type="Body" style={Styles.globalStyles.flexOne}>
{text}
</Kb.Text>
}
selected={props.selected}
onSelect={props.onSelect}
style={styles.choiceRadio}
/>
</Kb.Box2>
)
}

const styles = Styles.styleSheetCreate(
() =>
({
approveNote: {paddingTop: Styles.globalMargins.tiny},
buttonBar: {minHeight: undefined},
choiceRadio: {
flex: 1,
paddingBottom: Styles.globalMargins.tiny,
paddingLeft: Styles.globalMargins.small,
paddingTop: Styles.globalMargins.tiny,
},
id: {paddingBottom: Styles.globalMargins.tiny, paddingTop: Styles.globalMargins.tiny},
idInner: {
flex: 1,
paddingLeft: Styles.globalMargins.tiny,
},
outside: {paddingTop: Styles.globalMargins.tiny},
outsideBox: {paddingBottom: Styles.globalMargins.small},
sidePadding: {paddingLeft: Styles.globalMargins.small, paddingRight: Styles.globalMargins.small},
} as const)
)
Loading

0 comments on commit 3bba810

Please sign in to comment.