From c9ff68aa4facc11589d9c4f0296136c1f5405b43 Mon Sep 17 00:00:00 2001 From: chrisnojima Date: Fri, 29 May 2026 16:39:00 -0400 Subject: [PATCH 1/9] clickablebox 3 - teams (#29265) --- plans/clickablebox3.md | 2 +- shared/teams/add-members-wizard/confirm.tsx | 17 +- shared/teams/common/channels-widget.tsx | 4 +- shared/teams/common/use-autocompleter.tsx | 20 +-- shared/teams/emojis/add-emoji.tsx | 6 +- shared/teams/emojis/common.tsx | 6 +- .../teams/invite-by-contact/index.native.tsx | 6 +- shared/teams/main/index.tsx | 40 ++--- shared/teams/main/team-row.tsx | 163 +++++++++--------- shared/teams/role-picker.tsx | 4 +- shared/teams/team/member/add-to-channels.tsx | 21 ++- shared/teams/team/member/index.new.tsx | 6 +- .../teams/team/settings-tab/channel-popup.tsx | 26 ++- .../team/settings-tab/retention/index.tsx | 9 +- 14 files changed, 151 insertions(+), 179 deletions(-) diff --git a/plans/clickablebox3.md b/plans/clickablebox3.md index 0fcef11e62f4..77c28f8f2ad9 100644 --- a/plans/clickablebox3.md +++ b/plans/clickablebox3.md @@ -51,7 +51,7 @@ Use `migrate-clickable-box` skill for each chunk. Run `yarn lint && yarn tsc` an - [x] `shared/menubar/` (3) - [x] `shared/app/` (4) - [x] `shared/router-v2/` (9) -- [ ] `shared/teams/` (25+) +- [x] `shared/teams/` (25+) - [ ] `shared/team-building/` (9+) ### Round 3 — large diff --git a/shared/teams/add-members-wizard/confirm.tsx b/shared/teams/add-members-wizard/confirm.tsx index bc67ba28e9ec..d0c1b019db1b 100644 --- a/shared/teams/add-members-wizard/confirm.tsx +++ b/shared/teams/add-members-wizard/confirm.tsx @@ -358,18 +358,11 @@ const AddingMembers = ({ /> ))} {showDivider && ( - - - - {expanded ? 'Show less' : `+${addingMembers.length - 4} more`} - - - + + + {expanded ? 'Show less' : `+${addingMembers.length - 4} more`} + + )} {expanded && belowDivider.map(toAdd => ( diff --git a/shared/teams/common/channels-widget.tsx b/shared/teams/common/channels-widget.tsx index 60769381d7dc..f515aece6a08 100644 --- a/shared/teams/common/channels-widget.tsx +++ b/shared/teams/common/channels-widget.tsx @@ -101,7 +101,7 @@ const ChannelInputMobile = (props: ChannelInputProps) => { onAdd(channels) } return ( - setShowingPopup(true)}> + setShowingPopup(true)} direction="vertical"> { hideGeneral={disableGeneral} /> )} - + ) } diff --git a/shared/teams/common/use-autocompleter.tsx b/shared/teams/common/use-autocompleter.tsx index d74dc4f579c3..e6bff1b276b7 100644 --- a/shared/teams/common/use-autocompleter.tsx +++ b/shared/teams/common/use-autocompleter.tsx @@ -35,22 +35,18 @@ function useAutocompleter( positionFallbacks={positionFallbacks} > {itemsFiltered.map((item, idx) => ( - onSelect(item.value)} onMouseOver={() => setSelected(idx)} - style={styles.optionOuter} + direction="horizontal" + fullWidth={true} + style={Kb.Styles.collapseStyles([styles.optionOuter, styles.option, selected === idx && styles.optionSelected])} > - - - {item.label} - - - + + {item.label} + + ))} ) diff --git a/shared/teams/emojis/add-emoji.tsx b/shared/teams/emojis/add-emoji.tsx index 46663b5b4e4a..be79d1ad73a6 100644 --- a/shared/teams/emojis/add-emoji.tsx +++ b/shared/teams/emojis/add-emoji.tsx @@ -323,9 +323,9 @@ type EmojiToAddOrAddRow = const renderRow = (_: number, item: EmojiToAddOrAddRow) => item.type === 'add' ? ( - + - + ) : ( ({ addEmojiIconContainer: Kb.Styles.platformStyles({ common: { - ...Kb.Styles.globalStyles.flexBoxColumn, - ...Kb.Styles.centered(), ...Kb.Styles.border(Kb.Styles.globalColors.black_20, 1, Kb.Styles.globalMargins.xtiny), }, isElectron: { diff --git a/shared/teams/emojis/common.tsx b/shared/teams/emojis/common.tsx index bec023139104..44b33bbc9974 100644 --- a/shared/teams/emojis/common.tsx +++ b/shared/teams/emojis/common.tsx @@ -35,9 +35,9 @@ export function AliasInput(props: AliasInputProps & {ref?: React.Ref}) onEnterKeyDown={onEnterKeyDown} /> {onRemove && ( - + - + )} {!!error && ( @@ -165,8 +165,6 @@ const styles = Kb.Styles.styleSheetCreate(() => ({ }, }), removeBox: { - ...Kb.Styles.globalStyles.flexBoxRow, - ...Kb.Styles.centered(), padding: Kb.Styles.globalMargins.xtiny, }, })) diff --git a/shared/teams/invite-by-contact/index.native.tsx b/shared/teams/invite-by-contact/index.native.tsx index b81acc777456..491c72608445 100644 --- a/shared/teams/invite-by-contact/index.native.tsx +++ b/shared/teams/invite-by-contact/index.native.tsx @@ -105,12 +105,12 @@ export const InviteByContact = (props: InviteByContactProps) => { position="bottom center" disabledRoles={{owner: 'Cannot invite an owner via email.'}} /> - setRolePickerOpen(true)} style={styles.rolePickerBox}> + setRolePickerOpen(true)} style={styles.rolePickerBox}> Users will be invited to {props.teamName} as {' ' + props.selectedRole + 's'}. - + void; onJoinTeam: () => void; empty: boolean}) => ( - - - Create a team - - - - + Create a team + + + - - + - - Join a team - - - + Join a team + + {props.empty && !isMobile && ( Keybase team chats are encrypted – unlike Slack – and work for any size group, from casual friends to @@ -88,12 +90,10 @@ const SortHeader = ({onChangeSort, sortOrder}: {onChangeSort: Props['onChangeSor const {popup, showPopup, popupAnchor} = Kb.usePopup2(makePopup) return ( - - - - {sortOrderToTitle[sortOrder]} - - + + + {sortOrderToTitle[sortOrder]} + {popup} ) diff --git a/shared/teams/main/team-row.tsx b/shared/teams/main/team-row.tsx index 7d8b211bbda5..119e14763419 100644 --- a/shared/teams/main/team-row.tsx +++ b/shared/teams/main/team-row.tsx @@ -61,66 +61,7 @@ const TeamRow = function TeamRow(props: Props) { if (isMobile) { return ( <> - - - - - - - {!!badgeCount && } - {crownIcon} - - - - - - {teamMeta.teamname} - - {teamMeta.isOpen && ( - - )} - - - {isNew && ( - - )} - - {teamMeta.memberCount.toLocaleString()} {pluralize('member', teamMeta.memberCount)} - - - {activity} - - - {showChat && ( - - )} - - - - - {popup} - - ) - } - - return ( - <> - - + @@ -129,30 +70,26 @@ const TeamRow = function TeamRow(props: Props) { {crownIcon} - - - - - {teamMeta.teamname} - - {teamMeta.isOpen && ( - - )} - - - {isNew && ( - - )} - - {teamMeta.memberCount.toLocaleString()} {pluralize('member', teamMeta.memberCount)} - - + + + + {teamMeta.teamname} + + {teamMeta.isOpen && ( + + )} - - {activity} + + {isNew && ( + + )} + + {teamMeta.memberCount.toLocaleString()} {pluralize('member', teamMeta.memberCount)} + + {activity} - + {showChat && ( )} + + {popup} + + ) + } + + return ( + <> + + + + + + {!!badgeCount && } + {crownIcon} + + + + + + + {teamMeta.teamname} + + {teamMeta.isOpen && ( + + )} + + + {isNew && ( + + )} + + {teamMeta.memberCount.toLocaleString()} {pluralize('member', teamMeta.memberCount)} + + + + + {activity} + + + + {showChat && ( + + )} + - + {popup} ) @@ -234,7 +230,6 @@ const styles = Kb.Styles.styleSheetCreate(() => ({ common: { backgroundColor: Kb.Styles.globalColors.white, flexShrink: 0, - width: '100%', }, isElectron: {minHeight: smallHeight}, isPhone: {minHeight: 72}, diff --git a/shared/teams/role-picker.tsx b/shared/teams/role-picker.tsx index 27455cec58a2..87125e785422 100644 --- a/shared/teams/role-picker.tsx +++ b/shared/teams/role-picker.tsx @@ -117,7 +117,7 @@ const RoleRowWrapper = (props: RoleRowWrapperProps) => { ...(isMobile ? {} : {height: selected ? 160 : 42}), } return ( - + { onSelect={onSelect} disabledReason={disabledReason} /> - + ) } diff --git a/shared/teams/team/member/add-to-channels.tsx b/shared/teams/team/member/add-to-channels.tsx index fec8830aa389..057afd789873 100644 --- a/shared/teams/team/member/add-to-channels.tsx +++ b/shared/teams/team/member/add-to-channels.tsx @@ -495,15 +495,15 @@ const ChannelRow = function ChannelRow(p: ChannelRowProps) { } return isMobile ? ( - - + #{channelMeta.channelname} @@ -531,8 +531,7 @@ const ChannelRow = function ChannelRow(p: ChannelRowProps) { } /> )} - - + ) : ( { open={open} disabledRoles={disabledRoles} /> - setExpanded(!expanded)}> - + setExpanded(!expanded)} direction="vertical" fullWidth={true} style={!expanded && styles.rowCollapsedFixedHeight}> {props.idx !== 0 && } @@ -754,8 +753,7 @@ const NodeInRow = (props: NodeInRowProps) => { )} - - + ) } diff --git a/shared/teams/team/settings-tab/channel-popup.tsx b/shared/teams/team/settings-tab/channel-popup.tsx index 31576c06a0dd..dbde462ee100 100644 --- a/shared/teams/team/settings-tab/channel-popup.tsx +++ b/shared/teams/team/settings-tab/channel-popup.tsx @@ -81,20 +81,18 @@ const ChannelPopup = (props: Props) => { const disabled = disabledChannels?.some(c => c.conversationIDKey === channel.conversationIDKey) const onClick = disabled ? undefined : () => onSelect(channel) return ( - - - - #{channel.channelname} - - c.conversationIDKey === channel.conversationIDKey) - } - disabled={disabled} - /> - - + + + #{channel.channelname} + + c.conversationIDKey === channel.conversationIDKey) + } + disabled={disabled} + /> + ) }} /> diff --git a/shared/teams/team/settings-tab/retention/index.tsx b/shared/teams/team/settings-tab/retention/index.tsx index a6437700ce4a..3c869609349d 100644 --- a/shared/teams/team/settings-tab/retention/index.tsx +++ b/shared/teams/team/settings-tab/retention/index.tsx @@ -165,17 +165,18 @@ const RetentionPicker = (p: Props) => { Message deletion - {policyToLabel(policy, teamPolicy)} - + {policyIsExploding && ( Participants will see their message explode. @@ -238,8 +239,6 @@ const styles = Kb.Styles.styleSheetCreate( }, retentionDropdown: Kb.Styles.platformStyles({ common: { - ...Kb.Styles.globalStyles.flexBoxRow, - alignItems: 'center', ...Kb.Styles.border(Kb.Styles.globalColors.grey, 1, Kb.Styles.borderRadius), marginBottom: Kb.Styles.globalMargins.tiny, minWidth: 220, From 164ab2409cdfd001ba916281fb17ee326aa6bc77 Mon Sep 17 00:00:00 2001 From: chrisnojima Date: Fri, 29 May 2026 16:44:16 -0400 Subject: [PATCH 2/9] clickablebox 3 - team-building (#29265) --- plans/clickablebox3.md | 2 +- shared/common-adapters/box.tsx | 2 +- shared/team-building/contacts.tsx | 24 ++--- .../search-result/common-result.tsx | 97 +++++++++---------- .../search-result/people-result.tsx | 7 +- .../search-result/user-result.tsx | 23 +++-- shared/team-building/service-tab-bar.tsx | 30 +++--- shared/team-building/user-bubble.tsx | 4 +- 8 files changed, 92 insertions(+), 97 deletions(-) diff --git a/plans/clickablebox3.md b/plans/clickablebox3.md index 77c28f8f2ad9..410bc9aafaf9 100644 --- a/plans/clickablebox3.md +++ b/plans/clickablebox3.md @@ -52,7 +52,7 @@ Use `migrate-clickable-box` skill for each chunk. Run `yarn lint && yarn tsc` an - [x] `shared/app/` (4) - [x] `shared/router-v2/` (9) - [x] `shared/teams/` (25+) -- [ ] `shared/team-building/` (9+) +- [x] `shared/team-building/` (9+) ### Round 3 — large - [ ] `shared/fs/` (10+) diff --git a/shared/common-adapters/box.tsx b/shared/common-adapters/box.tsx index d377163dc69a..4858a2564ce9 100644 --- a/shared/common-adapters/box.tsx +++ b/shared/common-adapters/box.tsx @@ -310,7 +310,7 @@ const nativeStyles = { } as const export type ClickableBox3Props = Box2Props & { - onClick?: () => void + onClick?: (e?: React.SyntheticEvent) => void onLongPress?: () => void hitSlop?: number } diff --git a/shared/team-building/contacts.tsx b/shared/team-building/contacts.tsx index 871ec9eada12..8d94ae68a210 100644 --- a/shared/team-building/contacts.tsx +++ b/shared/team-building/contacts.tsx @@ -144,23 +144,15 @@ export const ContactsImportButton = () => { return null return ( - - - - - - - Import phone contacts - - + + + - + + Import phone contacts + + + ) } diff --git a/shared/team-building/search-result/common-result.tsx b/shared/team-building/search-result/common-result.tsx index d597e96cc657..c663681ae17f 100644 --- a/shared/team-building/search-result/common-result.tsx +++ b/shared/team-building/search-result/common-result.tsx @@ -91,61 +91,60 @@ const CommonResult = (props: CommonResultProps) => { const onClick = getRowAction(props) return ( - - - - - {serviceUsername ? ( - <> - + + + {serviceUsername ? ( + <> + + {props.bottomRow ?? ( + - {props.bottomRow ?? ( - - )} - - ) : ( - - )} - - - {/* Renders checkbox for new-chat and team-building, and chat buttons + dropdown for people search */} - {props.rightButtons ?? null} - + )} + + ) : ( + + )} + + + {/* Renders checkbox for new-chat and team-building, and chat buttons + dropdown for people search */} + {props.rightButtons ?? null} - + ) } diff --git a/shared/team-building/search-result/people-result.tsx b/shared/team-building/search-result/people-result.tsx index ff95ff59408e..afe14c80579f 100644 --- a/shared/team-building/search-result/people-result.tsx +++ b/shared/team-building/search-result/people-result.tsx @@ -135,12 +135,13 @@ const DropdownButton = (p: DropdownProps) => { const {showPopup, popup, popupAnchor} = Kb.usePopup2(makePopup) return ( - { - e.stopPropagation() + e?.stopPropagation() showPopup() }} ref={popupAnchor} + direction="vertical" > @@ -148,7 +149,7 @@ const DropdownButton = (p: DropdownProps) => { {popup} - + ) } diff --git a/shared/team-building/search-result/user-result.tsx b/shared/team-building/search-result/user-result.tsx index fcc8da0cce87..52031d5ee9da 100644 --- a/shared/team-building/search-result/user-result.tsx +++ b/shared/team-building/search-result/user-result.tsx @@ -22,8 +22,8 @@ const UserResult = function UserResult(props: ResultProps) { !props.isPreExistingTeamMember && ( { - e.stopPropagation() + onAdd={(e?: React.BaseSyntheticEvent) => { + e?.stopPropagation() props.onAdd(props.userId) }} onRemove={() => { @@ -39,21 +39,20 @@ const actionButtonSize = isMobile ? 22 : Kb.Styles.globalMargins.small const ActionButton = (props: { inTeam: boolean - onAdd: (e: React.BaseSyntheticEvent) => void + onAdd: (e?: React.BaseSyntheticEvent) => void onRemove: () => void }) => { const Icon = props.inTeam ? AlreadyAddedIconButton : AddButton return ( - - - - - + + + ) } diff --git a/shared/team-building/service-tab-bar.tsx b/shared/team-building/service-tab-bar.tsx index d3f1cbd1e064..2297ab364368 100644 --- a/shared/team-building/service-tab-bar.tsx +++ b/shared/team-building/service-tab-bar.tsx @@ -120,7 +120,7 @@ const ServiceIconNative = function ServiceIcon(props: IconProps) { }) return ( - onClick(service)} style={{position: 'relative'}}> + onClick(service)} direction="vertical" relative={true}> {serviceIdToBadge(service) && ( @@ -156,7 +156,7 @@ const ServiceIconNative = function ServiceIcon(props: IconProps) { Kb.Styles.platformStyles({isMobile: animatedTransform}), ])} /> - + ) } @@ -282,11 +282,19 @@ const MoreNetworksButton = (props: { ref={popupAnchor} > - + ••• - + @@ -302,10 +310,12 @@ const ServiceIconDesktop = (props: IconProps) => { const color = props.isActive || hover ? serviceIdToAccentColor(props.service, isDarkMode) : Kb.Styles.globalColors.black return ( - props.onClick(props.service)} onMouseOver={() => setHover(true)} onMouseLeave={() => setHover(false)} + direction="vertical" + flex={1} style={desktopStyles.serviceIconFlex} > @@ -343,7 +353,7 @@ const ServiceIconDesktop = (props: IconProps) => { props.isActive && {backgroundColor: serviceIdToAccentColor(props.service, isDarkMode)}, ])} /> - + ) } @@ -435,18 +445,12 @@ const desktopStyles = Kb.Styles.styleSheetCreate( width: '100%', }, moreNetworks3: { - alignItems: 'center', borderColor: Kb.Styles.globalColors.black_20, borderRadius: Kb.Styles.borderRadius, borderStyle: 'solid', borderWidth: 1, - display: 'flex', - flexDirection: 'row', - height: '100%', - justifyContent: 'center', maxHeight: '100%', maxWidth: '100%', - width: '100%', }, moreText: {color: Kb.Styles.globalColors.black_50}, serviceIconBox: {marginTop: 14}, @@ -457,7 +461,7 @@ const desktopStyles = Kb.Styles.styleSheetCreate( maxWidth: 72, minWidth: 40, }, - serviceIconFlex: {flex: 1, maxWidth: 90}, + serviceIconFlex: {maxWidth: 90}, tabBarContainer: { borderBottomColor: Kb.Styles.globalColors.black_10, borderBottomWidth: 1, diff --git a/shared/team-building/user-bubble.tsx b/shared/team-building/user-bubble.tsx index 908f2c5595f5..8d8b46de8574 100644 --- a/shared/team-building/user-bubble.tsx +++ b/shared/team-building/user-bubble.tsx @@ -50,7 +50,7 @@ const UserBubble = (props: Props) => { } const RemoveBubble = ({onRemove}: {onRemove: () => void}) => ( - + void}) => ( style={styles.removeIcon} className="hover_color_black" /> - + ) const styles = Kb.Styles.styleSheetCreate( From cec6d20a926d7ff2679b313d431b2fb7add29e9c Mon Sep 17 00:00:00 2001 From: chrisnojima Date: Fri, 29 May 2026 16:46:23 -0400 Subject: [PATCH 3/9] clickablebox 3 - fs (#29265) --- plans/clickablebox3.md | 2 +- shared/fs/browser/destination-picker.tsx | 20 ++++++++------------ shared/fs/common/path-item-action/header.tsx | 7 ++++--- shared/fs/common/sfmi-popup.tsx | 15 +++++---------- shared/fs/top-bar/sort.tsx | 14 ++++++-------- 5 files changed, 24 insertions(+), 34 deletions(-) diff --git a/plans/clickablebox3.md b/plans/clickablebox3.md index 410bc9aafaf9..c1f9c1b89f41 100644 --- a/plans/clickablebox3.md +++ b/plans/clickablebox3.md @@ -55,7 +55,7 @@ Use `migrate-clickable-box` skill for each chunk. Run `yarn lint && yarn tsc` an - [x] `shared/team-building/` (9+) ### Round 3 — large -- [ ] `shared/fs/` (10+) +- [x] `shared/fs/` (10+) - [ ] `shared/chat/` (60+) ### Last — shared primitives diff --git a/shared/fs/browser/destination-picker.tsx b/shared/fs/browser/destination-picker.tsx index f0b7b1da7e7a..c740a772dfea 100644 --- a/shared/fs/browser/destination-picker.tsx +++ b/shared/fs/browser/destination-picker.tsx @@ -126,7 +126,7 @@ const ConnectedDestinationPicker = (ownProps: OwnProps) => { {!!onBackUp && ( - + { style={RowCommon.rowStyles.pathItemIcon} /> .. - + )} {!!onCopyHere && ( - + { {isShare ? 'Save here' : 'Copy here'} - + )} {!!onMoveHere && ( - + { Move here - + )} {parentPath === FS.defaultPath ? ( @@ -198,12 +198,12 @@ const Screen = (props: OwnProps) => ( const NewFolder = (p: {onNewFolder?: () => void}) => { const {onNewFolder} = p return ( - + Create new folder - + ) } @@ -211,8 +211,6 @@ const styles = Kb.Styles.styleSheetCreate( () => ({ actionRowContainer: { - ...Kb.Styles.globalStyles.flexBoxRow, - alignItems: 'center', backgroundColor: Kb.Styles.globalColors.blueLighter3, flexShrink: 0, height: RowCommon.normalRowHeight, @@ -237,8 +235,6 @@ const styles = Kb.Styles.styleSheetCreate( }, }), newFolderBox: { - ...Kb.Styles.globalStyles.flexBoxRow, - alignItems: 'center', padding: Kb.Styles.globalMargins.tiny, }, newFolderText: { diff --git a/shared/fs/common/path-item-action/header.tsx b/shared/fs/common/path-item-action/header.tsx index 55bbb437e630..c03b15ef04d4 100644 --- a/shared/fs/common/path-item-action/header.tsx +++ b/shared/fs/common/path-item-action/header.tsx @@ -6,17 +6,18 @@ import PathInfo from '../path-info' export type Props = {path: T.FS.Path} const Header = (props: Props) => ( - event.stopPropagation() + e => e?.stopPropagation() } + direction="vertical" > - + ) export default Header diff --git a/shared/fs/common/sfmi-popup.tsx b/shared/fs/common/sfmi-popup.tsx index eb9be19fe476..1c248df40b19 100644 --- a/shared/fs/common/sfmi-popup.tsx +++ b/shared/fs/common/sfmi-popup.tsx @@ -25,11 +25,10 @@ const SFMIPopup = (props: Props) => { return ( - { - e.stopPropagation() - }} + e?.stopPropagation()} > @@ -52,7 +51,7 @@ const SFMIPopup = (props: Props) => { onClick={enableDriver} /> - + ) } @@ -94,10 +93,6 @@ const styles = Kb.Styles.styleSheetCreate(() => ({ buttonBox: { ...Kb.Styles.padding(Kb.Styles.globalMargins.small, Kb.Styles.globalMargins.small, Kb.Styles.globalMargins.tiny), }, - container: { - ...Kb.Styles.globalStyles.flexBoxColumn, - width: '100%', - }, divider: { marginBottom: Kb.Styles.globalMargins.tiny, marginTop: Kb.Styles.globalMargins.small, diff --git a/shared/fs/top-bar/sort.tsx b/shared/fs/top-bar/sort.tsx index c6dea78ba806..43a8934d6084 100644 --- a/shared/fs/top-bar/sort.tsx +++ b/shared/fs/top-bar/sort.tsx @@ -80,14 +80,12 @@ const Container = (ownProps: OwnProps) => { const {showPopup, popup, popupAnchor} = Kb.usePopup2(makePopup) return shownSortSetting ? ( <> - - - - - {getTextFromSortSetting(shownSortSetting)} - - - + + + + {getTextFromSortSetting(shownSortSetting)} + + {popup} ) : null From 0d9e0a7bb2e70638b14347ffa1d09d389e2b3e8b Mon Sep 17 00:00:00 2001 From: chrisnojima Date: Fri, 29 May 2026 16:55:21 -0400 Subject: [PATCH 4/9] only pick up the folders from shared --- shared/metro.config.js | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/shared/metro.config.js b/shared/metro.config.js index ac43ab5e5950..5b612b961e95 100644 --- a/shared/metro.config.js +++ b/shared/metro.config.js @@ -4,6 +4,7 @@ const ignoredModules = require('./ignored-modules') const desktopOnlyModules = require('./desktop-only-modules') const root = path.resolve(__dirname, '.') +const rootRe = root.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') const nullModule = path.join(root, 'null-module.js') const config = getDefaultConfig(__dirname) @@ -26,21 +27,25 @@ config.resolver = { } config.resolver.blockList = [ - ...(Array.isArray(config.resolver.blockList) ? config.resolver.blockList : config.resolver.blockList ? [config.resolver.blockList] : []), - /tests\/results\//, - /\.maestro\//, - /desktop\//, - /ios\/build\//, - /ios\/Pods\//, - /ios\/dist\//, - /android\/app\/build\//, - /android\/build\//, - /android\/\.gradle\//, - /docs\//, - /coverage-ts\//, - /patches\//, - /scripts\//, - /tools\//, + ...(Array.isArray(config.resolver.blockList) + ? config.resolver.blockList + : config.resolver.blockList + ? [config.resolver.blockList] + : []), + new RegExp(`^${rootRe}/tests/results/`), + new RegExp(`^${rootRe}/\\.maestro/`), + new RegExp(`^${rootRe}/desktop/`), + new RegExp(`^${rootRe}/ios/build/`), + new RegExp(`^${rootRe}/ios/Pods/`), + new RegExp(`^${rootRe}/ios/dist/`), + new RegExp(`^${rootRe}/android/app/build/`), + new RegExp(`^${rootRe}/android/build/`), + new RegExp(`^${rootRe}/android/\\.gradle/`), + new RegExp(`^${rootRe}/docs/`), + new RegExp(`^${rootRe}/coverage-ts/`), + new RegExp(`^${rootRe}/patches/`), + new RegExp(`^${rootRe}/scripts/`), + new RegExp(`^${rootRe}/tools/`), ] module.exports = config From 69ea954f68b7dd865b655673c2cb4d57bcdd129b Mon Sep 17 00:00:00 2001 From: chrisnojima Date: Fri, 29 May 2026 17:01:04 -0400 Subject: [PATCH 5/9] fix profile dropdown button full-width regression on mobile (#29265) --- shared/profile/user/actions/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared/profile/user/actions/index.tsx b/shared/profile/user/actions/index.tsx index b7b37964f035..eb061bd43022 100644 --- a/shared/profile/user/actions/index.tsx +++ b/shared/profile/user/actions/index.tsx @@ -208,7 +208,7 @@ const DropdownButton = (p: DropdownProps) => { const {showPopup, popup, popupAnchor} = Kb.usePopup2(makePopup) return ( - + From 5fdab5c1d5fe04a1bf10dc760073c5d79747afbb Mon Sep 17 00:00:00 2001 From: chrisnojima Date: Fri, 29 May 2026 17:05:26 -0400 Subject: [PATCH 6/9] fix fs sort button content-sizing regression on desktop (#29265) --- shared/fs/top-bar/sort.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared/fs/top-bar/sort.tsx b/shared/fs/top-bar/sort.tsx index 43a8934d6084..1416c200d9c4 100644 --- a/shared/fs/top-bar/sort.tsx +++ b/shared/fs/top-bar/sort.tsx @@ -80,7 +80,7 @@ const Container = (ownProps: OwnProps) => { const {showPopup, popup, popupAnchor} = Kb.usePopup2(makePopup) return shownSortSetting ? ( <> - + {getTextFromSortSetting(shownSortSetting)} From f029628e2d74d0a1fdba28b6baa72e2dc775355f Mon Sep 17 00:00:00 2001 From: chrisnojima Date: Fri, 29 May 2026 17:07:47 -0400 Subject: [PATCH 7/9] fix fs path-item header and destination-picker full-width regression on mobile (#29265) --- shared/fs/browser/destination-picker.tsx | 8 ++++---- shared/fs/common/path-item-action/header.tsx | 1 + 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/shared/fs/browser/destination-picker.tsx b/shared/fs/browser/destination-picker.tsx index c740a772dfea..938874c6e49b 100644 --- a/shared/fs/browser/destination-picker.tsx +++ b/shared/fs/browser/destination-picker.tsx @@ -126,7 +126,7 @@ const ConnectedDestinationPicker = (ownProps: OwnProps) => { {!!onBackUp && ( - + { )} {!!onCopyHere && ( - + { )} {!!onMoveHere && ( - + ( const NewFolder = (p: {onNewFolder?: () => void}) => { const {onNewFolder} = p return ( - + Create new folder diff --git a/shared/fs/common/path-item-action/header.tsx b/shared/fs/common/path-item-action/header.tsx index c03b15ef04d4..ee1e6d50dbac 100644 --- a/shared/fs/common/path-item-action/header.tsx +++ b/shared/fs/common/path-item-action/header.tsx @@ -13,6 +13,7 @@ const Header = (props: Props) => ( e => e?.stopPropagation() } direction="vertical" + fullWidth={true} > From b2795a84459fa986cd6555f1ded1ea78b44ee39c Mon Sep 17 00:00:00 2001 From: chrisnojima Date: Fri, 29 May 2026 17:08:25 -0400 Subject: [PATCH 8/9] update migrate-clickable-box skill with fullWidth gotchas (#29265) --- skill/migrate-clickable-box/SKILL.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/skill/migrate-clickable-box/SKILL.md b/skill/migrate-clickable-box/SKILL.md index 3a340d9ad9e0..f8e33040e966 100644 --- a/skill/migrate-clickable-box/SKILL.md +++ b/skill/migrate-clickable-box/SKILL.md @@ -72,6 +72,18 @@ Read each matched file fully before classifying. ``` +**⚠️ `fullWidth` content-sizing gotcha (mobile):** When the outer CB1 is **content-sized** (no explicit width, sitting alongside siblings in a `justifyContent: center` row), the inner Box2's `fullWidth` only stretched the Box2 to fill the CB1 — it did NOT make the CB1 itself full-width. Promoting `fullWidth` to CB3 changes this: CB3 gets `width: '100%'` on mobile, making it fill its entire parent and breaking the centered layout. + +**Diagnosis:** Look at the CB's parent. If it's a horizontal container with `justifyContent: center` or `centerChildren={true}` that has OTHER siblings alongside this CB, the CB was content-sized. In that case, do NOT add `fullWidth` to CB3. + +```tsx +// ❌ Wrong — CB1 was content-sized, moving fullWidth to CB3 breaks centering + + +// ✅ Correct — drop fullWidth since the old CB1 itself had no width + +``` + ### Pattern B — CB with only click props, no style ```tsx @@ -88,6 +100,8 @@ Read each matched file fully before classifying. ``` +**⚠️ CB1 stretched by parent — CB3 doesn't (mobile):** In RN, the default `alignItems: stretch` on a vertical flex parent made CB1 (TouchableOpacity/WithoutFeedback) fill the full width automatically. CB3 overrides this with `alignSelf: center` when neither `fullWidth` nor `fullHeight` is set. **Any Pattern B or C conversion where the old CB1 filled its parent via the default stretch behavior now needs `fullWidth={true}` added explicitly.** This is most common for rows in vertical lists, popup/menu headers, and full-width banner items. + **⚠️ `box2_centered` / `alignSelf: center` gotcha:** CB3 applies `align-self: center` (desktop: `box2_centered` CSS class; mobile: `nativeStyles.centered = {alignSelf: 'center'}`) whenever neither `fullWidth` nor `fullHeight` is set. CB1 did NOT do this. This affects **both platforms**. If the original CB was expected to fill its parent (e.g. list rows, banners, full-width wrappers), omitting `fullWidth={true}` will shrink it to content-width. Always check the parent layout context — when in doubt, add `fullWidth={true}`. ### Pattern C — CB with style that encodes flex layout From 9ffd20405fd44bb603724917daaa399b8e390467 Mon Sep 17 00:00:00 2001 From: chrisnojima Date: Sat, 30 May 2026 11:18:08 -0400 Subject: [PATCH 9/9] cb3 5 (#29267) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * migrate shared/chat/ ClickableBox/CB2 → CB3 * migrate shared/common-adapters/ ClickableBox/CB2 → CB3 * complete ClickableBox3 migration: remove legacy CB1/CB2 exports * WIP * fixes * Fix info panel tabs: natural width, centered text, divider spans full tab width * WIP * fix prove-your dialog items to be full width Without fullWidth={true}, ClickableBox3 gets alignSelf:center applied, centering each provider row instead of spanning the modal width. * fix CardListItem body text centering: add fullWidth to body Box2 Nested Box2 direction="vertical" without fullWidth gets box2_centered (align-self:center) applied, horizontally centering it within its column flex parent. Fixed across all CardListItem callers and in list-item.tsx's body wrapper. * remove ChoiceList/RichButton, replace usages with ListItem Card * remove ClickableBox/ClickableBox2 and migration plan — all usages migrated to ClickableBox3 * mass clean (#29268) * simplify-ui: git/ — remove redundant wrappers, dead styles/comments, normalize patterns * simplify-ui: devices/ — deduplicate icon logic, extract constants, replace style props * simplify-ui: wallets/ — rename Container, extract shared styles, remove redundant props * simplify-ui: tracker/ — fix hover-opacity typo, dedup utilities, rename Container, replace flexShrink props * simplify-ui: settings/ — remove redundant wrappers, move styles to props, clean dead code * simplify-ui: crypto/ — inline IIFEs, merge imports, clean up style props and names * simplify-ui: teams/ — merge styles, fix functions-as-values, extract string constants, remove wrappers * simplify-ui: signup/ — extract shared input width, fix prop shorthands, remove dead code * simplify-ui: people/ — remove identity maps, dead code, inline wrappers, move style props * simplify-ui: profile/ — remove dead code, dedup styles, replace Kb shims, noShrink props * address PR feedback: safe nav in async callback, fix avatar overlay positioning, restore .tsx extension * simplify-ui: full codebase pass — rename Containers, remove dead code, move style props Ran simplify-ui-section skill across all UI directories via parallel subagents: chat/, common-adapters/, fs/, login/, provision/, team-building/, unlock-folders/, menubar/, pinentry/, incoming-share/, deeplinks/, router-v2/, and revisits of profile/, people/, signup/, crypto/, teams/, settings/, tracker/, wallets/, devices/, git/. * fix back button hover area: remove inline-block and size(14) from iconContainer The 14×14px fixed size caused the hover highlight to appear only in the upper-left corner while the icon extended beyond it. The container now sizes naturally around the icon with padding defining the hit area. * fix Checkbox centering: add alignSelf=flex-start to ClickableBox3 * WIP * fix iOS e2e: restore testID on mobile crypto nav rows The RichButton→ListItem migration dropped testID; wrap ListItem in Box2 to carry it. --- plans/clickablebox3.md | 67 ----- shared/chat/audio/audio-player.tsx | 7 +- shared/chat/avatars.tsx | 6 +- shared/chat/blocking/block-modal.tsx | 4 +- shared/chat/blocking/invitation-to-block.tsx | 3 +- .../attachment-fullscreen/index.tsx | 24 +- .../conversation/attachment-get-titles.tsx | 75 +++--- shared/chat/conversation/bot/team-picker.tsx | 22 +- shared/chat/conversation/error.tsx | 9 +- shared/chat/conversation/fwd-msg.tsx | 38 ++- .../conversation/info-panel/attachments.tsx | 104 ++++---- shared/chat/conversation/info-panel/index.tsx | 16 +- .../info-panel/settings/min-writer-role.tsx | 9 +- .../conversation/input-area/normal/input.tsx | 22 +- .../input-area/suggestors/common.tsx | 4 +- .../conversation/list-area/jump-to-recent.tsx | 3 +- .../conversation/messages/attachment/file.tsx | 4 +- .../messages/attachment/image/index.tsx | 5 +- .../messages/attachment/shared.tsx | 8 +- .../conversation/messages/cards/make-team.tsx | 38 ++- .../conversation/messages/cards/new-chat.tsx | 38 ++- .../chat/conversation/messages/emoji-row.tsx | 30 +-- .../messages/message-popup/reactionitem.tsx | 9 +- .../conversation/messages/react-button.tsx | 63 ++--- .../chat/conversation/messages/text/reply.tsx | 56 ++-- .../text/unfurl/unfurl-list/image/index.tsx | 4 +- .../text/unfurl/unfurl-list/image/video.tsx | 5 +- .../messages/wrapper/exploding-meta.tsx | 6 +- shared/chat/conversation/no-conversation.tsx | 12 +- shared/chat/conversation/pinned-message.tsx | 72 +++--- .../conversation/rekey/participant-rekey.tsx | 59 ++--- shared/chat/conversation/search.tsx | 7 +- shared/chat/conversation/you-are-reset.tsx | 7 +- shared/chat/create-channel/index.tsx | 14 +- shared/chat/delete-history-warning.tsx | 5 +- shared/chat/emoji-picker/container.tsx | 21 +- shared/chat/emoji-picker/index.tsx | 8 +- shared/chat/emoji-picker/skin-tone-picker.tsx | 19 +- .../inbox-and-conversation-get-options.tsx | 4 +- shared/chat/inbox-search/index.tsx | 8 +- shared/chat/inbox/filter-row.tsx | 8 +- shared/chat/inbox/index.tsx | 9 +- shared/chat/inbox/row/big-team-channel.tsx | 5 +- shared/chat/inbox/row/big-team-header.tsx | 5 +- shared/chat/inbox/row/big-teams-divider.tsx | 5 +- shared/chat/inbox/row/small-team/index.tsx | 4 +- shared/chat/inbox/row/start-new-chat.tsx | 8 +- shared/chat/inbox/search-row.tsx | 2 - shared/chat/inbox/unread-shortcut.tsx | 38 +-- shared/chat/new-team-dialog-container.tsx | 16 +- shared/chat/payments/status/index.tsx | 12 +- shared/chat/pdf/index.tsx | 8 +- shared/chat/selectable-big-team-channel.tsx | 35 ++- shared/chat/selectable-small-team.tsx | 49 ++-- .../conversation-list/conversation-list.tsx | 65 ++--- shared/chat/send-to-chat/index.tsx | 76 +++--- shared/chat/top-line.tsx | 4 +- .../avatar/icon-to-img-set.tsx | 6 +- shared/common-adapters/avatar/index.tsx | 3 +- shared/common-adapters/badge.tsx | 6 +- shared/common-adapters/banner.tsx | 12 +- shared/common-adapters/button-bar.tsx | 17 +- shared/common-adapters/checkbox.tsx | 16 +- shared/common-adapters/choice-list.css | 23 -- shared/common-adapters/choice-list.tsx | 160 ------------ shared/common-adapters/clickable-box.tsx | 239 ------------------ shared/common-adapters/copy-text.tsx | 7 - shared/common-adapters/dropdown.tsx | 89 +++---- shared/common-adapters/emoji/custom-emoji.tsx | 7 +- shared/common-adapters/emoji/index.tsx | 6 +- .../floating-menu/menu-layout/index.tsx | 51 ++-- shared/common-adapters/index-impl.js | 6 - shared/common-adapters/index.tsx | 3 - shared/common-adapters/info-note.tsx | 14 +- shared/common-adapters/list-item.tsx | 69 +++-- shared/common-adapters/list.tsx | 1 - shared/common-adapters/markdown/channel.tsx | 4 +- .../markdown/maybe-mention/index.tsx | 14 +- shared/common-adapters/markdown/spoiler.tsx | 46 ++-- shared/common-adapters/name-with-icon.tsx | 27 +- shared/common-adapters/phone-input.tsx | 30 +-- shared/common-adapters/placeholder.tsx | 2 +- shared/common-adapters/popup/index.tsx | 11 +- shared/common-adapters/profile-card.tsx | 9 +- shared/common-adapters/radio-button.tsx | 14 +- shared/common-adapters/rich-button.tsx | 74 ------ shared/common-adapters/search-filter.tsx | 30 +-- shared/common-adapters/section-divider.tsx | 12 +- shared/common-adapters/switch.tsx | 13 +- shared/common-adapters/tabs.tsx | 33 +-- shared/common-adapters/wave-button.tsx | 10 +- shared/common-adapters/with-tooltip.tsx | 7 +- shared/crypto/decrypt.tsx | 13 +- shared/crypto/encrypt.tsx | 32 +-- shared/crypto/input.tsx | 62 ++--- shared/crypto/output.tsx | 35 ++- shared/crypto/sign.tsx | 25 +- shared/crypto/sub-nav/left-nav.desktop.tsx | 48 ++-- shared/crypto/sub-nav/nav-row.tsx | 23 +- shared/crypto/verify.tsx | 13 +- shared/deeplinks/error.tsx | 21 +- shared/devices/add-device.tsx | 4 +- shared/devices/device-icon.tsx | 3 +- shared/devices/device-page.tsx | 31 ++- shared/devices/device-revoke.tsx | 8 +- shared/devices/index.tsx | 45 ++-- shared/devices/paper-key.tsx | 53 ++-- shared/fs/banner/conflict-banner.tsx | 7 +- shared/fs/banner/reset-banner.tsx | 37 ++- .../container.tsx | 8 +- shared/fs/browser/destination-picker.tsx | 2 +- shared/fs/browser/index.tsx | 2 +- shared/fs/browser/offline.tsx | 48 ++-- shared/fs/browser/rows/editing.tsx | 14 +- shared/fs/browser/rows/still.tsx | 6 +- shared/fs/browser/rows/tlf.tsx | 2 +- shared/fs/browser/sort-state.tsx | 4 +- shared/fs/common/folder-view-filter-icon.tsx | 15 +- shared/fs/common/hooks.tsx | 3 - .../path-item-action/confirm-delete.tsx | 44 +--- shared/fs/common/path-status-icon.tsx | 2 +- shared/fs/common/pie-slice.tsx | 15 +- shared/fs/common/rpc-state.tsx | 2 +- shared/fs/common/status.tsx | 3 +- shared/fs/footer/upload-container.tsx | 11 +- shared/fs/nav-header/main-banner.tsx | 14 +- shared/fs/nav-header/title.tsx | 6 +- shared/fs/top-bar/sort.tsx | 39 +-- shared/fs/top-bar/sync-toggle.tsx | 4 +- shared/git/delete-repo.tsx | 170 ++++++------- shared/git/index.tsx | 12 +- shared/git/new-repo.tsx | 196 ++++++-------- shared/git/row.tsx | 87 ++++--- shared/git/select-channel.tsx | 9 +- shared/incoming-share/index.tsx | 6 +- shared/login/forms/container.tsx | 1 - shared/login/join-or-login.tsx | 15 +- shared/login/loading.tsx | 13 +- .../recover-password/device-selector.tsx | 26 +- shared/login/recover-password/error-modal.tsx | 6 +- shared/login/recover-password/error.tsx | 6 +- .../login/recover-password/explain-device.tsx | 3 +- shared/login/recover-password/paper-key.tsx | 29 +-- shared/login/relogin/container.tsx | 11 +- shared/login/reset/password-enter.tsx | 18 +- shared/login/signup/common.tsx | 20 +- shared/menubar/index.desktop.tsx | 136 +++++----- shared/people/announcement.tsx | 17 +- shared/people/container.tsx | 1 - shared/people/follow-notification.tsx | 4 +- shared/people/follow-suggestions.tsx | 4 +- shared/people/index.tsx | 25 +- shared/people/item.tsx | 2 +- shared/people/routes.tsx | 6 +- shared/people/todo.tsx | 68 ++--- shared/pinentry/index.desktop.tsx | 15 +- shared/profile/add-to-team.tsx | 77 +++--- shared/profile/edit-avatar/index.tsx | 6 +- shared/profile/edit-profile.tsx | 86 +++---- shared/profile/generic/proofs-list.tsx | 60 +++-- shared/profile/modal.tsx | 27 +- shared/profile/pgp/choice/index.tsx | 65 +++-- shared/profile/pgp/import/index.tsx | 61 +++-- shared/profile/platform-icon.tsx | 37 ++- shared/profile/prove-website-choice.tsx | 42 +-- shared/profile/showcase-team-offer.tsx | 86 +++---- shared/profile/user/actions/follow-button.tsx | 8 +- shared/profile/user/actions/index.tsx | 41 +-- shared/profile/user/friend.tsx | 6 +- shared/profile/user/hooks.tsx | 34 +-- shared/profile/user/index.tsx | 3 +- shared/profile/user/teams/index.tsx | 18 +- shared/profile/user/teams/openmeta.tsx | 15 +- shared/profile/user/teams/team-section.tsx | 3 +- shared/profile/user/teams/teaminfo.tsx | 51 +--- shared/provision/code-page/container.tsx | 50 ++-- .../code-page/qr-scan/not-authorized.tsx | 3 +- shared/provision/error.tsx | 21 +- shared/provision/forgot-username.tsx | 2 +- shared/provision/paper-key.tsx | 30 +-- shared/provision/password.tsx | 18 +- .../select-other-device-connected.tsx | 4 +- shared/provision/set-public-name.tsx | 22 +- shared/provision/troubleshooting.tsx | 3 +- shared/provision/username-or-email.tsx | 13 +- shared/router-v2/account-switcher/index.tsx | 5 +- shared/router-v2/common.tsx | 4 +- shared/router-v2/header/index.desktop.tsx | 2 - shared/router-v2/linking.tsx | 104 ++++---- .../router-v2/screen-layout-modal.desktop.tsx | 2 +- shared/settings/about.tsx | 5 +- shared/settings/account/email-phone-row.tsx | 2 +- shared/settings/advanced.tsx | 8 +- shared/settings/chat.tsx | 51 ++-- shared/settings/delete-confirm/index.tsx | 3 +- shared/settings/display.tsx | 5 +- shared/settings/feedback/container.shared.tsx | 4 - shared/settings/feedback/container.tsx | 5 +- shared/settings/feedback/index.tsx | 18 +- shared/settings/notifications/index.tsx | 51 ++-- shared/settings/notifications/render.tsx | 3 +- shared/settings/password.tsx | 14 +- shared/settings/proxy.tsx | 12 +- shared/settings/routes.tsx | 2 +- shared/settings/subheading.shared.tsx | 5 - shared/signup/common.tsx | 35 +-- shared/signup/device-name.tsx | 9 +- shared/signup/email.tsx | 31 +-- shared/signup/feedback.tsx | 3 +- shared/signup/phone-number/index.tsx | 28 +- shared/signup/phone-number/verify.tsx | 8 +- shared/signup/username.tsx | 12 +- shared/team-building/contact-restricted.tsx | 16 +- shared/team-building/continue-button.tsx | 2 +- shared/team-building/email-search.tsx | 16 +- shared/team-building/go-button.tsx | 2 +- shared/team-building/index.tsx | 10 +- shared/team-building/input.tsx | 20 +- shared/team-building/list-body.tsx | 8 +- shared/team-building/phone-search.tsx | 2 +- shared/team-building/recs-and-recos.tsx | 2 +- .../search-result/common-result.tsx | 9 + .../search-result/hellobot-result.tsx | 17 +- .../search-result/people-result.tsx | 8 +- .../search-result/user-result.tsx | 12 +- .../search-result/you-result.tsx | 22 +- shared/team-building/shared.tsx | 6 + shared/team-building/team-box.tsx | 23 +- .../add-members-wizard/add-from-where.tsx | 36 +-- shared/teams/common/activity.tsx | 10 +- shared/teams/common/channels-widget.tsx | 26 +- shared/teams/delete-team.tsx | 9 +- shared/teams/invite-by-email.tsx | 25 +- shared/teams/main/header.tsx | 6 - shared/teams/main/index.tsx | 52 ++-- shared/teams/main/team-row.tsx | 39 ++- .../teams/new-team/wizard/make-big-team.tsx | 19 +- shared/teams/new-team/wizard/team-purpose.tsx | 39 +-- shared/teams/rename-team.tsx | 12 +- shared/teams/role-picker-utils.tsx | 31 ++- shared/teams/role-picker.tsx | 2 +- shared/teams/team/index.tsx | 2 - shared/teams/team/member/index.new.tsx | 6 +- shared/teams/team/rows/bot-row/bot.tsx | 4 +- shared/teams/team/rows/emoji-row/item.tsx | 99 ++++---- shared/teams/team/rows/empty-row.tsx | 4 +- shared/teams/team/rows/invite-row/invite.tsx | 22 +- shared/teams/team/rows/loading.tsx | 8 +- shared/teams/team/settings-tab/index.tsx | 15 +- .../team/settings-tab/retention/index.tsx | 126 ++++----- shared/teams/team/tabs.tsx | 26 +- shared/tracker/assertion.tsx | 97 ++----- shared/tracker/bio.tsx | 18 +- shared/tracker/index.desktop.tsx | 79 ++---- shared/tracker/model.tsx | 56 ++++ shared/tracker/use-profile.tsx | 16 +- shared/unlock-folders/device-list.desktop.tsx | 27 +- shared/unlock-folders/index.desktop.tsx | 8 +- shared/unlock-folders/success.desktop.tsx | 14 +- shared/wallets/index.tsx | 9 +- shared/wallets/really-remove-account.tsx | 33 +-- shared/wallets/remove-account.tsx | 13 +- shared/wallets/wallet-popup.tsx | 6 + skill/simplify-ui-section/SKILL.md | 9 + 264 files changed, 2493 insertions(+), 3953 deletions(-) delete mode 100644 plans/clickablebox3.md delete mode 100644 shared/common-adapters/choice-list.css delete mode 100644 shared/common-adapters/choice-list.tsx delete mode 100644 shared/common-adapters/clickable-box.tsx delete mode 100644 shared/common-adapters/rich-button.tsx delete mode 100644 shared/settings/feedback/container.shared.tsx delete mode 100644 shared/settings/subheading.shared.tsx diff --git a/plans/clickablebox3.md b/plans/clickablebox3.md deleted file mode 100644 index c1f9c1b89f41..000000000000 --- a/plans/clickablebox3.md +++ /dev/null @@ -1,67 +0,0 @@ -# ClickableBox3 Migration Plan - -> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. - -**Goal:** Replace all `ClickableBox` and `ClickableBox2` usages with `ClickableBox3`, a single component that combines Box2's layout prop surface with CB2's click/press handling, eliminating the ubiquitous `` nesting pattern. - -**Architecture:** `ClickableBox3` is `Box2Props & {onClick?, onLongPress?, hitSlop?}` — `direction` is required (same as Box2). On desktop it calls `box2ClassNames()` (shared helper extracted from Box2) and adds `clickable-box2` for cursor. On mobile it calls `box2SharedProps()` and passes the result to `Pressable`. - -**Tech Stack:** React, React Native, TypeScript, existing Box2/CB2 internals in `common-adapters/` - ---- - -## Background: CB1 vs CB2 vs CB3 - -| | CB1 | CB2 | CB3 | -|---|---|---|---| -| Desktop | `
` + JS hover state, underlay overlay | `
` + `.clickable-box2` CSS cursor | `
` + Box2 CSS classes + `.clickable-box2` | -| Mobile | `TouchableOpacity` / `TouchableWithoutFeedback` | `Pressable` | `Pressable` + Box2 style computation | -| Layout | `display:flex, flexDirection:column` injected by default | none | required via `direction` prop (same as Box2) | -| Props | large (hoverColor, underlayColor, feedback, etc.) | minimal | Box2Props + onClick/onLongPress/hitSlop | - ---- - -## ✅ Done: ClickableBox3 implemented and devices/ migrated - -Committed in `3ac6c14b82`. Key points for future reference: -- `ClickableBox3Props = Box2Props & {onClick?, onLongPress?, hitSlop?}` — `direction` required; desktop mouse events (`onMouseDown/Up/Leave/Move/Over/Enter`, `onContextMenu`) are in `Box2Props` and passed through to the `
` -- `box2ClassNames()` extracted from Box2 and shared; `box2SharedProps` exported from `box.tsx` -- `devices/` pilot complete: 3 CB2 usages → CB3, inner Box2 wrappers eliminated, `mobileAddHeader` style simplified - ---- - -## Migration Checklist (all remaining files) - -Use `migrate-clickable-box` skill for each chunk. Run `yarn lint && yarn tsc` and commit after each directory. - -### Pilot -- [x] `shared/devices/` (6 total) - -### Round 1 — small -- [x] `shared/git/` (3) -- [x] `shared/incoming-share/` (2) -- [x] `shared/signup/` (2) -- [x] `shared/provision/` (4) -- [x] `shared/people/` (2) -- [x] `shared/settings/` (4) -- [x] `shared/profile/` (10) - -### Round 2 — medium -- [x] `shared/tracker/` (4) -- [x] `shared/menubar/` (3) -- [x] `shared/app/` (4) -- [x] `shared/router-v2/` (9) -- [x] `shared/teams/` (25+) -- [x] `shared/team-building/` (9+) - -### Round 3 — large -- [x] `shared/fs/` (10+) -- [ ] `shared/chat/` (60+) - -### Last — shared primitives -- [ ] `shared/common-adapters/` (26) - -### Completion criteria -- [ ] `grep -rn "ClickableBox[^3]" shared/ | grep -v "clickable-box\|Props\|import\|export"` → zero results -- [ ] `yarn lint && yarn tsc` — zero errors -- [ ] Remove `ClickableBox` default export, `ClickableBox2`, `Props`, `Props2` from `clickable-box.tsx` diff --git a/shared/chat/audio/audio-player.tsx b/shared/chat/audio/audio-player.tsx index 7fdd934a5ca5..89556b0f0b5e 100644 --- a/shared/chat/audio/audio-player.tsx +++ b/shared/chat/audio/audio-player.tsx @@ -98,14 +98,14 @@ const AudioPlayer = (props: Props) => { style={Kb.Styles.collapseStyles([styles.container, {height: big ? 56 : 40}])} gap="tiny" > - + - - + + {formatAudioRecordDuration(timeLeft)} @@ -123,7 +123,6 @@ const styles = Kb.Styles.styleSheetCreate(() => ({ backgroundColor: Kb.Styles.globalColors.white, }, visContainer: { - alignItems: 'flex-start', minWidth: 40, }, })) diff --git a/shared/chat/avatars.tsx b/shared/chat/avatars.tsx index 3289bb3dd442..f6dadd14c090 100644 --- a/shared/chat/avatars.tsx +++ b/shared/chat/avatars.tsx @@ -82,10 +82,8 @@ const Avatars = function Avatars(p: Props) { if (!participantTwo) { return ( - - - - + + ) } diff --git a/shared/chat/blocking/block-modal.tsx b/shared/chat/blocking/block-modal.tsx index fbaca092b401..faf333f238ea 100644 --- a/shared/chat/blocking/block-modal.tsx +++ b/shared/chat/blocking/block-modal.tsx @@ -127,7 +127,7 @@ const ReportOptions = (props: ReportOptionsProps) => { ) } -const Container = function BlockModal(ownProps: OwnProps) { +const BlockModal = (ownProps: OwnProps) => { const {context, conversationIDKey, blockUserByDefault = false, filterUserByDefault = false} = ownProps const {flagUserByDefault = false, reportsUserByDefault = false, team: teamname} = ownProps let {username: adderUsername, others} = ownProps @@ -496,7 +496,7 @@ const Container = function BlockModal(ownProps: OwnProps) { ) } -export default Container +export default BlockModal const getListHeightStyle = (numOthers: number, expanded: boolean) => ({ height: diff --git a/shared/chat/blocking/invitation-to-block.tsx b/shared/chat/blocking/invitation-to-block.tsx index 155028481a0e..34840a423940 100644 --- a/shared/chat/blocking/invitation-to-block.tsx +++ b/shared/chat/blocking/invitation-to-block.tsx @@ -141,7 +141,7 @@ const BlockButtons = () => { ) : ( - + {team ? `${adder} added you to this team.` : `You don't follow ${adder}.`} @@ -166,7 +166,6 @@ const styles = Kb.Styles.styleSheetCreate( }), buttonContainer: {maxWidth: 322}, container: { - alignItems: 'center', alignSelf: 'flex-start', marginLeft: 57, }, diff --git a/shared/chat/conversation/attachment-fullscreen/index.tsx b/shared/chat/conversation/attachment-fullscreen/index.tsx index 1a8504345b0d..b5315e66d4b1 100644 --- a/shared/chat/conversation/attachment-fullscreen/index.tsx +++ b/shared/chat/conversation/attachment-fullscreen/index.tsx @@ -31,12 +31,14 @@ type ArrowProps = { const Arrow = (props: ArrowProps) => { const {left, onClick} = props return ( - { - e.stopPropagation() + e?.stopPropagation() onClick() } : undefined @@ -48,7 +50,7 @@ const Arrow = (props: ArrowProps) => { color={Kb.Styles.globalColors.white} style={Kb.Styles.collapseStyles([styles.arrow, left && styles.arrowLeft, !left && styles.arrowRight])} /> - + ) } @@ -64,7 +66,9 @@ const DesktopFullscreen = (p: Props) => { const preload = (src: string, onLoad: () => void, onError: () => void) => { // Use dynamic require to avoid DOM type dependency - const ctor = (globalThis as unknown as {Image?: new () => {src: string; onload: () => void; onerror: () => void}}).Image + const ctor = ( + globalThis as unknown as {Image?: new () => {src: string; onload: () => void; onerror: () => void}} + ).Image if (!ctor) return const img = new ctor() img.src = src @@ -114,7 +118,7 @@ const DesktopFullscreen = (p: Props) => { {path && ( - + {!isZoomed ? : undefined} { )} {!isZoomed && } - + )} @@ -413,11 +417,8 @@ const styles = Kb.Styles.styleSheetCreate( arrowRight: {left: 1}, circle: Kb.Styles.platformStyles({ isElectron: { - ...Kb.Styles.globalStyles.flexBoxColumn, - ...Kb.Styles.centered(), alignSelf: 'center', borderRadius: 36, - cursor: 'pointer', flexShrink: 0, ...Kb.Styles.size(36), margin: Kb.Styles.globalMargins.small, @@ -429,11 +430,6 @@ const styles = Kb.Styles.styleSheetCreate( padding: Kb.Styles.globalMargins.small, }, }), - contentsFit: { - ...Kb.Styles.globalStyles.flexBoxRow, - flex: 1, - ...Kb.Styles.size('100%'), - }, disabled: {opacity: 0.3}, ellipsisContainer: Kb.Styles.platformStyles({ isElectron: Kb.Styles.desktopStyles.windowDraggingClickable, diff --git a/shared/chat/conversation/attachment-get-titles.tsx b/shared/chat/conversation/attachment-get-titles.tsx index 2c938875bd84..c0646705aa72 100644 --- a/shared/chat/conversation/attachment-get-titles.tsx +++ b/shared/chat/conversation/attachment-get-titles.tsx @@ -198,38 +198,36 @@ const ContainerInner = (ownProps: OwnProps) => { return ( <> - inputRef.current?.blur()}> - - {preview} - {pathAndInfos.length > 0 && !isMobile && ( - - Filename - - {info.filename} ({index + 1} of {pathAndInfos.length}) - - - )} - - { - e.stopPropagation() - }} - autoCorrect={true} - placeholder={titleHint} - multiline={true} - rowsMin={2} - value={titles[index]} - onEnterKeyDown={onNext} - onChangeText={updateTitle} - hideBorder={true} - containerStyle={styles.inputBare} - inputStyle={styles.input} - /> + inputRef.current?.blur()}> + {preview} + {pathAndInfos.length > 0 && !isMobile && ( + + Filename + + {info.filename} ({index + 1} of {pathAndInfos.length}) + + )} + + { + e.stopPropagation() + }} + autoCorrect={true} + placeholder={titleHint} + multiline={true} + rowsMin={2} + value={titles[index]} + onEnterKeyDown={onNext} + onChangeText={updateTitle} + hideBorder={true} + containerStyle={styles.inputBare} + inputStyle={styles.input} + /> - + {!isMobile && } {isLast ? ( @@ -273,16 +271,9 @@ const styles = Kb.Styles.styleSheetCreate( isMobile: {flexShrink: 1}, }), container2: Kb.Styles.platformStyles({ - common: { - alignItems: 'center', - flexGrow: 1, - width: '100%', - }, - isMobile: {flexShrink: 1}, - }), - containerOuter: Kb.Styles.platformStyles({ + common: {flexGrow: 1}, isElectron: {height: '100%', overflow: 'hidden'}, - isMobile: {flexGrow: 1, flexShrink: 1}, + isMobile: {flexShrink: 1, flexGrow: 1}, }), filename: Kb.Styles.platformStyles({ isElectron: { @@ -323,8 +314,4 @@ const styles = Kb.Styles.styleSheetCreate( }) as const ) -const Container = (ownProps: OwnProps) => { - return -} - -export default Container +export default ContainerInner diff --git a/shared/chat/conversation/bot/team-picker.tsx b/shared/chat/conversation/bot/team-picker.tsx index fcda27213d97..1cc6088612b2 100644 --- a/shared/chat/conversation/bot/team-picker.tsx +++ b/shared/chat/conversation/bot/team-picker.tsx @@ -44,18 +44,16 @@ const BotTeamPicker = (props: Props) => { } const renderResult = (index: number, item: T.RPCChat.ConvSearchHit) => { return ( - onSelect(item.convID)}> - - {item.isTeam ? ( - - ) : ( - - )} - - {item.name} - - - + onSelect(item.convID)} direction="horizontal" fullWidth={true} gap="tiny" style={styles.results}> + {item.isTeam ? ( + + ) : ( + + )} + + {item.name} + + ) } return ( diff --git a/shared/chat/conversation/error.tsx b/shared/chat/conversation/error.tsx index aa47fb7a036c..867be46841ff 100644 --- a/shared/chat/conversation/error.tsx +++ b/shared/chat/conversation/error.tsx @@ -4,11 +4,9 @@ import {useConversationThreadSelector} from './thread-context' const ConversationError = () => { const text = useConversationThreadSelector(s => s.meta.snippet) ?? '' return ( - + There was an error loading this conversation. - - The error is: - + The error is: @@ -19,9 +17,6 @@ const ConversationError = () => { const styles = Kb.Styles.styleSheetCreate( () => ({ - container: { - padding: Kb.Styles.globalMargins.medium, - }, errorText: {flexGrow: 1}, }) as const ) diff --git a/shared/chat/conversation/fwd-msg.tsx b/shared/chat/conversation/fwd-msg.tsx index 77916902fc06..18e179f5c929 100644 --- a/shared/chat/conversation/fwd-msg.tsx +++ b/shared/chat/conversation/fwd-msg.tsx @@ -159,23 +159,21 @@ const TeamPickerInner = (props: Props) => { const renderResult = (index: number, item: T.RPCChat.ConvSearchHit) => { return ( - onSelect(item.convID)}> - - {item.isTeam ? ( - - ) : ( - - )} - - {item.name} - - - + onSelect(item.convID)} direction="horizontal" fullWidth={true} gap="tiny" style={styles.results}> + {item.isTeam ? ( + + ) : ( + + )} + + {item.name} + + ) } @@ -306,8 +304,4 @@ const styles = Kb.Styles.styleSheetCreate( }) as const ) -const TeamPicker = (props: Props) => { - return -} - -export default TeamPicker +export default TeamPickerInner diff --git a/shared/chat/conversation/info-panel/attachments.tsx b/shared/chat/conversation/info-panel/attachments.tsx index c56651a3efcd..e0094cb63780 100644 --- a/shared/chat/conversation/info-panel/attachments.tsx +++ b/shared/chat/conversation/info-panel/attachments.tsx @@ -188,7 +188,7 @@ const MediaThumb = (props: MediaThumbProps) => { const {sizing, thumb} = props return ( - + {thumb.typ === ThumbTyp.AUDIO ? ( @@ -206,7 +206,7 @@ const MediaThumb = (props: MediaThumbProps) => { ) : ( )} - + {thumb.typ === ThumbTyp.VIDEO && ( @@ -231,18 +231,16 @@ const DocViewRow = (props: DocViewRowProps) => { }) return ( - - - - - {item.name} - {item.name !== item.fileName && {item.fileName}} - - Sent by {item.author} • {formatTimeForMessages(item.ctime)} - - + + + + {item.name} + {item.name !== item.fileName && {item.fileName}} + + Sent by {item.author} • {formatTimeForMessages(item.ctime)} + - + {item.downloading && ( Downloading... @@ -273,7 +271,10 @@ const getColor = (selected: boolean) => const AttachmentTypeSelector = (props: SelectorProps) => ( - props.onSelectView(T.RPCChat.GalleryItemTyp.media)} style={Kb.Styles.collapseStyles([ styles.selectorItemContainer, @@ -284,8 +285,11 @@ const AttachmentTypeSelector = (props: SelectorProps) => ( Media - - + props.onSelectView(T.RPCChat.GalleryItemTyp.doc)} style={Kb.Styles.collapseStyles([ styles.selectorDocContainer, @@ -296,8 +300,11 @@ const AttachmentTypeSelector = (props: SelectorProps) => ( Docs - - + props.onSelectView(T.RPCChat.GalleryItemTyp.link)} style={Kb.Styles.collapseStyles([ styles.selectorItemContainer, @@ -308,7 +315,7 @@ const AttachmentTypeSelector = (props: SelectorProps) => ( Links - + ) @@ -392,13 +399,10 @@ const styles = Kb.Styles.styleSheetCreate( }, selectorItemContainer: Kb.Styles.platformStyles({ common: { - ...Kb.Styles.globalStyles.flexBoxColumn, - ...Kb.Styles.globalStyles.flexBoxCenter, borderBottomWidth: 1, borderColor: Kb.Styles.globalColors.blue, borderStyle: 'solid', borderTopWidth: 1, - flex: 1, height: 32, }, isMobile: {paddingTop: Kb.Styles.globalMargins.xxtiny}, @@ -912,39 +916,41 @@ export const useAttachmentSections = ( key: month.key, renderItem: ({item}: {item: Item}) => { return item.type === 'link' ? ( - { jumpToAttachment(item.id) }} > - - - - - - {formatTimeForMessages(item.ctime)} - - - - {item.snippet} - + + + + + {formatTimeForMessages(item.ctime)} + - {!!item.title && } - + + {item.snippet} + - + {!!item.title && } + + ) : null }, renderSectionHeader: () => , diff --git a/shared/chat/conversation/info-panel/index.tsx b/shared/chat/conversation/info-panel/index.tsx index d84cb066169a..2781a99ee52d 100644 --- a/shared/chat/conversation/info-panel/index.tsx +++ b/shared/chat/conversation/info-panel/index.tsx @@ -20,13 +20,8 @@ type Props = { tab?: 'settings' | 'members' | 'attachments' | 'bots' } -const InfoPanelConnector = (ownProps: Props) => { - const conversationIDKey = ownProps.conversationIDKey ?? Chat.noConversationIDKey - return -} - -const InfoPanelConnectorInner = (ownProps: Props & {conversationIDKey: T.Chat.ConversationIDKey}) => { - const {conversationIDKey} = ownProps +const InfoPanelConnector = ({conversationIDKey: _conversationIDKey, tab}: Props) => { + const conversationIDKey = _conversationIDKey ?? Chat.noConversationIDKey const meta = useConversationMeta(conversationIDKey) const shouldNavigateOut = meta.conversationIDKey === Chat.noConversationIDKey const isPreview = meta.membershipType === 'youArePreviewing' @@ -34,8 +29,8 @@ const InfoPanelConnectorInner = (ownProps: Props & {conversationIDKey: T.Chat.Co const teamname = meta.teamname const {role: yourRole} = useChatTeam(meta.teamID, teamname) - const [uncontrolledSelectedTab, onSelectTab] = React.useState(() => ownProps.tab ?? 'members') - const selectedTab = ownProps.tab ?? uncontrolledSelectedTab + const [uncontrolledSelectedTab, onSelectTab] = React.useState(() => tab ?? 'members') + const selectedTab = tab ?? uncontrolledSelectedTab const hideInfoPanel = React.useEffectEvent(() => { showConversationInfoPanel(conversationIDKey, false, undefined) @@ -168,6 +163,7 @@ const styles = Kb.Styles.styleSheetCreate( () => ({ clickableTabStyle: Kb.Styles.platformStyles({ + isElectron: {width: 'auto'}, isMobile: {width: undefined}, }), container: Kb.Styles.platformStyles({ @@ -188,12 +184,12 @@ const styles = Kb.Styles.styleSheetCreate( }, containerOuterTablet: {width: infoPanelWidthTablet + tabletContainerBorderSize}, tab: { + justifyContent: 'center', paddingLeft: Kb.Styles.globalMargins.xsmall, paddingRight: Kb.Styles.globalMargins.xsmall, }, tabContainer: Kb.Styles.platformStyles({ common: {backgroundColor: Kb.Styles.globalColors.white}, - // TODO: this is less than ideal isElectron: { overflowX: 'hidden', overflowY: 'hidden', diff --git a/shared/chat/conversation/info-panel/settings/min-writer-role.tsx b/shared/chat/conversation/info-panel/settings/min-writer-role.tsx index ecb9c1847f61..f8ea37b6dde8 100644 --- a/shared/chat/conversation/info-panel/settings/min-writer-role.tsx +++ b/shared/chat/conversation/info-panel/settings/min-writer-role.tsx @@ -140,17 +140,18 @@ const Dropdown = (p: DropdownProps) => { ]) return ( <> - {upperFirst(minWriterRole)} - + {popup} @@ -169,8 +170,6 @@ const styles = Kb.Styles.styleSheetCreate( ({ dropdown: Kb.Styles.platformStyles({ common: { - ...Kb.Styles.globalStyles.flexBoxRow, - alignItems: 'center', ...Kb.Styles.border(Kb.Styles.globalColors.grey, 1, Kb.Styles.borderRadius), minWidth: 220, paddingRight: Kb.Styles.globalMargins.small, diff --git a/shared/chat/conversation/input-area/normal/input.tsx b/shared/chat/conversation/input-area/normal/input.tsx index ed4bc0aee5a6..3ea834ada2c9 100644 --- a/shared/chat/conversation/input-area/normal/input.tsx +++ b/shared/chat/conversation/input-area/normal/input.tsx @@ -463,7 +463,10 @@ const ExplodingButton = function ExplodingButton(p: ExplodingButtonProps) { const {popup, popupAnchor, showingPopup, showPopup} = Kb.usePopup2(makePopup) return ( - )} - + ) } @@ -853,18 +856,14 @@ const desktopStyles = Kb.Styles.styleSheetCreate( }, explodingIconContainer: Kb.Styles.platformStyles({ common: { - ...Kb.Styles.globalStyles.flexBoxColumn, - alignItems: 'center', alignSelf: 'stretch', borderBottomLeftRadius: 3, borderTopLeftRadius: 3, - justifyContent: 'flex-end', textAlign: 'center', width: 32, }, isElectron: { borderRight: `1px solid ${Kb.Styles.globalColors.black_20}`, - ...Kb.Styles.desktopStyles.clickable, }, }), explodingInsideWrapper: {alignItems: 'center', height: 32}, @@ -987,7 +986,7 @@ const NativeButtons = function NativeButtons(p: NativeButtonsProps) { } const explodingIcon = !isEditing && !cannotWrite && ( - + {isExploding ? ( @@ -997,7 +996,7 @@ const NativeButtons = function NativeButtons(p: NativeButtonsProps) { ) : ( )} - + ) return ( @@ -1066,14 +1065,14 @@ const NativeAnimatedExpand = (() => { }, [expanded, offset]) return ( - + - + ) } } @@ -1475,8 +1474,6 @@ const nativeStyles = Kb.Styles.styleSheetCreate( lineHeight: 16, }, explodingWrapper: { - ...Kb.Styles.globalStyles.flexBoxColumn, - ...Kb.Styles.centered(), height: 38, width: 36, }, @@ -1489,7 +1486,6 @@ const nativeStyles = Kb.Styles.styleSheetCreate( height: 28, marginRight: -Kb.Styles.globalMargins.xtiny, marginTop: Kb.Styles.globalMargins.tiny, - position: 'relative', width: 28, }, iconTop: { diff --git a/shared/chat/conversation/input-area/suggestors/common.tsx b/shared/chat/conversation/input-area/suggestors/common.tsx index 0b9c6a1f6787..d7c4c49fdecf 100644 --- a/shared/chat/conversation/input-area/suggestors/common.tsx +++ b/shared/chat/conversation/input-area/suggestors/common.tsx @@ -61,9 +61,9 @@ export function List(p: ListProps) { const [selectedIndex, setSelectedIndex] = React.useState(0) const renderItem = (idx: number, item: T) => ( - onSelected(item, true)}> + onSelected(item, true)}> - + ) const lastSelectedIndex = React.useRef(selectedIndex) diff --git a/shared/chat/conversation/list-area/jump-to-recent.tsx b/shared/chat/conversation/list-area/jump-to-recent.tsx index c82cd7039f27..b84933f2bcc6 100644 --- a/shared/chat/conversation/list-area/jump-to-recent.tsx +++ b/shared/chat/conversation/list-area/jump-to-recent.tsx @@ -7,7 +7,7 @@ type Props = { const JumpToRecent = (props: Props) => { return ( - + + )} - + ) } diff --git a/shared/chat/conversation/messages/attachment/image/index.tsx b/shared/chat/conversation/messages/attachment/image/index.tsx index 19b2a22797f5..c189ccc40afa 100644 --- a/shared/chat/conversation/messages/attachment/image/index.tsx +++ b/shared/chat/conversation/messages/attachment/image/index.tsx @@ -64,14 +64,15 @@ function Image(p: Props) { gap="xxtiny" > - - + {showTitle ? : null} <Transferring transferState={transferState} ratio={transferProgress} /> </Kb.Box2> diff --git a/shared/chat/conversation/messages/attachment/shared.tsx b/shared/chat/conversation/messages/attachment/shared.tsx index efc34f666651..032afbee1f88 100644 --- a/shared/chat/conversation/messages/attachment/shared.tsx +++ b/shared/chat/conversation/messages/attachment/shared.tsx @@ -279,11 +279,9 @@ const useCollapseAction = (ordinal: T.Chat.Ordinal) => { const useCollapseIconDesktop = (ordinal: T.Chat.Ordinal, isCollapsed: boolean, isWhite: boolean) => { const onCollapse = useCollapseAction(ordinal) return ( - <Kb.ClickableBox2 onClick={onCollapse}> - <Kb.Box2 alignSelf="flex-start" direction="horizontal" gap="xtiny"> - <CollapseIcon isCollapsed={isCollapsed} isWhite={isWhite} /> - </Kb.Box2> - </Kb.ClickableBox2> + <Kb.ClickableBox3 direction="horizontal" alignSelf="flex-start" gap="xtiny" onClick={onCollapse}> + <CollapseIcon isCollapsed={isCollapsed} isWhite={isWhite} /> + </Kb.ClickableBox3> ) } const useCollapseIconMobile = (_ordinal: T.Chat.Ordinal, _isCollapsed: boolean, _isWhite: boolean) => null diff --git a/shared/chat/conversation/messages/cards/make-team.tsx b/shared/chat/conversation/messages/cards/make-team.tsx index ee65e612ccaf..f24a68134b6e 100644 --- a/shared/chat/conversation/messages/cards/make-team.tsx +++ b/shared/chat/conversation/messages/cards/make-team.tsx @@ -12,30 +12,22 @@ const MakeTeam = () => { <Kb.Text type="BodySmallSemibold" style={styles.header} negative={true}> {"Make it a team? You'll be able to add and delete members as you wish."} </Kb.Text> - <Kb.ClickableBox onClick={onShowNewTeamDialog}> - <Kb.Box2 - direction="horizontal" - alignItems="center" - fullWidth={true} - className="hover_container" - gap="xtiny" + <Kb.ClickableBox3 onClick={onShowNewTeamDialog} direction="horizontal" alignItems="center" fullWidth={true} className="hover_container" gap="xtiny"> + <Kb.Text + type="BodySmallSemiboldPrimaryLink" + style={styles.link} + className="color_greenLightOrWhite hover_contained_color_white" > - <Kb.Text - type="BodySmallSemiboldPrimaryLink" - style={styles.link} - className="color_greenLightOrWhite hover_contained_color_white" - > - Enter a team name - </Kb.Text> - <Kb.Icon - color={Kb.Styles.globalColors.greenLight} - sizeType="Tiny" - type="iconfont-arrow-right" - className="hover_contained_color_white" - style={styles.icon} - /> - </Kb.Box2> - </Kb.ClickableBox> + Enter a team name + </Kb.Text> + <Kb.Icon + color={Kb.Styles.globalColors.greenLight} + sizeType="Tiny" + type="iconfont-arrow-right" + className="hover_contained_color_white" + style={styles.icon} + /> + </Kb.ClickableBox3> </Kb.Box2> <Kb.ImageIcon type="icon-illustration-teams-80" style={styles.image} /> </Kb.Box2> diff --git a/shared/chat/conversation/messages/cards/new-chat.tsx b/shared/chat/conversation/messages/cards/new-chat.tsx index f98960f3cdee..ed7a916c1d54 100644 --- a/shared/chat/conversation/messages/cards/new-chat.tsx +++ b/shared/chat/conversation/messages/cards/new-chat.tsx @@ -43,30 +43,22 @@ function NewCard(outerProps: Props) { <Kb.Text type="BodySmallSemibold" style={styles.header} negative={true}> {props.text} </Kb.Text> - <Kb.ClickableBox onClick={props.action}> - <Kb.Box2 - direction="horizontal" - alignItems="center" - fullWidth={true} - className="hover_container" - gap="xtiny" + <Kb.ClickableBox3 onClick={props.action} direction="horizontal" alignItems="center" fullWidth={true} className="hover_container" gap="xtiny"> + <Kb.Text + type="BodySmallSemiboldPrimaryLink" + style={styles.link} + className="color_blueLighterOrWhite hover_contained_color_white" > - <Kb.Text - type="BodySmallSemiboldPrimaryLink" - style={styles.link} - className="color_blueLighterOrWhite hover_contained_color_white" - > - {props.label} - </Kb.Text> - <Kb.Icon - color={Kb.Styles.globalColors.blueLighter} - sizeType="Tiny" - type="iconfont-arrow-right" - className="hover_contained_color_white" - style={styles.icon} - /> - </Kb.Box2> - </Kb.ClickableBox> + {props.label} + </Kb.Text> + <Kb.Icon + color={Kb.Styles.globalColors.blueLighter} + sizeType="Tiny" + type="iconfont-arrow-right" + className="hover_contained_color_white" + style={styles.icon} + /> + </Kb.ClickableBox3> </Kb.Box2> <Kb.ImageIcon type={props.icon} diff --git a/shared/chat/conversation/messages/emoji-row.tsx b/shared/chat/conversation/messages/emoji-row.tsx index 9b000a471f1a..07499ceffe6f 100644 --- a/shared/chat/conversation/messages/emoji-row.tsx +++ b/shared/chat/conversation/messages/emoji-row.tsx @@ -82,33 +82,36 @@ function EmojiRowContainer(p: OwnProps) { </Kb.Box2> <Kb.Box2 direction="horizontal"> <Kb.Divider style={styles.divider} vertical={true} /> - <Kb.ClickableBox + <Kb.ClickableBox3 + direction="vertical" className="hover_container" onClick={hasMessageID ? _showPicker : undefined} style={Kb.Styles.collapseStyles([styles.iconContainer, !hasMessageID && styles.disabled])} tooltip="React" > <Kb.Icon className="hover_contained_color_blue" style={styles.icon} type="iconfont-reacji" /> - </Kb.ClickableBox> + </Kb.ClickableBox3> {!!onReply && ( - <Kb.ClickableBox + <Kb.ClickableBox3 + direction="vertical" className="hover_container" onClick={onReply} style={styles.iconContainer} tooltip="Reply" > <Kb.Icon className="hover_contained_color_blue" style={styles.icon} type="iconfont-reply" /> - </Kb.ClickableBox> + </Kb.ClickableBox3> )} {!!onForward && ( - <Kb.ClickableBox + <Kb.ClickableBox3 + direction="vertical" className="hover_container" onClick={onForward} style={styles.iconContainer} tooltip="Forward" > <Kb.Icon className="hover_contained_color_blue" style={styles.icon} type="iconfont-forward" /> - </Kb.ClickableBox> + </Kb.ClickableBox3> )} </Kb.Box2> {showingPicker && message && hasMessageID && ( @@ -135,12 +138,12 @@ const HoverEmoji = (props: {emoji: T.RPCGen.UserReacji; onClick: () => void}) => const _setHovering = () => setHovering(true) const _setNotHovering = () => setHovering(false) return ( - <Kb.ClickableBox + <Kb.ClickableBox3 + direction="horizontal" + centerChildren={true} onClick={props.onClick} onMouseOver={_setHovering} onMouseLeave={_setNotHovering} - underlayColor={Kb.Styles.globalColors.transparent} - hoverColor={Kb.Styles.globalColors.transparent} style={styles.emojiBox} > <Kb.Emoji @@ -151,7 +154,7 @@ const HoverEmoji = (props: {emoji: T.RPCGen.UserReacji; onClick: () => void}) => style={styles.hoverEmoji} virtualText={true} /> - </Kb.ClickableBox> + </Kb.ClickableBox3> ) } @@ -173,8 +176,6 @@ const styles = Kb.Styles.styleSheetCreate( marginTop: Kb.Styles.globalMargins.tiny, }, emojiBox: { - ...Kb.Styles.globalStyles.flexBoxRow, - ...Kb.Styles.centered(), height: Kb.Styles.globalMargins.small, marginRight: Kb.Styles.globalMargins.xxtiny, width: Kb.Styles.globalMargins.small, @@ -184,10 +185,7 @@ const styles = Kb.Styles.styleSheetCreate( position: 'relative', top: 1, }, - iconContainer: Kb.Styles.platformStyles({ - common: {padding: Kb.Styles.globalMargins.tiny}, - isElectron: {...Kb.Styles.desktopStyles.clickable}, - }), + iconContainer: {padding: Kb.Styles.globalMargins.tiny}, pickerContainer: Kb.Styles.platformStyles({ isElectron: { ...Kb.Styles.desktopStyles.boxShadow, diff --git a/shared/chat/conversation/messages/message-popup/reactionitem.tsx b/shared/chat/conversation/messages/message-popup/reactionitem.tsx index d73da2016e29..4e582712074a 100644 --- a/shared/chat/conversation/messages/message-popup/reactionitem.tsx +++ b/shared/chat/conversation/messages/message-popup/reactionitem.tsx @@ -23,13 +23,13 @@ const ReactionItem = (props: Props) => { return ( <Kb.Box2 direction="horizontal" fullWidth={true} flex={1} style={styles.container} justifyContent="space-between"> {topReacjis.map((r, idx) => ( - <Kb.ClickableBox key={r.name || idx} onClick={() => onReact(r.name)} style={styles.clickableBox}> + <Kb.ClickableBox3 direction="vertical" centerChildren={true} key={r.name || idx} onClick={() => onReact(r.name)} style={styles.clickableBox}> <Kb.Emoji userReacji={r} noAnim={true} showTooltip={false} size={28} /> - </Kb.ClickableBox> + </Kb.ClickableBox3> ))} - <Kb.ClickableBox onClick={showPicker} style={styles.clickableBox}> + <Kb.ClickableBox3 direction="vertical" centerChildren={true} onClick={showPicker} style={styles.clickableBox}> <Kb.Icon type="iconfont-reacji" /> - </Kb.ClickableBox> + </Kb.ClickableBox3> </Kb.Box2> ) } @@ -37,7 +37,6 @@ const styles = Kb.Styles.styleSheetCreate( () => ({ clickableBox: { - ...Kb.Styles.centered(), height: 50, width: 40, }, diff --git a/shared/chat/conversation/messages/react-button.tsx b/shared/chat/conversation/messages/react-button.tsx index 0d729c18aec9..c7e2b1ccf178 100644 --- a/shared/chat/conversation/messages/react-button.tsx +++ b/shared/chat/conversation/messages/react-button.tsx @@ -37,7 +37,11 @@ function ReactionButton({ text: string }) { return ( - <Kb.ClickableBox2 + <Kb.ClickableBox3 + direction="horizontal" + centerChildren={true} + fullHeight={true} + gap="xtiny" className={Kb.Styles.classNames('react-button', className, {noShadow: active})} onLongPress={onLongPress} onClick={onClick} @@ -49,28 +53,26 @@ function ReactionButton({ style, ])} > - <Kb.Box2 centerChildren={true} fullHeight={true} direction="horizontal" gap="xtiny"> - <Kb.Box2 centerChildren={true} fullHeight={true} direction="horizontal"> - <Kb.Markdown - serviceOnlyNoWrap={false /* MUST be false to support non-emojis in reactions for bots */} - styleOverride={markdownOverride} - lineClamp={1} - smallStandaloneEmoji={true} - disallowAnimation={false} - virtualText={true} - > - {text} - </Kb.Markdown> - </Kb.Box2> - <Kb.Text - type="BodyTinyBold" + <Kb.Box2 centerChildren={true} fullHeight={true} direction="horizontal"> + <Kb.Markdown + serviceOnlyNoWrap={false /* MUST be false to support non-emojis in reactions for bots */} + styleOverride={markdownOverride} + lineClamp={1} + smallStandaloneEmoji={true} + disallowAnimation={false} virtualText={true} - style={Kb.Styles.collapseStyles([styles.count, active && styles.countActive])} > - {count} - </Kb.Text> + {text} + </Kb.Markdown> </Kb.Box2> - </Kb.ClickableBox2> + <Kb.Text + type="BodyTinyBold" + virtualText={true} + style={Kb.Styles.collapseStyles([styles.count, active && styles.countActive])} + > + {count} + </Kb.Text> + </Kb.ClickableBox3> ) } @@ -120,7 +122,10 @@ export function NewReactionButton(p: NewReactionButtonProps) { } return ( - <Kb.ClickableBox2 + <Kb.ClickableBox3 + direction="horizontal" + centerChildren={true} + fullHeight={true} onClick={hasMessageID ? onOpenEmojiPicker : undefined} style={Kb.Styles.collapseStyles([ styles.borderBase, @@ -131,15 +136,13 @@ export function NewReactionButton(p: NewReactionButtonProps) { p.style, ])} > - <Kb.Box2 centerChildren={true} fullHeight={true} direction="horizontal"> - <Kb.Icon - type="iconfont-reacji" - color={Kb.Styles.globalColors.black_50} - fontSize={18} - style={styles.emojiIconWrapper} - /> - </Kb.Box2> - </Kb.ClickableBox2> + <Kb.Icon + type="iconfont-reacji" + color={Kb.Styles.globalColors.black_50} + fontSize={18} + style={styles.emojiIconWrapper} + /> + </Kb.ClickableBox3> ) } diff --git a/shared/chat/conversation/messages/text/reply.tsx b/shared/chat/conversation/messages/text/reply.tsx index 579888619eb5..b278232af4de 100644 --- a/shared/chat/conversation/messages/text/reply.tsx +++ b/shared/chat/conversation/messages/text/reply.tsx @@ -82,39 +82,31 @@ function ReplyStructure(p: RS) { const {showImage, showEdited, isDeleted, onClick} = p return ( - <Kb.ClickableBox2 onClick={onClick}> - <Kb.Box2 - direction="horizontal" - gap="tiny" - fullWidth={true} - style={styles.replyContainer} - className={Kb.Styles.classNames('ReplyBox')} - > - <Kb.Box2 direction="horizontal" style={styles.quoteContainer} /> - <Kb.Box2 direction="vertical" gap="xtiny" flex={1}> - <Kb.Box2 direction="horizontal" fullWidth={true}> - <AvatarHolder /> - </Kb.Box2> - <Kb.Box2 direction="horizontal" fullWidth={true} gap="tiny"> - {showImage && <ReplyImage />} - <Kb.Box2 direction="horizontal" flex={1} style={styles.replyTextContainer}> - {isDeleted ? ( - <Kb.Text type="BodyTiny" style={styles.replyEdited} virtualText={true}> - The original message was deleted. - </Kb.Text> - ) : ( - <ReplyText /> - )} - </Kb.Box2> + <Kb.ClickableBox3 direction="horizontal" gap="tiny" fullWidth={true} style={styles.replyContainer} className={Kb.Styles.classNames('ReplyBox')} onClick={onClick}> + <Kb.Box2 direction="horizontal" alignSelf="stretch" style={styles.quoteContainer} /> + <Kb.Box2 direction="vertical" gap="xtiny" flex={1}> + <Kb.Box2 direction="horizontal" fullWidth={true}> + <AvatarHolder /> + </Kb.Box2> + <Kb.Box2 direction="horizontal" fullWidth={true} gap="tiny"> + {showImage && <ReplyImage />} + <Kb.Box2 direction="horizontal" flex={1} alignSelf="flex-start"> + {isDeleted ? ( + <Kb.Text type="BodyTiny" style={styles.replyEdited} virtualText={true}> + The original message was deleted. + </Kb.Text> + ) : ( + <ReplyText /> + )} </Kb.Box2> - {showEdited && ( - <Kb.Text type="BodyTiny" style={styles.replyEdited} virtualText={true}> - EDITED - </Kb.Text> - )} </Kb.Box2> + {showEdited && ( + <Kb.Text type="BodyTiny" style={styles.replyEdited} virtualText={true}> + EDITED + </Kb.Text> + )} </Kb.Box2> - </Kb.ClickableBox2> + </Kb.ClickableBox3> ) } @@ -136,7 +128,6 @@ const styles = Kb.Styles.styleSheetCreate( () => ({ quoteContainer: { - alignSelf: 'stretch', backgroundColor: Kb.Styles.globalColors.grey, paddingLeft: Kb.Styles.globalMargins.xtiny, }, @@ -145,9 +136,6 @@ const styles = Kb.Styles.styleSheetCreate( paddingTop: Kb.Styles.globalMargins.xtiny, }, replyEdited: {color: Kb.Styles.globalColors.black_35}, - replyTextContainer: { - alignSelf: 'flex-start', - }, replyUsername: {alignSelf: 'center'}, replyUsernameHighlighted: {color: Kb.Styles.globalColors.blackOrBlack}, textHighlighted: {color: Kb.Styles.globalColors.black_50OrBlack_50}, diff --git a/shared/chat/conversation/messages/text/unfurl/unfurl-list/image/index.tsx b/shared/chat/conversation/messages/text/unfurl/unfurl-list/image/index.tsx index b66962827b2d..72db22882892 100644 --- a/shared/chat/conversation/messages/text/unfurl/unfurl-list/image/index.tsx +++ b/shared/chat/conversation/messages/text/unfurl/unfurl-list/image/index.tsx @@ -44,7 +44,7 @@ const UnfurlImage = (p: Props) => { width={width} /> ) : ( - <Kb.ClickableBox onClick={onClick || onOpenURL}> + <Kb.ClickableBox3 direction="vertical" onClick={onClick || onOpenURL}> <Kb.Image src={url} style={Kb.Styles.collapseStyles([ @@ -53,7 +53,7 @@ const UnfurlImage = (p: Props) => { style, ])} /> - </Kb.ClickableBox> + </Kb.ClickableBox3> ) } diff --git a/shared/chat/conversation/messages/text/unfurl/unfurl-list/image/video.tsx b/shared/chat/conversation/messages/text/unfurl/unfurl-list/image/video.tsx index 1ef4c74d9d5a..358d6b7613fe 100644 --- a/shared/chat/conversation/messages/text/unfurl/unfurl-list/image/video.tsx +++ b/shared/chat/conversation/messages/text/unfurl/unfurl-list/image/video.tsx @@ -167,7 +167,7 @@ const NativeVideo = (props: Props) => { } return ( - <Kb.ClickableBox onClick={_onClick} style={Kb.Styles.collapseStyles([style, nativeStyles.container])}> + <Kb.ClickableBox3 direction="vertical" relative={true} onClick={_onClick} style={Kb.Styles.collapseStyles([style, nativeStyles.container])}> {active && ( <NativeActiveVideo sourceUri={sourceUri} @@ -179,7 +179,7 @@ const NativeVideo = (props: Props) => { <Kb.Box2 direction="vertical" style={Kb.Styles.collapseStyles([sharedStyles.absoluteContainer, {height, width}])}> {!playing && <Kb.ImageIcon type="icon-play-64" style={sharedStyles.playButton} />} </Kb.Box2> - </Kb.ClickableBox> + </Kb.ClickableBox3> ) } @@ -197,7 +197,6 @@ const nativeStyles = Kb.Styles.styleSheetCreate( ({ container: { alignSelf: 'flex-start', - position: 'relative', }, player: { position: 'relative', diff --git a/shared/chat/conversation/messages/wrapper/exploding-meta.tsx b/shared/chat/conversation/messages/wrapper/exploding-meta.tsx index 6816fd3011e8..33fb1d20e9c8 100644 --- a/shared/chat/conversation/messages/wrapper/exploding-meta.tsx +++ b/shared/chat/conversation/messages/wrapper/exploding-meta.tsx @@ -195,9 +195,9 @@ function ExplodingMetaInner(p: ExplodingMetaInnerProps) { } return ( - <Kb.ClickableBox onClick={onClick} style={styles.container}> + <Kb.ClickableBox3 direction="horizontal" relative={true} onClick={onClick} style={styles.container}> {children} - </Kb.ClickableBox> + </Kb.ClickableBox3> ) } @@ -251,9 +251,7 @@ const styles = Kb.Styles.styleSheetCreate( () => ({ container: { - ...Kb.Styles.globalStyles.flexBoxRow, height: 20, - position: 'relative', }, countdown: Kb.Styles.platformStyles({ common: {color: Kb.Styles.globalColors.white, fontWeight: 'bold'}, diff --git a/shared/chat/conversation/no-conversation.tsx b/shared/chat/conversation/no-conversation.tsx index 31e6640dbe39..fc88ff72a41a 100644 --- a/shared/chat/conversation/no-conversation.tsx +++ b/shared/chat/conversation/no-conversation.tsx @@ -1,20 +1,10 @@ import * as Kb from '@/common-adapters' const NoConversation = () => ( - <Kb.Box2 direction="vertical" gap="xsmall" centerChildren={true} flex={1} style={styles.noConvoText}> + <Kb.Box2 direction="vertical" gap="xsmall" centerChildren={true} flex={1} alignSelf="center"> <Kb.ImageIcon type="icon-fancy-encrypted-computer-desktop-150-72" /> <Kb.Text type="BodySmall">All conversations are end-to-end encrypted.</Kb.Text> </Kb.Box2> ) -const styles = Kb.Styles.styleSheetCreate( - () => - ({ - noConvoText: { - alignSelf: 'center', - justifyContent: 'center', - }, - }) as const -) - export default NoConversation diff --git a/shared/chat/conversation/pinned-message.tsx b/shared/chat/conversation/pinned-message.tsx index 5bd4dd894e5c..c7edd057cf0d 100644 --- a/shared/chat/conversation/pinned-message.tsx +++ b/shared/chat/conversation/pinned-message.tsx @@ -87,45 +87,43 @@ const PinnedMessage = function PinnedMessage() { } const sizing = imageWidth && imageHeight ? zoomImage(imageWidth, imageHeight, 30) : undefined const pin = ( - <Kb.ClickableBox className="hover_container" onClick={onClick} style={styles.container}> - <Kb.Box2 direction="horizontal" fullWidth={true} gap="tiny"> - <Kb.Box2 direction="horizontal" style={styles.blueBar} /> - {!!imageURL && ( - <Kb.Box2 direction="vertical" overflow="hidden" relative={true}> - <Kb.Box2 direction="vertical" style={{...(sizing ? sizing.margins : {})}}> - <Kb.Image src={imageURL} style={{...(sizing ? sizing.dims : {})}} /> - </Kb.Box2> + <Kb.ClickableBox3 direction="horizontal" fullWidth={true} gap="tiny" className="hover_container" onClick={onClick} style={styles.container}> + <Kb.Box2 direction="horizontal" alignSelf="stretch" style={styles.blueBar} /> + {!!imageURL && ( + <Kb.Box2 direction="vertical" overflow="hidden" relative={true}> + <Kb.Box2 direction="vertical" style={{...(sizing ? sizing.margins : {})}}> + <Kb.Image src={imageURL} style={{...(sizing ? sizing.dims : {})}} /> </Kb.Box2> - )} - <Kb.Box2 direction="vertical" fullWidth={true} flex={1}> - <Kb.Box2 direction="horizontal" gap="tiny" fullWidth={true}> - <Kb.Text type="BodyTinyBold" style={styles.author}> - {author} - </Kb.Text> - <Kb.Text type="BodyTinySemibold" style={styles.label}> - Pinned - </Kb.Text> - </Kb.Box2> - <Kb.Markdown smallStandaloneEmoji={true} lineClamp={1} style={styles.text} serviceOnly={true}> - {text} - </Kb.Markdown> </Kb.Box2> - {unpinning ? ( - <Kb.Box2 direction="vertical" alignSelf="center"> - <Kb.ProgressIndicator type="Small" /> - </Kb.Box2> - ) : ( - <Kb.Box2 direction="vertical" ref={closeref} style={styles.close}> - <Kb.Icon - onClick={onIconClick} - type="iconfont-close" - sizeType="Small" - color={Kb.Styles.globalColors.black_20} - /> - </Kb.Box2> - )} + )} + <Kb.Box2 direction="vertical" fullWidth={true} flex={1}> + <Kb.Box2 direction="horizontal" gap="tiny" fullWidth={true}> + <Kb.Text type="BodyTinyBold" style={styles.author}> + {author} + </Kb.Text> + <Kb.Text type="BodyTinySemibold" style={styles.label}> + Pinned + </Kb.Text> + </Kb.Box2> + <Kb.Markdown smallStandaloneEmoji={true} lineClamp={1} style={styles.text} serviceOnly={true}> + {text} + </Kb.Markdown> </Kb.Box2> - </Kb.ClickableBox> + {unpinning ? ( + <Kb.Box2 direction="vertical" alignSelf="center"> + <Kb.ProgressIndicator type="Small" /> + </Kb.Box2> + ) : ( + <Kb.Box2 direction="vertical" ref={closeref} style={styles.close}> + <Kb.Icon + onClick={onIconClick} + type="iconfont-close" + sizeType="Small" + color={Kb.Styles.globalColors.black_20} + /> + </Kb.Box2> + )} + </Kb.ClickableBox3> ) const popup = ( <UnpinPrompt @@ -179,7 +177,6 @@ const styles = Kb.Styles.styleSheetCreate( ({ author: {color: Kb.Styles.globalColors.black}, blueBar: { - alignSelf: 'stretch', backgroundColor: Kb.Styles.globalColors.blue, width: Kb.Styles.globalMargins.xtiny, }, @@ -198,7 +195,6 @@ const styles = Kb.Styles.styleSheetCreate( borderBottomWidth: 1, borderColor: Kb.Styles.globalColors.black_10, borderStyle: 'solid', - width: '100%', }, label: {color: Kb.Styles.globalColors.blueDark}, popup: Kb.Styles.platformStyles({ diff --git a/shared/chat/conversation/rekey/participant-rekey.tsx b/shared/chat/conversation/rekey/participant-rekey.tsx index 8749563db84a..4967c4423c50 100644 --- a/shared/chat/conversation/rekey/participant-rekey.tsx +++ b/shared/chat/conversation/rekey/participant-rekey.tsx @@ -2,42 +2,36 @@ import * as Kb from '@/common-adapters' import type {Props} from './participant-rekey.types' const Row = ({username, onUsernameClicked}: {username: string; onUsernameClicked: (s: string) => void}) => ( - <Kb.ClickableBox onClick={() => onUsernameClicked(username)}> + <Kb.ClickableBox3 direction="horizontal" alignItems={isMobile ? 'center' : undefined} style={styles.row} onClick={() => onUsernameClicked(username)}> + <Kb.Avatar + username={username} + size={48} + style={{marginRight: Kb.Styles.globalMargins.small, padding: 4}} + /> <Kb.Box2 - direction="horizontal" - alignItems={isMobile ? 'center' : undefined} - style={styles.row} + direction="vertical" + justifyContent={isMobile ? 'center' : undefined} + flex={isMobile ? 1 : undefined} + style={styles.innerRow} > - <Kb.Avatar - username={username} - size={48} - style={{marginRight: Kb.Styles.globalMargins.small, padding: 4}} + <Kb.ConnectedUsernames + inline={true} + backgroundMode={isMobile ? 'Terminal' : undefined} + type="BodyBold" + usernames={username} /> - <Kb.Box2 - direction="vertical" - justifyContent={isMobile ? 'center' : undefined} - flex={isMobile ? 1 : undefined} - style={styles.innerRow} + <Kb.Text + type="BodySmall" + negative={isMobile} + style={Kb.Styles.platformStyles({ + isElectron: {lineHeight: '17px'}, + isMobile: {color: Kb.Styles.globalColors.blueLighter_40, lineHeight: 17}, + })} > - <Kb.ConnectedUsernames - inline={true} - backgroundMode={isMobile ? 'Terminal' : undefined} - type="BodyBold" - usernames={username} - /> - <Kb.Text - type="BodySmall" - negative={isMobile} - style={Kb.Styles.platformStyles({ - isElectron: {lineHeight: '17px'}, - isMobile: {color: Kb.Styles.globalColors.blueLighter_40, lineHeight: 17}, - })} - > - Can rekey this chat by opening the Keybase app. - </Kb.Text> - </Kb.Box2> + Can rekey this chat by opening the Keybase app. + </Kb.Text> </Kb.Box2> - </Kb.ClickableBox> + </Kb.ClickableBox3> ) const ParticipantRekey = ({rekeyers, onShowProfile: onUsernameClicked}: Props) => ( @@ -103,9 +97,6 @@ const styles = Kb.Styles.styleSheetCreate(() => ({ common: { minHeight: 48, }, - isElectron: { - ...Kb.Styles.desktopStyles.clickable, - }, isMobile: { minHeight: 56, }, diff --git a/shared/chat/conversation/search.tsx b/shared/chat/conversation/search.tsx index 60d012d8dc19..ad66b83eadba 100644 --- a/shared/chat/conversation/search.tsx +++ b/shared/chat/conversation/search.tsx @@ -359,7 +359,7 @@ const ThreadSearchDesktopInner = function ThreadSearchDesktopInner(p: CommonProp const _renderHit = (index: number, item: SearchHit) => { return ( - <Kb.ClickableBox key={index} onClick={() => selectResult(index)} style={styles.hitRow}> + <Kb.ClickableBox3 direction="horizontal" alignItems="center" justifyContent="space-between" key={index} onClick={() => selectResult(index)} style={styles.hitRow}> <Kb.Avatar username={item.author} size={24} /> <Kb.Text type="Body" style={styles.hitSummary}> {item.summary} @@ -367,7 +367,7 @@ const ThreadSearchDesktopInner = function ThreadSearchDesktopInner(p: CommonProp <Kb.Text type="BodySmall" style={styles.time}> {formatTimeForMessages(item.timestamp)} </Kb.Text> - </Kb.ClickableBox> + </Kb.ClickableBox3> ) } @@ -523,10 +523,7 @@ const styles = Kb.Styles.styleSheetCreate( }, }), hitRow: { - ...Kb.Styles.globalStyles.flexBoxRow, - alignItems: 'center', height: hitHeight, - justifyContent: 'space-between', padding: Kb.Styles.globalMargins.tiny, }, hitSummary: Kb.Styles.platformStyles({ diff --git a/shared/chat/conversation/you-are-reset.tsx b/shared/chat/conversation/you-are-reset.tsx index 87f5d7d62054..e226c2516dcc 100644 --- a/shared/chat/conversation/you-are-reset.tsx +++ b/shared/chat/conversation/you-are-reset.tsx @@ -2,12 +2,7 @@ import * as Kb from '@/common-adapters' const YouAreReset = () => ( <Kb.Box2 direction="vertical" fullWidth={true} flex={1}> - <Kb.Box2 - direction="vertical" - centerChildren={true} - fullWidth={true} - flex={1} - > + <Kb.Box2 direction="vertical" centerChildren={true} fullWidth={true} flex={1}> <Kb.ImageIcon type={isMobile ? 'icon-skull-64' : 'icon-skull-48'} /> </Kb.Box2> <Kb.Box2 direction="vertical" alignItems="center" fullWidth={true} style={styles.box}> diff --git a/shared/chat/create-channel/index.tsx b/shared/chat/create-channel/index.tsx index aa9417021b98..9e79d25127c0 100644 --- a/shared/chat/create-channel/index.tsx +++ b/shared/chat/create-channel/index.tsx @@ -29,10 +29,10 @@ const CreateChannel = (p: Props) => { </Kb.Banner> )} <Kb.Box2 direction="vertical" alignItems="center" fullWidth={true} style={desktopStyles.box}> - <Kb.ClickableBox style={desktopStyles.back} onClick={props.onBack}> + <Kb.ClickableBox3 direction="horizontal" alignItems="center" style={desktopStyles.back} onClick={props.onBack}> <Kb.Icon style={desktopStyles.backIcon} type="iconfont-arrow-left" /> <Kb.Text type="BodyPrimaryLink">Back</Kb.Text> - </Kb.ClickableBox> + </Kb.ClickableBox3> <Kb.Box2 direction="vertical" fullWidth={true} gap="tiny" gapEnd={true} gapStart={true}> <Kb.Input3 autoFocus={true} @@ -55,7 +55,7 @@ const CreateChannel = (p: Props) => { onChangeText={props.onDescriptionChange} /> </Kb.Box2> - <Kb.ButtonBar fullWidth={true} style={desktopStyles.buttonBar}> + <Kb.ButtonBar fullWidth={true} style={buttonBarStyle}> <Kb.Button type="Dim" onClick={props.onBack} label="Cancel" /> <Kb.WaitingButton waitingKey={C.waitingKeyTeamsCreateChannel(props.teamID)} @@ -96,7 +96,7 @@ const CreateChannel = (p: Props) => { onChangeText={props.onDescriptionChange} /> </Kb.Box2> - <Kb.ButtonBar fullWidth={true} style={nativeStyles.buttonBar}> + <Kb.ButtonBar fullWidth={true} style={buttonBarStyle}> <Kb.WaitingButton waitingKey={C.waitingKeyTeamsCreateChannel(props.teamID)} onClick={props.onSubmit} @@ -108,12 +108,12 @@ const CreateChannel = (p: Props) => { ) } +const buttonBarStyle = {alignItems: 'center'} as const + const desktopStyles = Kb.Styles.styleSheetCreate( () => ({ back: { - ...Kb.Styles.globalStyles.flexBoxRow, - alignItems: 'center', left: 32, position: 'absolute', top: 32, @@ -128,7 +128,6 @@ const desktopStyles = Kb.Styles.styleSheetCreate( paddingRight: Kb.Styles.globalMargins.large, paddingTop: Kb.Styles.globalMargins.medium, }, - buttonBar: {alignItems: 'center'}, }) as const ) @@ -136,7 +135,6 @@ const nativeStyles = Kb.Styles.styleSheetCreate( () => ({ box: {padding: 16}, - buttonBar: {alignItems: 'center'}, }) as const ) diff --git a/shared/chat/delete-history-warning.tsx b/shared/chat/delete-history-warning.tsx index 3ed402f81f65..c6fa211253bf 100644 --- a/shared/chat/delete-history-warning.tsx +++ b/shared/chat/delete-history-warning.tsx @@ -34,10 +34,7 @@ const DeleteHistoryWarning = (props: Props) => { return ( <Kb.Box2 direction="vertical" - style={Kb.Styles.collapseStyles([ - styles.padding, - styles.box, - ])} + style={Kb.Styles.collapseStyles([styles.padding, styles.box])} > <Kb.ImageIcon type={isMobile ? 'icon-message-deletion-64' : 'icon-message-deletion-48'} /> <Kb.Text style={{padding: Kb.Styles.globalMargins.small}} type="Header"> diff --git a/shared/chat/emoji-picker/container.tsx b/shared/chat/emoji-picker/container.tsx index 0fb9f51a319d..05a1310a37c5 100644 --- a/shared/chat/emoji-picker/container.tsx +++ b/shared/chat/emoji-picker/container.tsx @@ -69,12 +69,6 @@ const useReacji = ({ } } -const useSkinTone = () => { - const currentSkinTone = useCurrentSkinTone() - const setSkinTone = useSetSkinTone() - return {currentSkinTone, setSkinTone} -} - const useCustomReacji = ( conversationIDKey: T.Chat.ConversationIDKey, onlyInTeam: boolean | undefined, @@ -107,7 +101,8 @@ const WrapperMobile = (props: Props) => { ) const [width, setWidth] = React.useState(0) const onLayout = (evt: LayoutEvent) => setWidth(evt.nativeEvent.layout.width) - const {currentSkinTone, setSkinTone} = useSkinTone() + const currentSkinTone = useCurrentSkinTone() + const setSkinTone = useSetSkinTone() const [skinTonePickerExpanded, setSkinTonePickerExpanded] = React.useState(false) const onCancel = C.Router2.navigateUp const addEmoji = () => @@ -126,9 +121,9 @@ const WrapperMobile = (props: Props) => { style={styles.contain} > <Kb.Box2 direction="horizontal" fullWidth={true} alignItems="center"> - <Kb.ClickableBox onClick={onCancel} style={styles.cancelContainerMobile}> + <Kb.ClickableBox3 direction="vertical" onClick={onCancel} style={styles.cancelContainerMobile}> <Kb.Text type="BodyBigLink">Cancel</Kb.Text> - </Kb.ClickableBox> + </Kb.ClickableBox3> <Kb.SearchFilter focusOnMount={true} size="small" @@ -149,7 +144,7 @@ const WrapperMobile = (props: Props) => { skinTone={currentSkinTone} hideFrequentEmoji={props.hideFrequentEmoji ?? false} /> - <Kb.Box2 direction="horizontal" fullWidth={true} alignItems="center" style={styles.footerContainer}> + <Kb.Box2 direction="horizontal" fullWidth={true} alignItems="center" noShrink={true} style={styles.footerContainer}> <SkinTonePicker currentSkinTone={currentSkinTone} onExpandChange={setSkinTonePickerExpanded} @@ -174,7 +169,8 @@ const EmojiPickerDesktopInner = (props: Props) => { const {onDidPick} = props const conversationIDKey = props.conversationIDKey ?? T.Chat.noConversationIDKey const {filter, onChoose, setFilter: _setFilter, topReacjis} = useReacji(props) - const {currentSkinTone, setSkinTone} = useSkinTone() + const currentSkinTone = useCurrentSkinTone() + const setSkinTone = useSetSkinTone() const [hoveredEmoji, setHoveredEmoji] = React.useState(emojiData.defaultHoverEmoji) const {waiting, customEmojiGroups} = useCustomReacji( conversationIDKey, @@ -235,7 +231,7 @@ const EmojiPickerDesktopInner = (props: Props) => { direction="horizontal" fullWidth={true} alignItems="center" - style={styles.footerContainer} + noShrink={true} style={styles.footerContainer} gap="small" > <Kb.Emoji @@ -306,7 +302,6 @@ const styles = Kb.Styles.styleSheetCreate( }, footerContainer: Kb.Styles.platformStyles({ common: { - flexShrink: 0, ...Kb.Styles.paddingH(Kb.Styles.globalMargins.small), }, isElectron: { diff --git a/shared/chat/emoji-picker/index.tsx b/shared/chat/emoji-picker/index.tsx index 392d7cf3bc9d..92b8a0952590 100644 --- a/shared/chat/emoji-picker/index.tsx +++ b/shared/chat/emoji-picker/index.tsx @@ -223,7 +223,8 @@ function EmojiPicker(props: Props) { const getEmojiSingle = (emoji: EmojiData, skinTone?: T.Chat.EmojiSkinTone) => { const skinToneModifier = getSkinToneModifierStrIfAvailable(emoji, skinTone) return ( - <Kb.ClickableBox2 + <Kb.ClickableBox3 + direction="vertical" className="emoji-picker-emoji-box" onClick={() => { props.onChoose( @@ -242,7 +243,7 @@ function EmojiPicker(props: Props) { showTooltip={false} size={singleEmojiWidth} /> - </Kb.ClickableBox2> + </Kb.ClickableBox3> ) } @@ -299,7 +300,7 @@ function EmojiPicker(props: Props) { } const getSectionHeader = (title: string) => ( - <Kb.Box2 direction="horizontal" fullWidth={true} style={styles.sectionHeader}> + <Kb.Box2 direction="horizontal" fullWidth={true} alignItems="center" style={styles.sectionHeader}> <Kb.Text type="BodySmallSemibold">{title}</Kb.Text> </Kb.Box2> ) @@ -454,7 +455,6 @@ const styles = Kb.Styles.styleSheetCreate( ...Kb.Styles.padding(Kb.Styles.globalMargins.medium, 0), }, sectionHeader: { - alignItems: 'center', backgroundColor: Kb.Styles.globalColors.white, height: 32, paddingLeft: Kb.Styles.globalMargins.tiny, diff --git a/shared/chat/emoji-picker/skin-tone-picker.tsx b/shared/chat/emoji-picker/skin-tone-picker.tsx index 3828c9da8d5f..a248233f8431 100644 --- a/shared/chat/emoji-picker/skin-tone-picker.tsx +++ b/shared/chat/emoji-picker/skin-tone-picker.tsx @@ -41,7 +41,8 @@ function SkinTonePicker(props: Props) { props.onExpandChange?.(toSet) } const optionSkinTones = reorderedSkinTones(props.currentSkinTone).map((skinTone, index) => ( - <Kb.ClickableBox + <Kb.ClickableBox3 + direction="vertical" key={index.toString()} style={styles.dotContainerExpanded} onClick={() => { @@ -50,7 +51,7 @@ function SkinTonePicker(props: Props) { }} > {circle(skinTone, true, isMobile && skinTone === props.currentSkinTone)} - </Kb.ClickableBox> + </Kb.ClickableBox3> )) return isMobile ? ( @@ -64,12 +65,10 @@ function SkinTonePicker(props: Props) { {optionSkinTones} </Kb.Box2> ) : ( - <Kb.ClickableBox onClick={() => setExpanded(true)}> - <Kb.Box2 direction="horizontal" alignItems="center" gap="tiny"> - {circle(props.currentSkinTone, false, false)} - <Kb.Text type="BodySmallSemibold">Skin tone</Kb.Text> - </Kb.Box2> - </Kb.ClickableBox> + <Kb.ClickableBox3 direction="horizontal" alignItems="center" gap="tiny" onClick={() => setExpanded(true)}> + {circle(props.currentSkinTone, false, false)} + <Kb.Text type="BodySmallSemibold">Skin tone</Kb.Text> + </Kb.ClickableBox3> ) ) : ( <Kb.Box2 direction="vertical" relative={true}> @@ -79,9 +78,9 @@ function SkinTonePicker(props: Props) { </Kb.Box2> ) : ( <Kb.WithTooltip tooltip="Skin tone" containerStyle={styles.absolute}> - <Kb.ClickableBox style={styles.dotContainerDesktop} onClick={() => setExpanded(true)}> + <Kb.ClickableBox3 direction="vertical" style={styles.dotContainerDesktop} onClick={() => setExpanded(true)}> {circle(props.currentSkinTone, false, false)} - </Kb.ClickableBox> + </Kb.ClickableBox3> </Kb.WithTooltip> )} <Kb.Box2 direction="vertical" style={styles.dotPlaceholder} /> diff --git a/shared/chat/inbox-and-conversation-get-options.tsx b/shared/chat/inbox-and-conversation-get-options.tsx index 302e028c84a8..82dc4ee37d11 100644 --- a/shared/chat/inbox-and-conversation-get-options.tsx +++ b/shared/chat/inbox-and-conversation-get-options.tsx @@ -27,7 +27,5 @@ export default Kb.Styles.isTablet headerTitleContainerStyle: {}, } : { - headerTitle: () => { - return <InboxAndConvoHeader /> - }, + headerTitle: () => <InboxAndConvoHeader />, } diff --git a/shared/chat/inbox-search/index.tsx b/shared/chat/inbox-search/index.tsx index 28aebf329056..af6a6c496893 100644 --- a/shared/chat/inbox-search/index.tsx +++ b/shared/chat/inbox-search/index.tsx @@ -445,7 +445,11 @@ const OpenTeamRow = (p: OpenTeamProps) => { }, [showingDueToSelect, showPopup, hidePopup, showingPopup, isSelected]) return ( - <Kb.ClickableBox onClick={showPopup} style={{width: '100%'}}> + <Kb.ClickableBox3 + direction="vertical" + fullWidth={true} + onClick={showPopup} + > <Kb.Box2 direction="horizontal" fullWidth={true} @@ -485,7 +489,7 @@ const OpenTeamRow = (p: OpenTeamProps) => { </Kb.Box2> </Kb.Box2> {popup} - </Kb.ClickableBox> + </Kb.ClickableBox3> ) } diff --git a/shared/chat/inbox/filter-row.tsx b/shared/chat/inbox/filter-row.tsx index 56930b3e222d..caf4aad22cd2 100644 --- a/shared/chat/inbox/filter-row.tsx +++ b/shared/chat/inbox/filter-row.tsx @@ -81,7 +81,7 @@ function ConversationFilterInput(ownProps: OwnProps) { /> ) : ( <Kb.Box2 direction="horizontal" style={styles.searchPlaceholderOuter} alignItems="center"> - <Kb.ClickableBox2 onClick={startSearch} style={styles.searchPlaceholder}> + <Kb.ClickableBox3 direction="horizontal" alignItems="center" flex={1} onClick={startSearch} style={styles.searchPlaceholder}> <Kb.Icon type="iconfont-search" sizeType={isMobile ? 'Small' : 'Default'} @@ -91,7 +91,7 @@ function ConversationFilterInput(ownProps: OwnProps) { <Kb.Text type="BodySemibold" style={styles.searchPlaceholderText}> {isMobile ? 'Search' : 'Search (\u2318K)'} </Kb.Text> - </Kb.ClickableBox2> + </Kb.ClickableBox3> </Kb.Box2> ) return ( @@ -136,12 +136,8 @@ const styles = Kb.Styles.styleSheetCreate( isTablet: {maxWidth: 270 - 16 * 2}, }), searchPlaceholder: { - ...Kb.Styles.globalStyles.flexBoxRow, - ...Kb.Styles.globalStyles.flexGrow, - alignItems: 'center', backgroundColor: Kb.Styles.globalColors.black_10, borderRadius: Kb.Styles.borderRadius, - flex: 1, flexShrink: 1, height: 32, paddingLeft: Kb.Styles.globalMargins.xsmall, diff --git a/shared/chat/inbox/index.tsx b/shared/chat/inbox/index.tsx index e43e9a301c0a..0952b8fc5990 100644 --- a/shared/chat/inbox/index.tsx +++ b/shared/chat/inbox/index.tsx @@ -247,7 +247,6 @@ const NativeNoChats = (props: {onNewChat: () => void}) => ( onClick={props.onNewChat} mode="Primary" label="Start a new chat" - style={nativeStyles.button} /> </Kb.Box2> </> @@ -421,7 +420,7 @@ function DesktopInboxBody(props: ControlledInboxProps) { // Native InboxBody function NativeInboxBody(p: ControlledInboxProps) { -const {search} = p + const {search} = p const inbox = useInboxState(p.conversationIDKey, search.isSearching, p.refreshInbox) const {onUntrustedInboxVisible, toggleSmallTeamsExpanded, selectedConversationIDKey} = inbox const {unreadIndices, unreadTotal, rows, smallTeamsExpanded, isSearching, allowShowFloatingButton} = inbox @@ -528,9 +527,7 @@ const {search} = p <Kb.Box2 direction="vertical" fullWidth={true} style={nativeStyles.container} testID={TestIDs.CHAT_INBOX_LIST}> <NativeLoadingLine /> {isSearching ? ( - <Kb.Box2 direction="vertical" fullWidth={true}> - <InboxSearch header={headComponent} search={search} /> - </Kb.Box2> + <InboxSearch header={headComponent} search={search} /> ) : ( <Kb.List testID="inboxList" @@ -700,8 +697,6 @@ const desktopStyles = Kb.Styles.styleSheetCreate( const nativeStyles = Kb.Styles.styleSheetCreate( () => ({ - accessoryRow: {flex: 1}, - button: {width: '100%'}, container: Kb.Styles.platformStyles({ common: { flexGrow: 1, diff --git a/shared/chat/inbox/row/big-team-channel.tsx b/shared/chat/inbox/row/big-team-channel.tsx index c0e2e23619d6..a5778196e654 100644 --- a/shared/chat/inbox/row/big-team-channel.tsx +++ b/shared/chat/inbox/row/big-team-channel.tsx @@ -90,7 +90,7 @@ const BigTeamChannel = (props: Props) => { ) : null return ( - <Kb.ClickableBox2 onClick={onSelectConversation} style={styles.container}> + <Kb.ClickableBox3 direction="vertical" fullWidth={true} onClick={onSelectConversation} style={styles.container}> <Kb.Box2 direction="horizontal" fullHeight={true} style={styles.rowContainer}> <Kb.Box2 className="hover_background_color_blueGreyDark" @@ -117,7 +117,7 @@ const BigTeamChannel = (props: Props) => { </Kb.Box2> </Kb.Box2> </Kb.Box2> - </Kb.ClickableBox2> + </Kb.ClickableBox3> ) } @@ -166,7 +166,6 @@ const styles = Kb.Styles.styleSheetCreate( paddingLeft: Kb.Styles.globalMargins.tiny, paddingRight: 0, }, - isElectron: Kb.Styles.desktopStyles.clickable, isTablet: {alignItems: 'center'}, }), selectedChannelBackground: {backgroundColor: Kb.Styles.globalColors.blue}, diff --git a/shared/chat/inbox/row/big-team-header.tsx b/shared/chat/inbox/row/big-team-header.tsx index de5f479dd582..dbe2be773705 100644 --- a/shared/chat/inbox/row/big-team-header.tsx +++ b/shared/chat/inbox/row/big-team-header.tsx @@ -45,7 +45,8 @@ const BigTeamHeader = (props: Props) => { {teamname} </Kb.Text> </Kb.BoxGrow2> - <Kb.ClickableBox2 + <Kb.ClickableBox3 + direction="vertical" className="hover_container" onClick={showPopup} ref={popupAnchor} @@ -60,7 +61,7 @@ const BigTeamHeader = (props: Props) => { direction="vertical" style={Kb.Styles.collapseStyles([styles.badge, showBadge && styles.badgeVisible])} /> - </Kb.ClickableBox2> + </Kb.ClickableBox3> </Kb.Box2> ) } diff --git a/shared/chat/inbox/row/big-teams-divider.tsx b/shared/chat/inbox/row/big-teams-divider.tsx index 9e1ca2692b11..6483db0c73f3 100644 --- a/shared/chat/inbox/row/big-teams-divider.tsx +++ b/shared/chat/inbox/row/big-teams-divider.tsx @@ -18,7 +18,8 @@ const BigTeamsDivider = (props: Props) => { inlineLayout ? styles.inlineContainer : undefined, ]) return ( - <Kb.ClickableBox2 + <Kb.ClickableBox3 + direction="vertical" onClick={() => { T.RPCChat.localRequestInboxSmallResetRpcPromise().catch(() => {}) toggle() @@ -60,7 +61,7 @@ const BigTeamsDivider = (props: Props) => { ) : null} </Kb.Box2> )} - </Kb.ClickableBox2> + </Kb.ClickableBox3> ) } diff --git a/shared/chat/inbox/row/small-team/index.tsx b/shared/chat/inbox/row/small-team/index.tsx index 916c381f028e..8395e2dd49f8 100644 --- a/shared/chat/inbox/row/small-team/index.tsx +++ b/shared/chat/inbox/row/small-team/index.tsx @@ -100,9 +100,9 @@ const SmallTeam = (p: Props) => { {rowContents} </Kb.Box2> ) : ( - <Kb.ClickableBox2 onClick={onSelectConversation} className={className} testID={TestIDs.CHAT_INBOX_ROW} style={containerStyle}> + <Kb.ClickableBox3 direction="vertical" fullWidth={true} onClick={onSelectConversation} className={className} testID={TestIDs.CHAT_INBOX_ROW} style={containerStyle}> {rowContents} - </Kb.ClickableBox2> + </Kb.ClickableBox3> )} </SwipeConvActions> ) diff --git a/shared/chat/inbox/row/start-new-chat.tsx b/shared/chat/inbox/row/start-new-chat.tsx index 8a13068283e7..9a123d52a73c 100644 --- a/shared/chat/inbox/row/start-new-chat.tsx +++ b/shared/chat/inbox/row/start-new-chat.tsx @@ -9,12 +9,12 @@ const StartNewChat = (props: Props) => { if (isMobile) { return ( <Kb.Box2 direction="horizontal" alignItems="center" fullWidth={true} justifyContent="center" style={styles.container} relative={true}> - <Kb.ClickableBox2 style={styles.clickableBox} onClick={props.onNewChat}> + <Kb.ClickableBox3 direction="horizontal" alignItems="center" onClick={props.onNewChat}> <Kb.Icon type="iconfont-compose" style={styles.iconCompose} /> <Kb.Text type="BodyBigLink" style={{margin: Kb.Styles.globalMargins.tiny}}> Start a new chat </Kb.Text> - </Kb.ClickableBox2> + </Kb.ClickableBox3> </Kb.Box2> ) } @@ -35,10 +35,6 @@ const styles = Kb.Styles.styleSheetCreate( }, isElectron: Kb.Styles.desktopStyles.windowDraggingClickable, }), - clickableBox: { - alignItems: 'center', - flexDirection: 'row', - }, container: { backgroundColor: isMobile ? undefined diff --git a/shared/chat/inbox/search-row.tsx b/shared/chat/inbox/search-row.tsx index 2abc183295bb..92ce1eaea986 100644 --- a/shared/chat/inbox/search-row.tsx +++ b/shared/chat/inbox/search-row.tsx @@ -69,10 +69,8 @@ const styles = Kb.Styles.styleSheetCreate( () => ({ row: { - alignItems: 'center', height: '100%', paddingRight: Kb.Styles.globalMargins.tiny, - width: '100%', }, }) as const ) diff --git a/shared/chat/inbox/unread-shortcut.tsx b/shared/chat/inbox/unread-shortcut.tsx index e904a3838c9f..5651e38381ce 100644 --- a/shared/chat/inbox/unread-shortcut.tsx +++ b/shared/chat/inbox/unread-shortcut.tsx @@ -8,24 +8,26 @@ type Props = { } const UnreadShortcut = (props: Props) => ( - <Kb.ClickableBox2 onClick={props.onClick} style={props.inlineLayout ? styles.containerInline : styles.container}> - <Kb.Box2 - direction="horizontal" - gap="tiny" - centerChildren={!props.inlineLayout} - justifyContent={props.inlineLayout ? 'flex-start' : undefined} - alignItems="center" - fullWidth={true} - style={props.inlineLayout ? styles.unreadShortcutInline : styles.unreadShortcut} - > - <Kb.Icon type="iconfont-arrow-down" sizeType="Small" color={Kb.Styles.globalColors.white} /> - <Kb.Text negative={true} type="BodySmallSemibold"> - {props.inlineLayout - ? `${props.unreadCount} unread` - : `${props.unreadCount} unread ${pluralize('message', props.unreadCount)}`} - </Kb.Text> - </Kb.Box2> - </Kb.ClickableBox2> + <Kb.ClickableBox3 + direction="horizontal" + gap="tiny" + centerChildren={!props.inlineLayout} + justifyContent={props.inlineLayout ? 'flex-start' : undefined} + alignItems="center" + fullWidth={true} + onClick={props.onClick} + style={Kb.Styles.collapseStyles([ + props.inlineLayout ? styles.containerInline : styles.container, + props.inlineLayout ? styles.unreadShortcutInline : styles.unreadShortcut, + ])} + > + <Kb.Icon type="iconfont-arrow-down" sizeType="Small" color={Kb.Styles.globalColors.white} /> + <Kb.Text negative={true} type="BodySmallSemibold"> + {props.inlineLayout + ? `${props.unreadCount} unread` + : `${props.unreadCount} unread ${pluralize('message', props.unreadCount)}`} + </Kb.Text> + </Kb.ClickableBox3> ) const styles = Kb.Styles.styleSheetCreate( diff --git a/shared/chat/new-team-dialog-container.tsx b/shared/chat/new-team-dialog-container.tsx index a086b2d2ef4c..3af5b9538cc5 100644 --- a/shared/chat/new-team-dialog-container.tsx +++ b/shared/chat/new-team-dialog-container.tsx @@ -7,9 +7,8 @@ import {useConversationParticipants} from './conversation/data-hooks' type Props = {conversationIDKey?: T.Chat.ConversationIDKey} -const NewTeamDialogInner = (props: {conversationIDKey: T.Chat.ConversationIDKey}) => { - const {conversationIDKey} = props - const baseTeam = '' +const NewTeamDialog = (props: Props) => { + const conversationIDKey = props.conversationIDKey ?? T.Chat.noConversationIDKey const navigateUp = C.Router2.navigateUp const onCancel = () => { navigateUp() @@ -22,16 +21,7 @@ const NewTeamDialogInner = (props: {conversationIDKey: T.Chat.ConversationIDKey} .map(assertion => ({assertion, role: 'writer' as const})) void createNewTeamAndNavigate(teamname, false, {fromChat: true, usersToAdd}) } - const newTeamProps = { - baseTeam, - onCancel, - onSubmit, - } - return <CreateNewTeam {...newTeamProps} /> + return <CreateNewTeam baseTeam="" onCancel={onCancel} onSubmit={onSubmit} /> } -const NewTeamDialog = (props: Props) => ( - <NewTeamDialogInner conversationIDKey={props.conversationIDKey ?? T.Chat.noConversationIDKey} /> -) - export default NewTeamDialog diff --git a/shared/chat/payments/status/index.tsx b/shared/chat/payments/status/index.tsx index 5c33feced12d..a5ad5ac3e76b 100644 --- a/shared/chat/payments/status/index.tsx +++ b/shared/chat/payments/status/index.tsx @@ -66,12 +66,12 @@ const statusColor = (s: Status) => { const PaymentStatus = (props: Props) => { const statusRef = React.useRef<MeasureRef | null>(null) const [showPopup, setShowPopup] = React.useState(false) - const _showPopup = () => { + const showPopupIfAllowed = () => { if (props.allowPopup) { setShowPopup(true) } } - const _hidePopup = () => { + const hidePopup = () => { setShowPopup(false) } const text = ( @@ -79,7 +79,7 @@ const PaymentStatus = (props: Props) => { textRef={statusRef} type="BodyExtrabold" allowFontScaling={!!props.allowFontScaling} - onClick={_showPopup} + onClick={showPopupIfAllowed} > {' '} <Kb.Text type="BodyExtrabold" allowFontScaling={!!props.allowFontScaling} style={styles[props.status]}> @@ -91,7 +91,7 @@ const PaymentStatus = (props: Props) => { <PaymentStatusError attachTo={statusRef} error={props.errorDetail || ''} - onHidden={_hidePopup} + onHidden={hidePopup} visible={showPopup} /> ) : null @@ -104,8 +104,8 @@ const PaymentStatus = (props: Props) => { <Kb.Box2 style={styles.container} direction="horizontal" - onMouseOver={_showPopup} - onMouseLeave={_hidePopup} + onMouseOver={showPopupIfAllowed} + onMouseLeave={hidePopup} > {text} {popups} diff --git a/shared/chat/pdf/index.tsx b/shared/chat/pdf/index.tsx index 5cf1d2ca525d..bb2111df26f7 100644 --- a/shared/chat/pdf/index.tsx +++ b/shared/chat/pdf/index.tsx @@ -1,17 +1,17 @@ import * as C from '@/constants' import * as Kb from '@/common-adapters' import * as React from 'react' -import {useNavigation} from '@react-navigation/native' import * as T from '@/constants/types' +import {useNavigation} from '@react-navigation/native' +import {openLocalPathInSystemFileManagerDesktop} from '@/util/fs-storeless-actions' +import {attachmentDownloadMessage, takePDFMessage} from '../conversation/attachment-actions' +import {useConversationMessage} from '../conversation/data-hooks' type Props = { conversationIDKey?: T.Chat.ConversationIDKey messageID: T.Chat.MessageID url?: string } -import {openLocalPathInSystemFileManagerDesktop} from '@/util/fs-storeless-actions' -import {attachmentDownloadMessage, takePDFMessage} from '../conversation/attachment-actions' -import {useConversationMessage} from '../conversation/data-hooks' const ChatPDF = (props: Props) => { const {messageID} = props diff --git a/shared/chat/selectable-big-team-channel.tsx b/shared/chat/selectable-big-team-channel.tsx index f73f69ccd02e..3ffe2791fd9f 100644 --- a/shared/chat/selectable-big-team-channel.tsx +++ b/shared/chat/selectable-big-team-channel.tsx @@ -89,24 +89,23 @@ const SelectableBigTeamChannel = (props: Props) => { </> ) return ( - <Kb.ClickableBox onClick={props.onSelectConversation}> - <Kb.Box2 - direction="horizontal" - fullWidth={true} - centerChildren={true} - className="hover_background_color_blueGreyDark" - style={Kb.Styles.collapseStyles([ - styles.filteredRow, - { - backgroundColor: props.isSelected ? Kb.Styles.globalColors.blue : Kb.Styles.globalColors.white, - }, - ])} - onMouseLeave={_onMouseLeave} - onMouseOver={_onMouseOver} - > - {props.teamname ? rowLoadedContent : <Kb.ProgressIndicator type="Small" />} - </Kb.Box2> - </Kb.ClickableBox> + <Kb.ClickableBox3 + direction="horizontal" + fullWidth={true} + centerChildren={true} + className="hover_background_color_blueGreyDark" + onClick={props.onSelectConversation} + style={Kb.Styles.collapseStyles([ + styles.filteredRow, + { + backgroundColor: props.isSelected ? Kb.Styles.globalColors.blue : Kb.Styles.globalColors.white, + }, + ])} + onMouseLeave={_onMouseLeave} + onMouseOver={_onMouseOver} + > + {props.teamname ? rowLoadedContent : <Kb.ProgressIndicator type="Small" />} + </Kb.ClickableBox3> ) } diff --git a/shared/chat/selectable-small-team.tsx b/shared/chat/selectable-small-team.tsx index 2c5042b0291f..b8fdae688c08 100644 --- a/shared/chat/selectable-small-team.tsx +++ b/shared/chat/selectable-small-team.tsx @@ -30,32 +30,31 @@ const SelectableSmallTeam = (props: Props) => { if (!props.teamname && props.participants.length === 0) { return ( - <Kb.ClickableBox onClick={props.onSelectConversation}> - <Kb.Box2 direction="vertical" style={styles.container} centerChildren={true}> - <Kb.ProgressIndicator style={styles.spinner} type="Small" /> - </Kb.Box2> - </Kb.ClickableBox> + <Kb.ClickableBox3 direction="vertical" style={styles.container} centerChildren={true} onClick={props.onSelectConversation}> + <Kb.ProgressIndicator style={styles.spinner} type="Small" /> + </Kb.ClickableBox3> ) } return ( - <Kb.ClickableBox onClick={props.onSelectConversation} style={styles.container}> - <Kb.Box2 - alignItems="center" - direction="horizontal" - fullWidth={true} - fullHeight={true} - className={Kb.Styles.classNames('hover_background_color_blueGreyDark', { - background_color_blue: props.isSelected, - })} - style={Kb.Styles.collapseStyles([ - styles.rowContainer, - { - backgroundColor: props.isSelected ? Kb.Styles.globalColors.blue : Kb.Styles.globalColors.white, - }, - ])} - onMouseLeave={_onMouseLeave} - onMouseOver={_onMouseOver} - > + <Kb.ClickableBox3 + direction="horizontal" + alignItems="center" + fullWidth={true} + fullHeight={true} + className={Kb.Styles.classNames('hover_background_color_blueGreyDark', { + background_color_blue: props.isSelected, + })} + onClick={props.onSelectConversation} + style={Kb.Styles.collapseStyles([ + styles.container, + styles.rowContainer, + { + backgroundColor: props.isSelected ? Kb.Styles.globalColors.blue : Kb.Styles.globalColors.white, + }, + ])} + onMouseLeave={_onMouseLeave} + onMouseOver={_onMouseOver} + > {props.teamname ? ( <TeamAvatar teamname={props.teamname} @@ -94,8 +93,7 @@ const SelectableSmallTeam = (props: Props) => { )} </Kb.Box2> {props.showBadge && <Kb.Box2 direction="horizontal" style={styles.badge} />} - </Kb.Box2> - </Kb.ClickableBox> + </Kb.ClickableBox3> ) } @@ -114,7 +112,6 @@ const styles = Kb.Styles.styleSheetCreate(() => ({ }, rowContainer: Kb.Styles.platformStyles({ isElectron: { - ...Kb.Styles.desktopStyles.clickable, ...Kb.Styles.paddingH(Kb.Styles.globalMargins.xsmall), }, isMobile: { diff --git a/shared/chat/send-to-chat/conversation-list/conversation-list.tsx b/shared/chat/send-to-chat/conversation-list/conversation-list.tsx index fa5e3299934a..d2cecb8b23dd 100644 --- a/shared/chat/send-to-chat/conversation-list/conversation-list.tsx +++ b/shared/chat/send-to-chat/conversation-list/conversation-list.tsx @@ -23,35 +23,20 @@ type Row = { const _itemRenderer = (index: number, row: Row) => { const item = row.item return ( - <Kb.ClickableBox key={index} onClick={row.onSelect}> - <Kb.Box2 - direction="horizontal" - fullWidth={true} - gap="tiny" - style={Kb.Styles.collapseStyles([ - styles.results, - { - backgroundColor: - !isMobile && row.isSelected - ? Kb.Styles.globalColors.blue - : Kb.Styles.globalColors.white, - }, - ])} - > - {item.isTeam ? ( - <TeamAvatar isHovered={false} isMuted={false} isSelected={row.isSelected} teamname={item.tlfName} /> - ) : ( - <Avatars - isSelected={row.isSelected} - participantOne={item.parts?.[0]} - participantTwo={item.parts?.[1]} - /> - )} - <Kb.Text type="Body" style={{alignSelf: 'center'}} lineClamp={1}> - {item.name} - </Kb.Text> - </Kb.Box2> - </Kb.ClickableBox> + <Kb.ClickableBox3 key={index} onClick={row.onSelect} direction="horizontal" fullWidth={true} gap="tiny" style={Kb.Styles.collapseStyles([styles.results, {backgroundColor: !isMobile && row.isSelected ? Kb.Styles.globalColors.blue : Kb.Styles.globalColors.white}])}> + {item.isTeam ? ( + <TeamAvatar isHovered={false} isMuted={false} isSelected={row.isSelected} teamname={item.tlfName} /> + ) : ( + <Avatars + isSelected={row.isSelected} + participantOne={item.parts?.[0]} + participantTwo={item.parts?.[1]} + /> + )} + <Kb.Text type="Body" style={{alignSelf: 'center'}} lineClamp={1}> + {item.name} + </Kb.Text> + </Kb.ClickableBox3> ) } @@ -139,18 +124,16 @@ const ConversationListRender = (props: ConversationListRenderProps) => { }} /> </Kb.Box2> - <Kb.Box2 direction="vertical" fullWidth={true} fullHeight={true} flex={1}> - <Kb.List - itemHeight={{height: 65, type: 'fixed'}} - items={props.results.map((r, index) => ({ - isSelected: index === props.selected, - item: r, - onSelect: () => props.onSelect(T.Chat.conversationIDToKey(r.convID), r.tlfName), - }))} - renderItem={_itemRenderer} - indexAsKey={true} - /> - </Kb.Box2> + <Kb.List + itemHeight={{height: 65, type: 'fixed'}} + items={props.results.map((r, index) => ({ + isSelected: index === props.selected, + item: r, + onSelect: () => props.onSelect(T.Chat.conversationIDToKey(r.convID), r.tlfName), + }))} + renderItem={_itemRenderer} + indexAsKey={true} + /> </Kb.Box2> ) } diff --git a/shared/chat/send-to-chat/index.tsx b/shared/chat/send-to-chat/index.tsx index d78bc3ddf760..33cdd6a403ec 100644 --- a/shared/chat/send-to-chat/index.tsx +++ b/shared/chat/send-to-chat/index.tsx @@ -16,19 +16,6 @@ type Props = { sendPaths?: Array<string> // KBFS or incoming share (files) } -const MobileSendToChatRoutable = (props: Props) => { - const {canBack, isFromShareExtension, sendPaths, text} = props - - return ( - <MobileSendToChat - canBack={canBack} - isFromShareExtension={isFromShareExtension} - sendPaths={sendPaths} - text={text} - /> - ) -} - export const MobileSendToChat = (props: Props) => { const {isFromShareExtension, sendPaths, text} = props const navigateAppend = C.Router2.navigateAppend @@ -120,43 +107,41 @@ type DesktopSendToChatRenderProps = { export const DesktopSendToChatRender = (props: DesktopSendToChatRenderProps) => { return ( - <> - <Kb.Box2 direction="vertical" style={desktopStyles.container} centerChildren={true}> - <Kb.Box2 direction="horizontal" centerChildren={true} style={desktopStyles.header} fullWidth={true}> - <Kb.Text type="Header">Attach in conversation</Kb.Text> - </Kb.Box2> - <Kb.Box2 direction="vertical" style={desktopStyles.belly} fullWidth={true}> - <Kb.Box2 - direction="vertical" - centerChildren={true} - fullWidth={true} - style={desktopStyles.pathItem} - gap="tiny" - > - <Kbfs.ItemIcon size={48} path={props.path} badgeOverride="iconfont-attachment" /> - <Kb.Text type="BodySmall">{T.FS.getPathName(props.path)}</Kb.Text> - </Kb.Box2> - <ChooseConversation - convName={props.convName} - dropdownButtonStyle={desktopStyles.dropdown} - onSelect={props.onSelect} - /> - <Kb.Input3 - placeholder="Title" - value={props.title} - onChangeText={props.setTitle} - /> + <Kb.Box2 direction="vertical" style={desktopStyles.container} centerChildren={true}> + <Kb.Box2 direction="horizontal" centerChildren={true} style={desktopStyles.header} fullWidth={true}> + <Kb.Text type="Header">Attach in conversation</Kb.Text> + </Kb.Box2> + <Kb.Box2 direction="vertical" alignItems="center" style={desktopStyles.belly} fullWidth={true}> + <Kb.Box2 + direction="vertical" + centerChildren={true} + fullWidth={true} + style={desktopStyles.pathItem} + gap="tiny" + > + <Kbfs.ItemIcon size={48} path={props.path} badgeOverride="iconfont-attachment" /> + <Kb.Text type="BodySmall">{T.FS.getPathName(props.path)}</Kb.Text> </Kb.Box2> - <Kb.ButtonBar fullWidth={true} style={desktopStyles.buttonBar}> - <Kb.Button type="Dim" label="Cancel" onClick={props.onCancel} /> - <Kb.Button label="Send in conversation" onClick={props.onSend} disabled={!props.enabled} /> - </Kb.ButtonBar> + <ChooseConversation + convName={props.convName} + dropdownButtonStyle={desktopStyles.dropdown} + onSelect={props.onSelect} + /> + <Kb.Input3 + placeholder="Title" + value={props.title} + onChangeText={props.setTitle} + /> </Kb.Box2> - </> + <Kb.ButtonBar fullWidth={true} style={desktopStyles.buttonBar}> + <Kb.Button type="Dim" label="Cancel" onClick={props.onCancel} /> + <Kb.Button label="Send in conversation" onClick={props.onSend} disabled={!props.enabled} /> + </Kb.ButtonBar> + </Kb.Box2> ) } -const SendToChat = isMobile ? MobileSendToChatRoutable : DesktopSendToChat +const SendToChat = isMobile ? MobileSendToChat : DesktopSendToChat export default SendToChat @@ -165,7 +150,6 @@ const desktopStyles = Kb.Styles.styleSheetCreate( ({ belly: { ...Kb.Styles.globalStyles.flexGrow, - alignItems: 'center', marginBottom: Kb.Styles.globalMargins.small, paddingLeft: Kb.Styles.globalMargins.large, paddingRight: Kb.Styles.globalMargins.large, diff --git a/shared/chat/top-line.tsx b/shared/chat/top-line.tsx index 06558a057261..575604bf5716 100644 --- a/shared/chat/top-line.tsx +++ b/shared/chat/top-line.tsx @@ -43,9 +43,7 @@ const FilteredTopLine = (props: Props) => { } const styles = Kb.Styles.styleSheetCreate(() => ({ - boldOverride: { - ...Kb.Styles.globalStyles.fontBold, - }, + boldOverride: Kb.Styles.globalStyles.fontBold, selectedText: { color: Kb.Styles.globalColors.white, }, diff --git a/shared/common-adapters/avatar/icon-to-img-set.tsx b/shared/common-adapters/avatar/icon-to-img-set.tsx index 2e4f6045b8d8..5b073592b022 100644 --- a/shared/common-adapters/avatar/icon-to-img-set.tsx +++ b/shared/common-adapters/avatar/icon-to-img-set.tsx @@ -30,19 +30,19 @@ function getMultsMap(imgMap: {[size: string]: unknown}, targetSize: number): Mul const sizes = ssizes.map(s => parseInt(s, 10)).sort((a: number, b: number) => a - b) const multsMap: MultMap = {1: undefined, 2: undefined, 3: undefined} - multiKeys.forEach(mult => { + for (const mult of multiKeys) { const level1 = idealSizeMultMap[String(targetSize)] if (level1) { const level2 = level1[mult] if (level2) { multsMap[mult] = level2 - return + continue } } const ideal = mult * targetSize const size = sizes.find(size => size >= ideal) multsMap[mult] = size || sizes.at(-1) - }) + } _getMultsMapCache[sizeKey] = multsMap return multsMap diff --git a/shared/common-adapters/avatar/index.tsx b/shared/common-adapters/avatar/index.tsx index f4e4eac615d1..c06e14dea724 100644 --- a/shared/common-adapters/avatar/index.tsx +++ b/shared/common-adapters/avatar/index.tsx @@ -3,8 +3,7 @@ import {useState} from 'react' import * as Styles from '@/styles' import {useConfigState} from '@/stores/config' import * as AvatarZus from './store' -import {Pressable, View} from 'react-native' -import {useColorScheme} from 'react-native' +import {Pressable, View, useColorScheme} from 'react-native' import {navToProfile} from '@/constants/router' import {Image} from 'expo-image' import {iconTypeToImgSet} from './icon-to-img-set' diff --git a/shared/common-adapters/badge.tsx b/shared/common-adapters/badge.tsx index 159d37399931..17e1d0da798b 100644 --- a/shared/common-adapters/badge.tsx +++ b/shared/common-adapters/badge.tsx @@ -98,11 +98,7 @@ function Badge(p: Badge2Props) { type="BodyTinyBold" style={Styles.collapseStyles([ styles.text, - { - fontSize: fontSize, - height: height, - lineHeight: isMobile ? height : `${height}px`, - } as const, + {fontSize, height, lineHeight: isMobile ? height : `${height}px`} as const, badgeNumberStyle, ])} > diff --git a/shared/common-adapters/banner.tsx b/shared/common-adapters/banner.tsx index 78f23405e429..e22860235088 100644 --- a/shared/common-adapters/banner.tsx +++ b/shared/common-adapters/banner.tsx @@ -118,8 +118,8 @@ export const Banner = (props: BannerProps) => ( padding="xtiny" sizeType="Small" type="iconfont-close" - color={colorToIconColor()[props.color]} - hoverColor={colorToIconHoverColor()[props.color]} + color={colorToIconColor[props.color]} + hoverColor={colorToIconHoverColor[props.color]} onClick={props.onClose} /> </Box2> @@ -217,20 +217,20 @@ const colorToTextColorStyles = Styles.styleSheetCreate(() => ({ yellow: {color: Styles.globalColors.brown_75}, })) -const colorToIconColor = () => ({ +const colorToIconColor = { blue: Styles.globalColors.white_90, green: Styles.globalColors.white_90, grey: Styles.globalColors.black_50, red: Styles.globalColors.white_90, white: Styles.globalColors.black_50, yellow: Styles.globalColors.brown_75, -}) +} -const colorToIconHoverColor = () => ({ +const colorToIconHoverColor = { blue: Styles.globalColors.white, green: Styles.globalColors.white, grey: Styles.globalColors.black, red: Styles.globalColors.white, white: Styles.globalColors.black, yellow: Styles.globalColors.brown, -}) +} diff --git a/shared/common-adapters/button-bar.tsx b/shared/common-adapters/button-bar.tsx index bba49806ef8e..8199f72fdfbd 100644 --- a/shared/common-adapters/button-bar.tsx +++ b/shared/common-adapters/button-bar.tsx @@ -14,19 +14,9 @@ type Props = { } const ButtonBar = (props: Props) => { - const _spacing = () => { - if ((props.direction ?? 'row') === 'row' && props.small && !isMobile) { - return SmallSpacer - } - return BigSpacer - } - - const _surroundSpacing = () => { - return (props.direction ?? 'row') === 'column' - } - - const Spacing = _spacing() - const surroundSpacing = _surroundSpacing() + const isColumn = (props.direction ?? 'row') === 'column' + const Spacing = (!isColumn && props.small && !isMobile) ? SmallSpacer : BigSpacer + const surroundSpacing = isColumn const children = React.Children.toArray(props.children) const childrenWithSpacing = children.reduce<Array<React.ReactNode>>((arr, c, idx) => { if (surroundSpacing || idx > 0) { @@ -43,7 +33,6 @@ const ButtonBar = (props: Props) => { minHeight: isMobile ? (props.small ? 64 : 72) : props.small ? 44 : 64, } - const isColumn = (props.direction ?? 'row') === 'column' const style = Styles.collapseStyles([ { ...(Styles.isTablet ? {maxWidth: 460} : {}), diff --git a/shared/common-adapters/checkbox.tsx b/shared/common-adapters/checkbox.tsx index 4679b5ac9dd3..0009ffa4ffa7 100644 --- a/shared/common-adapters/checkbox.tsx +++ b/shared/common-adapters/checkbox.tsx @@ -1,5 +1,4 @@ -import {Box2} from './box' -import ClickableBox from './clickable-box' +import {Box2, ClickableBox3} from './box' import Icon from './icon' import Switch from '@/common-adapters/switch' import Text from './text' @@ -24,19 +23,22 @@ type Props = { const CHECKBOX_SIZE = 13 const CHECKBOX_MARGIN = 8 -const Kb = {Box2, ClickableBox, Icon, Styles, Switch, Text} +const Kb = {Box2, ClickableBox3, Icon, Styles, Switch, Text} const Checkbox = (props: Props) => { if (!isMobile) { return ( - <Kb.ClickableBox + <Kb.ClickableBox3 + direction="horizontal" + alignItems="flex-start" + alignSelf="flex-start" style={Kb.Styles.collapseStyles([ styles.container, !props.disabled && styles.clickable, props.style, ])} onClick={e => - props.disabled || e.defaultPrevented ? undefined : props.onCheck?.(!props.checked) + props.disabled || e?.defaultPrevented ? undefined : props.onCheck?.(!props.checked) } > <div @@ -67,7 +69,7 @@ const Checkbox = (props: Props) => { ))} {!!props.labelSubtitle && <Kb.Text type="BodySmall">{props.labelSubtitle}</Kb.Text>} </Kb.Box2> - </Kb.ClickableBox> + </Kb.ClickableBox3> ) } @@ -114,8 +116,6 @@ const styles = Kb.Styles.styleSheetCreate(() => ({ }, }), container: { - ...Kb.Styles.globalStyles.flexBoxRow, - alignItems: 'flex-start', ...Kb.Styles.paddingV(2), }, icon: Kb.Styles.platformStyles({ diff --git a/shared/common-adapters/choice-list.css b/shared/common-adapters/choice-list.css deleted file mode 100644 index 40aa8203137c..000000000000 --- a/shared/common-adapters/choice-list.css +++ /dev/null @@ -1,23 +0,0 @@ -.cl-entry { - background-color: transparent; - &:hover { - background-color: light-dark(var(--color-blueLighter2), #140d03); - .cl-icon-container { - background: transparent; - } - } -} - - -.cl-icon { - transform-origin: center center; - transition: 0.5s transform; - &:hover .cl-icon { - transform: translateX(25%); - } -} - -.cl-icon-container { - transition: 0.5s background; - border-radius: 50%; -} diff --git a/shared/common-adapters/choice-list.tsx b/shared/common-adapters/choice-list.tsx deleted file mode 100644 index 336ffab3f97e..000000000000 --- a/shared/common-adapters/choice-list.tsx +++ /dev/null @@ -1,160 +0,0 @@ -import {Box2} from './box' -import ClickableBox from './clickable-box' -import IconAuto from './icon-auto' -import Text from './text' -import * as React from 'react' -import * as Styles from '@/styles' -import './choice-list.css' -import type {IconType} from './icon' - -type Option = { - title: string - description: string - icon: IconType - onClick: () => void - onPress?: never -} - -type Props = { - options: Array<Option> -} - -const Kb = {Box2, ClickableBox, IconAuto, Text} - -const makeOptionsKey = (options: Props['options']) => - options.map(option => `${option.title}:${option.description}:${String(option.icon)}`).join('|') - -const ChoiceList = (props: Props) => { - const {options} = props - const optionsKey = makeOptionsKey(options) - const [active, setActive] = React.useState<{index?: number; optionsKey: string}>(() => ({ - optionsKey, - })) - const activeIndex = active.optionsKey === optionsKey ? active.index : undefined - - if (!isMobile) { - return ( - <Kb.Box2 direction="vertical" fullWidth={true}> - {options.map((op, idx) => { - const iconType = op.icon - return ( - <Kb.ClickableBox key={idx} onClick={() => op.onClick()}> - <Kb.Box2 direction="horizontal" fullWidth={true} style={styles.entry} className="cl-entry"> - <Kb.Box2 - direction="vertical" - centerChildren={true} - style={styles.iconContainer} - className="cl-icon-container" - > - {typeof op.icon === 'string' ? ( - <Kb.IconAuto style={styles.icon} type={iconType} className="cl-icon" /> - ) : ( - <Kb.Box2 direction="vertical" style={styles.icon} className="cl-icon"> - {op.icon} - </Kb.Box2> - )} - </Kb.Box2> - <Kb.Box2 - direction="vertical" - alignItems="flex-start" - justifyContent="center" - flex={1} - style={styles.infoContainer} - > - <Text type="BodyBigLink">{op.title}</Text> - <Text type="Body">{op.description}</Text> - </Kb.Box2> - </Kb.Box2> - </Kb.ClickableBox> - ) - })} - </Kb.Box2> - ) - } - - return ( - <Kb.Box2 direction="vertical" fullWidth={true}> - {options.map((op, idx) => { - const iconType = op.icon - return ( - <Kb.ClickableBox - key={idx} - underlayColor={Styles.globalColors.blueLighter2} - onClick={op.onClick} - onPressIn={() => setActive({index: idx, optionsKey})} - onPressOut={() => setActive({optionsKey})} - > - <Kb.Box2 direction="horizontal" fullWidth={true} style={styleEntry}> - <Kb.Box2 direction="vertical" centerChildren={true} style={styleIconContainer(activeIndex === idx)}> - {typeof op.icon === 'string' ? ( - <IconAuto style={styleIcon} type={iconType} /> - ) : ( - <Kb.Box2 direction="vertical" style={styleIcon}> - {op.icon} - </Kb.Box2> - )} - </Kb.Box2> - <Kb.Box2 direction="vertical" justifyContent="center" flex={1} style={styleInfoContainer}> - <Kb.Text style={styleInfoTitle} type="Header"> - {op.title} - </Kb.Text> - <Kb.Text type="Body">{op.description}</Kb.Text> - </Kb.Box2> - </Kb.Box2> - </Kb.ClickableBox> - ) - })} - </Kb.Box2> - ) -} - -const styles = Styles.styleSheetCreate(() => ({ - entry: Styles.platformStyles({ - isElectron: { - ...Styles.desktopStyles.clickable, - ...Styles.padding(Styles.globalMargins.tiny, Styles.globalMargins.small), - }, - }), - icon: { - ...Styles.size(48), - }, - iconContainer: { - background: Styles.globalColors.greyLight, - ...Styles.size(80), - }, - infoContainer: { - marginLeft: Styles.globalMargins.small, - textAlign: 'left', - }, -})) - -const styleEntry = { - paddingBottom: Styles.globalMargins.tiny, - paddingLeft: Styles.globalMargins.small, - paddingRight: Styles.globalMargins.small, - paddingTop: Styles.globalMargins.tiny, -} - -const styleIconContainer = (isActive: boolean) => - ({ - alignSelf: 'center', - borderRadius: (Styles.globalMargins.large + Styles.globalMargins.medium) / 2, - height: Styles.globalMargins.large + Styles.globalMargins.medium, - ...(isActive ? {} : {backgroundColor: Styles.globalColors.greyLight}), - width: Styles.globalMargins.large + Styles.globalMargins.medium, - }) as const - -const styleIcon = { - height: Styles.globalMargins.large, - width: Styles.globalMargins.large, -} - -const styleInfoContainer = { - marginLeft: Styles.globalMargins.small, -} - -const styleInfoTitle = { - color: Styles.globalColors.blueDark, -} - -export default ChoiceList diff --git a/shared/common-adapters/clickable-box.tsx b/shared/common-adapters/clickable-box.tsx deleted file mode 100644 index e840acc95e05..000000000000 --- a/shared/common-adapters/clickable-box.tsx +++ /dev/null @@ -1,239 +0,0 @@ -import * as React from 'react' -import * as Styles from '@/styles' -import {Pressable, View, TouchableOpacity, TouchableWithoutFeedback} from 'react-native' -import type {_StylesCrossPlatform} from '@/styles/css' -import type {MeasureRef} from './measure-ref' - -type Props = { - className?: string - children?: React.ReactNode - style?: Styles.StylesCrossPlatform - onClick?: (event: React.BaseSyntheticEvent) => void - onDoubleClick?: (event: React.BaseSyntheticEvent) => void - onPress?: never - onLongPress?: (event: React.BaseSyntheticEvent) => void - underlayColor?: string - onPressIn?: () => void - onPressOut?: () => void - feedback?: boolean - activeOpacity?: number - hoverColor?: string - onMouseOver?: (event: React.MouseEvent) => void - onMouseEnter?: (event: React.MouseEvent) => void - onMouseLeave?: (event: React.MouseEvent) => void - onMouseDown?: (event: React.MouseEvent) => void - onMouseMove?: (event: React.MouseEvent) => void - onMouseUp?: (event: React.MouseEvent) => void - testID?: string - title?: string - tooltip?: string -} - -type Props2 = { - onLongPress?: () => void - hitSlop?: number - testID?: string - onMouseOver?: (event: React.MouseEvent) => void - onClick?: () => void - children: React.ReactNode - className?: string - style?: Styles.StylesCrossPlatform -} - -const ClickableBox = (props: Props & {children: React.ReactNode; ref?: React.Ref<MeasureRef | null>}) => { - const {ref} = props - const [mouseDown, setMouseDown] = React.useState(false) - const [mouseIn, setMouseIn] = React.useState(false) - - if (!isMobile) { - const needMouseEnterLeaveHandlers = !!( - props.hoverColor || - props.underlayColor || - props.onMouseEnter || - props.onMouseLeave - ) - const onMouseEnter = needMouseEnterLeaveHandlers - ? (e: React.MouseEvent): void => { - setMouseIn(true) - props.onMouseEnter?.(e) - } - : undefined - const onMouseLeave = needMouseEnterLeaveHandlers - ? (e: React.MouseEvent) => { - setMouseIn(false) - props.onMouseLeave?.(e) - } - : undefined - const onMouseDown = (e: React.MouseEvent) => { - setMouseDown(true) - props.onMouseDown?.(e) - } - const onMouseUp = (e: React.MouseEvent) => { - setMouseDown(false) - props.onMouseUp?.(e) - } - - const { - style, - children, - underlayColor, - hoverColor, - onClick, - onDoubleClick, - className, - tooltip, - ref: _ref, - ...otherProps - } = props - - const {onPress, onLongPress, onPressIn, onPressOut, activeOpacity, feedback, testID: _testID, ...passThroughProps} = - otherProps - - let underlay: React.ReactNode - if (mouseIn && props.onClick && (props.feedback || props.feedback === undefined)) { - let borderRadius = 0 - if (style && typeof style === 'object') { - borderRadius = ((style as _StylesCrossPlatform).borderRadius as number) || 0 - } - const backgroundColor = mouseDown - ? underlayColor || 'rgba(255, 255, 255, 0.2)' - : hoverColor || 'rgba(255, 255, 255, 0.1)' - underlay = ( - <div - style={{ - ...Styles.globalStyles.fillAbsolute, - backgroundColor, - borderRadius, - }} - /> - ) - } - - return ( - <div - ref={ref as React.Ref<HTMLDivElement>} - className={Styles.classNames(className, {tooltip})} - data-tooltip={tooltip} - data-testid={props.testID} - {...passThroughProps} - onMouseDown={onMouseDown} - onMouseEnter={onMouseEnter} - onMouseLeave={onMouseLeave} - onMouseUp={onMouseUp} - onDoubleClick={onDoubleClick} - onClick={onClick} - style={ - Styles.collapseStyles([ - desktopStyles.container, - onClick || props.onMouseDown ? desktopStyles.click : null, - style, - ]) as React.CSSProperties - } - > - {underlay} - {children} - </div> - ) - } - - const {feedback = true, onClick, onPressIn, onPressOut, onLongPress} = props - const {style, activeOpacity, children, testID} = props - - if (onClick) { - const clickStyle = Styles.collapseStyles([nativeStyles.box, style]) - if (feedback) { - return ( - <TouchableOpacity - disabled={!onClick} - onPress={onClick} - onPressIn={onPressIn} - onPressOut={onPressOut} - onLongPress={onLongPress} - style={clickStyle} - testID={testID} - activeOpacity={activeOpacity ?? 0.7} - > - {children} - </TouchableOpacity> - ) - } else { - return ( - <TouchableWithoutFeedback - onPressIn={onPressIn} - onPressOut={onPressOut} - onPress={onClick} - onLongPress={onLongPress} - > - <View style={clickStyle} testID={testID}>{children}</View> - </TouchableWithoutFeedback> - ) - } - } else { - if (__DEV__) { - if (onPressIn || onPressOut || onLongPress) { - console.warn("Passed onPress*/on*Press with no onPress, which isn't supported on the native side") - } - } - return <View style={style} testID={testID}>{children}</View> - } -} - -const desktopStyles = Styles.styleSheetCreate( - () => - ({ - click: Styles.platformStyles({ - isElectron: { - ...Styles.desktopStyles.clickable, - }, - }), - container: Styles.platformStyles({ - isElectron: { - alignItems: 'stretch', - borderRadius: 0, - display: 'flex', - flexDirection: 'column', - height: undefined, - lineHeight: 0, - minWidth: undefined, - position: 'relative', - textAlign: 'left', - transform: 'none', - transition: 'none', - }, - }), - }) as const -) - -const nativeStyles = Styles.styleSheetCreate(() => ({ - box: {borderRadius: 3}, -})) - -export default ClickableBox - -export const ClickableBox2 = (p: Props2 & {ref?: React.Ref<MeasureRef | null>}) => { - if (!isMobile) { - const {onClick, children, style, className, onMouseOver, ref, testID} = p - return ( - <div - onClick={onClick} - onMouseOver={onMouseOver} - style={Styles.castStyleDesktop(style)} - ref={ref as React.Ref<HTMLDivElement>} - className={Styles.classNames('clickable-box2', className)} - data-testid={testID} - > - {children} - </div> - ) - } - const {onLongPress, onClick, children, hitSlop, style, testID} = p - const onPress = () => { - onClick?.() - } - return ( - <Pressable onLongPress={onLongPress} onPress={onPress} style={style} hitSlop={hitSlop} testID={testID}> - {children} - </Pressable> - ) -} - diff --git a/shared/common-adapters/copy-text.tsx b/shared/common-adapters/copy-text.tsx index dd35f1d46d3f..db4a3764f516 100644 --- a/shared/common-adapters/copy-text.tsx +++ b/shared/common-adapters/copy-text.tsx @@ -226,9 +226,6 @@ const styles = Styles.styleSheetCreate( maxWidth: 460, overflow: 'hidden', }, - isMobile: { - // minHeight: 40, - }, }), containerDisabled: { backgroundColor: Styles.globalColors.black_10, @@ -248,10 +245,6 @@ const styles = Styles.styleSheetCreate( minWidth: 0, textAlign: 'left', }, - isAndroid: { - // position: 'relative', - // top: 3, - }, isElectron: { userSelect: 'all', wordBreak: 'break-all', diff --git a/shared/common-adapters/dropdown.tsx b/shared/common-adapters/dropdown.tsx index 226c93a63ab7..893a49746e66 100644 --- a/shared/common-adapters/dropdown.tsx +++ b/shared/common-adapters/dropdown.tsx @@ -1,7 +1,6 @@ import type * as React from 'react' -import {Box2} from './box' +import {Box2, ClickableBox3} from './box' import ProgressIndicator from './progress-indicator' -import ClickableBox from './clickable-box' import Text from './text' import Popup from './popup' import ScrollView from './scroll-view' @@ -15,7 +14,7 @@ import {useSafeAreaInsets} from './safe-area-view' const Kb = { Box2, - ClickableBox, + ClickableBox3, Icon, Popup, ProgressIndicator, @@ -31,47 +30,45 @@ type DropdownButtonProps = { selectedBoxStyle?: Styles.StylesCrossPlatform style?: Styles.StylesCrossPlatform popupAnchor?: React.RefObject<MeasureRef | null> - toggleOpen: (e: React.BaseSyntheticEvent) => void + toggleOpen: (e?: React.BaseSyntheticEvent) => void inline?: boolean loading?: boolean } export const DropdownButton = (props: DropdownButtonProps) => { const {disabled, toggleOpen, style, popupAnchor, selectedBoxStyle, inline, loading, selected} = props return ( - <Kb.ClickableBox + <Kb.ClickableBox3 onClick={!disabled ? toggleOpen : undefined} - style={Styles.collapseStyles([styles.dropdownBoxContainer, style])} + direction="vertical" + ref={popupAnchor} + className={Styles.classNames('dropdown_border', { + hover: !disabled, + })} + style={Styles.collapseStyles([ + styles.dropdownBoxContainer, + styles.measureBox, + { + paddingRight: inline + ? Styles.globalMargins.tiny + : isMobile + ? Styles.globalMargins.large + : Styles.globalMargins.small, + }, + disabled ? {opacity: 0.3} : {}, + {cursor: !disabled ? 'pointer' : undefined}, + {width: inline ? undefined : '100%'}, + style, + ])} > - <Kb.Box2 - direction="vertical" - ref={popupAnchor} - className={Styles.classNames('dropdown_border', { - hover: !disabled, - })} - style={Styles.collapseStyles([ - styles.measureBox, - { - paddingRight: inline - ? Styles.globalMargins.tiny - : isMobile - ? Styles.globalMargins.large - : Styles.globalMargins.small, - }, - disabled ? {opacity: 0.3} : {}, - {cursor: !disabled ? 'pointer' : undefined}, - {width: inline ? undefined : '100%'}, - ])} - > - <Kb.Box2 direction="vertical" centerChildren={true} fullWidth={true} style={Styles.collapseStyles([styles.selectedBox, selectedBoxStyle])}> - {loading ? <Kb.ProgressIndicator type="Small" /> : selected} - </Kb.Box2> - <Kb.Icon - type="iconfont-caret-down" - sizeType="Tiny" - style={{marginTop: isMobile ? 2 : -8}} - /> + <Kb.Box2 direction="vertical" centerChildren={true} fullWidth={true} style={Styles.collapseStyles([styles.selectedBox, selectedBoxStyle])}> + {loading ? <Kb.ProgressIndicator type="Small" /> : selected} </Kb.Box2> - </Kb.ClickableBox> + <Kb.Icon + type="iconfont-caret-down" + sizeType="Tiny" + style={{marginTop: isMobile ? 2 : -8}} + /> + </Kb.ClickableBox3> ) } @@ -105,26 +102,22 @@ function Dropdown<N extends React.ReactNode>(p: Props<N>) { > <Kb.ScrollView style={styles.scrollView} contentInset={{bottom}}> {items.map((i: N, idx) => ( - <Kb.ClickableBox + <Kb.ClickableBox3 key={idx} onClick={evt => { - evt.stopPropagation() - evt.preventDefault() + evt?.stopPropagation() + evt?.preventDefault() // Bug in flow that doesn't let us just call this function // onSelect(i) onChangedIdx?.(idx) hidePopup() }} - style={styles.itemClickBox} + direction="vertical" + className="hover_background_color_blueLighter2" + style={Styles.collapseStyles([styles.itemClickBox, styles.itemBox, itemBoxStyle])} > - <Kb.Box2 - direction="vertical" - style={Styles.collapseStyles([styles.itemBox, itemBoxStyle])} - className="hover_background_color_blueLighter2" - > - {i} - </Kb.Box2> - </Kb.ClickableBox> + {i} + </Kb.ClickableBox3> ))} </Kb.ScrollView> </Kb.Popup> @@ -184,7 +177,7 @@ export const InlineDropdown = (props: InlineDropdownProps) => { loading={props.loading} style={Styles.collapseStyles([styles.inlineDropdown, props.containerStyle])} toggleOpen={e => { - e.stopPropagation() + e?.stopPropagation() props.onPress() }} selectedBoxStyle={Styles.collapseStyles([styles.inlineDropdownSelected, props.style])} diff --git a/shared/common-adapters/emoji/custom-emoji.tsx b/shared/common-adapters/emoji/custom-emoji.tsx index 04bf917c8f07..5236ecc22d43 100644 --- a/shared/common-adapters/emoji/custom-emoji.tsx +++ b/shared/common-adapters/emoji/custom-emoji.tsx @@ -46,12 +46,7 @@ const CustomEmoji = (props: Props) => { <Kb.WithTooltip tooltip={alias ?? null} containerStyle={styles.tooltipContainer}> <Kb.Image src={src} - style={Kb.Styles.collapseStyles([ - { - maxHeight: size, - width: size, - }, - ])} + style={{maxHeight: size, width: size}} /> </Kb.WithTooltip> </Kb.Box2> diff --git a/shared/common-adapters/emoji/index.tsx b/shared/common-adapters/emoji/index.tsx index 52bbf78f7c68..6dcf1b2bfb59 100644 --- a/shared/common-adapters/emoji/index.tsx +++ b/shared/common-adapters/emoji/index.tsx @@ -4,10 +4,6 @@ import type * as ED from './slow-data' import type * as Styles from '@/styles' import CustomEmoji from './custom-emoji' -const Kb = { - NativeEmoji, -} - export type RenderableEmoji = { aliasForCustom?: string unicodeStock?: string @@ -121,7 +117,7 @@ const Emoji = (props: EmojiProps) => { if (emoji.renderStock) { return ( - <Kb.NativeEmoji + <NativeEmoji size={size} emojiName={emoji.renderStock} disableSelecting={virtualText} diff --git a/shared/common-adapters/floating-menu/menu-layout/index.tsx b/shared/common-adapters/floating-menu/menu-layout/index.tsx index 75a128ee3099..a39d4883aedf 100644 --- a/shared/common-adapters/floating-menu/menu-layout/index.tsx +++ b/shared/common-adapters/floating-menu/menu-layout/index.tsx @@ -2,7 +2,7 @@ import type * as React from 'react' import type {MenuLayoutProps, MenuItem} from './index.shared' export type {MenuItem, MenuItems, MenuLayoutProps, _InnerMenuItem} from './index.shared' import {Box2} from '@/common-adapters/box' -import ClickableBox from '@/common-adapters/clickable-box' +import {ClickableBox3} from '@/common-adapters/box' import Divider from '@/common-adapters/divider' import Icon from '@/common-adapters/icon' import IconAuto from '@/common-adapters/icon-auto' @@ -53,8 +53,10 @@ const DesktopMenuLayout = (props: MenuLayoutProps) => { return item.unWrapped ? ( item.view ) : ( - <ClickableBox + <ClickableBox3 key={index} + direction="vertical" + fullWidth={true} className={hoverClassName} style={Styles.collapseStyles([desktopStyles.itemContainer, styleClickable])} onClick={() => { @@ -107,7 +109,7 @@ const DesktopMenuLayout = (props: MenuLayoutProps) => { </Text> )} {!!item.progressIndicator && <ProgressIndicator type="Large" style={desktopStyles.progressIndicator} />} - </ClickableBox> + </ClickableBox3> ) } @@ -122,32 +124,29 @@ const DesktopMenuLayout = (props: MenuLayoutProps) => { }, []) return ( - <ClickableBox + <ClickableBox3 onClick={event => { - event.stopPropagation() + event?.stopPropagation() }} + direction="vertical" + alignItems="stretch" + fullWidth={true} + style={Styles.collapseStyles([desktopStyles.menuContainer, props.style])} > - <Box2 - direction="vertical" - alignItems="stretch" - fullWidth={true} - style={Styles.collapseStyles([desktopStyles.menuContainer, props.style])} - > - {props.header} - {items.some(item => item !== 'Divider') && ( - <Box2 - direction="vertical" - fullWidth={true} - style={Styles.collapseStyles([desktopStyles.menuItemList, props.listStyle])} - > - {items.map( - (item, index): React.ReactNode => - item === 'Divider' ? renderDivider(index) : renderMenuItem(item, index) - )} - </Box2> - )} - </Box2> - </ClickableBox> + {props.header} + {items.some(item => item !== 'Divider') && ( + <Box2 + direction="vertical" + fullWidth={true} + style={Styles.collapseStyles([desktopStyles.menuItemList, props.listStyle])} + > + {items.map( + (item, index): React.ReactNode => + item === 'Divider' ? renderDivider(index) : renderMenuItem(item, index) + )} + </Box2> + )} + </ClickableBox3> ) } diff --git a/shared/common-adapters/index-impl.js b/shared/common-adapters/index-impl.js index b636bd06dbd6..6569d00f13bd 100644 --- a/shared/common-adapters/index-impl.js +++ b/shared/common-adapters/index-impl.js @@ -63,12 +63,6 @@ module.exports = { get ChoiceList() { return require('./choice-list').default }, - get ClickableBox() { - return require('./clickable-box').default - }, - get ClickableBox2() { - return require('./clickable-box').ClickableBox2 - }, get ConfirmModal() { return require('./confirm-modal').default }, diff --git a/shared/common-adapters/index.tsx b/shared/common-adapters/index.tsx index 18a170de3d46..bdac814e91e9 100644 --- a/shared/common-adapters/index.tsx +++ b/shared/common-adapters/index.tsx @@ -26,8 +26,6 @@ export {default as IconAuto} from './icon-auto' export {default as BoxGrow, BoxGrow2} from './box-grow' export {default as Checkbox} from './checkbox' export {default as CheckCircle} from './check-circle' -export {default as ChoiceList} from './choice-list' -export {default as ClickableBox, ClickableBox2} from './clickable-box' export {ClickableBox3} from './box' export type {ClickableBox3Props} from './box' export {default as ConfirmModal} from './confirm-modal' @@ -68,7 +66,6 @@ export {default as ProgressIndicator} from './progress-indicator' export {default as ProofBrokenBanner} from './proof-broken-banner' export {default as RadioButton} from './radio-button' export {default as Reloadable} from './reload' -export {default as RichButton} from './rich-button' export {default as RoundedBox} from './rounded-box' export {default as SafeAreaView, SafeAreaViewTop, useSafeAreaInsets} from './safe-area-view' export {default as SaveIndicator} from './save-indicator' diff --git a/shared/common-adapters/info-note.tsx b/shared/common-adapters/info-note.tsx index f9003a5b7d21..fd5bd6201e16 100644 --- a/shared/common-adapters/info-note.tsx +++ b/shared/common-adapters/info-note.tsx @@ -13,9 +13,10 @@ const InfoNote = (props: Props) => ( <Box2 direction="vertical" gap="xtiny" - style={Styles.collapseStyles([styles.alignCenter, props.containerStyle])} + alignItems="center" + style={props.containerStyle} > - <Box2 direction="horizontal" gap="tiny" style={styles.alignCenter}> + <Box2 direction="horizontal" gap="tiny" alignItems="center"> <Box2 direction="vertical" style={{backgroundColor: props.color || Styles.globalColors.black_10, height: 1, width: 24}} /> <Icon color={props.color || Styles.globalColors.black_10} @@ -28,13 +29,4 @@ const InfoNote = (props: Props) => ( </Box2> ) -const styles = Styles.styleSheetCreate( - () => - ({ - alignCenter: { - alignItems: 'center', - }, - }) as const -) - export default InfoNote diff --git a/shared/common-adapters/list-item.tsx b/shared/common-adapters/list-item.tsx index 8db6c35d63fb..e10ef10663ab 100644 --- a/shared/common-adapters/list-item.tsx +++ b/shared/common-adapters/list-item.tsx @@ -1,7 +1,6 @@ import type * as React from 'react' import * as Styles from '@/styles' -import ClickableBox from './clickable-box' -import {Box2} from './box' +import {Box2, ClickableBox3} from './box' import BoxGrow from './box-grow' import Divider from './divider' import './list-item.css' @@ -9,14 +8,14 @@ import './list-item.css' const Kb = { Box2, BoxGrow, - ClickableBox, + ClickableBox3, Divider, } // List item following stylesheet specs. TODO deprecate list-item.*.js type Props = { - type: 'Small' | 'Large' + type: 'Small' | 'Large' | 'Card' icon?: React.ReactNode statusIcon?: React.ReactNode body: React.ReactNode @@ -37,20 +36,24 @@ type Props = { containerStyleOverride?: Styles.StylesCrossPlatform } -const ListItem = (props: Props) => ( - <Kb.ClickableBox +const ListItem = (props: Props) => { + if (props.type === 'Card') return <CardListItem {...props} /> + return ( + <Kb.ClickableBox3 onClick={props.onClick || (props.onMouseDown ? () => {} : undefined)} // make sure clickable box applies click styles if just onMouseDown is given. onMouseDown={props.onMouseDown} + direction="horizontal" + className={Styles.classNames({ + listItem2: !props.hideHover, + })} style={Styles.collapseStyles([ props.type === 'Small' ? styles.clickableBoxSmall : styles.clickableBoxLarge, !!props.height && {minHeight: props.height}, props.style, ])} + fullWidth={true} > <Kb.Box2 - className={Styles.classNames({ - listItem2: !props.hideHover, - })} direction="horizontal" style={Styles.collapseStyles([ props.type === 'Small' ? styles.rowSmall : styles.rowLarge, @@ -101,8 +104,9 @@ const ListItem = (props: Props) => ( </Kb.Box2> </Kb.Box2> </Kb.Box2> - </Kb.ClickableBox> -) + </Kb.ClickableBox3> + ) +} export const smallHeight = isMobile ? 56 : 48 export const largeHeight = isMobile ? 64 : 56 @@ -113,15 +117,7 @@ const afterStatusIconItemLeftDistance = statusIconWidth - (isMobile ? 10 : 14) const styles = Styles.styleSheetCreate(() => { const _styles = { - actionLargeContainer: { - alignItems: 'center', - flexGrow: 0, - flexShrink: 0, - justifyContent: 'flex-start', - marginRight: 8, - position: 'relative', - } as const, - actionSmallContainer: { + actionContainer: { alignItems: 'center', flexGrow: 0, flexShrink: 0, @@ -262,21 +258,21 @@ const styles = Styles.styleSheetCreate(() => { const _actionStyles = { actionLargeIsGrowOnHover: { - ..._styles.actionLargeContainer, + ..._styles.actionContainer, ..._styles.heightLarge, justifyContent: 'flex-end', } as const, actionLargeNotGrowOnHover: { - ..._styles.actionLargeContainer, + ..._styles.actionContainer, ..._styles.heightLarge, } as const, actionSmallIsGrowOnHover: { - ..._styles.actionSmallContainer, + ..._styles.actionContainer, ..._styles.heightSmall, justifyContent: 'flex-end', } as const, actionSmallNotGrowOnHover: { - ..._styles.actionSmallContainer, + ..._styles.actionContainer, ..._styles.heightSmall, } as const, } @@ -336,4 +332,29 @@ const getActionStyle = (props: Props) => !!props.height && {minHeight: props.height}, ]) +const CardListItem = (props: Props) => ( + <Kb.ClickableBox3 + onClick={props.onClick} + direction="horizontal" + alignItems="center" + fullWidth={true} + style={Styles.collapseStyles([cardStyles.card, props.style])} + > + {props.icon && <Kb.Box2 direction="vertical" style={cardStyles.icon}>{props.icon}</Kb.Box2>} + <Kb.Box2 direction="vertical" flex={1} fullWidth={true}>{props.body}</Kb.Box2> + </Kb.ClickableBox3> +) + +const cardStyles = Styles.styleSheetCreate(() => ({ + card: { + ...Styles.border(Styles.globalColors.grey, 1, Styles.borderRadius), + backgroundColor: Styles.globalColors.white, + overflow: 'hidden', + padding: Styles.globalMargins.small, + }, + icon: { + marginRight: Styles.globalMargins.small, + }, +})) + export default ListItem diff --git a/shared/common-adapters/list.tsx b/shared/common-adapters/list.tsx index d3681b975c4f..b3b569e6adfc 100644 --- a/shared/common-adapters/list.tsx +++ b/shared/common-adapters/list.tsx @@ -50,7 +50,6 @@ const NativeList = function List<T>({ref, ...p}: Props<T>) { ) } - const styles = Styles.styleSheetCreate( () => ({ diff --git a/shared/common-adapters/markdown/channel.tsx b/shared/common-adapters/markdown/channel.tsx index b65a372798fc..ce76e55ad2fd 100644 --- a/shared/common-adapters/markdown/channel.tsx +++ b/shared/common-adapters/markdown/channel.tsx @@ -10,7 +10,7 @@ type OwnProps = { allowFontScaling?: boolean } -const Container = (ownProps: OwnProps) => { +const Channel = (ownProps: OwnProps) => { const {name, convID, style, allowFontScaling} = ownProps const onClick = () => previewConversation({ @@ -26,4 +26,4 @@ const Container = (ownProps: OwnProps) => { ) } -export default Container +export default Channel diff --git a/shared/common-adapters/markdown/maybe-mention/index.tsx b/shared/common-adapters/markdown/maybe-mention/index.tsx index 0baa404a4df5..07aa6f5b1c1f 100644 --- a/shared/common-adapters/markdown/maybe-mention/index.tsx +++ b/shared/common-adapters/markdown/maybe-mention/index.tsx @@ -63,21 +63,13 @@ type OwnProps = { style?: StylesTextCrossPlatform } -const Container = (ownProps: OwnProps) => { +const MaybeMentionContainer = (ownProps: OwnProps) => { const {name, channel} = ownProps const info = useMaybeMentionInfo(name, channel) const onResolve = () => { ignorePromise(T.RPCChat.localResolveMaybeMentionRpcPromise({mention: {channel, name}})) } - const props = { - allowFontScaling: ownProps.allowFontScaling, - channel: ownProps.channel, - info, - name: ownProps.name, - onResolve, - style: ownProps.style, - } - return <MaybeMention {...props} /> + return <MaybeMention {...ownProps} info={info} onResolve={onResolve} /> } -export default Container +export default MaybeMentionContainer diff --git a/shared/common-adapters/markdown/spoiler.tsx b/shared/common-adapters/markdown/spoiler.tsx index 482894b00365..3446391ef879 100644 --- a/shared/common-adapters/markdown/spoiler.tsx +++ b/shared/common-adapters/markdown/spoiler.tsx @@ -49,29 +49,27 @@ const Spoiler = (p: Props) => { ) } -const styles = Styles.styleSheetCreate(() => { - return { - hidden: Styles.platformStyles({ - common: { - backgroundColor: Styles.globalColors.black_on_white, - color: Styles.globalColors.black_on_white, - }, - isElectron: { - borderRadius: Styles.borderRadius, - ...Styles.paddingH(2), - }, - }), - shown: Styles.platformStyles({ - common: { - backgroundColor: Styles.globalColors.black_on_white, - color: Styles.globalColors.white, - }, - isElectron: { - borderRadius: Styles.borderRadius, - ...Styles.paddingH(2), - }, - }), - } as const -}) +const styles = Styles.styleSheetCreate(() => ({ + hidden: Styles.platformStyles({ + common: { + backgroundColor: Styles.globalColors.black_on_white, + color: Styles.globalColors.black_on_white, + }, + isElectron: { + borderRadius: Styles.borderRadius, + ...Styles.paddingH(2), + }, + }), + shown: Styles.platformStyles({ + common: { + backgroundColor: Styles.globalColors.black_on_white, + color: Styles.globalColors.white, + }, + isElectron: { + borderRadius: Styles.borderRadius, + ...Styles.paddingH(2), + }, + }), +} as const)) export default Spoiler diff --git a/shared/common-adapters/name-with-icon.tsx b/shared/common-adapters/name-with-icon.tsx index 78528184f234..8008f507c10b 100644 --- a/shared/common-adapters/name-with-icon.tsx +++ b/shared/common-adapters/name-with-icon.tsx @@ -2,8 +2,7 @@ import type * as React from 'react' import * as Styles from '@/styles' import * as C from '@/constants' import Avatar from './avatar' -import {Box2} from './box' -import ClickableBox from './clickable-box' +import {Box2, ClickableBox3} from './box' import IconAuto from './icon-auto' import type {IconType} from './icon.constants-gen' import Icon from './icon' @@ -204,11 +203,7 @@ export const NameWithIcon = (props: NameWithIconProps) => { ) const containerStyle = Styles.collapseStyles([ - props.horizontal - ? size === 'big' - ? styles.hbContainerStyle - : styles.hContainerStyle - : styles.vContainerStyle, + props.horizontal && size === 'big' ? styles.hbContainerStyle : undefined, props.containerStyle, ]) @@ -235,9 +230,14 @@ export const NameWithIcon = (props: NameWithIconProps) => { ) return _onClickWrapper ? ( - <ClickableBox onClick={_onClickWrapper} style={containerStyle}> + <ClickableBox3 + onClick={e => e && _onClickWrapper(e)} + direction={props.horizontal ? 'horizontal' : 'vertical'} + alignItems="center" + style={containerStyle} + > {children} - </ClickableBox> + </ClickableBox3> ) : ( <Box2 direction={props.horizontal ? 'horizontal' : 'vertical'} @@ -295,10 +295,6 @@ const styles = Styles.styleSheetCreate(() => ({ marginRight: Styles.globalMargins.small, }, }), - hContainerStyle: { - ...Styles.globalStyles.flexBoxRow, - alignItems: 'center' as const, - }, hIconStyle: Styles.platformStyles({ isElectron: { ...Styles.size(32), @@ -314,7 +310,6 @@ const styles = Styles.styleSheetCreate(() => ({ marginRight: Styles.globalMargins.small, }, hbContainerStyle: { - ...Styles.globalStyles.flexBoxRow, width: '100%', }, hbIconStyle: Styles.platformStyles({ @@ -343,10 +338,6 @@ const styles = Styles.styleSheetCreate(() => ({ textContainer: { flex: 1, }, - vContainerStyle: { - ...Styles.globalStyles.flexBoxColumn, - alignItems: 'center' as const, - }, vUsernameContainerStyle: Styles.platformStyles({ isElectron: { textAlign: 'center', diff --git a/shared/common-adapters/phone-input.tsx b/shared/common-adapters/phone-input.tsx index 6b9e3b0522c6..c956c0ab9a8a 100644 --- a/shared/common-adapters/phone-input.tsx +++ b/shared/common-adapters/phone-input.tsx @@ -2,14 +2,13 @@ import * as React from 'react' import * as Styles from '@/styles' import NativeEmoji from './emoji/native-emoji' import Text from './text' -import {Box2} from './box' +import {Box2, ClickableBox3} from './box' import FloatingMenu from './floating-menu' import SearchFilter from './search-filter' import Input3 from './input3' import type {Input3Ref} from './input3.shared' import FloatingPicker from './floating-picker' import ProgressIndicator from './progress-indicator' -import ClickableBox from './clickable-box' import Icon from './icon' import {usePopup2, type Popup2Parms} from './popup/use-popup' import { @@ -24,7 +23,7 @@ import type {MeasureRef} from './measure-ref' const Kb = { Box2, - ClickableBox, + ClickableBox3, FloatingMenu, FloatingPicker, Icon, @@ -551,21 +550,20 @@ const PhoneInput = (p: Props) => { isSmall ? undefined : Styles.collapseStyles([styles.countrySelectorRowBig, styles.fakeInputBig]) } > - <Kb.ClickableBox + <Kb.ClickableBox3 onClick={toggleShowingMenu} - style={isSmall ? styles.fullWidthDesktopOnly : styles.fullWidth} + direction="horizontal" + style={Styles.collapseStyles([ + isSmall ? styles.fullWidthDesktopOnly : styles.fullWidth, + styles.countrySelectorContainer, + ])} + alignItems="center" + gap="xtiny" + ref={popupAnchor} > - <Kb.Box2 - direction="horizontal" - style={styles.countrySelectorContainer} - alignItems="center" - gap="xtiny" - ref={popupAnchor} - > - {renderCountrySelector()} - <Kb.Icon type="iconfont-caret-down" sizeType="Tiny" /> - </Kb.Box2> - </Kb.ClickableBox> + {renderCountrySelector()} + <Kb.Icon type="iconfont-caret-down" sizeType="Tiny" /> + </Kb.ClickableBox3> </Kb.Box2> <Kb.Box2 direction="horizontal" diff --git a/shared/common-adapters/placeholder.tsx b/shared/common-adapters/placeholder.tsx index b6697c2152df..c7db4fce4118 100644 --- a/shared/common-adapters/placeholder.tsx +++ b/shared/common-adapters/placeholder.tsx @@ -12,7 +12,7 @@ const Placeholder = (props: PlaceholderProps) => ( style={Styles.collapseStyles([ styles.placeholder, props.style, - ...(props.width ? [{width: props.width}] : []), + props.width ? {width: props.width} : undefined, ])} /> ) diff --git a/shared/common-adapters/popup/index.tsx b/shared/common-adapters/popup/index.tsx index 816dd572777c..0f431a9e25a1 100644 --- a/shared/common-adapters/popup/index.tsx +++ b/shared/common-adapters/popup/index.tsx @@ -153,22 +153,13 @@ function PopupSheet(props: PopupProps) { ) } -function PopupPortal(props: PopupProps) { - const {children} = props - return ( - <Portal hostName="popup-root"> - {children} - </Portal> - ) -} - function Popup(props: PopupProps) { if (props.attachTo) { return <PopupPositioned {...props} /> } if (isMobile) { if (!props.onHidden) { - return <PopupPortal {...props} /> + return <Portal hostName="popup-root">{props.children}</Portal> } return <PopupSheet {...props} /> } diff --git a/shared/common-adapters/profile-card.tsx b/shared/common-adapters/profile-card.tsx index 0b98c0c53be1..407b4d07f695 100644 --- a/shared/common-adapters/profile-card.tsx +++ b/shared/common-adapters/profile-card.tsx @@ -4,8 +4,7 @@ import * as Styles from '@/styles' import * as Platforms from '@/util/platforms' import * as T from '@/constants/types' import capitalize from 'lodash/capitalize' -import {Box2} from './box' -import ClickableBox from './clickable-box' +import {Box2, ClickableBox3} from './box' import ConnectedNameWithIcon from './name-with-icon' import {_setWithProfileCardPopup} from './usernames' import FloatingMenu from './floating-menu' @@ -28,7 +27,7 @@ const positionFallbacks = ['top center', 'bottom center'] as const const Kb = { Box2, - ClickableBox, + ClickableBox3, ConnectedNameWithIcon, FloatingMenu, Icon, @@ -118,9 +117,9 @@ const ServiceIcons = ({userDetailsAssertions}: ServiceIconsProps) => { ) })} {!!expandLabel && ( - <Kb.ClickableBox onClick={() => setExpanded(true)} style={styles.expand}> + <Kb.ClickableBox3 onClick={() => setExpanded(true)} direction="vertical" style={styles.expand}> <Kb.Meta title={expandLabel} backgroundColor={Styles.globalColors.greyDark} /> - </Kb.ClickableBox> + </Kb.ClickableBox3> )} </Kb.Box2> ) diff --git a/shared/common-adapters/radio-button.tsx b/shared/common-adapters/radio-button.tsx index c085df170c3a..4aa6ab891a6d 100644 --- a/shared/common-adapters/radio-button.tsx +++ b/shared/common-adapters/radio-button.tsx @@ -1,5 +1,5 @@ import {View} from 'react-native' -import ClickableBox from './clickable-box' +import {ClickableBox3} from './box' import Text from './text' import * as Styles from '@/styles' import './radio-button.css' @@ -14,7 +14,7 @@ type Props = { } const Kb = { - ClickableBox, + ClickableBox3, Text, } @@ -38,8 +38,10 @@ const RadioButton = ({disabled, label, onSelect, selected, style}: Props) => { ) } return ( - <Kb.ClickableBox - style={{...nativeStyles.container, ...style}} + <Kb.ClickableBox3 + direction="horizontal" + alignItems="center" + style={Styles.collapseStyles([nativeStyles.container, style])} onClick={disabled ? undefined : () => onSelect(!selected)} > <View @@ -65,7 +67,7 @@ const RadioButton = ({disabled, label, onSelect, selected, style}: Props) => { ) : ( label )} - </Kb.ClickableBox> + </Kb.ClickableBox3> ) } @@ -92,8 +94,6 @@ const nativeStyles = Styles.styleSheetCreate( () => ({ container: { - ...Styles.globalStyles.flexBoxRow, - alignItems: 'center', paddingBottom: Styles.globalMargins.xtiny, paddingTop: Styles.globalMargins.xtiny, }, diff --git a/shared/common-adapters/rich-button.tsx b/shared/common-adapters/rich-button.tsx deleted file mode 100644 index f1780c5b89d2..000000000000 --- a/shared/common-adapters/rich-button.tsx +++ /dev/null @@ -1,74 +0,0 @@ -import * as React from 'react' -import * as Styles from '@/styles' - -import {Box2} from './box' -import ClickableBox from './clickable-box' -import Text from './text' -import type {IconType} from './icon.constants-gen' -import IconAuto from './icon-auto' - -type Props = { - icon: IconType - title: string - description: string - onClick?: (event: React.BaseSyntheticEvent) => void - testID?: string -} - -const Kb = { - Box2, - ClickableBox, - IconAuto, - Text, -} - -const RichButton = (props: Props) => { - const [isPressing, setPressing] = React.useState(false) - - return ( - <Kb.ClickableBox - className="hover_container" - style={Styles.collapseStyles([styles.containerStyle, isPressing && styles.mobileContainer])} - testID={props.testID} - onClick={props.onClick} - onPressIn={() => setPressing(true)} - onPressOut={() => setPressing(false)} - hoverColor={Styles.globalColors.blueLighter_20} - > - <Kb.IconAuto type={props.icon} style={styles.thumbnail} /> - - <Kb.Box2 direction="vertical" style={Styles.globalStyles.flexOne} gap="xtiny"> - <Kb.Text - className="hover_contained_color_blueDark" - style={isPressing ? styles.mobileTitle : undefined} - type="BodySemibold" - > - {props.title} - </Kb.Text> - <Kb.Text type="BodySmall">{props.description}</Kb.Text> - </Kb.Box2> - </Kb.ClickableBox> - ) -} - -const styles = Styles.styleSheetCreate(() => ({ - containerStyle: { - ...Styles.globalStyles.flexBoxRow, - alignItems: 'center', - backgroundColor: Styles.globalColors.white, - ...Styles.border(Styles.globalColors.grey, 1, Styles.borderRadius), - justifyContent: 'flex-start', - padding: Styles.globalMargins.small, - }, - mobileContainer: { - backgroundColor: Styles.globalColors.blueLighter_20, - }, - mobileTitle: { - color: Styles.globalColors.blueDark, - }, - thumbnail: { - marginRight: Styles.globalMargins.small, - }, -})) - -export default RichButton diff --git a/shared/common-adapters/search-filter.tsx b/shared/common-adapters/search-filter.tsx index 20729014377b..f9455c7ef64f 100644 --- a/shared/common-adapters/search-filter.tsx +++ b/shared/common-adapters/search-filter.tsx @@ -1,7 +1,6 @@ import * as React from 'react' import Animation from './animation' -import {Box2} from './box' -import ClickableBox, {ClickableBox2} from './clickable-box' +import {Box2, ClickableBox3} from './box' import Input3 from './input3' import type {Input3Ref} from './input3.shared' import Text from './text' @@ -18,8 +17,7 @@ import type {MeasureRef} from './measure-ref' const Kb = { Animation, Box2, - ClickableBox, - ClickableBox2, + ClickableBox3, Icon, IconAuto, Input3, @@ -223,20 +221,21 @@ function SearchFilter(props: Props & {ref?: React.Ref<SearchFilterRef>}) { } if (isMobile) { return ( - <Kb.ClickableBox2 onClick={props.mobileCancelButton ? clear : cancel} hitSlop={10}> + <Kb.ClickableBox3 onClick={props.mobileCancelButton ? clear : cancel} hitSlop={10} direction="vertical"> <Kb.Icon type="iconfont-remove" sizeType={iconSizeType()} color={iconColor()} style={styles.removeIconNonFullWidth} /> - </Kb.ClickableBox2> + </Kb.ClickableBox3> ) } else { return ( - <Kb.ClickableBox + <Kb.ClickableBox3 onClick={() => {}} onMouseDown={cancel} + direction="vertical" style={props.size === 'full-width' ? styles.removeIconFullWidth : styles.removeIconNonFullWidth} > <Kb.Icon @@ -244,7 +243,7 @@ function SearchFilter(props: Props & {ref?: React.Ref<SearchFilterRef>}) { sizeType={iconSizeType()} color={iconColor()} /> - </Kb.ClickableBox> + </Kb.ClickableBox3> ) } } @@ -264,8 +263,9 @@ function SearchFilter(props: Props & {ref?: React.Ref<SearchFilterRef>}) { ) const content = isMobile ? ( - <Kb.ClickableBox2 + <Kb.ClickableBox3 data-search-filter={true} + direction="horizontal" style={Styles.collapseStyles([ styles.container, props.placeholderCentered && styles.containerCenter, @@ -275,10 +275,12 @@ function SearchFilter(props: Props & {ref?: React.Ref<SearchFilterRef>}) { onClick={props.onClick || focus} > {inside} - </Kb.ClickableBox2> + </Kb.ClickableBox3> ) : ( - <Kb.ClickableBox + <Kb.ClickableBox3 data-search-filter={true} + direction="horizontal" + alignSelf={props.size === 'full-width' ? 'stretch' : undefined} style={Styles.collapseStyles([ styles.container, props.placeholderCentered && styles.containerCenter, @@ -290,11 +292,9 @@ function SearchFilter(props: Props & {ref?: React.Ref<SearchFilterRef>}) { onMouseOver={mouseOver} onMouseLeave={mouseLeave} onClick={props.onClick || (!focused ? focus : undefined)} - underlayColor={Styles.globalColors.transparent} - hoverColor={Styles.globalColors.transparent} > {inside} - </Kb.ClickableBox> + </Kb.ClickableBox3> ) return isMobile ? ( @@ -321,9 +321,7 @@ export default SearchFilter const styles = Styles.styleSheetCreate(() => ({ container: Styles.platformStyles({ common: { - ...Styles.globalStyles.flexBoxRow, ...Styles.globalStyles.flexGrow, - alignItems: 'center', borderRadius: Styles.borderRadius, flexShrink: 1, }, diff --git a/shared/common-adapters/section-divider.tsx b/shared/common-adapters/section-divider.tsx index d2590e94958d..40e135851e1d 100644 --- a/shared/common-adapters/section-divider.tsx +++ b/shared/common-adapters/section-divider.tsx @@ -1,14 +1,13 @@ import type * as React from 'react' import * as Styles from '@/styles' -import {Box2} from './box' +import {Box2, ClickableBox3} from './box' import Text from './text' import Icon from './icon' import ProgressIndicator from './progress-indicator' -import ClickableBox from './clickable-box' const Kb = { Box2, - ClickableBox, + ClickableBox3, Icon, ProgressIndicator, Text, @@ -41,9 +40,9 @@ const SectionDivider = (props: Props) => { </Kb.Box2> ) return collapsible ? ( - <Kb.ClickableBox onClick={props.onToggleCollapsed} style={styles.fullWidth}> + <Kb.ClickableBox3 onClick={props.onToggleCollapsed} direction="horizontal" fullWidth={true}> {children} - </Kb.ClickableBox> + </Kb.ClickableBox3> ) : ( children ) @@ -65,9 +64,6 @@ const styles = Styles.styleSheetCreate(() => ({ ...Styles.padding(Styles.globalMargins.xtiny, Styles.globalMargins.small), }, }), - fullWidth: { - width: '100%', - }, progress: { ...Styles.size(20), }, diff --git a/shared/common-adapters/switch.tsx b/shared/common-adapters/switch.tsx index 02cb56061d32..006efc2b9966 100644 --- a/shared/common-adapters/switch.tsx +++ b/shared/common-adapters/switch.tsx @@ -1,7 +1,6 @@ import type * as React from 'react' import * as Styles from '@/styles' -import ClickableBox from './clickable-box' -import {Box2} from './box' +import {Box2, ClickableBox3} from './box' import ProgressIndicator from './progress-indicator' import Text from './text' import SwitchToggle from './switch-toggle' @@ -11,7 +10,7 @@ import type {TextType} from './text.shared' const Kb = { Box2, - ClickableBox, + ClickableBox3, ProgressIndicator, Text, WithTooltip, @@ -46,9 +45,9 @@ const LabelContainer = (props: Props) => </Kb.WithTooltip> ) : ( <Kb.Box2 direction="vertical" style={styles.labelContainer}> - <Kb.ClickableBox onClick={props.allowLabelClick ? props.onClick : undefined}> + <Kb.ClickableBox3 onClick={props.allowLabelClick ? props.onClick : undefined} direction="vertical"> {props.children} - </Kb.ClickableBox> + </Kb.ClickableBox3> </Kb.Box2> ) @@ -63,7 +62,7 @@ function Switch(props: Props & {ref?: React.Ref<MeasureRef>}) { const {ref} = props const content = ( <> - <Kb.ClickableBox onClick={props.disabled ? undefined : props.onClick} ref={ref}> + <Kb.ClickableBox3 onClick={props.disabled ? undefined : props.onClick} ref={ref} direction="vertical"> <SwitchToggle on={props.on} color={props.color || 'blue'} @@ -74,7 +73,7 @@ function Switch(props: Props & {ref?: React.Ref<MeasureRef>}) { !!props.labelSubtitle && styles.switch, ] as const)} /> - </Kb.ClickableBox> + </Kb.ClickableBox3> {!!props.gapInBetween && <Kb.Box2 direction="vertical" flex={1} />} {!!props.gapSize && <Kb.Box2 direction="vertical" style={{width: props.gapSize}} />} {typeof props.label === 'string' ? ( diff --git a/shared/common-adapters/tabs.tsx b/shared/common-adapters/tabs.tsx index 2b6b84abc767..64efcd101ce1 100644 --- a/shared/common-adapters/tabs.tsx +++ b/shared/common-adapters/tabs.tsx @@ -1,18 +1,17 @@ import * as Styles from '@/styles' import Badge from './badge' -import ClickableBox from './clickable-box' import Divider from './divider' import IconAuto from './icon-auto' import type {IconType} from './icon.constants-gen' import ProgressIndicator from './progress-indicator' import Text from './text' -import {Box2} from './box' +import {Box2, ClickableBox3} from './box' import capitalize from 'lodash/capitalize' const Kb = { Badge, Box2, - ClickableBox, + ClickableBox3, Divider, IconAuto, ProgressIndicator, @@ -55,23 +54,23 @@ const Tabs = <TitleT extends string>(props: Props<TitleT>) => ( {props.tabs.map((tab: Tab<TitleT>) => { const selected = props.selectedTab === tab.title return ( - <Kb.ClickableBox + <Kb.ClickableBox3 onClick={() => props.onSelect(tab.title)} key={tab.title} - style={props.clickableBoxStyle} + direction="vertical" + style={Styles.collapseStyles([styles.tabContainer, props.clickableBoxStyle, props.clickableTabStyle])} + fullWidth={true} > - <Kb.Box2 direction="vertical" style={styles.tabContainer} fullWidth={true}> - <Kb.Box2 direction="horizontal" fullWidth={true} alignItems="center" style={Styles.collapseStyles([styles.tab, selected && styles.selected, props.tabStyle])}> - {tab.icon ? ( - <Kb.IconAuto type={tab.icon} style={selected ? styles.iconSelected : styles.icon} /> - ) : ( - <TabText selected={selected} text={tab.text ?? capitalize(tab.title)} /> - )} - {!!tab.badgeNumber && <Kb.Badge badgeNumber={tab.badgeNumber} badgeStyle={styles.badge} />} - </Kb.Box2> - <Kb.Divider style={selected ? styles.dividerSelected : styles.divider} /> + <Kb.Box2 direction="horizontal" fullWidth={true} alignItems="center" style={Styles.collapseStyles([styles.tab, selected && styles.selected, props.tabStyle])}> + {tab.icon ? ( + <Kb.IconAuto type={tab.icon} style={selected ? styles.iconSelected : styles.icon} /> + ) : ( + <TabText selected={selected} text={tab.text ?? capitalize(tab.title)} /> + )} + {!!tab.badgeNumber && <Kb.Badge badgeNumber={tab.badgeNumber} badgeStyle={styles.badge} />} </Kb.Box2> - </Kb.ClickableBox> + <Kb.Divider style={selected ? styles.dividerSelected : styles.divider} /> + </Kb.ClickableBox3> ) })} {props.showProgressIndicator && <Kb.ProgressIndicator style={styles.progressIndicator} />} @@ -99,11 +98,13 @@ const styles = Styles.styleSheetCreate(() => ({ ...Styles.globalStyles.flexBoxRow, backgroundColor: Styles.globalColors.transparent, minHeight: 2, + width: '100%', }, dividerSelected: { ...Styles.globalStyles.flexBoxRow, backgroundColor: Styles.globalColors.blue, minHeight: 2, + width: '100%', }, icon: { alignSelf: 'center', diff --git a/shared/common-adapters/wave-button.tsx b/shared/common-adapters/wave-button.tsx index 336875d1358e..b43a30d30e84 100644 --- a/shared/common-adapters/wave-button.tsx +++ b/shared/common-adapters/wave-button.tsx @@ -33,12 +33,8 @@ const getWaveWaitingKey = (recipient: string) => { return `settings:waveButton:${recipient}` } -const WaveButton = (props: Props) => { - return <WaveButtonImpl {...props} /> -} - // A button that sends a wave emoji into a chat. -const WaveButtonImpl = (props: Props) => { +const WaveButton = (props: Props) => { const [waved, setWaved] = React.useState(false) const waitingKey = getWaveWaitingKey(props.username || props.conversationIDKey || 'missing') const waving = C.Waiting.useAnyWaiting(waitingKey) @@ -110,6 +106,8 @@ const WaveButtonImpl = (props: Props) => { ) } +export default WaveButton + const styles = Styles.styleSheetCreate( () => ({ @@ -123,5 +121,3 @@ const styles = Styles.styleSheetCreate( }, }) as const ) - -export default WaveButton diff --git a/shared/common-adapters/with-tooltip.tsx b/shared/common-adapters/with-tooltip.tsx index 0364afa4cbed..2ca1c163ac40 100644 --- a/shared/common-adapters/with-tooltip.tsx +++ b/shared/common-adapters/with-tooltip.tsx @@ -3,8 +3,7 @@ import * as React from 'react' import * as Styles from '@/styles' import {Portal} from './portal' import {useTimeout} from './use-timers' -import {Box2} from './box' -import ClickableBox from './clickable-box' +import {Box2, ClickableBox3} from './box' import Toast from './toast' import Text from './text' import type {MeasureRef} from './measure-ref' @@ -31,7 +30,7 @@ const IGNORE_FOR_PROFILING = false as boolean const Kb = { Box2, - ClickableBox, + ClickableBox3, Portal, Text, Toast, @@ -163,7 +162,7 @@ function WithTooltip(p: Props) { return ( <> <View style={Styles.castStyleNative(containerStyle)} ref={clickableRef} collapsable={false}> - <Kb.ClickableBox onClick={_onClick}>{children}</Kb.ClickableBox> + <Kb.ClickableBox3 onClick={_onClick} direction="vertical">{children}</Kb.ClickableBox3> </View> <Kb.Portal hostName="popup-root"> <Kb.Box2 diff --git a/shared/crypto/decrypt.tsx b/shared/crypto/decrypt.tsx index c488438f69b7..4990f4760f5a 100644 --- a/shared/crypto/decrypt.tsx +++ b/shared/crypto/decrypt.tsx @@ -9,6 +9,8 @@ import {CryptoOutput, CryptoOutputActionsBar, CryptoSignedSender} from './output import { beginRun, clearInputState, + createCommonState, + getStatusCodeMessage, maybeAutoRunTextOperation, nextInputState, nextOpenedFileState, @@ -16,10 +18,6 @@ import { resetWarnings, useCommittedState, useSeededCryptoInput, -} from './helpers' -import { - createCommonState, - getStatusCodeMessage, type CommonOutputRouteParams, type CryptoInputRouteParams, type CommonState, @@ -240,12 +238,7 @@ export const DecryptIO = () => { outputFileIcon="icon-file-64" outputTextType="plain" state={controller.state} - onChooseOutputFolder={destinationDir => { - const f = async () => { - await controller.decrypt(destinationDir) - } - C.ignorePromise(f()) - }} + onChooseOutputFolder={destinationDir => C.ignorePromise(controller.decrypt(destinationDir) as unknown as Promise<void>)} /> <CryptoOutputActionsBar canReplyInChat={true} canSaveAsText={false} state={controller.state} /> </Kb.Box2> diff --git a/shared/crypto/encrypt.tsx b/shared/crypto/encrypt.tsx index 3efcd1bff074..dd2d8921ded4 100644 --- a/shared/crypto/encrypt.tsx +++ b/shared/crypto/encrypt.tsx @@ -344,13 +344,8 @@ const EncryptOptionsPanel = ({ setEncryptOptions: (options: {includeSelf?: boolean; sign?: boolean}, hideIncludeSelf?: boolean) => void sign: boolean }) => { - const onSetOptions = (opts: {newIncludeSelf: boolean; newSign: boolean}) => { - const {newIncludeSelf, newSign} = opts - setEncryptOptions({includeSelf: newIncludeSelf, sign: newSign}) - } - - const direction = Kb.Styles.isTablet ? 'horizontal' : isMobile ? 'vertical' : 'horizontal' - const gap = Kb.Styles.isTablet ? 'medium' : isMobile ? 'xtiny' : 'medium' + const direction = isMobile && !Kb.Styles.isTablet ? 'vertical' : 'horizontal' + const gap = isMobile && !Kb.Styles.isTablet ? 'xtiny' : 'medium' return ( <Kb.Box2 @@ -365,14 +360,14 @@ const EncryptOptionsPanel = ({ label="Include yourself" disabled={inProgress || hasSBS || !hasRecipients} checked={hasSBS || includeSelf} - onCheck={newValue => onSetOptions({newIncludeSelf: newValue, newSign: sign})} + onCheck={newValue => setEncryptOptions({includeSelf: newValue, sign})} /> )} <Kb.Checkbox label="Sign" disabled={inProgress || hasSBS} checked={sign} - onCheck={newValue => onSetOptions({newIncludeSelf: includeSelf, newSign: newValue})} + onCheck={newValue => setEncryptOptions({includeSelf, sign: newValue})} /> </Kb.Box2> ) @@ -454,9 +449,6 @@ const EncryptInputBody = ({params}: {params?: EncryptRouteParams}) => { const blurCBRef = React.useRef(() => {}) const navigateAppend = C.Router2.navigateAppend const appendEncryptRecipientsBuilder = C.Router2.appendEncryptRecipientsBuilder - const setBlurCB = (cb: () => void) => { - blurCBRef.current = cb - } const onRun = () => { const f = async () => { @@ -507,7 +499,7 @@ const EncryptInputBody = ({params}: {params?: EncryptRouteParams}) => { fileIcon={inputFileIcon} inputPlaceholder={inputPlaceholder} state={controller.state} - setBlurCB={setBlurCB} + setBlurCB={(cb: () => void) => { blurCBRef.current = cb }} textInputType="plain" onSetInput={controller.setInput} onClearInput={controller.clearInput} @@ -619,23 +611,13 @@ export const EncryptIO = () => { outputFileIcon="icon-file-saltpack-64" outputTextType="cipher" state={controller.state} - onChooseOutputFolder={destinationDir => { - const f = async () => { - await controller.runEncrypt(destinationDir) - } - C.ignorePromise(f()) - }} + onChooseOutputFolder={destinationDir => C.ignorePromise(controller.runEncrypt(destinationDir) as unknown as Promise<void>)} /> <CryptoOutputActionsBar canReplyInChat={false} canSaveAsText={true} state={controller.state} - onSaveAsText={() => { - const f = async () => { - await controller.saveOutputAsText() - } - C.ignorePromise(f()) - }} + onSaveAsText={() => C.ignorePromise(controller.saveOutputAsText() as unknown as Promise<void>)} /> </Kb.Box2> </Kb.Box2> diff --git a/shared/crypto/input.tsx b/shared/crypto/input.tsx index 14bf50ae2941..bfbac3573e63 100644 --- a/shared/crypto/input.tsx +++ b/shared/crypto/input.tsx @@ -114,37 +114,41 @@ const TextInput = (props: TextProps) => { ) : null return ( - <Kb.ClickableBox onClick={onFocusInput} style={styles.containerInputFocus}> - <Kb.Box2 direction="vertical" fullWidth={true} fullHeight={true} style={styles.commonContainer}> - <Kb.Box2 - direction={isMobile ? 'vertical' : 'horizontal'} - alignItems="flex-start" - alignSelf="flex-start" - fullWidth={isMobile || !!value} - fullHeight={isMobile || !!value} - style={styles.inputAndFilePickerContainer} - > - <Kb.Input3 - value={value} - placeholder={inputPlaceholder} - multiline={true} - autoFocus={true} - hideBorder={true} - rowsMax={rowsMax} - growAndScroll={growAndScroll} - containerStyle={inputContainerStyle} - inputStyle={inputStyle} - textType={textInputType === 'cipher' ? 'Terminal' : 'Body'} - autoCorrect={textInputType !== 'cipher'} - spellCheck={textInputType !== 'cipher'} - onChangeText={onChangeText} - ref={inputRef} - /> - {!isMobile && browseButton} - </Kb.Box2> + <Kb.ClickableBox3 + direction="vertical" + fullWidth={true} + fullHeight={true} + onClick={onFocusInput} + style={Kb.Styles.collapseStyles([styles.containerInputFocus, styles.commonContainer])} + > + <Kb.Box2 + direction={isMobile ? 'vertical' : 'horizontal'} + alignItems="flex-start" + alignSelf="flex-start" + fullWidth={isMobile || !!value} + fullHeight={isMobile || !!value} + style={styles.inputAndFilePickerContainer} + > + <Kb.Input3 + value={value} + placeholder={inputPlaceholder} + multiline={true} + autoFocus={true} + hideBorder={true} + rowsMax={rowsMax} + growAndScroll={growAndScroll} + containerStyle={inputContainerStyle} + inputStyle={inputStyle} + textType={textInputType === 'cipher' ? 'Terminal' : 'Body'} + autoCorrect={textInputType !== 'cipher'} + spellCheck={textInputType !== 'cipher'} + onChangeText={onChangeText} + ref={inputRef} + /> + {!isMobile && browseButton} </Kb.Box2> {!isMobile && clearButton} - </Kb.ClickableBox> + </Kb.ClickableBox3> ) } diff --git a/shared/crypto/output.tsx b/shared/crypto/output.tsx index b098ee3fe93c..93f13dd500b8 100644 --- a/shared/crypto/output.tsx +++ b/shared/crypto/output.tsx @@ -60,6 +60,7 @@ export const CryptoSignedSender = ({isSelfSigned, state}: SignedSenderProps) => direction="horizontal" fullWidth={true} alignItems="center" + justifyContent="center" style={Kb.Styles.collapseStyles([ styles.signedContainer, isSelfSigned ? styles.signedContainerSelf : styles.signedContainerOther, @@ -70,7 +71,6 @@ export const CryptoSignedSender = ({isSelfSigned, state}: SignedSenderProps) => direction="horizontal" gap={isSelfSigned ? 'xtiny' : 'xsmall'} alignItems="center" - style={styles.signedSender} > <Kb.Avatar key="avatar" size={avatarSize} username={signedByUsername} /> {isSelfSigned ? ( @@ -99,7 +99,7 @@ export const CryptoSignedSender = ({isSelfSigned, state}: SignedSenderProps) => )} </Kb.Box2> ) : ( - <Kb.Box2 direction="horizontal" gap="xtiny" alignItems="center" style={styles.signedSender}> + <Kb.Box2 direction="horizontal" gap="xtiny" alignItems="center"> <Kb.ImageIcon key="avatar" type="icon-placeholder-secret-user-16" /> {isSelfSigned ? null : ( <Kb.Text key="username" type="BodySmallSemibold"> @@ -325,22 +325,21 @@ export const CryptoOutput = ({ if (state.outputType === 'file') { return ( - <Kb.Box2 direction="vertical" fullHeight={true} fullWidth={true}> - <Kb.Box2 - direction="horizontal" - fullWidth={true} - alignItems="center" - style={styles.fileOutputContainer} + <Kb.Box2 + direction="horizontal" + fullHeight={true} + fullWidth={true} + alignItems="center" + style={styles.fileOutputContainer} + > + {outputFileIcon ? <Kb.ImageIcon type={outputFileIcon} /> : null} + <Kb.Text + type="BodyPrimaryLink" + style={Kb.Styles.collapseStyles([styles.fileOutputText, {color: fileOutputTextColor}])} + onClick={() => state.output && openLocalPathInSystemFileManagerDesktop(state.output)} > - {outputFileIcon ? <Kb.ImageIcon type={outputFileIcon} /> : null} - <Kb.Text - type="BodyPrimaryLink" - style={Kb.Styles.collapseStyles([styles.fileOutputText, {color: fileOutputTextColor}])} - onClick={() => state.output && openLocalPathInSystemFileManagerDesktop(state.output)} - > - {state.output} - </Kb.Text> - </Kb.Box2> + {state.output} + </Kb.Text> </Kb.Box2> ) } @@ -421,7 +420,6 @@ const styles = Kb.Styles.styleSheetCreate( signedContainer: Kb.Styles.platformStyles({ common: { flexShrink: 0, - justifyContent: 'center', minHeight: Kb.Styles.globalMargins.mediumLarge, }, isMobile: { @@ -446,7 +444,6 @@ const styles = Kb.Styles.styleSheetCreate( ...Kb.Styles.padding(Kb.Styles.globalMargins.xsmall, Kb.Styles.globalMargins.small), }, }), - signedSender: {alignItems: 'center'}, toastText: {color: Kb.Styles.globalColors.white}, }) as const ) diff --git a/shared/crypto/sign.tsx b/shared/crypto/sign.tsx index 05a56b8c6a62..017d05c18a17 100644 --- a/shared/crypto/sign.tsx +++ b/shared/crypto/sign.tsx @@ -10,6 +10,8 @@ import {CryptoOutput, CryptoOutputActionsBar, CryptoSignedSender, OutputInfoBann import { beginRun, clearInputState, + createCommonState, + getStatusCodeMessage, maybeAutoRunTextOperation, nextInputState, nextOpenedFileState, @@ -17,10 +19,6 @@ import { resetWarnings, useCommittedState, useSeededCryptoInput, -} from './helpers' -import { - createCommonState, - getStatusCodeMessage, type CommonOutputRouteParams, type CryptoInputRouteParams, type CommonState, @@ -149,9 +147,6 @@ export const SignInput = (_props: unknown) => { const controller = useSignState(params) const blurCBRef = React.useRef(() => {}) const navigateAppend = C.Router2.navigateAppend - const setBlurCB = (cb: () => void) => { - blurCBRef.current = cb - } const onRun = () => { const f = async () => { @@ -172,7 +167,7 @@ export const SignInput = (_props: unknown) => { fileIcon={inputFileIcon} inputPlaceholder={inputPlaceholder} state={controller.state} - setBlurCB={setBlurCB} + setBlurCB={(cb: () => void) => { blurCBRef.current = cb }} textInputType="plain" onSetInput={controller.setInput} onClearInput={controller.clearInput} @@ -250,23 +245,13 @@ export const SignIO = () => { outputFileIcon="icon-file-saltpack-64" outputTextType="cipher" state={controller.state} - onChooseOutputFolder={destinationDir => { - const f = async () => { - await controller.sign(destinationDir) - } - C.ignorePromise(f()) - }} + onChooseOutputFolder={destinationDir => C.ignorePromise(controller.sign(destinationDir) as unknown as Promise<void>)} /> <CryptoOutputActionsBar canReplyInChat={false} canSaveAsText={true} state={controller.state} - onSaveAsText={() => { - const f = async () => { - await controller.saveOutputAsText() - } - C.ignorePromise(f()) - }} + onSaveAsText={() => C.ignorePromise(controller.saveOutputAsText() as unknown as Promise<void>)} /> </Kb.Box2> </Kb.Box2> diff --git a/shared/crypto/sub-nav/left-nav.desktop.tsx b/shared/crypto/sub-nav/left-nav.desktop.tsx index cf65da1ec87b..becc59b36100 100644 --- a/shared/crypto/sub-nav/left-nav.desktop.tsx +++ b/shared/crypto/sub-nav/left-nav.desktop.tsx @@ -1,4 +1,3 @@ -import type * as React from 'react' import * as Kb from '@/common-adapters' import * as Crypto from '@/constants/crypto' import NavRow from './nav-row' @@ -12,20 +11,14 @@ type Row = (typeof Crypto.Tabs)[number] & { type Props = { onClick: (a: string) => void selected: string - children?: React.ReactNode } -const SubNav = (props: Props) => { -const getRows = () => - Crypto.Tabs.map(t => ({ - ...t, - isSelected: props.selected === t.tab, - key: t.tab, - })) - - const _onClick = (tab: string) => { - props.onClick(tab) - } +const LeftNav = (props: Props) => { + const rows = Crypto.Tabs.map(t => ({ + ...t, + isSelected: props.selected === t.tab, + key: t.tab, + })) const renderItem = (_: number, row: Row) => { return ( @@ -35,26 +28,23 @@ const getRows = () => title={row.title} tab={row.tab} icon={row.icon} - onClick={() => _onClick(row.tab)} + onClick={() => props.onClick(row.tab)} /> ) } return ( - <Kb.Box2 direction="horizontal" fullHeight={true} fullWidth={true} testID={TestIDs.CRYPTO_INPUT}> - <Kb.Box2 direction="vertical" fullHeight={true} style={styles.listContainer}> - <Kb.BoxGrow> - <Kb.List - items={getRows()} - renderItem={renderItem} - keyProperty="key" - extraData={props.selected} - style={styles.list} - itemHeight={{sizeType: 'Small', type: 'fixedListItemAuto'}} - /> - </Kb.BoxGrow> - </Kb.Box2> - {props.children} + <Kb.Box2 direction="vertical" fullHeight={true} style={styles.listContainer} testID={TestIDs.CRYPTO_INPUT}> + <Kb.BoxGrow> + <Kb.List + items={rows} + renderItem={renderItem} + keyProperty="key" + extraData={props.selected} + style={styles.list} + itemHeight={{sizeType: 'Small', type: 'fixedListItemAuto'}} + /> + </Kb.BoxGrow> </Kb.Box2> ) } @@ -71,4 +61,4 @@ const styles = Kb.Styles.styleSheetCreate(() => ({ }, })) -export default SubNav +export default LeftNav diff --git a/shared/crypto/sub-nav/nav-row.tsx b/shared/crypto/sub-nav/nav-row.tsx index 5d3dd7b9ac48..b1495f01dd00 100644 --- a/shared/crypto/sub-nav/nav-row.tsx +++ b/shared/crypto/sub-nav/nav-row.tsx @@ -7,7 +7,7 @@ type Props = { // Desktop only icon?: IconType isSelected?: boolean - // Moible only + // Mobile only description?: string illustration?: IconType onClick: () => void @@ -44,7 +44,8 @@ const NavRow = (props: Props) => { direction="vertical" fullHeight={true} fullWidth={true} - style={Kb.Styles.collapseStyles([styles.textContainer])} + justifyContent="center" + style={styles.desktopItemBody} > <Kb.Text type="BodySemibold" @@ -62,15 +63,27 @@ const NavRow = (props: Props) => { const mobileRow = description && illustration ? ( - <Kb.RichButton testID={`crypto-nav-${props.tab}`} title={title} description={description} icon={illustration} onClick={onClick} /> + <Kb.Box2 direction="vertical" fullWidth={true} testID={`crypto-nav-${props.tab}`}> + <Kb.ListItem + type="Card" + firstItem={true} + icon={<Kb.IconAuto type={illustration} />} + body={ + <Kb.Box2 direction="vertical" fullWidth={true}> + <Kb.Text type="BodySemibold">{title}</Kb.Text> + <Kb.Text type="BodySmall">{description}</Kb.Text> + </Kb.Box2> + } + onClick={onClick} + /> + </Kb.Box2> ) : null return isMobile ? mobileRow : desktopRow } const styles = Kb.Styles.styleSheetCreate(() => ({ - textContainer: { - justifyContent: 'center', + desktopItemBody: { marginLeft: Kb.Styles.globalMargins.tiny, }, })) diff --git a/shared/crypto/verify.tsx b/shared/crypto/verify.tsx index 8e683984f2a4..aaf851864728 100644 --- a/shared/crypto/verify.tsx +++ b/shared/crypto/verify.tsx @@ -9,6 +9,8 @@ import {CryptoOutput, CryptoOutputActionsBar, CryptoSignedSender} from './output import { beginRun, clearInputState, + createCommonState, + getStatusCodeMessage, maybeAutoRunTextOperation, nextInputState, nextOpenedFileState, @@ -16,10 +18,6 @@ import { resetWarnings, useCommittedState, useSeededCryptoInput, -} from './helpers' -import { - createCommonState, - getStatusCodeMessage, type CommonOutputRouteParams, type CryptoInputRouteParams, type CommonState, @@ -237,12 +235,7 @@ export const VerifyIO = () => { outputFileIcon="icon-file-64" outputTextType="plain" state={controller.state} - onChooseOutputFolder={destinationDir => { - const f = async () => { - await controller.verify(destinationDir) - } - C.ignorePromise(f()) - }} + onChooseOutputFolder={destinationDir => C.ignorePromise(controller.verify(destinationDir) as unknown as Promise<void>)} /> <CryptoOutputActionsBar canReplyInChat={true} canSaveAsText={false} state={controller.state} /> </Kb.Box2> diff --git a/shared/deeplinks/error.tsx b/shared/deeplinks/error.tsx index 1bca793fc79c..7b9218cd57b9 100644 --- a/shared/deeplinks/error.tsx +++ b/shared/deeplinks/error.tsx @@ -8,22 +8,17 @@ type KeybaseLinkErrorBodyProps = { export const KeybaseLinkErrorBody = (props: KeybaseLinkErrorBodyProps) => { const bannerColor = props.isError ? 'red' : 'green' return ( - <> - <Kb.Box2 direction="vertical" fullWidth={true} style={styles.container}> - <Kb.Banner color={bannerColor}> - <Kb.BannerParagraph bannerColor={bannerColor} content={props.message} selectable={true} /> - </Kb.Banner> - </Kb.Box2> - </> + <Kb.Box2 direction="vertical" fullWidth={true} style={styles.container}> + <Kb.Banner color={bannerColor}> + <Kb.BannerParagraph bannerColor={bannerColor} content={props.message} selectable={true} /> + </Kb.Banner> + </Kb.Box2> ) } -const LinkError = (props: {error?: string}) => { - const error = props.error ?? 'Invalid page! (sorry)' - const message = error - const isError = true - return <KeybaseLinkErrorBody isError={isError} message={message} /> -} +const LinkError = (props: {error?: string}) => ( + <KeybaseLinkErrorBody isError={true} message={props.error ?? 'Invalid page! (sorry)'} /> +) const styles = Kb.Styles.styleSheetCreate(() => ({ container: Kb.Styles.platformStyles({ diff --git a/shared/devices/add-device.tsx b/shared/devices/add-device.tsx index 82c007770a0f..db670c970999 100644 --- a/shared/devices/add-device.tsx +++ b/shared/devices/add-device.tsx @@ -5,12 +5,12 @@ import {useProvisionState} from '@/stores/provision' import * as T from '@/constants/types' import {getDeviceIconType} from './device-icon' -type OwnProps = { +type AddDeviceProps = { highlight?: Array<'computer' | 'phone' | 'paper key'> } const noHighlight = new Array<'computer' | 'phone' | 'paper key'>() -export default function AddDevice(ownProps: OwnProps) { +export default function AddDevice(ownProps: AddDeviceProps) { const highlight = ownProps.highlight ?? noHighlight const [iconNumbers, setIconNumbers] = React.useState({ desktop: 1 as T.Devices.IconNumber, diff --git a/shared/devices/device-icon.tsx b/shared/devices/device-icon.tsx index 0794c76308ea..3415dff81f81 100644 --- a/shared/devices/device-icon.tsx +++ b/shared/devices/device-icon.tsx @@ -34,15 +34,14 @@ export const getDeviceRevokeIconType = ( iconNumber: T.Devices.IconNumber ): Kb.IconType => { const size = isMobile ? 64 : 48 + if (type === 'backup') return `icon-paper-key-revoke-${size}` as Kb.IconType const maybeIcon = ( { - backup: `icon-paper-key-revoke-${size}`, desktop: `icon-computer-revoke-background-${iconNumber}-${size}`, mobile: `icon-phone-revoke-background-${iconNumber}-${size}`, } as const )[type] const fallback = ({ - backup: `icon-paper-key-revoke-${size}`, desktop: `icon-computer-revoke-${size}`, mobile: `icon-phone-revoke-${size}`, } as const)[type] diff --git a/shared/devices/device-page.tsx b/shared/devices/device-page.tsx index 84f5835e46b5..b03cd22cefdf 100644 --- a/shared/devices/device-page.tsx +++ b/shared/devices/device-page.tsx @@ -4,7 +4,9 @@ import * as T from '@/constants/types' import {formatTimeForDeviceTimeline, formatTimeRelativeToNow} from '@/util/timestamp' import {getDeviceIconType} from './device-icon' -type OwnProps = {canRevoke: boolean; device: T.Devices.Device} +type DevicePageProps = {canRevoke: boolean; device: T.Devices.Device} + +type TimelineEventType = 'Revoked' | 'LastUsed' | 'Added' const TimelineMarker = (p: {first: boolean; last: boolean; closedCircle: boolean}) => { const {first, last, closedCircle} = p @@ -36,20 +38,20 @@ const TimelineLabel = (p: { </Kb.Text> )} {!!subDesc && !subDescIsName && <Kb.Text type="BodySmall">{subDesc}</Kb.Text>} - {spacerOnBottom && <Kb.Box2 direction="vertical" style={{height: 15}} />} + {spacerOnBottom && <Kb.Box2 direction="vertical" style={styles.timelineSpacer} />} </Kb.Box2> ) } const Timeline = (p: {device: T.Devices.Device}) => { const {device} = p - const timeline = [ + const timeline: Array<{desc: string; subDesc: string; type: TimelineEventType}> = [ ...(device.revokedAt ? [ { desc: `Revoked ${formatTimeForDeviceTimeline(device.revokedAt)}`, subDesc: device.revokedByName || '', - type: 'Revoked', + type: 'Revoked' as const, }, ] : []), @@ -58,14 +60,14 @@ const Timeline = (p: {device: T.Devices.Device}) => { { desc: `Last used ${formatTimeForDeviceTimeline(device.lastUsed)}`, subDesc: formatTimeRelativeToNow(device.lastUsed), - type: 'LastUsed', + type: 'LastUsed' as const, }, ] : []), { desc: `Added ${formatTimeForDeviceTimeline(device.created)}`, subDesc: device.provisionerName || '', - type: 'Added', + type: 'Added' as const, }, ] @@ -90,7 +92,7 @@ const Timeline = (p: {device: T.Devices.Device}) => { ) } -const DevicePage = (ownProps: OwnProps) => { +const DevicePage = (ownProps: DevicePageProps) => { const {canRevoke, device} = ownProps const navigateAppend = C.Router2.navigateAppend const showRevokeDevicePage = () => { @@ -141,25 +143,27 @@ const DevicePage = (ownProps: OwnProps) => { </Kb.Box2> ) } +const circleSize = 8 + const styles = Kb.Styles.styleSheetCreate( () => ({ circleClosed: { backgroundColor: Kb.Styles.globalColors.grey, borderColor: Kb.Styles.globalColors.white, - borderRadius: 8 / 2, + borderRadius: circleSize / 2, borderStyle: 'solid', borderWidth: 2, - height: 8, - width: 8, + height: circleSize, + width: circleSize, }, circleOpen: { borderColor: Kb.Styles.globalColors.grey, - borderRadius: 8 / 2, + borderRadius: circleSize / 2, borderStyle: 'solid', borderWidth: 2, - height: 8, - width: 8, + height: circleSize, + width: circleSize, }, invisible: {opacity: 0}, meta: { @@ -177,6 +181,7 @@ const styles = Kb.Styles.styleSheetCreate( height: 6, width: 2, }, + timelineSpacer: {height: 15}, }) as const ) diff --git a/shared/devices/device-revoke.tsx b/shared/devices/device-revoke.tsx index b7ace9430b14..61b4232cb064 100644 --- a/shared/devices/device-revoke.tsx +++ b/shared/devices/device-revoke.tsx @@ -8,7 +8,7 @@ import {useCurrentUserState} from '@/stores/current-user' import {rpcDeviceDetailToDevice} from './common' import {getDeviceRevokeIconType} from './device-icon' -type OwnProps = {device?: T.Devices.Device; deviceID?: T.Devices.DeviceID} +type DeviceRevokeProps = {device?: T.Devices.Device; deviceID?: T.Devices.DeviceID} const renderTLFEntry = (index: number, tlf: string) => ( <Kb.Box2 direction="horizontal" key={index} gap="tiny" fullWidth={true} style={styles.row}> @@ -25,7 +25,7 @@ const EndangeredTLFList = (props: {endangeredTLFs: Array<string>}) => { <Kb.Text center={true} type="Body"> You may lose access to these folders forever: </Kb.Text> - <Kb.Box2 direction="vertical" style={styles.listContainer}> + <Kb.Box2 direction="vertical" fullWidth={true} style={styles.listContainer}> <Kb.ScrollView>{props.endangeredTLFs.map((tlf, index) => renderTLFEntry(index, tlf))}</Kb.ScrollView> </Kb.Box2> </> @@ -89,7 +89,7 @@ const useRevoke = (device: T.Devices.Device) => { } } -const DeviceRevoke = (ownProps: OwnProps) => { +const DeviceRevoke = (ownProps: DeviceRevokeProps) => { const loadDeviceHistory = C.useRPC(T.RPCGen.deviceDeviceHistoryListRpcPromise) const navigateUp = C.Router2.navigateUp const selectedDeviceID = ownProps.device?.deviceID ?? ownProps.deviceID ?? T.Devices.stringToDeviceID('') @@ -213,12 +213,10 @@ const styles = Kb.Styles.styleSheetCreate( italicName: {...Kb.Styles.globalStyles.italic}, listContainer: Kb.Styles.platformStyles({ common: { - ...Kb.Styles.globalStyles.flexBoxColumn, alignContent: 'center', ...Kb.Styles.border(Kb.Styles.globalColors.black_10, 1, Kb.Styles.borderRadius), flexGrow: 1, ...Kb.Styles.marginV(Kb.Styles.globalMargins.small), - width: '100%', }, isElectron: {height: 162, width: 440}, }), diff --git a/shared/devices/index.tsx b/shared/devices/index.tsx index fe98e95d96bc..2558d10c1e9a 100644 --- a/shared/devices/index.tsx +++ b/shared/devices/index.tsx @@ -151,10 +151,10 @@ const styles = Kb.Styles.styleSheetCreate( height: isMobile ? 64 : 48, ...Kb.Styles.paddingH(Kb.Styles.globalMargins.small), }, - paperKeyNudgeBorder: Kb.Styles.platformStyles({ + paperKeyNudgeContainer: Kb.Styles.platformStyles({ common: { ...Kb.Styles.border(Kb.Styles.globalColors.black_05, 1, Kb.Styles.borderRadius), - flex: 1, + padding: Kb.Styles.globalMargins.small, }, isElectron: { ...Kb.Styles.padding(Kb.Styles.globalMargins.tiny, Kb.Styles.globalMargins.small), @@ -163,14 +163,6 @@ const styles = Kb.Styles.styleSheetCreate( ...Kb.Styles.padding(Kb.Styles.globalMargins.tiny, Kb.Styles.globalMargins.xsmall), }, }), - paperKeyNudgeContainer: Kb.Styles.platformStyles({ - common: { - padding: Kb.Styles.globalMargins.small, - }, - isMobile: { - padding: Kb.Styles.globalMargins.tiny, - }, - }), paperKeyNudgeDesc: Kb.Styles.platformStyles({ isElectron: { maxWidth: 450, @@ -187,20 +179,25 @@ const styles = Kb.Styles.styleSheetCreate( ) const PaperKeyNudge = ({onAddDevice}: {onAddDevice: () => void}) => ( - <Kb.ClickableBox3 onClick={onAddDevice} direction="horizontal" style={styles.paperKeyNudgeContainer} fullWidth={true}> - <Kb.Box2 direction="horizontal" gap="xsmall" alignItems="center" style={styles.paperKeyNudgeBorder}> - <Kb.IconAuto - type={isMobile ? 'icon-onboarding-paper-key-48' : 'icon-onboarding-paper-key-32'} - /> - <Kb.Box2 direction="vertical" flex={1}> - <Kb.Text type="BodySemibold">Create a paper key</Kb.Text> - <Kb.Text type={isMobile ? 'BodySmall' : 'Body'} style={styles.paperKeyNudgeDesc}> - A paper key can be used to access your account in case you lose all your devices. Keep one in a - safe place (like a wallet) to keep your data safe. - </Kb.Text> - </Kb.Box2> - {!isMobile && <Kb.Text type="BodyBigLink">Create a paper key</Kb.Text>} - </Kb.Box2> + <Kb.ClickableBox3 + onClick={onAddDevice} + direction="horizontal" + gap="xsmall" + alignItems="center" + fullWidth={true} + style={styles.paperKeyNudgeContainer} + > + <Kb.IconAuto + type={isMobile ? 'icon-onboarding-paper-key-48' : 'icon-onboarding-paper-key-32'} + /> + <Kb.Box2 direction="vertical" flex={1}> + <Kb.Text type="BodySemibold">Create a paper key</Kb.Text> + <Kb.Text type={isMobile ? 'BodySmall' : 'Body'} style={styles.paperKeyNudgeDesc}> + A paper key can be used to access your account in case you lose all your devices. Keep one in a + safe place (like a wallet) to keep your data safe. + </Kb.Text> + </Kb.Box2> + {!isMobile && <Kb.Text type="BodyBigLink">Create a paper key</Kb.Text>} </Kb.ClickableBox3> ) export default ReloadableDevices diff --git a/shared/devices/paper-key.tsx b/shared/devices/paper-key.tsx index 25ab8233a84a..b0f909341bd9 100644 --- a/shared/devices/paper-key.tsx +++ b/shared/devices/paper-key.tsx @@ -38,33 +38,33 @@ const PaperKey = () => { style={styles.container} gap="medium" > - <Kb.Text type="Header">Paper key generated!</Kb.Text> - <Kb.Text type="Body" style={styles.intro}> - Here is your unique paper key, it will allow you to perform important Keybase tasks in the future. - This is the only time you'll see this so be sure to write it down. - </Kb.Text> - <Kb.Box2 direction="vertical" style={styles.keyBox} centerChildren={true} fullWidth={true}> - {paperkey ? ( - <Kb.Text center={true} type="Header" selectable={true} style={styles.text}> - {paperkey} - </Kb.Text> - ) : ( - <Kb.ProgressIndicator type="Large" /> - )} - </Kb.Box2> - <Kb.Checkbox - label="Yes, I wrote this down." - checked={wroteItDown} - disabled={!paperkey} - onCheck={setWroteItDown} - /> - <Kb.WaitingButton - label="Done" - onClick={clearModals} - disabled={!wroteItDown} - waitingKey={C.waitingKeyDevices} - /> + <Kb.Text type="Header">Paper key generated!</Kb.Text> + <Kb.Text type="Body" center={true}> + Here is your unique paper key, it will allow you to perform important Keybase tasks in the future. + This is the only time you'll see this so be sure to write it down. + </Kb.Text> + <Kb.Box2 direction="vertical" style={styles.keyBox} centerChildren={true} fullWidth={true}> + {paperkey ? ( + <Kb.Text center={true} type="Header" selectable={true} style={styles.text}> + {paperkey} + </Kb.Text> + ) : ( + <Kb.ProgressIndicator type="Large" /> + )} </Kb.Box2> + <Kb.Checkbox + label="Yes, I wrote this down." + checked={wroteItDown} + disabled={!paperkey} + onCheck={setWroteItDown} + /> + <Kb.WaitingButton + label="Done" + onClick={clearModals} + disabled={!wroteItDown} + waitingKey={C.waitingKeyDevices} + /> + </Kb.Box2> ) } @@ -78,7 +78,6 @@ const styles = Kb.Styles.styleSheetCreate( maxWidth: isMobile ? undefined : 560, padding: Kb.Styles.globalMargins.medium, }, - intro: {textAlign: 'center'}, keyBox: { backgroundColor: Kb.Styles.globalColors.white, borderColor: Kb.Styles.globalColors.blueDarker, diff --git a/shared/fs/banner/conflict-banner.tsx b/shared/fs/banner/conflict-banner.tsx index 76e9a2b8b76b..499930ccc75b 100644 --- a/shared/fs/banner/conflict-banner.tsx +++ b/shared/fs/banner/conflict-banner.tsx @@ -13,8 +13,7 @@ const ConnectedBanner = (ownProps: OwnProps) => { const {path} = ownProps const errorToActionOrThrow = Kbfs.useFsErrorActionOrThrow() const openPathInSystemFileManagerDesktop = Kbfs.useOpenPathInSystemFileManagerDesktop() - const _tlf = Kbfs.useFsTlf(path) - const navigateAppend = C.Router2.navigateAppend + const tlf = Kbfs.useFsTlf(path) const onFinishResolving = () => { const f = async () => { try { @@ -28,7 +27,7 @@ const ConnectedBanner = (ownProps: OwnProps) => { C.ignorePromise(f()) } const onGoToSamePathInDifferentTlf = (tlfPath: T.FS.Path) => { - navigateAppend({name: 'fsRoot', params: {path: FS.rebasePathToDifferentTlf(path, tlfPath)}}) + C.Router2.navigateAppend({name: 'fsRoot', params: {path: FS.rebasePathToDifferentTlf(path, tlfPath)}}) } const onHelp = () => { void openUrl('https://book.keybase.io/docs/files/details#conflict-resolution') @@ -50,7 +49,7 @@ const ConnectedBanner = (ownProps: OwnProps) => { openPathInSystemFileManagerDesktop(path, errorToActionOrThrow) } - const conflictState = _tlf.conflictState + const conflictState = tlf.conflictState const finishRes = {onClick: onFinishResolving, text: ' Delete this conflict view '} const helpAction = {onClick: onHelp, text: ' What does this mean? '} const startRes = {onClick: onStartResolving, text: ' Resolve conflict '} diff --git a/shared/fs/banner/reset-banner.tsx b/shared/fs/banner/reset-banner.tsx index 6f80ce1056b2..af0e51676182 100644 --- a/shared/fs/banner/reset-banner.tsx +++ b/shared/fs/banner/reset-banner.tsx @@ -11,42 +11,35 @@ type OwnProps = {path: T.FS.Path} const ConnectedBanner = (ownProps: OwnProps) => { const {path} = ownProps - const _tlf = useFsTlf(path) + const tlf = useFsTlf(path) const errorToActionOrThrow = useFsErrorActionOrThrow() - const _onOpenWithoutResetUsers = (currPath: T.FS.Path, users: {[K in string]: boolean}) => { - const pathElems = T.FS.getPathElements(currPath) + const onOpenProfile = (username: string) => () => { + navToProfile(username) + } + const onOpenWithoutResetUsers = () => { + const pathElems = T.FS.getPathElements(path) if (pathElems.length < 3) return + const users = tlf.resetParticipants.reduce<Record<string, boolean>>((acc, u) => { + acc[u] = true + return acc + }, {}) const filteredPathName = folderNameWithoutUsers(pathElems[2] ?? '', users) const filteredPath = T.FS.stringToPath(['', pathElems[0], pathElems[1], filteredPathName].join('/')) FS.navToPath(filteredPath) } - const _onReAddToTeam = (id: T.RPCGen.TeamID, username: string) => { + const onReAddToTeam = (username: string) => () => { + if (!tlf.teamId) return + const {teamId} = tlf const f = async () => { try { - await T.RPCGen.teamsTeamReAddMemberAfterResetRpcPromise({id, username}) + await T.RPCGen.teamsTeamReAddMemberAfterResetRpcPromise({id: teamId, username}) } catch (error) { errorToActionOrThrow(error) } } C.ignorePromise(f()) } - - const onOpenProfile = (username: string) => () => { - navToProfile(username) - } - const onOpenWithoutResetUsers = () => - _onOpenWithoutResetUsers( - path, - _tlf.resetParticipants.reduce<{ - [x: string]: boolean - }>((acc, i: string) => { - acc[i] = true - return acc - }, {}) - ) - const onReAddToTeam = (username: string) => () => - _tlf.teamId ? _onReAddToTeam(_tlf.teamId, username) : undefined - const resetParticipants = _tlf.resetParticipants + const resetParticipants = tlf.resetParticipants return ( <Kb.Box2 diff --git a/shared/fs/banner/system-file-manager-integration-banner/container.tsx b/shared/fs/banner/system-file-manager-integration-banner/container.tsx index 2e912421cc9d..f3219bec8e4d 100644 --- a/shared/fs/banner/system-file-manager-integration-banner/container.tsx +++ b/shared/fs/banner/system-file-manager-integration-banner/container.tsx @@ -84,15 +84,11 @@ type BannerProps = { const backgroundToTextStyle = (background: Background) => { switch (background) { case Background.Blue: - return styles.textWhite case Background.Green: + case Background.Black: return styles.textWhite case Background.Yellow: return styles.textBrown - case Background.Black: - return styles.textWhite - default: - return styles.textWhite } } @@ -106,8 +102,6 @@ const backgroundToBackgroundColor = (background: Background) => { return Kb.Styles.globalColors.yellow case Background.Black: return Kb.Styles.globalColors.black - default: - return Kb.Styles.globalColors.black } } diff --git a/shared/fs/browser/destination-picker.tsx b/shared/fs/browser/destination-picker.tsx index 938874c6e49b..fdf3e80584d7 100644 --- a/shared/fs/browser/destination-picker.tsx +++ b/shared/fs/browser/destination-picker.tsx @@ -116,7 +116,7 @@ const ConnectedDestinationPicker = (ownProps: OwnProps) => { FsCommon.useFsOnlineStatus() return ( - <Kb.Box2 direction="vertical" style={Kb.Styles.globalStyles.flexOne} fullWidth={true} fullHeight={true}> + <Kb.Box2 direction="vertical" flex={1} fullWidth={true} fullHeight={true}> {!isMobile && ( <Kb.Box2 direction="horizontal" fullWidth={true} centerChildren={true} style={styles.anotherHeader} justifyContent="space-between"> <NavHeaderTitle destinationPickerSource={source} inDestinationPicker={true} path={parentPath} /> diff --git a/shared/fs/browser/index.tsx b/shared/fs/browser/index.tsx index 9122a746ab98..a5373a2ec303 100644 --- a/shared/fs/browser/index.tsx +++ b/shared/fs/browser/index.tsx @@ -24,7 +24,7 @@ type OwnProps = { } const Container = (ownProps: OwnProps) => { -const {path} = ownProps + const {path} = ownProps const filter = useModalHeaderState(s => s.folderViewFilter) const _pathItem = useFsPathItem(path) const tlf = useFsTlf(path) diff --git a/shared/fs/browser/offline.tsx b/shared/fs/browser/offline.tsx index 3a298d641b7f..8316e87e2761 100644 --- a/shared/fs/browser/offline.tsx +++ b/shared/fs/browser/offline.tsx @@ -5,26 +5,28 @@ import {useFsTlf} from '../common' type Props = { path: T.FS.Path - syncEnabled: boolean } -const OfflineFolder = (props: Props) => ( - <Kb.Box2 direction="vertical" flex={1} fullWidth={true} alignItems="stretch"> - <TopBar path={props.path} /> - <Kb.Box2 direction="vertical" flex={1} style={styles.emptyContainer} fullWidth={true} centerChildren={true}> - <Kb.Icon - type={props.syncEnabled ? 'iconfont-clock' : 'iconfont-cloud'} - sizeType="Huge" - color={Kb.Styles.globalColors.black_10} - /> - <Kb.Text type="BodySmall"> - {props.syncEnabled - ? 'This folder will sync once you get back online.' - : "You haven't synced this folder."} - </Kb.Text> +const OfflineFolder = ({path}: Props) => { + const syncEnabled = useFsTlf(path).syncConfig.mode === T.FS.TlfSyncMode.Enabled + return ( + <Kb.Box2 direction="vertical" flex={1} fullWidth={true} alignItems="stretch"> + <TopBar path={path} /> + <Kb.Box2 direction="vertical" flex={1} style={styles.emptyContainer} fullWidth={true} centerChildren={true}> + <Kb.Icon + type={syncEnabled ? 'iconfont-clock' : 'iconfont-cloud'} + sizeType="Huge" + color={Kb.Styles.globalColors.black_10} + /> + <Kb.Text type="BodySmall"> + {syncEnabled + ? 'This folder will sync once you get back online.' + : "You haven't synced this folder."} + </Kb.Text> + </Kb.Box2> </Kb.Box2> - </Kb.Box2> -) + ) +} const styles = Kb.Styles.styleSheetCreate( () => @@ -36,14 +38,4 @@ const styles = Kb.Styles.styleSheetCreate( }) as const ) -type OwnProps = { - path: T.FS.Path -} - -const Container = (ownProps: OwnProps) => { - const {path} = ownProps - const syncConfig = useFsTlf(path).syncConfig - return <OfflineFolder path={path} syncEnabled={syncConfig.mode === T.FS.TlfSyncMode.Enabled} /> -} - -export default Container +export default OfflineFolder diff --git a/shared/fs/browser/rows/editing.tsx b/shared/fs/browser/rows/editing.tsx index 17a881ee100f..aa321745b5b7 100644 --- a/shared/fs/browser/rows/editing.tsx +++ b/shared/fs/browser/rows/editing.tsx @@ -10,14 +10,8 @@ type Props = { function Editing({editSession}: Props) { const {commitEdit, discardEdit, edit} = editSession - const onCancel = () => { - discardEdit() - } - const onSubmit = () => { - commitEdit() - } const onKeyDown = (event: React.KeyboardEvent) => { - if (event.key === 'Escape') onCancel() + if (event.key === 'Escape') discardEdit() } return ( <Kb.ListItem @@ -42,7 +36,7 @@ function Editing({editSession}: Props) { placeholder={edit.originalName} selectTextOnFocus={true} inputStyle={styles.text} - onEnterKeyDown={onSubmit} + onEnterKeyDown={commitEdit} onChangeText={editSession.setEditName} autoFocus={true} onKeyDown={onKeyDown} @@ -63,10 +57,10 @@ function Editing({editSession}: Props) { small={true} label={edit.error ? 'Retry' : edit.type === T.FS.EditType.NewFolder ? 'Create' : 'Save'} waiting={editSession.isSubmitting} - onClick={onSubmit} + onClick={commitEdit} /> <Kb.Icon - onClick={onCancel} + onClick={discardEdit} type={edit.type === T.FS.EditType.NewFolder ? 'iconfont-trash' : 'iconfont-close'} color={Kb.Styles.globalColors.black_50} hoverColor={Kb.Styles.globalColors.black} diff --git a/shared/fs/browser/rows/still.tsx b/shared/fs/browser/rows/still.tsx index aa5ca779ef95..92260b251319 100644 --- a/shared/fs/browser/rows/still.tsx +++ b/shared/fs/browser/rows/still.tsx @@ -75,7 +75,7 @@ const StillContainer = (p: OwnProps) => { Upload has failed.{' '} <Kb.Text type="BodySmallPrimaryLink" - style={styles.redDark} + style={{color: Kb.Styles.globalColors.redDark}} onClick={e => { e.stopPropagation() dismissUploadError() @@ -98,8 +98,4 @@ const StillContainer = (p: OwnProps) => { ) } -const styles = Kb.Styles.styleSheetCreate(() => ({ - redDark: {color: Kb.Styles.globalColors.redDark}, -})) - export default StillContainer diff --git a/shared/fs/browser/rows/tlf.tsx b/shared/fs/browser/rows/tlf.tsx index 3d6156721a61..c88c609dfeb5 100644 --- a/shared/fs/browser/rows/tlf.tsx +++ b/shared/fs/browser/rows/tlf.tsx @@ -18,7 +18,7 @@ const TLFContainer = (p: OwnProps) => { const {tlfType, name, mixedMode, destinationPickerSource, disabled} = p const username = useCurrentUserState(s => s.username) const path = FS.tlfTypeAndNameToPath(tlfType, name) - const _usernames = FS.getUsernamesFromTlfName(name).filter(name => name !== username) + const _usernames = FS.getUsernamesFromTlfName(name).filter(u => u !== username) const onOpen = useOpen({destinationPickerSource, path}) // Only include the user if they're the only one const usernames = !_usernames.length ? [username] : _usernames diff --git a/shared/fs/browser/sort-state.tsx b/shared/fs/browser/sort-state.tsx index eab7783e5401..84edb03fb13a 100644 --- a/shared/fs/browser/sort-state.tsx +++ b/shared/fs/browser/sort-state.tsx @@ -27,7 +27,7 @@ export const FsBrowserSortProvider = ({children}: {children: React.ReactNode}) = const username = useCurrentUserState(s => s.username) const usernameRef = React.useRef(username) const [sortSettings, setSortSettings] = React.useState<ReadonlyMap<T.FS.Path, T.FS.SortSetting>>( - () => new Map<T.FS.Path, T.FS.SortSetting>() + () => new Map() ) React.useEffect(() => { @@ -35,7 +35,7 @@ export const FsBrowserSortProvider = ({children}: {children: React.ReactNode}) = return } usernameRef.current = username - setSortSettings(new Map<T.FS.Path, T.FS.SortSetting>()) + setSortSettings(new Map()) }, [username]) const setSortSetting = (path: T.FS.Path, sortSetting: T.FS.SortSetting) => { diff --git a/shared/fs/common/folder-view-filter-icon.tsx b/shared/fs/common/folder-view-filter-icon.tsx index b5cf46503c4e..b609d8554e42 100644 --- a/shared/fs/common/folder-view-filter-icon.tsx +++ b/shared/fs/common/folder-view-filter-icon.tsx @@ -6,21 +6,14 @@ import * as FS from '@/constants/fs' type Props = { onClick: () => void path: T.FS.Path - pathItem: T.FS.PathItem style?: Kb.Styles.StylesCrossPlatform } -const FolderViewFilterIcon = (props: Props) => - FS.isFolder(props.path, props.pathItem) && T.FS.getPathLevel(props.path) > 1 ? ( +const FolderViewFilterIcon = (props: Props) => { + const pathItem = useFsPathItem(props.path) + return FS.isFolder(props.path, pathItem) && T.FS.getPathLevel(props.path) > 1 ? ( <Kb.Icon type="iconfont-filter" onClick={props.onClick} padding="tiny" style={props.style} /> ) : null - -type OwnProps = Omit<Props, 'pathItem'> - -const Container = (ownProps: OwnProps) => { - const {path} = ownProps - const pathItem = useFsPathItem(path) - return <FolderViewFilterIcon {...ownProps} pathItem={pathItem} /> } -export default Container +export default FolderViewFilterIcon diff --git a/shared/fs/common/hooks.tsx b/shared/fs/common/hooks.tsx index e5c3e9108cbf..82e2f74f5ab3 100644 --- a/shared/fs/common/hooks.tsx +++ b/shared/fs/common/hooks.tsx @@ -827,9 +827,6 @@ export const useFsPathMetadata = (path: T.FS.Path, _options?: FsPathItemOptions) export const useFsFolderChildren = (path: T.FS.Path, _options?: {initialLoadRecursive?: boolean}) => FS.getPathItem(useLoadedPathItems(), path) -export const useFsChildren = (path: T.FS.Path, initialLoadRecursive?: boolean) => - useFsFolderChildren(path, {initialLoadRecursive}) - export const useFsFolderChildItems = ( path: T.FS.Path, options?: { diff --git a/shared/fs/common/path-item-action/confirm-delete.tsx b/shared/fs/common/path-item-action/confirm-delete.tsx index 5d7bfd35822f..cefc701812ee 100644 --- a/shared/fs/common/path-item-action/confirm-delete.tsx +++ b/shared/fs/common/path-item-action/confirm-delete.tsx @@ -5,35 +5,14 @@ import * as FS from '@/constants/fs' import {makeUUID} from '@/util/uuid' import {useFsErrorActionOrThrow} from '../error-state' -export type Props = { - onBack: () => void - onDelete: () => void - path: T.FS.Path - title: string -} - -const ReallyDeleteFile = (props: Props) => - props.path ? ( - <Kb.ConfirmModal - confirmText="Yes, delete" - description="It will be deleted for everyone. This cannot be undone." - header={<Kb.Icon type="iconfont-trash" sizeType="Big" color={Kb.Styles.globalColors.red} />} - onCancel={props.onBack} - onConfirm={props.onDelete} - prompt={`Are you sure you want to delete "${T.FS.getPathName(props.path)}"?`} - /> - ) : null - -type OwnProps = { +type Props = { path: T.FS.Path mode: 'row' | 'screen' } -const Container = (ownProps: OwnProps) => { - const {path, mode} = ownProps +const ConfirmDelete = ({path, mode}: Props) => { const errorToActionOrThrow = useFsErrorActionOrThrow() const navigateUp = C.Router2.navigateUp - const onBack = navigateUp const onDelete = () => { if (path !== FS.defaultPath) { const f = async () => { @@ -60,13 +39,16 @@ const Container = (ownProps: OwnProps) => { navigateUp() } } - const props = { - onBack, - onDelete, - path, - title: 'Confirmation', - } - return <ReallyDeleteFile {...props} /> + return path ? ( + <Kb.ConfirmModal + confirmText="Yes, delete" + description="It will be deleted for everyone. This cannot be undone." + header={<Kb.Icon type="iconfont-trash" sizeType="Big" color={Kb.Styles.globalColors.red} />} + onCancel={navigateUp} + onConfirm={onDelete} + prompt={`Are you sure you want to delete "${T.FS.getPathName(path)}"?`} + /> + ) : null } -export default Container +export default ConfirmDelete diff --git a/shared/fs/common/path-status-icon.tsx b/shared/fs/common/path-status-icon.tsx index 8de7dfe28031..0c96e1d81e96 100644 --- a/shared/fs/common/path-status-icon.tsx +++ b/shared/fs/common/path-status-icon.tsx @@ -78,7 +78,7 @@ function PathStatusIcon(props: Props) { > {typeof props.statusIcon === 'number' ? ( <Kb.Box2 direction="horizontal" style={{margin: Kb.Styles.globalMargins.xtiny}}> - <PieSlice degrees={360 * props.statusIcon} animated={true} /> + <PieSlice degrees={360 * props.statusIcon} /> </Kb.Box2> ) : props.statusIcon === T.FS.UploadIcon.AwaitingToUpload || props.statusIcon === T.FS.UploadIcon.Uploading || diff --git a/shared/fs/common/pie-slice.tsx b/shared/fs/common/pie-slice.tsx index e1f9592cb15b..7321984576de 100644 --- a/shared/fs/common/pie-slice.tsx +++ b/shared/fs/common/pie-slice.tsx @@ -35,18 +35,9 @@ const Slice = (props: Props) => { ) } -const AnimatedPieSlice = (props: Props) => { - const {degrees} = props - return <Slice degrees={degrees} style={props.style} negative={props.negative} /> -} - -const PieSlice = (props: Props) => { - return props.animated ? ( - <AnimatedPieSlice {...props} /> - ) : ( - <Slice degrees={props.degrees} style={props.style} negative={props.negative} /> - ) -} +const PieSlice = (props: Props) => ( + <Slice degrees={props.degrees} style={props.style} negative={props.negative} /> +) const pieSize = isMobile ? 16 : 12 const pieHalfSize = isMobile ? 8 : 6 const stylePieHalf = { diff --git a/shared/fs/common/rpc-state.tsx b/shared/fs/common/rpc-state.tsx index 9aefc8790a45..78d79b5d9033 100644 --- a/shared/fs/common/rpc-state.tsx +++ b/shared/fs/common/rpc-state.tsx @@ -68,7 +68,7 @@ const rpcFolderTypeToTlfType = (rpcFolderType: T.RPCGen.FolderType) => { } } -const rpcPathToPath = (rpcPath: T.RPCGen.KBFSPath) => T.FS.pathConcat(FS.defaultPath, rpcPath.path) +export const rpcPathToPath = (rpcPath: T.RPCGen.KBFSPath) => T.FS.pathConcat(FS.defaultPath, rpcPath.path) const rpcConflictStateToConflictState = (rpcConflictState?: T.RPCGen.ConflictState): T.FS.ConflictState => { if (rpcConflictState) { diff --git a/shared/fs/common/status.tsx b/shared/fs/common/status.tsx index ba535d0b3fb2..1d98869ee864 100644 --- a/shared/fs/common/status.tsx +++ b/shared/fs/common/status.tsx @@ -9,6 +9,7 @@ import isEqual from 'lodash/isEqual' import {clientID as fsClientID, makeUUID} from './client' import {FsDaemonProvider, useFsDaemonActions, useKbfsDaemonStatus} from './daemon' import {useFsErrorActionOrThrow} from './error-state' +import {rpcPathToPath} from './rpc-state' type FsStatusState = { generation: number @@ -38,8 +39,6 @@ const emptyFsStatusState = makeInitialFsStatusState() const FsOverallSyncStatusContext = React.createContext<T.FS.OverallSyncStatus | undefined>(undefined) const FsUploadStatusContext = React.createContext<T.FS.Uploads | undefined>(undefined) -const rpcPathToPath = (rpcPath: T.RPCGen.KBFSPath) => T.FS.pathConcat(Constants.defaultPath, rpcPath.path) - const unsubscribe = (subscriptionID: string) => { C.ignorePromise( T.RPCGen.SimpleFSSimpleFSUnsubscribeRpcPromise({ diff --git a/shared/fs/footer/upload-container.tsx b/shared/fs/footer/upload-container.tsx index 530cbc9f5937..5de75422fb42 100644 --- a/shared/fs/footer/upload-container.tsx +++ b/shared/fs/footer/upload-container.tsx @@ -4,21 +4,14 @@ import {useUploadCountdown} from './use-upload-countdown' import {useFsUploadStatus, useKbfsDaemonStatus} from '../common' import {useNonFolderSyncingPaths} from '../common/use-non-folder-syncing-paths' -const UpoadContainer = () => { +const UploadContainer = () => { const kbfsDaemonStatus = useKbfsDaemonStatus() const uploads = useFsUploadStatus() - // We just use syncingPaths rather than merging with writingToJournal here - // since journal status comes a bit slower, and merging the two causes - // flakes on our perception of overall upload status. - // Filter out folder paths. const filePaths = useNonFolderSyncingPaths(uploads.syncingPaths) const np = useUploadCountdown({ - // We just use syncingPaths rather than merging with writingToJournal here - // since journal status comes a bit slower, and merging the two causes - // flakes on our perception of overall upload status. endEstimate: uploads.endEstimate || 0, fileName: filePaths.length === 1 ? T.FS.getPathName(filePaths[0] || T.FS.stringToPath('')) : undefined, files: filePaths.length, @@ -28,4 +21,4 @@ const UpoadContainer = () => { return <Upload {...np} /> } -export default UpoadContainer +export default UploadContainer diff --git a/shared/fs/nav-header/main-banner.tsx b/shared/fs/nav-header/main-banner.tsx index 9f71a709ef4f..802747c7cb41 100644 --- a/shared/fs/nav-header/main-banner.tsx +++ b/shared/fs/nav-header/main-banner.tsx @@ -54,13 +54,13 @@ const styles = Kb.Styles.styleSheetCreate(() => ({ })) const ConnectedBanner = () => { - const _kbfsDaemonStatus = useKbfsDaemonStatus() - const _overallSyncStatus = useFsOverallSyncStatus() - const _name = useCurrentUserState(s => s.username) + const kbfsDaemonStatus = useKbfsDaemonStatus() + const overallSyncStatus = useFsOverallSyncStatus() + const name = useCurrentUserState(s => s.username) const errorToActionOrThrow = useFsErrorActionOrThrow() // Stat'ing the path nudges the service to retry sync. const onRetry = () => { - const path = T.FS.stringToPath('/keybase/private/' + _name) + const path = T.FS.stringToPath('/keybase/private/' + name) const f = async () => { try { await T.RPCGen.SimpleFSSimpleFSStatRpcPromise({ @@ -74,11 +74,7 @@ const ConnectedBanner = () => { C.ignorePromise(f()) } - const props = { - bannerType: FS.getMainBannerType(_kbfsDaemonStatus, _overallSyncStatus), - onRetry, - } - return <Banner {...props} /> + return <Banner bannerType={FS.getMainBannerType(kbfsDaemonStatus, overallSyncStatus)} onRetry={onRetry} /> } export default ConnectedBanner diff --git a/shared/fs/nav-header/title.tsx b/shared/fs/nav-header/title.tsx index 9be1f4bbee8c..8322bae4e427 100644 --- a/shared/fs/nav-header/title.tsx +++ b/shared/fs/nav-header/title.tsx @@ -98,11 +98,7 @@ const Breadcrumb = (props: Props) => { } const MaybePublicTag = ({path}: {path: T.FS.Path}) => - FS.hasPublicTag(path) ? ( - <Kb.Box2 direction="horizontal"> - <Kb.Meta title="public" backgroundColor={Kb.Styles.globalColors.green} /> - </Kb.Box2> - ) : null + FS.hasPublicTag(path) ? <Kb.Meta title="public" backgroundColor={Kb.Styles.globalColors.green} /> : null const MainTitle = (props: Props) => ( <Kb.Box2 direction="horizontal" fullWidth={true} alignItems="center" gap="tiny"> diff --git a/shared/fs/top-bar/sort.tsx b/shared/fs/top-bar/sort.tsx index 1416c200d9c4..e49559a2b255 100644 --- a/shared/fs/top-bar/sort.tsx +++ b/shared/fs/top-bar/sort.tsx @@ -28,7 +28,7 @@ const makeSortOptionItem = (sortSetting: T.FS.SortSetting, onClick?: () => void) title: getTextFromSortSetting(sortSetting), }) -const Container = (ownProps: OwnProps) => { +const Sort = (ownProps: OwnProps) => { const {path} = ownProps const pathItem = useFsPathItem(path) const {setSortSetting, sortSetting} = useFsBrowserSort(path) @@ -37,30 +37,10 @@ const Container = (ownProps: OwnProps) => { const shownSortSetting = FS.showSortSetting(path, pathItem, kbfsDaemonStatus) ? sortSetting : undefined const makePopup = (p: Kb.Popup2Parms) => { const {attachTo, hidePopup} = p - const sortByNameAsc = - path === FS.defaultPath - ? undefined - : () => { - setSortSetting(path, T.FS.SortSetting.NameAsc) - } - const sortByNameDesc = - path === FS.defaultPath - ? undefined - : () => { - setSortSetting(path, T.FS.SortSetting.NameDesc) - } - const sortByTimeAsc = - path === FS.defaultPath - ? undefined - : () => { - setSortSetting(path, T.FS.SortSetting.TimeAsc) - } - const sortByTimeDesc = - path === FS.defaultPath - ? undefined - : () => { - setSortSetting(path, T.FS.SortSetting.TimeDesc) - } + const isRoot = path === FS.defaultPath + const sortSettings: Array<T.FS.SortSetting> = isRoot + ? [] + : [T.FS.SortSetting.NameAsc, T.FS.SortSetting.NameDesc, T.FS.SortSetting.TimeAsc, T.FS.SortSetting.TimeDesc] return ( <Kb.FloatingMenu attachTo={attachTo} @@ -68,12 +48,7 @@ const Container = (ownProps: OwnProps) => { onHidden={hidePopup} position="bottom left" closeOnSelect={true} - items={[ - ...(sortByNameAsc ? [makeSortOptionItem(T.FS.SortSetting.NameAsc, sortByNameAsc)] : []), - ...(sortByNameDesc ? [makeSortOptionItem(T.FS.SortSetting.NameDesc, sortByNameDesc)] : []), - ...(sortByTimeAsc ? [makeSortOptionItem(T.FS.SortSetting.TimeAsc, sortByTimeAsc)] : []), - ...(sortByTimeDesc ? [makeSortOptionItem(T.FS.SortSetting.TimeDesc, sortByTimeDesc)] : []), - ]} + items={sortSettings.map(s => makeSortOptionItem(s, () => setSortSetting(path, s)))} /> ) } @@ -98,4 +73,4 @@ const styles = Kb.Styles.styleSheetCreate( }) as const ) -export default Container +export default Sort diff --git a/shared/fs/top-bar/sync-toggle.tsx b/shared/fs/top-bar/sync-toggle.tsx index 983d059c50ec..7a1f7e433d84 100644 --- a/shared/fs/top-bar/sync-toggle.tsx +++ b/shared/fs/top-bar/sync-toggle.tsx @@ -9,7 +9,7 @@ type OwnProps = { tlfPath: T.FS.Path } -const Container = (ownProps: OwnProps) => { +const SyncToggle = (ownProps: OwnProps) => { const {tlfPath} = ownProps const tlfPathItem = useFsFolderChildren(tlfPath) const tlf = useFsTlf(tlfPath) @@ -180,4 +180,4 @@ const styles = Kb.Styles.styleSheetCreate( }) as const ) -export default Container +export default SyncToggle diff --git a/shared/git/delete-repo.tsx b/shared/git/delete-repo.tsx index c35920f0b3d4..ab7a31a8c5fc 100644 --- a/shared/git/delete-repo.tsx +++ b/shared/git/delete-repo.tsx @@ -8,7 +8,7 @@ type OwnProps = { teamname?: string } -const Container = (ownProps: OwnProps) => { +const DeleteRepo = (ownProps: OwnProps) => { const _name = ownProps.name const teamname = ownProps.teamname ?? '' const [error, setError] = React.useState('') @@ -18,33 +18,21 @@ const Container = (ownProps: OwnProps) => { const deleteTeamRepo = C.useRPC(T.RPCGen.gitDeleteTeamRepoRpcPromise) const navigateUp = C.Router2.navigateUp - const _onDelete = (teamname: string | undefined, name: string, notifyTeam: boolean) => { + const onDelete = (notifyTeam: boolean) => { if (teamname) { deleteTeamRepo( - [{notifyTeam, repoName: name, teamName: {parts: teamname.split('.')}}, waitingKey], - () => { - navigateUp() - }, - err => { - setError(err.message) - } + [{notifyTeam, repoName: _name, teamName: {parts: teamname.split('.')}}, waitingKey], + navigateUp, + err => setError(err.message) ) } else { deletePersonalRepo( - [{repoName: name}, waitingKey], - () => { - navigateUp() - }, - err => { - setError(err.message) - } + [{repoName: _name}, waitingKey], + navigateUp, + err => setError(err.message) ) } } - const onClose = () => { - navigateUp() - } - const onDelete = (notifyTeam: boolean) => _onDelete(teamname, _name, notifyTeam) const [name, setName] = React.useState('') const [notifyTeam, setNotifyTeam] = React.useState(true) @@ -68,80 +56,69 @@ const Container = (ownProps: OwnProps) => { } } return ( - <> - <Kb.ScrollView> - <Kb.Box2 direction="vertical" alignItems="center" fullWidth={true} style={styles.container}> - {!!error && ( - <Kb.Box2 direction="vertical" style={styles.error}> - <Kb.Text type="Body" negative={true}> - {error} - </Kb.Text> - </Kb.Box2> - )} - <Kb.Text center={true} type="Header" style={{marginBottom: 27}}> - Are you sure you want to delete this {teamname ? 'team ' : ''} - repository? - </Kb.Text> - <Kb.ImageIcon type={teamname ? 'icon-repo-team-delete-48' : 'icon-repo-personal-delete-48'} /> - <Kb.Box2 direction="horizontal" alignItems="center" style={styles.avatarBox}> - {!!teamname && ( - <Kb.Avatar - isTeam={true} - teamname={teamname} - size={16} - style={{marginRight: Kb.Styles.globalMargins.xtiny}} - /> - )} - <Kb.Text - type="BodySemibold" - style={{color: Kb.Styles.globalColors.redDark, textDecorationLine: 'line-through'}} - > - {teamname ? `${teamname}/${_name}` : _name} - </Kb.Text> - </Kb.Box2> - <Kb.Text center={true} type="Body" style={{marginBottom: Kb.Styles.globalMargins.medium}}> - {teamname - ? 'This will permanently delete your remote files and history, and all members of the team will be notified. This action cannot be undone.' - : 'This will permanently delete your remote files and history. This action cannot be undone.'} - </Kb.Text> - <Kb.Text style={styles.confirm} type="BodySemibold"> - Enter the name of the repository to confirm: - </Kb.Text> - <Kb.Input3 - autoFocus={true} - value={name} - onChangeText={setName} - onEnterKeyDown={onSubmit} - placeholder="Name of the repository" - /> + <Kb.ScrollView> + <Kb.Box2 direction="vertical" alignItems="center" fullWidth={true} style={styles.container}> + {!!error && <Kb.Banner color="red">{error}</Kb.Banner>} + <Kb.Text center={true} type="Header" style={styles.headerText}> + Are you sure you want to delete this {teamname ? 'team ' : ''} + repository? + </Kb.Text> + <Kb.ImageIcon type={teamname ? 'icon-repo-team-delete-48' : 'icon-repo-personal-delete-48'} /> + <Kb.Box2 direction="horizontal" alignItems="center" style={styles.avatarBox}> {!!teamname && ( - <Kb.Checkbox - label="Notify the team" - checked={notifyTeam} - onCheck={setNotifyTeam} - style={styles.checkbox} + <Kb.Avatar + isTeam={true} + teamname={teamname} + size={16} + style={styles.teamAvatar} /> )} - <Kb.ButtonBar fullWidth={true} style={styles.buttonBar}> - <Kb.WaitingButton - type="Dim" - onClick={onClose} - label="Cancel" - style={{marginRight: Kb.Styles.globalMargins.tiny}} - waitingKey={waitingKey} - onlyDisable={true} - /> - <Kb.WaitingButton - type="Danger" - onClick={onSubmit} - label={isMobile ? 'Delete' : 'Delete this repository'} - disabled={!matchesName()} - waitingKey={waitingKey} - /> - </Kb.ButtonBar> + <Kb.Text type="BodySemibold" style={styles.repoName}> + {teamname ? `${teamname}/${_name}` : _name} + </Kb.Text> </Kb.Box2> - </Kb.ScrollView> - </> + <Kb.Text center={true} type="Body" style={styles.warningText}> + {teamname + ? 'This will permanently delete your remote files and history, and all members of the team will be notified. This action cannot be undone.' + : 'This will permanently delete your remote files and history. This action cannot be undone.'} + </Kb.Text> + <Kb.Text style={styles.confirm} type="BodySemibold"> + Enter the name of the repository to confirm: + </Kb.Text> + <Kb.Input3 + autoFocus={true} + value={name} + onChangeText={setName} + onEnterKeyDown={onSubmit} + placeholder="Name of the repository" + /> + {!!teamname && ( + <Kb.Checkbox + label="Notify the team" + checked={notifyTeam} + onCheck={setNotifyTeam} + style={styles.checkbox} + /> + )} + <Kb.ButtonBar fullWidth={true} style={styles.buttonBar}> + <Kb.WaitingButton + type="Dim" + onClick={navigateUp} + label="Cancel" + style={styles.cancelButton} + waitingKey={waitingKey} + onlyDisable={true} + /> + <Kb.WaitingButton + type="Danger" + onClick={onSubmit} + label={isMobile ? 'Delete' : 'Delete this repository'} + disabled={!matchesName()} + waitingKey={waitingKey} + /> + </Kb.ButtonBar> + </Kb.Box2> + </Kb.ScrollView> ) } @@ -150,6 +127,7 @@ const styles = Kb.Styles.styleSheetCreate(() => ({ marginBottom: Kb.Styles.globalMargins.medium, }, buttonBar: {alignItems: 'center'}, + cancelButton: {marginRight: Kb.Styles.globalMargins.tiny}, checkbox: { alignSelf: 'flex-start', ...Kb.Styles.marginV(Kb.Styles.globalMargins.tiny), @@ -173,12 +151,10 @@ const styles = Kb.Styles.styleSheetCreate(() => ({ padding: Kb.Styles.globalMargins.small, }, }), - error: { - alignSelf: 'stretch', - backgroundColor: Kb.Styles.globalColors.red, - marginBottom: Kb.Styles.globalMargins.small, - padding: Kb.Styles.globalMargins.tiny, - }, + headerText: {marginBottom: 27}, + repoName: {color: Kb.Styles.globalColors.redDark, textDecorationLine: 'line-through'}, + teamAvatar: {marginRight: Kb.Styles.globalMargins.xtiny}, + warningText: {marginBottom: Kb.Styles.globalMargins.medium}, })) -export default Container +export default DeleteRepo diff --git a/shared/git/index.tsx b/shared/git/index.tsx index 265c2595910a..5219bbd67bba 100644 --- a/shared/git/index.tsx +++ b/shared/git/index.tsx @@ -93,8 +93,8 @@ type ExpandedState = { expandedSet: Set<string> } -const Container = (ownProps: OwnProps) => { -const loading = C.Waiting.useAnyWaiting(C.waitingKeyGitLoading) +const GitRoot = (ownProps: OwnProps) => { + const loading = C.Waiting.useAnyWaiting(C.waitingKeyGitLoading) const loadGit = C.useRPC(T.RPCGen.gitGetAllGitMetadataRpcPromise) const clearGitBadges = C.useRPC(T.RPCGen.gregorDismissCategoryRpcPromise) const [error, setError] = React.useState<Error | undefined>() @@ -194,10 +194,10 @@ const loading = C.Waiting.useAnyWaiting(C.waitingKeyGitLoading) <Kb.Box2 direction="vertical" fullWidth={true} fullHeight={true} relative={true} testID={TestIDs.GIT_REPO_LIST}> {!!error && <Kb.Banner color="red">{error.message}</Kb.Banner>} {isMobile && ( - <Kb.ClickableBox3 ref={popupAnchor} direction="horizontal" centerChildren={true} style={styles.header} onClick={showPopup}> + <Kb.ClickableBox3 ref={popupAnchor} direction="horizontal" centerChildren={true} noShrink={true} style={styles.header} onClick={showPopup}> <Kb.Icon type="iconfont-new" - style={{marginRight: Kb.Styles.globalMargins.tiny}} + style={styles.newIcon} color={Kb.Styles.globalColors.blue} fontSize={20} /> @@ -238,10 +238,10 @@ const styles = Kb.Styles.styleSheetCreate( () => ({ header: { - flexShrink: 0, height: 48, }, + newIcon: {marginRight: Kb.Styles.globalMargins.tiny}, }) as const ) -export default Container +export default GitRoot diff --git a/shared/git/new-repo.tsx b/shared/git/new-repo.tsx index 15c352da6711..802b2393e717 100644 --- a/shared/git/new-repo.tsx +++ b/shared/git/new-repo.tsx @@ -9,7 +9,7 @@ import {useTeamsList} from '@/teams/use-teams-list' type OwnProps = {isTeam: boolean} const NewTeamSentry = '---NewTeam---' -const Container = (ownProps: OwnProps) => { +const NewRepo = (ownProps: OwnProps) => { const {isTeam} = ownProps const [error, setError] = React.useState('') const {teams: loadedTeams} = useTeamsList() @@ -17,31 +17,21 @@ const Container = (ownProps: OwnProps) => { () => loadedTeams.map(team => team.teamname).sort(Teams.sortTeamnames), [loadedTeams] ) - const waitingKey = C.waitingKeyGitLoading const navigateUp = C.Router2.navigateUp const createPersonalRepo = C.useRPC(T.RPCGen.gitCreatePersonalRepoRpcPromise) const createTeamRepo = C.useRPC(T.RPCGen.gitCreateTeamRepoRpcPromise) - const onClose = navigateUp const onCreate = (name: string, teamname: string, notifyTeam: boolean) => { if (isTeam && teamname) { createTeamRepo( - [{notifyTeam, repoName: name, teamName: {parts: teamname.split('.')}}, waitingKey], - () => { - navigateUp() - }, - err => { - setError(err.message) - } + [{notifyTeam, repoName: name, teamName: {parts: teamname.split('.')}}, C.waitingKeyGitLoading], + navigateUp, + err => setError(err.message) ) } else { createPersonalRepo( - [{repoName: name}, waitingKey], - () => { - navigateUp() - }, - err => { - setError(err.message) - } + [{repoName: name}, C.waitingKeyGitLoading], + navigateUp, + err => setError(err.message) ) } } @@ -61,7 +51,7 @@ const Container = (ownProps: OwnProps) => { const makeDropdownItem = (item?: string) => { if (!item) { return ( - <Kb.Box2 alignItems="center" direction="horizontal" fullWidth={true} style={styles.dropdownItem} justifyContent="flex-start"> + <Kb.Box2 alignItems="center" direction="horizontal" fullWidth={true} style={styles.avatarBox} justifyContent="flex-start"> <Kb.Text type="BodyBig">Pick a team</Kb.Text> </Kb.Box2> ) @@ -69,16 +59,9 @@ const Container = (ownProps: OwnProps) => { if (item === NewTeamSentry) { return ( - <Kb.Box2 - key={NewTeamSentry} - direction="horizontal" - alignItems="center" - style={{ - paddingLeft: Kb.Styles.globalMargins.small, - }} - > - <Kb.Text type="Header">New team...</Kb.Text> - </Kb.Box2> + <Kb.Text key={NewTeamSentry} type="Header" style={styles.newTeamItem}> + New team... + </Kb.Text> ) } @@ -88,22 +71,9 @@ const Container = (ownProps: OwnProps) => { isTeam={true} teamname={item} size={16} - style={{marginRight: Kb.Styles.globalMargins.tiny}} + style={styles.teamAvatar} /> - <Kb.Text - type="Header" - style={Kb.Styles.platformStyles({ - common: { - overflow: 'hidden', - width: '100%', - }, - isElectron: { - display: 'block', - textOverflow: 'ellipsis', - whiteSpace: 'nowrap', - }, - })} - > + <Kb.Text type="Header" style={styles.teamName}> {item} </Kb.Text> </Kb.Box2> @@ -128,76 +98,67 @@ const Container = (ownProps: OwnProps) => { return name && !(isTeam && !selectedTeam) } return ( - <> - <Kb.ScrollView> - <Kb.Box2 direction="vertical" fullWidth={true} alignItems="center" style={styles.container}> - {!!error && ( - <Kb.Box2 direction="vertical" fullWidth={true} style={styles.error}> - <Kb.Text type="Body" negative={true}> - {error} - </Kb.Text> - </Kb.Box2> - )} - <Kb.Text type="Header" style={{marginBottom: 27}}> - New {isTeam ? 'team' : 'personal'} git repository - </Kb.Text> - <Kb.IconAuto - type={isTeam ? 'icon-repo-team-add-48' : 'icon-repo-personal-add-48'} - style={styles.addIcon} + <Kb.ScrollView> + <Kb.Box2 direction="vertical" fullWidth={true} alignItems="center" style={styles.container}> + {!!error && <Kb.Banner color="red">{error}</Kb.Banner>} + <Kb.Text type="Header" style={styles.marginBottom27}> + New {isTeam ? 'team' : 'personal'} git repository + </Kb.Text> + <Kb.IconAuto + type={isTeam ? 'icon-repo-team-add-48' : 'icon-repo-personal-add-48'} + style={styles.marginBottom27} + /> + <Kb.Text type="Body" style={styles.marginBottom27}> + {isTeam + ? 'Your repository will be end-to-end encrypted and accessible by all members in the team.' + : 'Your repository will be encrypted and only accessible by you.'} + </Kb.Text> + {isTeam && ( + <Kb.Dropdown + items={makeDropdownItems()} + selected={makeDropdownItem(selectedTeam)} + onChangedIdx={dropdownChanged} + style={styles.dropdown} /> - <Kb.Text type="Body" style={{marginBottom: 27}}> - {isTeam - ? 'Your repository will be end-to-end encrypted and accessible by all members in the team.' - : 'Your repository will be encrypted and only accessible by you.'} - </Kb.Text> - {isTeam && ( - <Kb.Dropdown - items={makeDropdownItems()} - selected={makeDropdownItem(selectedTeam)} - onChangedIdx={dropdownChanged} - style={styles.dropdown} - /> - )} - <Kb.Input3 - value={name} - autoFocus={true} - onChangeText={setName} - placeholder="Name your repository" - onEnterKeyDown={onSubmit} + )} + <Kb.Input3 + value={name} + autoFocus={true} + onChangeText={setName} + placeholder="Name your repository" + onEnterKeyDown={onSubmit} + /> + {isTeam && ( + <Kb.Checkbox + label="Notify the team" + checked={notifyTeam} + onCheck={setNotifyTeam} + style={styles.checkbox} /> - {isTeam && ( - <Kb.Checkbox - label="Notify the team" - checked={notifyTeam} - onCheck={setNotifyTeam} - style={styles.checkbox} - /> - )} - <Kb.ButtonBar fullWidth={true} style={styles.buttonBar}> - <Kb.WaitingButton - type="Dim" - onClick={onClose} - label="Cancel" - waitingKey={waitingKey} - onlyDisable={true} - /> - <Kb.WaitingButton - onClick={onSubmit} - label="Create" - disabled={!canSubmit()} - waitingKey={waitingKey} - /> - </Kb.ButtonBar> - </Kb.Box2> - </Kb.ScrollView> - </> + )} + <Kb.ButtonBar fullWidth={true} style={styles.buttonBar}> + <Kb.WaitingButton + type="Dim" + onClick={navigateUp} + label="Cancel" + waitingKey={C.waitingKeyGitLoading} + onlyDisable={true} + /> + <Kb.WaitingButton + onClick={onSubmit} + label="Create" + disabled={!canSubmit()} + waitingKey={C.waitingKeyGitLoading} + /> + </Kb.ButtonBar> + </Kb.Box2> + </Kb.ScrollView> ) } const styles = Kb.Styles.styleSheetCreate( () => ({ - addIcon: {marginBottom: 27}, avatarBox: { paddingLeft: Kb.Styles.globalMargins.xsmall, paddingRight: Kb.Styles.globalMargins.small, @@ -225,16 +186,21 @@ const styles = Kb.Styles.styleSheetCreate( marginBottom: Kb.Styles.globalMargins.small, width: '100%', }, - dropdownItem: { - paddingLeft: Kb.Styles.globalMargins.xsmall, - }, - error: { - alignSelf: 'stretch', - backgroundColor: Kb.Styles.globalColors.red, - marginBottom: Kb.Styles.globalMargins.small, - padding: Kb.Styles.globalMargins.tiny, - }, + marginBottom27: {marginBottom: 27}, + newTeamItem: {paddingLeft: Kb.Styles.globalMargins.small}, + teamAvatar: {marginRight: Kb.Styles.globalMargins.tiny}, + teamName: Kb.Styles.platformStyles({ + common: { + overflow: 'hidden', + width: '100%', + }, + isElectron: { + display: 'block', + textOverflow: 'ellipsis', + whiteSpace: 'nowrap', + }, + }), }) as const ) -export default Container +export default NewRepo diff --git a/shared/git/row.tsx b/shared/git/row.tsx index b978267b4a57..508e738f16a9 100644 --- a/shared/git/row.tsx +++ b/shared/git/row.tsx @@ -106,14 +106,14 @@ function ConnectedRow(ownProps: OwnProps) { } const canEdit = canDelete && !!teamname - // TODO use ListItem return ( - <Kb.Box2 direction="vertical" fullWidth={true}> + <> <Kb.Box2 direction="vertical" fullWidth={true} style={styles.containerMobile}> <Kb.Box2 direction="vertical" fullWidth={true} alignItems="flex-start" + noShrink={true} style={Kb.Styles.collapseStyles([ styles.rowStyle, expanded && {backgroundColor: Kb.Styles.globalColors.white}, @@ -129,24 +129,24 @@ function ConnectedRow(ownProps: OwnProps) { styles.rowTop, ])} > - <Kb.Icon - type={expanded ? 'iconfont-caret-down' : 'iconfont-caret-right'} - style={styles.iconCaret} - sizeType="Tiny" - /> - <Kb.Avatar - size={isMobile ? 48 : 32} - isTeam={!!teamname} - teamname={teamname} - username={teamname ? undefined : you} - style={styles.iconTiny} - /> - <Kb.Text lineClamp={1} type="BodySemibold" style={{color: Kb.Styles.globalColors.black}}> - {teamname ? `${teamname}/${name}` : name} - </Kb.Text> - {isNew && ( - <Kb.Meta title="new" style={styles.meta} backgroundColor={Kb.Styles.globalColors.orange} /> - )} + <Kb.Icon + type={expanded ? 'iconfont-caret-down' : 'iconfont-caret-right'} + style={styles.iconCaret} + sizeType="Tiny" + /> + <Kb.Avatar + size={isMobile ? 48 : 32} + isTeam={!!teamname} + teamname={teamname} + username={teamname ? undefined : you} + style={styles.iconTiny} + /> + <Kb.Text lineClamp={1} type="BodySemibold" style={styles.repoName}> + {teamname ? `${teamname}/${name}` : name} + </Kb.Text> + {isNew && ( + <Kb.Meta title="new" style={styles.meta} backgroundColor={Kb.Styles.globalColors.orange} /> + )} </Kb.ClickableBox3> {expanded && ( <Kb.Box2 direction="vertical" fullWidth={true} style={styles.rowBottom}> @@ -155,13 +155,11 @@ function ConnectedRow(ownProps: OwnProps) { fullWidth={true} alignItems="center" relative={true} - style={{ - maxWidth: '100%', - }} + style={styles.cloneRow} > <Kb.Text type="Body">Clone:</Kb.Text> <Kb.Box2 direction="horizontal" style={styles.copyTextContainer}> - <Kb.CopyText text={gitURL} containerStyle={{width: '100%'}} /> + <Kb.CopyText text={gitURL} containerStyle={styles.copyTextWidth} /> </Kb.Box2> </Kb.Box2> <Kb.Box2 @@ -169,10 +167,7 @@ function ConnectedRow(ownProps: OwnProps) { fullWidth={true} alignItems="center" alignSelf="flex-start" - style={{ - flexWrap: 'wrap', - marginTop: Kb.Styles.globalMargins.tiny, - }} + style={styles.lastPushRow} > <Kb.Text type="BodySmall"> {`Last push ${lastEditTime}${!!teamname && !!lastEditUser ? ' by ' : ''}`} @@ -181,19 +176,18 @@ function ConnectedRow(ownProps: OwnProps) { <Kb.Avatar username={lastEditUser} size={16} - style={{marginLeft: isMobile ? 0 : 4}} + style={styles.lastEditAvatar} /> )} {!!teamname && !!lastEditUser && ( - <Kb.Box2 direction="vertical" style={{marginLeft: 2}}> - <Kb.ConnectedUsernames - type="BodySmallBold" - underline={true} - colorFollowing={true} - usernames={lastEditUser} - onUsernameClicked={() => openUserProfile(lastEditUser)} - /> - </Kb.Box2> + <Kb.ConnectedUsernames + type="BodySmallBold" + underline={true} + colorFollowing={true} + usernames={lastEditUser} + onUsernameClicked={() => openUserProfile(lastEditUser)} + containerStyle={styles.usernameContainer} + /> )} {isMobile && <Kb.Text type="BodySmall">. </Kb.Text>} <Kb.Text type="BodySmall"> @@ -241,7 +235,7 @@ function ConnectedRow(ownProps: OwnProps) { <Kb.Box2 direction="horizontal" fullWidth={true} - style={{marginTop: Kb.Styles.globalMargins.tiny}} + style={styles.actionRow} gap="tiny" > <Kb.Button @@ -291,13 +285,16 @@ function ConnectedRow(ownProps: OwnProps) { fullWidth={true} style={expanded ? styles.expandedSpacer : undefined} /> - </Kb.Box2> + </> ) } const styles = Kb.Styles.styleSheetCreate( () => ({ + actionRow: {marginTop: Kb.Styles.globalMargins.tiny}, + cloneRow: {maxWidth: '100%'}, + copyTextWidth: {width: '100%'}, containerMobile: Kb.Styles.platformStyles({ isMobile: { ...Kb.Styles.paddingH(Kb.Styles.globalMargins.small), @@ -319,6 +316,14 @@ const styles = Kb.Styles.styleSheetCreate( backgroundColor: Kb.Styles.globalColors.blueLighter3, height: 6, }, + lastEditAvatar: Kb.Styles.platformStyles({ + isElectron: {marginLeft: 4}, + }), + lastPushRow: { + flexWrap: 'wrap', + marginTop: Kb.Styles.globalMargins.tiny, + }, + repoName: {color: Kb.Styles.globalColors.black}, iconCaret: Kb.Styles.platformStyles({ common: { marginBottom: 2, @@ -345,8 +350,8 @@ const styles = Kb.Styles.styleSheetCreate( paddingTop: Kb.Styles.globalMargins.tiny, }, + usernameContainer: {marginLeft: 2}, rowStyle: { - flexShrink: 0, minHeight: Kb.Styles.globalMargins.large, paddingLeft: 0, }, diff --git a/shared/git/select-channel.tsx b/shared/git/select-channel.tsx index b79df5e68f8f..6f2c5b388fe7 100644 --- a/shared/git/select-channel.tsx +++ b/shared/git/select-channel.tsx @@ -1,9 +1,9 @@ -import {useSafeNavigation} from '@/util/safe-navigation' import * as Kb from '@/common-adapters' import * as React from 'react' import * as C from '@/constants' import * as T from '@/constants/types' import {useAllChannelMetas} from '../teams/common/channel-hooks' +import {useSafeNavigation} from '@/util/safe-navigation' type OwnProps = { teamID: T.Teams.TeamID @@ -21,7 +21,7 @@ const SelectChannel = (ownProps: OwnProps) => { const channelNames = [...channelMetas.values()].map(info => info.channelname) const [selected, setSelected] = React.useState(_selected) const [error, setError] = React.useState('') - const nav = useSafeNavigation() + const {safeNavigateUp} = useSafeNavigation() const setTeamRepoSettings = C.useRPC(T.RPCGen.gitSetTeamRepoSettingsRpcPromise) const onSubmit = (channelName: string) => setTeamRepoSettings( @@ -39,20 +39,19 @@ const SelectChannel = (ownProps: OwnProps) => { C.waitingKeyGitLoading, ], () => { - nav.safeNavigateUp() + safeNavigateUp() }, err => { setError(err.message) } ) - const onCancel = () => nav.safeNavigateUp() + const onCancel = () => C.Router2.navigateUp() const submit = () => { setError('') onSubmit(selected) } - // TODO: this modal could use a little bit of love return ( <Kb.Box2 direction="vertical" fullHeight={true} style={styles.container}> <Kb.ScrollView contentContainerStyle={styles.scrollContainer}> diff --git a/shared/incoming-share/index.tsx b/shared/incoming-share/index.tsx index 1eaf7f218382..482502b65682 100644 --- a/shared/incoming-share/index.tsx +++ b/shared/incoming-share/index.tsx @@ -29,14 +29,12 @@ export const OriginalOrCompressedButton = ({incomingShareItems}: IncomingSharePr .catch(() => {}) } - // If it's original only, set original in store. React.useEffect(() => { if (originalOnly) { setUseOriginalInStore(true) } }, [originalOnly, setUseOriginalInStore]) - // From service to store, but only if this is not original only. const getRPC = C.useRPC(T.RPCGen.incomingShareGetPreferenceRpcPromise) React.useEffect(() => { if (!originalOnly) { @@ -250,7 +248,7 @@ const IncomingShare = (props: IncomingShareWithSelectionProps) => { return ( <> <Kb.Box2 direction="vertical" fullWidth={true} fullHeight={true}> - <Kb.Box2 direction="vertical" fullWidth={true} style={Kb.Styles.globalStyles.flexOne}> + <Kb.Box2 direction="vertical" fullWidth={true} flex={1}> <MobileSendToChat isFromShareExtension={true} sendPaths={sendPaths} text={text} /> </Kb.Box2> </Kb.Box2> @@ -288,7 +286,6 @@ const useIncomingShareItems = () => { >([]) const [incomingShareError, setIncomingShareError] = React.useState<unknown>(undefined) - // iOS const rpc = C.useRPC(T.RPCGen.incomingShareGetIncomingShareItemsRpcPromise) React.useEffect(() => { if (!isIOS) { @@ -302,7 +299,6 @@ const useIncomingShareItems = () => { ) }, [rpc, setIncomingShareError, setIncomingShareItems]) - // Android const androidShare = useConfigState(s => s.androidShare) const androidShareItems = isAndroid && androidShare diff --git a/shared/login/forms/container.tsx b/shared/login/forms/container.tsx index 883fc430a21c..3cd73310ad7a 100644 --- a/shared/login/forms/container.tsx +++ b/shared/login/forms/container.tsx @@ -2,7 +2,6 @@ import type * as React from 'react' import * as Kb from '@/common-adapters' type Props = { - onBack?: () => void children?: React.ReactNode style?: Kb.Styles.StylesCrossPlatform outerStyle?: Kb.Styles.StylesCrossPlatform diff --git a/shared/login/join-or-login.tsx b/shared/login/join-or-login.tsx index 7688aab82166..0ff57906eb7f 100644 --- a/shared/login/join-or-login.tsx +++ b/shared/login/join-or-login.tsx @@ -17,22 +17,15 @@ const Intro = () => { const isOnline = useConfigState(s => s.isOnline) const loadIsOnline = useConfigState(s => s.dispatch.loadIsOnline) - - const navigateAppend = C.Router2.navigateAppend - const checkIsOnline = loadIsOnline const startProvision = useProvisionState(s => s.dispatch.startProvision) - const onLogin = () => { - startProvision() - } const requestAutoInvite = useRequestAutoInvite() - const onSignup = () => { - requestAutoInvite() - } + const onLogin = () => startProvision() + const onSignup = () => requestAutoInvite() const showProxySettings = () => { - navigateAppend({name: 'proxySettingsModal', params: {}}) + C.Router2.navigateAppend({name: 'proxySettingsModal', params: {}}) } const [showing, setShowing] = React.useState(true) - Kb.useInterval(checkIsOnline, showing ? 5000 : undefined) + Kb.useInterval(loadIsOnline, showing ? 5000 : undefined) C.Router2.useSafeFocusEffect(() => { setShowing(true) diff --git a/shared/login/loading.tsx b/shared/login/loading.tsx index e4dcf75204b5..4310fa3d4a3e 100644 --- a/shared/login/loading.tsx +++ b/shared/login/loading.tsx @@ -7,8 +7,6 @@ const SplashContainer = () => { const failedReason = useDaemonState(s => s.handshakeFailedReason) const retriesLeft = useDaemonState(s => s.handshakeRetriesLeft) const startHandshake = useDaemonState(s => s.dispatch.startHandshake) - const navigateAppend = C.Router2.navigateAppend - let status = '' let failed = '' @@ -25,7 +23,7 @@ const SplashContainer = () => { const onFeedback = isMobile ? () => { - navigateAppend({name: 'feedback', params: {}}) + C.Router2.navigateAppend({name: 'feedback', params: {}}) } : undefined const onRetry = retriesLeft === 0 ? startHandshake : undefined @@ -52,7 +50,7 @@ export const Splash = (p: SplashProps) => { }, []) return ( - <Kb.Box2 direction="vertical" fullWidth={true} fullHeight={true} justifyContent="center" style={styles.container} gap="small"> + <Kb.Box2 direction="vertical" fullWidth={true} fullHeight={true} justifyContent="center" alignItems="center" gap="small"> <Kb.ImageIcon type={onRetry ? 'icon-keybase-logo-logged-out-80' : 'icon-keybase-logo-80'} /> <Kb.ImageIcon type="icon-keybase-wordmark-128-48" /> {!!status && <Kb.Text type="BodySmall">{status}</Kb.Text>} @@ -87,11 +85,4 @@ const Feedback = ({onFeedback}: {onFeedback?: () => void}) => </Kb.Text> ) -const styles = Kb.Styles.styleSheetCreate( - () => - ({ - container: {alignItems: 'center'}, - }) as const -) - export default SplashContainer diff --git a/shared/login/recover-password/device-selector.tsx b/shared/login/recover-password/device-selector.tsx index 6f0ad7c36000..f8bd65e443be 100644 --- a/shared/login/recover-password/device-selector.tsx +++ b/shared/login/recover-password/device-selector.tsx @@ -10,23 +10,15 @@ type Props = {route: {params: {devices: ReadonlyArray<Device>}}} const RecoverPasswordDeviceSelector = ({route}: Props) => { const {devices} = route.params - const onBack = () => { - cancelRecoverPassword() - } - const onResetAccount = () => { - submitRecoverPasswordNoDevice() - } - const onSelect = (name: string) => { - submitRecoverPasswordDeviceSelect(devices.find(device => device.name === name)?.id) - } - const props = { - devices, - onBack, - onResetAccount, - onSelect, - passwordRecovery: true, - } - return <SelectOtherDevice {...props} /> + return ( + <SelectOtherDevice + devices={devices} + onBack={cancelRecoverPassword} + onResetAccount={submitRecoverPasswordNoDevice} + onSelect={(name: string) => submitRecoverPasswordDeviceSelect(devices.find(d => d.name === name)?.id)} + passwordRecovery={true} + /> + ) } export default RecoverPasswordDeviceSelector diff --git a/shared/login/recover-password/error-modal.tsx b/shared/login/recover-password/error-modal.tsx index f9ed4051e39f..cfad4663d846 100644 --- a/shared/login/recover-password/error-modal.tsx +++ b/shared/login/recover-password/error-modal.tsx @@ -22,13 +22,11 @@ type Props = {route: {params: {error: string}}} const ConnectedErrorModal = ({route}: Props) => { const loggedIn = useConfigState(s => s.loggedIn) const {error} = route.params - const popStack = C.Router2.popStack - const navigateUp = C.Router2.navigateUp const onBack = () => { if (loggedIn) { - navigateUp() + C.Router2.navigateUp() } else { - popStack() + C.Router2.popStack() } } diff --git a/shared/login/recover-password/error.tsx b/shared/login/recover-password/error.tsx index 370181f9d9db..10773ce68bf4 100644 --- a/shared/login/recover-password/error.tsx +++ b/shared/login/recover-password/error.tsx @@ -9,13 +9,11 @@ type Props = {route: {params: {error: string}}} const ConnectedError = ({route}: Props) => { const loggedIn = useConfigState(s => s.loggedIn) const {error} = route.params - const popStack = C.Router2.popStack - const navigateUp = C.Router2.navigateUp const onBack = () => { if (loggedIn) { - navigateUp() + C.Router2.navigateUp() } else { - popStack() + C.Router2.popStack() } } return ( diff --git a/shared/login/recover-password/explain-device.tsx b/shared/login/recover-password/explain-device.tsx index e918de4a0cee..b93a45ce4f62 100644 --- a/shared/login/recover-password/explain-device.tsx +++ b/shared/login/recover-password/explain-device.tsx @@ -15,9 +15,8 @@ const ConnectedExplainDevice = ({route}: Props) => { username, }) } - const navigateUp = C.Router2.navigateUp const onComplete = () => { - navigateUp() + C.Router2.navigateUp() } const explainingMobile = deviceType === T.RPCGen.DeviceType.mobile diff --git a/shared/login/recover-password/paper-key.tsx b/shared/login/recover-password/paper-key.tsx index ae75829bbdb3..cd298a63f243 100644 --- a/shared/login/recover-password/paper-key.tsx +++ b/shared/login/recover-password/paper-key.tsx @@ -45,20 +45,18 @@ const PaperKey = ({route}: Props) => { <Kb.Box2 direction="vertical" gap="tiny" centerChildren={true} gapEnd={true}> <Kb.ImageIcon type="icon-paper-key-96" /> </Kb.Box2> - <Kb.Box2 direction="vertical" style={styles.inputContainer} fullWidth={true}> - <Kb.Input3 - autoFocus={true} - multiline={true} - rowsMax={3} - placeholder="Type your paper key" - textType="Header" - containerStyle={styles.inputContainer2} - inputStyle={styles.inputText} - onEnterKeyDown={onSubmit} - onChangeText={paperKey => setPaperKey(paperKey)} - value={paperKey} - /> - </Kb.Box2> + <Kb.Input3 + autoFocus={true} + multiline={true} + rowsMax={3} + placeholder="Type your paper key" + textType="Header" + containerStyle={styles.inputContainer2} + inputStyle={styles.inputText} + onEnterKeyDown={onSubmit} + onChangeText={paperKey => setPaperKey(paperKey)} + value={paperKey} + /> {!!error && <Kb.Text type="BodySmallError">{error}</Kb.Text>} </Kb.Box2> </Kb.Box2> @@ -71,9 +69,6 @@ const styles = Kb.Styles.styleSheetCreate(() => ({ maxWidth: isMobile ? '100%' : 460, width: '100%', }, - inputContainer: { - width: '100%', - }, inputContainer2: { marginTop: 10, }, diff --git a/shared/login/relogin/container.tsx b/shared/login/relogin/container.tsx index 4a9644f927ca..4b02227555e5 100644 --- a/shared/login/relogin/container.tsx +++ b/shared/login/relogin/container.tsx @@ -13,16 +13,11 @@ const ReloginContainer = () => { const _users = useConfigState(s => s.configuredAccounts) const perror = useConfigState(s => s.loginError) const pselectedUser = useConfigState(s => s.defaultUsername) - const onForgotPassword = (username: string) => { - startRecoverPassword({username}) - } - const navigateAppend = C.Router2.navigateAppend const onFeedback = () => { - navigateAppend({name: 'signupSendFeedbackLoggedOut', params: {}}) + C.Router2.navigateAppend({name: 'signupSendFeedbackLoggedOut', params: {}}) } const onLogin = useConfigState(s => s.dispatch.login) - const requestAutoInvite = useRequestAutoInvite() - const onSignup = () => requestAutoInvite() + const onSignup = useRequestAutoInvite() const onSomeoneElse = useProvisionState(s => s.dispatch.startProvision) const error = perror?.desc || '' const loggedInMap = new Map<string, boolean>(_users.map(account => [account.username, account.hasStoredSecret])) @@ -85,7 +80,7 @@ const ReloginContainer = () => { error={error} needPassword={!loggedInMap.get(selectedUser) || gotNeedPasswordError} onFeedback={onFeedback} - onForgotPassword={() => onForgotPassword(selectedUser)} + onForgotPassword={() => startRecoverPassword({username: selectedUser})} onLogin={onLogin} onSignup={onSignup} onSomeoneElse={onSomeoneElse} diff --git a/shared/login/reset/password-enter.tsx b/shared/login/reset/password-enter.tsx index 158a9cb8cb4a..ec498f81b5e7 100644 --- a/shared/login/reset/password-enter.tsx +++ b/shared/login/reset/password-enter.tsx @@ -38,16 +38,14 @@ const EnterPassword = ({route}: Props) => { } buttons={[{label: 'Continue', onClick: onContinue, waiting}]} > - <Kb.Box2 direction="vertical" fullWidth={true}> - <Kb.Input3 - placeholder="Enter your password" - containerStyle={styles.input} - secureTextEntry={true} - onChangeText={setPassword} - onEnterKeyDown={onContinue} - autoFocus={true} - /> - </Kb.Box2> + <Kb.Input3 + placeholder="Enter your password" + containerStyle={styles.input} + secureTextEntry={true} + onChangeText={setPassword} + onEnterKeyDown={onContinue} + autoFocus={true} + /> </SignupScreen> ) } diff --git a/shared/login/signup/common.tsx b/shared/login/signup/common.tsx index 38129f534c12..96bfa4565eaa 100644 --- a/shared/login/signup/common.tsx +++ b/shared/login/signup/common.tsx @@ -8,17 +8,15 @@ type Props = { } export const Wrapper = (props: Props) => ( - <Kb.Box2 direction="vertical" fullWidth={true} fullHeight={true}> - <Kb.Box2 - direction="vertical" - fullWidth={true} - fullHeight={true} - centerChildren={true} - style={styles.wrapper} - gap={isMobile ? 'xtiny' : 'small'} - > - {props.children} - </Kb.Box2> + <Kb.Box2 + direction="vertical" + fullWidth={true} + fullHeight={true} + centerChildren={true} + style={styles.wrapper} + gap={isMobile ? 'xtiny' : 'small'} + > + {props.children} </Kb.Box2> ) diff --git a/shared/menubar/index.desktop.tsx b/shared/menubar/index.desktop.tsx index 3d70402e3829..2023adaaa12a 100644 --- a/shared/menubar/index.desktop.tsx +++ b/shared/menubar/index.desktop.tsx @@ -313,40 +313,40 @@ const useMenuItems = ( const startingUp = daemonHandshakeState !== 'done' const common = [ - {onClick: () => { void openUrl(`https://keybase.io/${username || ''}`) }, title: 'Keybase.io'}, - { - onClick: () => { - const version = __VERSION__ - void openUrl( - `https://github.com/keybase/client/issues/new?body=Keybase%20GUI%20Version:%20${encodeURIComponent(version)}` - ) - }, - title: 'Report a bug', + {onClick: () => { void openUrl(`https://keybase.io/${username || ''}`) }, title: 'Keybase.io'}, + { + onClick: () => { + const version = __VERSION__ + void openUrl( + `https://github.com/keybase/client/issues/new?body=Keybase%20GUI%20Version:%20${encodeURIComponent(version)}` + ) }, - { - onClick: () => { - void openUrl('https://keybase.io/docs') - hideWindow?.() - }, - title: 'Help', + title: 'Report a bug', + }, + { + onClick: () => { + void openUrl('https://keybase.io/docs') + hideWindow?.() }, - { - onClick: () => { - if (!__DEV__) { - if (isLinux) { - R.remoteDispatch(RemoteGen.createStop({exitCode: T.RPCGen.ExitCode.ok})) - } else { - R.remoteDispatch(RemoteGen.createDumpLogs({reason: 'quitting through menu'})) - } + title: 'Help', + }, + { + onClick: () => { + if (!__DEV__) { + if (isLinux) { + R.remoteDispatch(RemoteGen.createStop({exitCode: T.RPCGen.ExitCode.ok})) + } else { + R.remoteDispatch(RemoteGen.createDumpLogs({reason: 'quitting through menu'})) } - hideWindow?.() - setTimeout(() => { - ctlQuit?.() - }, 2000) - }, - title: 'Quit Keybase', + } + hideWindow?.() + setTimeout(() => { + ctlQuit?.() + }, 2000) }, - ] + title: 'Quit Keybase', + }, + ] if (startingUp) { return common @@ -356,36 +356,36 @@ const useMenuItems = ( if (showBadges) { return [ - { - onClick: () => openApp(C.Tabs.gitTab), - title: 'Git', - view: <TabView title="Git" iconType="iconfont-nav-2-git" count={navBadges[C.Tabs.gitTab]} />, - }, - { - onClick: () => openApp(C.Tabs.devicesTab), - title: 'Devices', - view: <TabView title="Devices" iconType="iconfont-nav-2-devices" count={navBadges[C.Tabs.devicesTab]} />, - }, - { - onClick: () => openApp(C.Tabs.settingsTab), - title: 'Settings', - view: <TabView title="Settings" iconType="iconfont-nav-2-settings" count={navBadges[C.Tabs.settingsTab]} />, - }, - 'Divider' as const, - ...openAppItem, - ...(kbfsEnabled - ? ([ - { - onClick: () => { - R.remoteDispatch(RemoteGen.createOpenPathInSystemFileManager({path: '/keybase'})) - }, - title: `Open folders in ${Kb.Styles.fileUIName}`, + { + onClick: () => openApp(C.Tabs.gitTab), + title: 'Git', + view: <TabView title="Git" iconType="iconfont-nav-2-git" count={navBadges[C.Tabs.gitTab]} />, + }, + { + onClick: () => openApp(C.Tabs.devicesTab), + title: 'Devices', + view: <TabView title="Devices" iconType="iconfont-nav-2-devices" count={navBadges[C.Tabs.devicesTab]} />, + }, + { + onClick: () => openApp(C.Tabs.settingsTab), + title: 'Settings', + view: <TabView title="Settings" iconType="iconfont-nav-2-settings" count={navBadges[C.Tabs.settingsTab]} />, + }, + 'Divider' as const, + ...openAppItem, + ...(kbfsEnabled + ? ([ + { + onClick: () => { + R.remoteDispatch(RemoteGen.createOpenPathInSystemFileManager({path: '/keybase'})) }, - 'Divider', - ] as const) - : []), - ...common, - ] as const + title: `Open folders in ${Kb.Styles.fileUIName}`, + }, + 'Divider', + ] as const) + : []), + ...common, + ] as const } return [...openAppItem, ...common] as const } @@ -435,16 +435,14 @@ const IconBar = (p: Props & {showBadges?: boolean}) => { )) : null} </Kb.Box2> - <Kb.Box2 direction="vertical" style={styles.hamburgerContainer}> - <Kb.Box2 direction="vertical" ref={popupAnchor}> - <Kb.Icon - color={isDarkMode ? Kb.Styles.globalColors.black_50OrBlack_60 : Kb.Styles.globalColors.blueDarker} - hoverColor={Kb.Styles.globalColors.whiteOrWhite} - onClick={showPopup} - type="iconfont-nav-2-hamburger" - sizeType="Big" - /> - </Kb.Box2> + <Kb.Box2 direction="vertical" ref={popupAnchor} style={styles.hamburgerContainer}> + <Kb.Icon + color={isDarkMode ? Kb.Styles.globalColors.black_50OrBlack_60 : Kb.Styles.globalColors.blueDarker} + hoverColor={Kb.Styles.globalColors.whiteOrWhite} + onClick={showPopup} + type="iconfont-nav-2-hamburger" + sizeType="Big" + /> {!!badgeCountInMenu && <Kb.Badge badgeNumber={badgeCountInMenu} badgeStyle={styles.badge} />} </Kb.Box2> {popup} diff --git a/shared/people/announcement.tsx b/shared/people/announcement.tsx index 92c185ca4821..a3bbb3164a05 100644 --- a/shared/people/announcement.tsx +++ b/shared/people/announcement.tsx @@ -18,9 +18,9 @@ type OwnProps = { url?: string } -const Container = (ownProps: OwnProps) => { +const Announcement = (props: OwnProps) => { const {appLink, badged, confirmLabel, dismissAnnouncement, dismissable, getData, iconUrl, id, text, url} = - ownProps + props const {navigateAppend, switchTab, navigateToInbox} = C.Router2 const onConfirm = () => { if (url) { @@ -68,11 +68,12 @@ const Container = (ownProps: OwnProps) => { dismissAnnouncement(id) getData(true, true) } - const _onDismiss = () => { - dismissAnnouncement(id) - getData(true, true) - } - const onDismiss = dismissable ? _onDismiss : undefined + const onDismiss = dismissable + ? () => { + dismissAnnouncement(id) + getData(true, true) + } + : undefined return ( <PeopleItem @@ -104,4 +105,4 @@ const styles = Kb.Styles.styleSheetCreate( }) as const ) -export default Container +export default Announcement diff --git a/shared/people/container.tsx b/shared/people/container.tsx index d1854766d417..a300fc79f578 100644 --- a/shared/people/container.tsx +++ b/shared/people/container.tsx @@ -470,7 +470,6 @@ const PeopleReloadable = () => { signupEmail={signupEmail} skipTodo={skipTodo} waiting={waiting} - // wotUpdates={wotUpdates} /> </Kb.Reloadable> ) diff --git a/shared/people/follow-notification.tsx b/shared/people/follow-notification.tsx index 4d7e6f1d7717..2d7107a211f2 100644 --- a/shared/people/follow-notification.tsx +++ b/shared/people/follow-notification.tsx @@ -3,6 +3,8 @@ import type * as T from '@/constants/types' import * as Kb from '@/common-adapters' import {FollowButton} from '@/settings/contacts-joined' +const horizontalScrollProps = isMobile ? ({alwaysBounceHorizontal: false, horizontal: true} as const) : {} + const connectedUsernamesProps = { colorFollowing: true, inline: true, @@ -109,7 +111,7 @@ function MultiFollowNotification(props: Props) { </Kb.Text> )} <Kb.ScrollView - {...(isMobile ? {alwaysBounceHorizontal: false, horizontal: true} : {})} // Causes error on desktop + {...horizontalScrollProps} contentContainerStyle={styles.scrollViewContainer} > {usernames.map(username => ( diff --git a/shared/people/follow-suggestions.tsx b/shared/people/follow-suggestions.tsx index 8fa3fbdbcd66..d8dbde5bdc3b 100644 --- a/shared/people/follow-suggestions.tsx +++ b/shared/people/follow-suggestions.tsx @@ -1,6 +1,8 @@ import type * as T from '@/constants/types' import * as Kb from '@/common-adapters' +const horizontalScrollProps = isMobile ? ({alwaysBounceHorizontal: false, horizontal: true} as const) : {} + export type FollowSuggestion = T.People.FollowSuggestion export type Props = { @@ -13,7 +15,7 @@ const FollowSuggestions = (props: Props) => ( Consider following... </Kb.Text> <Kb.ScrollView - {...(isMobile ? {alwaysBounceHorizontal: false, horizontal: true} : {})} // Causes error on desktop + {...horizontalScrollProps} contentContainerStyle={styles.scrollViewContainer} > {props.suggestions.map(suggestion => ( diff --git a/shared/people/index.tsx b/shared/people/index.tsx index 54f55f57f03c..cec604bb1746 100644 --- a/shared/people/index.tsx +++ b/shared/people/index.tsx @@ -17,7 +17,6 @@ type Props = { oldItems: T.Immutable<Array<T.People.PeopleScreenItem>> newItems: T.Immutable<Array<T.People.PeopleScreenItem>> onClickUser: (username: string) => void - onOpenAccountSwitcher?: () => void resentEmail: string setResentEmail: (email: string) => void signupEmail: string @@ -79,14 +78,6 @@ const renderPeopleItem = (item: T.Immutable<T.People.PeopleScreenItem>, props: P const shouldRenderNewItem = (item: T.Immutable<T.People.PeopleScreenItem>, signupEmail: string) => item.type !== 'todo' || item.todoType !== 'verifyAllEmail' || !signupEmail -const PeopleItems = ({ - items, - props, -}: { - items: ReadonlyArray<T.Immutable<T.People.PeopleScreenItem>> - props: Props -}): Array<React.ReactNode> => items.map((item): React.ReactNode => renderPeopleItem(item, props)) - function EmailVerificationBanner(props: {signupEmail: string}) { const {signupEmail} = props React.useEffect( @@ -141,25 +132,15 @@ function ResentEmailVerificationBanner(props: { } function PeoplePageList(props: Props) { -const visibleNewItems = props.newItems.filter(item => shouldRenderNewItem(item, props.signupEmail)) + const visibleNewItems = props.newItems.filter(item => shouldRenderNewItem(item, props.signupEmail)) return ( <Kb.Box2 direction="vertical" fullWidth={true} relative={true} testID={TestIDs.PEOPLE_FEED}> <EmailVerificationBanner signupEmail={props.signupEmail} /> <ResentEmailVerificationBanner resentEmail={props.resentEmail} setResentEmail={props.setResentEmail} /> - <PeopleItems items={visibleNewItems} props={props} /> - {/*Array.from(props.wotUpdates, ([key, item]) => ( - <WotTask - key={key} - voucher={item.voucher} - vouchee={item.vouchee} - status={item.status} - onClickUser={props.onClickUser} - /> - ))*/} - + {visibleNewItems.map((item): React.ReactNode => renderPeopleItem(item, props))} <FollowSuggestions suggestions={props.followSuggestions} /> - <PeopleItems items={props.oldItems} props={props} /> + {props.oldItems.map((item): React.ReactNode => renderPeopleItem(item, props))} </Kb.Box2> ) } diff --git a/shared/people/item.tsx b/shared/people/item.tsx index d220139e9487..28973240b9e7 100644 --- a/shared/people/item.tsx +++ b/shared/people/item.tsx @@ -34,6 +34,7 @@ const PeopleItem = (props: Props) => ( <Kb.Box2 direction="vertical" + flex={1} gap="xtiny" style={Kb.Styles.collapseStyles([styles.childrenContainer, props.contentStyle])} > @@ -78,7 +79,6 @@ const styles = Kb.Styles.styleSheetCreate(() => ({ }, button: {marginBottom: Kb.Styles.globalMargins.xtiny, marginRight: Kb.Styles.globalMargins.tiny}, childrenContainer: { - flex: 1, overflow: 'hidden', position: 'relative', width: 'auto', diff --git a/shared/people/routes.tsx b/shared/people/routes.tsx index 1fec36744521..5173c5bfb1fb 100644 --- a/shared/people/routes.tsx +++ b/shared/people/routes.tsx @@ -30,13 +30,17 @@ const AccountSignOutButton = () => { <Kb.Text type="BodyBigLink" onClick={() => navigateAppend({name: settingsLogOutTab, params: {}})} - style={{color: Kb.Styles.globalColors.red, padding: 8}} + style={styles.signOut} > Sign out </Kb.Text> ) } +const styles = Kb.Styles.styleSheetCreate(() => ({ + signOut: {color: Kb.Styles.globalColors.red, padding: 8}, +})) + export const newModalRoutes = defineRouteMap({ accountSwitcher: { getOptions: {headerRight: () => <AccountSignOutButton />}, diff --git a/shared/people/todo.tsx b/shared/people/todo.tsx index 2783104ceeb5..2845e33365ea 100644 --- a/shared/people/todo.tsx +++ b/shared/people/todo.tsx @@ -12,28 +12,6 @@ import {useCurrentUserState} from '@/stores/current-user' import {navToProfile} from '@/constants/router' import {makeNewTeamWizard} from '@/teams/new-team/wizard/state' -const todoTypes: {[K in T.People.TodoType]: T.People.TodoType} = { - addEmail: 'addEmail', - addPhoneNumber: 'addPhoneNumber', - annoncementPlaceholder: 'annoncementPlaceholder', // misspelled in protocol - avatarTeam: 'avatarTeam', - avatarUser: 'avatarUser', - bio: 'bio', - chat: 'chat', - device: 'device', - folder: 'folder', - follow: 'follow', - gitRepo: 'gitRepo', - legacyEmailVisibility: 'legacyEmailVisibility', - none: 'none', - paperkey: 'paperkey', - proof: 'proof', - team: 'team', - teamShowcase: 'teamShowcase', - verifyAllEmail: 'verifyAllEmail', - verifyAllPhoneNumber: 'verifyAllPhoneNumber', -} - type TodoOwnProps = { badged: boolean confirmLabel: string @@ -74,8 +52,6 @@ function makeDefaultButtons( return result } -const useRouterNavigation = () => C.Router2 - type BasicTaskProps = TodoOwnProps & { dismissLabel?: string dismissTodoType?: T.People.TodoType @@ -115,7 +91,7 @@ const SettingsAccountTask = ({ dismissTodoType, ...props }: SettingsAccountTaskProps) => { - const {navigateAppend, switchTab} = useRouterNavigation() + const {navigateAppend, switchTab} = C.Router2 const onConfirm = () => { switchTab(C.Tabs.settingsTab) navigateAppend({name: settingsAccountTab, params: {}}) @@ -186,7 +162,7 @@ const TeamTask = (props: TodoOwnProps) => { } const GitRepoTask = (props: TodoOwnProps) => { - const {navigateAppend, switchTab} = useRouterNavigation() + const {navigateAppend, switchTab} = C.Router2 const onConfirm = (isTeam: boolean) => { if (isMobile) { navigateAppend({name: settingsGitTab, params: {}}) @@ -219,7 +195,7 @@ const VerifyAllEmailTask = (props: TodoOwnProps) => { const onConfirm = (email: string) => { editEmail({email, onSuccess: () => props.setResentEmail(email), verify: true}) } - const {navigateAppend, switchTab} = useRouterNavigation() + const {navigateAppend, switchTab} = C.Router2 const onManage = () => { switchTab(C.Tabs.settingsTab) navigateAppend({name: settingsAccountTab, params: {}}) @@ -251,7 +227,7 @@ const VerifyAllEmailTask = (props: TodoOwnProps) => { } const VerifyAllPhoneNumberTask = (props: TodoOwnProps) => { - const {navigateAppend, switchTab} = useRouterNavigation() + const {navigateAppend, switchTab} = C.Router2 const onConfirm = (phoneNumber: string) => { navigateAppend({name: 'settingsVerifyPhone', params: {initialResend: true, phoneNumber}}) } @@ -285,7 +261,7 @@ const VerifyAllPhoneNumberTask = (props: TodoOwnProps) => { const LegacyEmailVisibilityTask = (props: TodoOwnProps) => { const editEmail = useSettingsEmailState(s => s.dispatch.editEmail) - const {navigateAppend, switchTab} = useRouterNavigation() + const {navigateAppend, switchTab} = C.Router2 const onConfirm = (email: string) => { switchTab(C.Tabs.settingsTab) navigateAppend({name: settingsAccountTab, params: {}}) @@ -319,41 +295,41 @@ const LegacyEmailVisibilityTask = (props: TodoOwnProps) => { const TaskChooser = (props: TodoOwnProps) => { switch (props.todoType) { - case todoTypes.addEmail: + case 'addEmail': return <SettingsAccountTask {...props} dismissTodoType="addEmail" destination="settingsAddEmail" /> - case todoTypes.addPhoneNumber: + case 'addPhoneNumber': return ( <SettingsAccountTask {...props} dismissTodoType="addPhoneNumber" destination="settingsAddPhone" /> ) - case todoTypes.avatarTeam: + case 'avatarTeam': return <SwitchTabTask {...props} tab={C.Tabs.teamsTab} /> - case todoTypes.avatarUser: + case 'avatarUser': return <AvatarUserTask {...props} /> - case todoTypes.bio: + case 'bio': return <BioTask {...props} /> - case todoTypes.proof: + case 'proof': return <ProofTask {...props} /> - case todoTypes.device: + case 'device': return <OpenURLTask {...props} dismissTodoType="device" url={installLinkURL} /> - case todoTypes.follow: + case 'follow': return <FollowTask {...props} /> - case todoTypes.chat: + case 'chat': return <SwitchTabTask {...props} dismissTodoType="chat" tab={C.Tabs.chatTab} /> - case todoTypes.paperkey: + case 'paperkey': return <PaperKeyTask {...props} /> - case todoTypes.team: + case 'team': return <TeamTask {...props} /> - case todoTypes.folder: + case 'folder': return <SwitchTabTask {...props} dismissTodoType="folder" tab={C.Tabs.fsTab} /> - case todoTypes.gitRepo: + case 'gitRepo': return <GitRepoTask {...props} /> - case todoTypes.legacyEmailVisibility: + case 'legacyEmailVisibility': return <LegacyEmailVisibilityTask {...props} /> - case todoTypes.teamShowcase: + case 'teamShowcase': return <SwitchTabTask {...props} dismissTodoType="teamShowcase" tab={C.Tabs.teamsTab} /> - case todoTypes.verifyAllEmail: + case 'verifyAllEmail': return <VerifyAllEmailTask {...props} /> - case todoTypes.verifyAllPhoneNumber: + case 'verifyAllPhoneNumber': return <VerifyAllPhoneNumberTask {...props} /> default: return null diff --git a/shared/pinentry/index.desktop.tsx b/shared/pinentry/index.desktop.tsx index d817690be95c..e1add448c948 100644 --- a/shared/pinentry/index.desktop.tsx +++ b/shared/pinentry/index.desktop.tsx @@ -26,10 +26,6 @@ const Pinentry = (props: Props) => { } }, [_showTyping]) - const handleCheck = (showTyping: boolean) => { - setShowTyping(showTyping) - } - const handleSubmit = () => { onSubmit(password) setPassword('') @@ -40,11 +36,11 @@ const Pinentry = (props: Props) => { return ( <Kb.Box2 direction="vertical" fullWidth={true} style={styles.container}> <DragHeader icon={false} title="" onClose={props.onCancel} windowDragging={true} /> - <Kb.Box2 direction="vertical" fullWidth={true} style={{...Kb.Styles.paddingH(30)}}> + <Kb.Box2 direction="vertical" fullWidth={true} style={styles.inner}> <Kb.Text type="Body" center={true}> {props.prompt} </Kb.Text> - {isPaperKey && <Kb.ImageIcon type="icon-paper-key-48" style={{alignSelf: 'center'}} />} + {isPaperKey && <Kb.ImageIcon type="icon-paper-key-48" style={styles.paperKeyIcon} />} <Kb.Box2 alignSelf="center" direction="vertical" @@ -72,13 +68,13 @@ const Pinentry = (props: Props) => { <Kb.Checkbox checked={showTyping} label={props.showTyping.label} - onCheck={handleCheck} + onCheck={setShowTyping} style={styles.alignment} /> )} </Kb.Box2> <Kb.Button - style={{alignSelf: 'center'}} + style={styles.button} label={props.submitLabel ?? 'Continue'} onClick={handleSubmit} disabled={!password} @@ -90,11 +86,14 @@ const Pinentry = (props: Props) => { const styles = Kb.Styles.styleSheetCreate(() => ({ alignment: {marginLeft: Kb.Styles.globalMargins.xsmall}, + button: {alignSelf: 'center' as const}, container: { backgroundColor: Kb.Styles.globalColors.white, paddingBottom: Kb.Styles.globalMargins.medium, }, + inner: {...Kb.Styles.paddingH(30)}, inputContainer: {maxWidth: 428}, + paperKeyIcon: {alignSelf: 'center' as const}, })) export default Pinentry diff --git a/shared/profile/add-to-team.tsx b/shared/profile/add-to-team.tsx index 207d5d2888a0..c0f13276c0bd 100644 --- a/shared/profile/add-to-team.tsx +++ b/shared/profile/add-to-team.tsx @@ -52,10 +52,6 @@ const makeAddUserToTeamsResult = ( } type OwnProps = {username: string} -const Container = (ownProps: OwnProps) => { - const {username} = ownProps - return <AddToTeam key={username} username={username} /> -} const AddToTeam = (ownProps: OwnProps) => { const {username: them} = ownProps @@ -213,19 +209,12 @@ const AddToTeam = (ownProps: OwnProps) => { setRolePickerOpen(false) setSelectedRole(role) } - const footerComponent = ( - <> - {sendNotificationFooter('Announce them in team chats', sendNotification, nextVal => - setSendNotification(nextVal) - )} - </> - ) - - const isRolePickerOpen = rolePickerOpen const onCancelRolePicker = () => { setRolePickerOpen(false) } - const onToggle = toggleTeamSelected + const footerComponent = sendNotificationFooter('Announce them in team chats', sendNotification, nextVal => + setSendNotification(nextVal) + ) const selectedTeamCount = selectedTeams.size @@ -246,20 +235,12 @@ const AddToTeam = (ownProps: OwnProps) => { )} <Kb.Box2 direction="horizontal"> <Kb.Text type="Header">Add</Kb.Text> - <Kb.Avatar - isTeam={false} - size={16} - style={{ - marginLeft: isMobile ? Kb.Styles.globalMargins.xxtiny : Kb.Styles.globalMargins.tiny, - marginRight: Kb.Styles.globalMargins.tiny, - }} - username={them} - /> + <Kb.Avatar isTeam={false} size={16} style={styles.headerAvatar} username={them} /> <Kb.Text type="Header">{them} to...</Kb.Text> </Kb.Box2> - <Kb.BoxGrow style={{width: '100%'}}> + <Kb.BoxGrow style={styles.boxGrow}> <Kb.ScrollView style={Kb.Styles.size('100%')}> - <Kb.Box2 direction="vertical" style={{flexShrink: 1, width: '100%'}}> + <Kb.Box2 direction="vertical" style={styles.teamListInner}> {!waiting ? ( teamProfileAddList.length > 0 ? ( teamProfileAddList.map(team => ( @@ -271,7 +252,7 @@ const AddToTeam = (ownProps: OwnProps) => { name={team.teamName} isOpen={team.open} onCheck={selected => { - onToggle(team.teamName, selected) + toggleTeamSelected(team.teamName, selected) }} them={them} /> @@ -288,13 +269,13 @@ const AddToTeam = (ownProps: OwnProps) => { ) ) : ( <Kb.Box2 direction="vertical" centerChildren={true}> - <Kb.ProgressIndicator style={{width: 64}} /> + <Kb.ProgressIndicator style={styles.progress} /> </Kb.Box2> )} </Kb.Box2> </Kb.ScrollView> </Kb.BoxGrow> - <Kb.Box2 direction="horizontal" style={styles.addToTeam}> + <Kb.Box2 direction="horizontal" noShrink={true} alignItems="center" style={styles.addToTeam}> <Kb.Text style={styles.addToTeamTitle} type="BodySmall"> {them} will be added as a </Kb.Text> @@ -305,7 +286,7 @@ const AddToTeam = (ownProps: OwnProps) => { onConfirm={onConfirmRolePicker} onCancel={onCancelRolePicker} position="top center" - open={isRolePickerOpen} + open={rolePickerOpen} disabledRoles={disabledReasonsForRolePicker} > <InlineDropdown textWrapperType="BodySmall" label={selectedRole} onPress={onOpenRolePicker} /> @@ -344,20 +325,16 @@ const TeamRow = (props: RowProps) => { <Kb.ClickableBox3 direction="vertical" fullWidth={true} onClick={props.canAddThem ? () => props.onCheck(!props.checked) : undefined}> <Kb.Box2 direction="horizontal" style={styles.teamRow}> <Kb.Checkbox disabled={!props.canAddThem} checked={props.checked} onCheck={props.onCheck} /> - <Kb.Box2 direction="vertical" relative={true} style={{display: 'flex'}}> - <Kb.Avatar - isTeam={true} - size={isMobile ? 48 : 32} - style={{marginRight: Kb.Styles.globalMargins.tiny}} - teamname={props.name} - /> - </Kb.Box2> + <Kb.Avatar + isTeam={true} + size={isMobile ? 48 : 32} + style={styles.teamRowAvatar} + teamname={props.name} + /> <Kb.Box2 direction="vertical"> - <Kb.Box2 direction="horizontal" style={{alignSelf: 'flex-start'}}> + <Kb.Box2 direction="horizontal" alignSelf="flex-start"> <Kb.Text - style={{ - color: props.canAddThem ? Kb.Styles.globalColors.black : Kb.Styles.globalColors.black_50, - }} + style={props.canAddThem ? styles.teamNameEnabled : styles.teamNameDisabled} type="BodySemibold" > {props.name} @@ -366,9 +343,7 @@ const TeamRow = (props: RowProps) => { <Kb.Meta title="open" style={styles.meta} backgroundColor={Kb.Styles.globalColors.green} /> )} </Kb.Box2> - <Kb.Box2 direction="horizontal" style={{alignSelf: 'flex-start'}}> - <Kb.Text type="BodySmall">{props.disabledReason}</Kb.Text> - </Kb.Box2> + <Kb.Text type="BodySmall">{props.disabledReason}</Kb.Text> </Kb.Box2> </Kb.Box2> {!isMobile && <Kb.Divider style={styles.divider} />} @@ -382,10 +357,11 @@ const styles = Kb.Styles.styleSheetCreate( addButton: Kb.Styles.platformStyles({ isMobile: {width: '100%'}, }), + boxGrow: {width: '100%'}, + progress: {width: 64}, + teamListInner: {flexShrink: 1, width: '100%'}, addToTeam: Kb.Styles.platformStyles({ common: { - alignItems: 'center', - flexShrink: 0, flexWrap: 'wrap', marginBottom: Kb.Styles.globalMargins.small, marginLeft: Kb.Styles.globalMargins.small, @@ -424,11 +400,18 @@ const styles = Kb.Styles.styleSheetCreate( isElectron: {maxHeight: '100%'}, }), divider: {marginLeft: 69}, + headerAvatar: Kb.Styles.platformStyles({ + isElectron: {marginLeft: Kb.Styles.globalMargins.tiny, marginRight: Kb.Styles.globalMargins.tiny}, + isMobile: {marginLeft: Kb.Styles.globalMargins.xxtiny, marginRight: Kb.Styles.globalMargins.tiny}, + }), meta: { alignSelf: 'center', marginLeft: Kb.Styles.globalMargins.xtiny, marginTop: 2, }, + teamNameDisabled: {color: Kb.Styles.globalColors.black_50}, + teamNameEnabled: {color: Kb.Styles.globalColors.black}, + teamRowAvatar: {marginRight: Kb.Styles.globalMargins.tiny}, modalFooter: Kb.Styles.platformStyles({ common: { ...Kb.Styles.padding(Kb.Styles.globalMargins.xsmall, Kb.Styles.globalMargins.small), @@ -457,4 +440,4 @@ const styles = Kb.Styles.styleSheetCreate( }) as const ) -export default Container +export default AddToTeam diff --git a/shared/profile/edit-avatar/index.tsx b/shared/profile/edit-avatar/index.tsx index 47e7f1b99850..dc790bc91597 100644 --- a/shared/profile/edit-avatar/index.tsx +++ b/shared/profile/edit-avatar/index.tsx @@ -21,11 +21,7 @@ type FileListLike = {length?: number; [key: number]: FileLike; [Symbol.iterator] type FileInputRef = {click?: () => void; files?: FileListLike | null; value?: string} // Desktop helpers -const validDrag = (e: React.DragEvent) => { - return Array.from(e.dataTransfer.types) - .map(t => t) - .includes('Files') -} +const validDrag = (e: React.DragEvent) => Array.from(e.dataTransfer.types).includes('Files') const getFile = async (fileList: FileListLike | undefined): Promise<string> => { const {isDirectory, getPathForFile} = desktopFns diff --git a/shared/profile/edit-profile.tsx b/shared/profile/edit-profile.tsx index c65b988341e7..39564202888d 100644 --- a/shared/profile/edit-profile.tsx +++ b/shared/profile/edit-profile.tsx @@ -5,7 +5,7 @@ import {useCurrentUserState} from '@/stores/current-user' import * as T from '@/constants/types' import {useTrackerProfile} from '@/tracker/use-profile' -const Container = () => { +const EditProfile = () => { const username = useCurrentUserState(s => s.username) const {details: d, loadProfile} = useTrackerProfile(username) const _bio = d.bio || '' @@ -61,49 +61,47 @@ const Container = () => { } return ( - <> - <Kb.ScrollView> - <Kb.Box2 fullWidth={true} direction="vertical" style={styles.container}> - <Kb.RoundedBox side="top"> - <Kb.Input3 - value={fullname} - placeholder="Full name" - autoFocus={true} - onChangeText={setFullname} - hideBorder={true} - /> - </Kb.RoundedBox> - <Kb.RoundedBox side="middle"> - <Kb.Input3 - value={bio} - placeholder="Bio" - multiline={true} - rowsMin={7} - rowsMax={7} - onChangeText={setBio} - hideBorder={true} - /> - </Kb.RoundedBox> - <Kb.RoundedBox side="bottom"> - <Kb.Input3 - value={location} - placeholder="Location" - onChangeText={setLocation} - onEnterKeyDown={submit} - hideBorder={true} - /> - </Kb.RoundedBox> - <Kb.Box2 direction="vertical" flex={1} style={styles.gap} /> - <Kb.WaitingButton - waitingKey={C.waitingKeyTracker} - label="Save" - disabled={disabled()} - onClick={submit} + <Kb.ScrollView> + <Kb.Box2 fullWidth={true} direction="vertical" style={styles.container}> + <Kb.RoundedBox side="top"> + <Kb.Input3 + value={fullname} + placeholder="Full name" + autoFocus={true} + onChangeText={setFullname} + hideBorder={true} /> - {bio.length > maxBio && <Kb.Text type="BodySmallError">Bio too long, sorry</Kb.Text>} - </Kb.Box2> - </Kb.ScrollView> - </> + </Kb.RoundedBox> + <Kb.RoundedBox side="middle"> + <Kb.Input3 + value={bio} + placeholder="Bio" + multiline={true} + rowsMin={7} + rowsMax={7} + onChangeText={setBio} + hideBorder={true} + /> + </Kb.RoundedBox> + <Kb.RoundedBox side="bottom"> + <Kb.Input3 + value={location} + placeholder="Location" + onChangeText={setLocation} + onEnterKeyDown={submit} + hideBorder={true} + /> + </Kb.RoundedBox> + <Kb.Box2 direction="vertical" flex={1} style={styles.gap} /> + <Kb.WaitingButton + waitingKey={C.waitingKeyTracker} + label="Save" + disabled={disabled()} + onClick={submit} + /> + {bio.length > maxBio && <Kb.Text type="BodySmallError">Bio too long, sorry</Kb.Text>} + </Kb.Box2> + </Kb.ScrollView> ) } @@ -119,4 +117,4 @@ const styles = Kb.Styles.styleSheetCreate(() => ({ gap: {minHeight: Kb.Styles.globalMargins.small}, })) -export default Container +export default EditProfile diff --git a/shared/profile/generic/proofs-list.tsx b/shared/profile/generic/proofs-list.tsx index 4ca32f5db9c5..ee20b37713ac 100644 --- a/shared/profile/generic/proofs-list.tsx +++ b/shared/profile/generic/proofs-list.tsx @@ -492,22 +492,32 @@ const Container = ({platform, reason = 'profile'}: Props) => { <Kb.Text center={true} type="Header"> Prove your website in two ways: </Kb.Text> - <Kb.ChoiceList - options={[ - { - description: 'Host a text file on your site, such as yoursite.com/keybase.txt.', - icon: 'icon-file-txt-48', - onClick: () => startProof('web', 'profile'), - title: 'Host a TXT file', - }, - { - description: 'Place a Keybase proof in your DNS records.', - icon: 'icon-dns-48', - onClick: () => startProof('dns', 'profile'), - title: 'Set a DNS', - }, - ]} - /> + <Kb.Box2 direction="vertical" gap="small" fullWidth={true}> + <Kb.ListItem + type="Card" + firstItem={true} + icon={<Kb.IconAuto type="icon-file-txt-48" />} + body={ + <Kb.Box2 direction="vertical" fullWidth={true}> + <Kb.Text type="BodyBigLink">Host a TXT file</Kb.Text> + <Kb.Text type="Body">Host a text file on your site, such as yoursite.com/keybase.txt.</Kb.Text> + </Kb.Box2> + } + onClick={() => startProof('web', 'profile')} + /> + <Kb.ListItem + type="Card" + firstItem={true} + icon={<Kb.IconAuto type="icon-dns-48" />} + body={ + <Kb.Box2 direction="vertical" fullWidth={true}> + <Kb.Text type="BodyBigLink">Set a DNS</Kb.Text> + <Kb.Text type="Body">Place a Keybase proof in your DNS records.</Kb.Text> + </Kb.Box2> + } + onClick={() => startProof('dns', 'profile')} + /> + </Kb.Box2> </Kb.Box2> </Modal> ) @@ -567,7 +577,7 @@ const Container = ({platform, reason = 'profile'}: Props) => { } })() - return <>{content}</> + return content } const ProviderPicker = ({ @@ -624,6 +634,7 @@ const ProviderPicker = ({ direction="horizontal" alignItems="center" justifyContent="flex-start" + fullWidth={true} className="hover_background_color_blueLighter2" onClick={() => onSelect(provider.key)} style={styles.containerBox} @@ -728,7 +739,7 @@ const EnterUsername = ({ </Kb.Text> )} <PlatformIcon - style={styles.centered} + style={styles.center} platform={platform} overlay="icon-proof-unfinished" overlayColor={Kb.Styles.globalColors.greyDark} @@ -1126,13 +1137,11 @@ const Unreachable = ({ </Kb.Text> <Kb.Meta title="unreachable" backgroundColor={Kb.Styles.globalColors.red} /> </Kb.Box2> - <Kb.Box2 direction="vertical" style={styles.marginLeftAuto}> - <Kb.Icon - type="iconfont-proof-broken" - color={Kb.Styles.globalColors.red} - style={styles.inlineIcon} - /> - </Kb.Box2> + <Kb.Icon + type="iconfont-proof-broken" + color={Kb.Styles.globalColors.red} + style={Kb.Styles.collapseStyles([styles.inlineIcon, styles.marginLeftAuto])} + /> </Kb.Box2> ) @@ -1304,7 +1313,6 @@ const styles = Kb.Styles.styleSheetCreate( buttonBig: {flex: 2.5}, buttonSmall: {flex: 1}, center: {alignSelf: 'center'}, - centered: {alignSelf: 'center'}, colorRed: {color: Kb.Styles.globalColors.redDark}, container: Kb.Styles.platformStyles({ common: {flex: 1}, diff --git a/shared/profile/modal.tsx b/shared/profile/modal.tsx index 609a1698b35d..73bba4c1fcd9 100644 --- a/shared/profile/modal.tsx +++ b/shared/profile/modal.tsx @@ -7,27 +7,24 @@ type Props = React.PropsWithChildren<{ }> const Modal = ({children, onCancel, skipButton}: Props) => ( - <> - <Kb.Box2 direction="vertical" style={styles.container} fullWidth={true}> - <Kb.ScrollView> - <Kb.Box2 direction="vertical" flex={1} fullWidth={true} alignItems="center" justifyContent="space-around"> - {children} - </Kb.Box2> - </Kb.ScrollView> - {onCancel && !skipButton && ( - <Kb.Box2 direction="vertical" fullWidth={true} style={styles.buttonBar} alignItems="center"> - <Kb.Button type="Dim" label="Cancel" onClick={onCancel} /> - </Kb.Box2> - )} - </Kb.Box2> - </> + <Kb.Box2 direction="vertical" style={styles.container} fullWidth={true}> + <Kb.ScrollView> + <Kb.Box2 direction="vertical" flex={1} fullWidth={true} alignItems="center" justifyContent="space-around"> + {children} + </Kb.Box2> + </Kb.ScrollView> + {onCancel && !skipButton && ( + <Kb.Box2 direction="vertical" fullWidth={true} noShrink={true} alignItems="center" style={styles.buttonBar}> + <Kb.Button type="Dim" label="Cancel" onClick={onCancel} /> + </Kb.Box2> + )} + </Kb.Box2> ) const styles = Kb.Styles.styleSheetCreate( () => ({ buttonBar: { - flexShrink: 0, padding: isMobile ? undefined : Kb.Styles.globalMargins.medium, }, container: { diff --git a/shared/profile/pgp/choice/index.tsx b/shared/profile/pgp/choice/index.tsx index 3725461c8569..195e7b188b7b 100644 --- a/shared/profile/pgp/choice/index.tsx +++ b/shared/profile/pgp/choice/index.tsx @@ -28,6 +28,17 @@ const makeInitialForm = (): GeneratePgpArgs => ({ pgpFullName: '', }) +export const PgpMobileUnsupported = ({onCancel}: {onCancel: () => void}) => ( + <Modal onCancel={onCancel}> + <Kb.Box2 direction="vertical" gap="small" gapEnd={true}> + <Kb.Text center={true} type="Header"> + Add a PGP key + </Kb.Text> + <Kb.Text type="Body">For now, please use our desktop app to create PGP keys.</Kb.Text> + </Kb.Box2> + </Modal> +) + export default function Choice() { const {clearModals, navigateAppend, navigateUp} = C.Router2 const mountedRef = React.useRef(true) @@ -48,17 +59,7 @@ export default function Choice() { }, []) if (isMobile) { - const onCancel = () => navigateUp() - return ( - <Modal onCancel={onCancel}> - <Kb.Box2 direction="vertical" gap="small" gapEnd={true}> - <Kb.Text center={true} type="Header"> - Add a PGP key - </Kb.Text> - <Kb.Text type="Body">For now, please use our desktop app to create PGP keys.</Kb.Text> - </Kb.Box2> - </Modal> - ) + return <PgpMobileUnsupported onCancel={() => navigateUp()} /> } const setStepSafe = (next: Step) => { @@ -165,22 +166,32 @@ export default function Choice() { return ( <Kb.Box2 direction="vertical" gap="small"> <Kb.Text type="Header">Add a PGP key</Kb.Text> - <Kb.ChoiceList - options={[ - { - description: 'Keybase will generate a new PGP key and add it to your profile.', - icon: 'icon-pgp-key-new-48', - onClick: onShowGetNew, - title: 'Get a new PGP key', - }, - { - description: 'Import an existing PGP key to your Keybase profile.', - icon: 'icon-pgp-key-import-48', - onClick: onShowImport, - title: 'I have one already', - }, - ]} - /> + <Kb.Box2 direction="vertical" gap="small" fullWidth={true}> + <Kb.ListItem + type="Card" + firstItem={true} + icon={<Kb.IconAuto type="icon-pgp-key-new-48" />} + body={ + <Kb.Box2 direction="vertical" fullWidth={true}> + <Kb.Text type="BodyBigLink">Get a new PGP key</Kb.Text> + <Kb.Text type="Body">Keybase will generate a new PGP key and add it to your profile.</Kb.Text> + </Kb.Box2> + } + onClick={onShowGetNew} + /> + <Kb.ListItem + type="Card" + firstItem={true} + icon={<Kb.IconAuto type="icon-pgp-key-import-48" />} + body={ + <Kb.Box2 direction="vertical" fullWidth={true}> + <Kb.Text type="BodyBigLink">I have one already</Kb.Text> + <Kb.Text type="Body">Import an existing PGP key to your Keybase profile.</Kb.Text> + </Kb.Box2> + } + onClick={onShowImport} + /> + </Kb.Box2> </Kb.Box2> ) case 'info': diff --git a/shared/profile/pgp/import/index.tsx b/shared/profile/pgp/import/index.tsx index 0d8a76c28668..0c6321176a89 100644 --- a/shared/profile/pgp/import/index.tsx +++ b/shared/profile/pgp/import/index.tsx @@ -1,6 +1,7 @@ import * as Kb from '@/common-adapters' import * as C from '@/constants' import Modal from '@/profile/modal' +import {PgpMobileUnsupported} from '../choice' export default function Import() { const navigateUp = C.Router2.navigateUp @@ -9,29 +10,20 @@ export default function Import() { } if (isMobile) { - return ( - <Modal onCancel={onCancel}> - <Kb.Box2 direction="vertical" gap="small" gapEnd={true}> - <Kb.Text center={true} type="Header"> - Add a PGP key - </Kb.Text> - <Kb.Text type="Body">For now, please use our desktop app to create PGP keys.</Kb.Text> - </Kb.Box2> - </Modal> - ) + return <PgpMobileUnsupported onCancel={onCancel} /> } return ( <Modal onCancel={onCancel}> <Kb.ImageIcon type="icon-pgp-key-import-48" /> - <Kb.Text style={styleHeader} type="Header"> + <Kb.Text style={styles.header} type="Header"> Import a PGP key </Kb.Text> - <Kb.Text style={styleBody} type="Body"> + <Kb.Text style={styles.body} type="Body"> To register your existing PGP public key on Keybase, please run the following command from your terminal: </Kb.Text> - <Kb.Box2 direction="vertical" fullWidth={true} style={styleTerminal}> + <Kb.Box2 direction="vertical" fullWidth={true} style={styles.terminal}> <Kb.Text type="TerminalComment">{"# import a key from gpg's key chain"}</Kb.Text> <Kb.Text type="Terminal">keybase pgp select</Kb.Text> <Kb.Text type="TerminalEmpty" /> @@ -42,22 +34,27 @@ export default function Import() { ) } -const styleHeader = { - marginTop: Kb.Styles.globalMargins.medium, -} - -const styleBody = { - marginBottom: Kb.Styles.globalMargins.small, - marginTop: Kb.Styles.globalMargins.small, -} - -const styleTerminal = { - backgroundColor: Kb.Styles.globalColors.blueDarker2, - borderRadius: Kb.Styles.borderRadius, - boxSizing: 'content-box', - color: Kb.Styles.globalColors.white, - marginLeft: -Kb.Styles.globalMargins.medium, - marginRight: -Kb.Styles.globalMargins.medium, - padding: Kb.Styles.globalMargins.medium, - textAlign: 'left', -} as const +const styles = Kb.Styles.styleSheetCreate( + () => + ({ + body: { + marginBottom: Kb.Styles.globalMargins.small, + marginTop: Kb.Styles.globalMargins.small, + }, + header: { + marginTop: Kb.Styles.globalMargins.medium, + }, + terminal: Kb.Styles.platformStyles({ + isElectron: { + backgroundColor: Kb.Styles.globalColors.blueDarker2, + borderRadius: Kb.Styles.borderRadius, + boxSizing: 'content-box', + color: Kb.Styles.globalColors.white, + marginLeft: -Kb.Styles.globalMargins.medium, + marginRight: -Kb.Styles.globalMargins.medium, + padding: Kb.Styles.globalMargins.medium, + textAlign: 'left', + } as const, + }), + }) as const +) diff --git a/shared/profile/platform-icon.tsx b/shared/profile/platform-icon.tsx index 20c5e77c81e2..2f58ad77b248 100644 --- a/shared/profile/platform-icon.tsx +++ b/shared/profile/platform-icon.tsx @@ -20,28 +20,25 @@ const standardOffsets = { offsetRight: isMobile ? -1 : -5, } -function _specsForMobileOrDesktop() { - return { - btc: {icon: isMobile ? 'icon-bitcoin-logo-64' : 'icon-bitcoin-logo-48'}, - dns: {icon: isMobile ? 'icon-website-64' : 'icon-website-48'}, - dnsOrGenericWebSite: {icon: isMobile ? 'icon-website-64' : 'icon-website-48'}, - facebook: {icon: isMobile ? 'icon-facebook-logo-64' : 'icon-facebook-logo-48'}, - github: {icon: isMobile ? 'icon-github-logo-64' : 'icon-github-logo-48'}, - hackernews: {icon: isMobile ? 'icon-hacker-news-logo-64' : 'icon-hacker-news-logo-48'}, - http: {icon: isMobile ? 'icon-website-64' : 'icon-website-48'}, - https: {icon: isMobile ? 'icon-website-64' : 'icon-website-48'}, - pgp: {icon: isMobile ? 'icon-pgp-key-64' : 'icon-pgp-key-48', offsetBottom: -2, offsetRight: 4}, - reddit: {icon: isMobile ? 'icon-reddit-logo-64' : 'icon-reddit-logo-48'}, - rooter: {icon: isMobile ? 'icon-website-64' : 'icon-website-48'}, - twitter: {icon: isMobile ? 'icon-twitter-logo-64' : 'icon-twitter-logo-48'}, - web: {icon: isMobile ? 'icon-website-64' : 'icon-website-48'}, - zcash: {icon: isMobile ? 'icon-zcash-logo-64' : 'icon-zcash-logo-48'}, - } as const -} +const platformSpecs = { + btc: {icon: isMobile ? 'icon-bitcoin-logo-64' : 'icon-bitcoin-logo-48'}, + dns: {icon: isMobile ? 'icon-website-64' : 'icon-website-48'}, + dnsOrGenericWebSite: {icon: isMobile ? 'icon-website-64' : 'icon-website-48'}, + facebook: {icon: isMobile ? 'icon-facebook-logo-64' : 'icon-facebook-logo-48'}, + github: {icon: isMobile ? 'icon-github-logo-64' : 'icon-github-logo-48'}, + hackernews: {icon: isMobile ? 'icon-hacker-news-logo-64' : 'icon-hacker-news-logo-48'}, + http: {icon: isMobile ? 'icon-website-64' : 'icon-website-48'}, + https: {icon: isMobile ? 'icon-website-64' : 'icon-website-48'}, + pgp: {icon: isMobile ? 'icon-pgp-key-64' : 'icon-pgp-key-48', offsetBottom: -2, offsetRight: 4}, + reddit: {icon: isMobile ? 'icon-reddit-logo-64' : 'icon-reddit-logo-48'}, + rooter: {icon: isMobile ? 'icon-website-64' : 'icon-website-48'}, + twitter: {icon: isMobile ? 'icon-twitter-logo-64' : 'icon-twitter-logo-48'}, + web: {icon: isMobile ? 'icon-website-64' : 'icon-website-48'}, + zcash: {icon: isMobile ? 'icon-zcash-logo-64' : 'icon-zcash-logo-48'}, +} as const const getSpecForPlatform = (platform: T.More.PlatformsExpandedType): IconSpec => { - const specs = _specsForMobileOrDesktop() - return {...standardOffsets, ...specs[platform]} + return {...standardOffsets, ...platformSpecs[platform]} } const PlatformIcon = ({platform, overlay, style}: Props) => { diff --git a/shared/profile/prove-website-choice.tsx b/shared/profile/prove-website-choice.tsx index 24107f56ab19..1908933c0738 100644 --- a/shared/profile/prove-website-choice.tsx +++ b/shared/profile/prove-website-choice.tsx @@ -21,22 +21,32 @@ const ProveWebsiteChoice = () => { <Kb.Text center={true} type="Header"> Prove your website in two ways: </Kb.Text> - <Kb.ChoiceList - options={[ - { - description: 'Host a text file on your site, such as yoursite.com/keybase.txt.', - icon: 'icon-file-txt-48', - onClick: onFile, - title: 'Host a TXT file', - }, - { - description: 'Place a Keybase proof in your DNS records.', - icon: 'icon-dns-48', - onClick: onDNS, - title: 'Set a DNS', - }, - ]} - /> + <Kb.Box2 direction="vertical" gap="small" fullWidth={true}> + <Kb.ListItem + type="Card" + firstItem={true} + icon={<Kb.IconAuto type="icon-file-txt-48" />} + body={ + <Kb.Box2 direction="vertical" fullWidth={true}> + <Kb.Text type="BodyBigLink">Host a TXT file</Kb.Text> + <Kb.Text type="Body">Host a text file on your site, such as yoursite.com/keybase.txt.</Kb.Text> + </Kb.Box2> + } + onClick={onFile} + /> + <Kb.ListItem + type="Card" + firstItem={true} + icon={<Kb.IconAuto type="icon-dns-48" />} + body={ + <Kb.Box2 direction="vertical" fullWidth={true}> + <Kb.Text type="BodyBigLink">Set a DNS</Kb.Text> + <Kb.Text type="Body">Place a Keybase proof in your DNS records.</Kb.Text> + </Kb.Box2> + } + onClick={onDNS} + /> + </Kb.Box2> </Kb.Box2> </Modal> ) diff --git a/shared/profile/showcase-team-offer.tsx b/shared/profile/showcase-team-offer.tsx index deacfc4a4314..df7a9b28bb7f 100644 --- a/shared/profile/showcase-team-offer.tsx +++ b/shared/profile/showcase-team-offer.tsx @@ -4,7 +4,7 @@ import * as T from '@/constants/types' import {useTeamsList} from '@/teams/use-teams-list' import {useConfigState} from '@/stores/config' -const Container = () => { +const ShowcaseTeamOffer = () => { const waiting = C.useWaitingState(s => s.counts) const {reload, teams} = useTeamsList() const setGlobalError = useConfigState(s => s.dispatch.setGlobalError) @@ -22,29 +22,27 @@ const Container = () => { } return ( - <> - <Kb.Box2 direction="vertical" style={styles.container}> - {!isMobile && <ShowcaseTeamOfferHeader />} - <Kb.ScrollView> - {isMobile && <ShowcaseTeamOfferHeader />} - {sortedTeams.map(teamMeta => ( - <TeamRow - key={teamMeta.id} - canShowcase={ - (teamMeta.allowPromote && teamMeta.isMember) || ['admin', 'owner'].includes(teamMeta.role) - } - isExplicitMember={teamMeta.isMember} - name={teamMeta.teamname} - isOpen={teamMeta.isOpen} - membercount={teamMeta.memberCount} - onPromote={promoted => onPromote(teamMeta.id, promoted)} - showcased={teamMeta.showcasing} - waiting={!!waiting.get(C.waitingKeyTeamsTeam(teamMeta.id))} - /> - ))} - </Kb.ScrollView> - </Kb.Box2> - </> + <Kb.Box2 direction="vertical" style={styles.container}> + {!isMobile && <ShowcaseTeamOfferHeader />} + <Kb.ScrollView> + {isMobile && <ShowcaseTeamOfferHeader />} + {sortedTeams.map(teamMeta => ( + <TeamRow + key={teamMeta.id} + canShowcase={ + (teamMeta.allowPromote && teamMeta.isMember) || ['admin', 'owner'].includes(teamMeta.role) + } + isExplicitMember={teamMeta.isMember} + name={teamMeta.teamname} + isOpen={teamMeta.isOpen} + membercount={teamMeta.memberCount} + onPromote={promoted => onPromote(teamMeta.id, promoted)} + showcased={teamMeta.showcasing} + waiting={!!waiting.get(C.waitingKeyTeamsTeam(teamMeta.id))} + /> + ))} + </Kb.ScrollView> + </Kb.Box2> ) } @@ -63,9 +61,9 @@ const TeamRow = (p: RowProps) => { const {canShowcase, name, isOpen, membercount, onPromote, showcased, waiting, isExplicitMember} = p return ( <Kb.Box2 direction="vertical" fullWidth={true}> - <Kb.Box2 direction="horizontal" fullWidth={true} style={styles.teamRowContainer}> + <Kb.Box2 direction="horizontal" fullWidth={true} style={styles.teamRowShowcaseTeamOffer}> <Kb.Avatar isTeam={true} size={isMobile ? 48 : 32} teamname={name} /> - <Kb.Box2 direction="vertical" fullWidth={true} style={styles.teamNameContainer}> + <Kb.Box2 direction="vertical" fullWidth={true} style={styles.teamNameShowcaseTeamOffer}> <Kb.Box2 direction="horizontal" fullWidth={true} style={styles.teamText}> <Kb.Text type="BodySemibold" lineClamp={1}> {name} @@ -79,18 +77,16 @@ const TeamRow = (p: RowProps) => { </Kb.Box2> </Kb.Box2> {showcased || canShowcase || waiting ? ( - <Kb.Box2 direction="vertical"> - <Kb.Button - label={showcased ? 'Featured' : 'Feature'} - onClick={() => onPromote(!showcased)} - small={true} - type="Success" - mode={showcased ? 'Secondary' : 'Primary'} - waiting={waiting} - /> - </Kb.Box2> + <Kb.Button + label={showcased ? 'Featured' : 'Feature'} + onClick={() => onPromote(!showcased)} + small={true} + type="Success" + mode={showcased ? 'Secondary' : 'Primary'} + waiting={waiting} + /> ) : ( - <Kb.Box2 direction="vertical" style={styles.membershipTextContainer}> + <Kb.Box2 direction="vertical" style={styles.membershipTextShowcaseTeamOffer}> <Kb.Text style={styles.membershipText} type="BodySmall"> {isExplicitMember ? "Admins aren't allowing members to feature." @@ -105,8 +101,8 @@ const TeamRow = (p: RowProps) => { } const ShowcaseTeamOfferHeader = () => ( - <Kb.Box2 direction="vertical" fullWidth={true} style={styles.headerContainer}> - <Kb.InfoNote containerStyle={styles.noteContainer}> + <Kb.Box2 direction="vertical" fullWidth={true} style={styles.headerShowcaseTeamOffer}> + <Kb.InfoNote containerStyle={styles.noteShowcaseTeamOffer}> <Kb.Text center={true} style={styles.noteText} type="BodySmall"> Featuring a team will encourage others to ask to join. The team's description and number of members will be public. @@ -119,7 +115,7 @@ const styles = Kb.Styles.styleSheetCreate( () => ({ container: {flex: 1, overflow: 'hidden'}, - headerContainer: Kb.Styles.platformStyles({ + headerShowcaseTeamOffer: Kb.Styles.platformStyles({ isElectron: { paddingLeft: Kb.Styles.globalMargins.small, paddingRight: Kb.Styles.globalMargins.small, @@ -131,13 +127,13 @@ const styles = Kb.Styles.styleSheetCreate( isElectron: {textAlign: 'right'}, isMobile: {textAlign: 'center'}, }), - membershipTextContainer: {flexShrink: 1}, + membershipTextShowcaseTeamOffer: {flexShrink: 1}, meta: { alignSelf: 'center', marginLeft: Kb.Styles.globalMargins.xtiny, marginTop: 2, }, - noteContainer: Kb.Styles.platformStyles({ + noteShowcaseTeamOffer: Kb.Styles.platformStyles({ isMobile: {paddingTop: Kb.Styles.globalMargins.small}, }), noteText: { @@ -146,12 +142,12 @@ const styles = Kb.Styles.styleSheetCreate( paddingRight: Kb.Styles.globalMargins.large, paddingTop: Kb.Styles.globalMargins.tiny, }, - teamNameContainer: { + teamNameShowcaseTeamOffer: { flexShrink: 1, marginLeft: Kb.Styles.globalMargins.small, marginRight: Kb.Styles.globalMargins.small, }, - teamRowContainer: Kb.Styles.platformStyles({ + teamRowShowcaseTeamOffer: Kb.Styles.platformStyles({ common: { ...Kb.Styles.padding(Kb.Styles.globalMargins.tiny, Kb.Styles.globalMargins.small), }, @@ -161,4 +157,4 @@ const styles = Kb.Styles.styleSheetCreate( }) as const ) -export default Container +export default ShowcaseTeamOffer diff --git a/shared/profile/user/actions/follow-button.tsx b/shared/profile/user/actions/follow-button.tsx index f80cf9201d30..62dfff4b0ad6 100644 --- a/shared/profile/user/actions/follow-button.tsx +++ b/shared/profile/user/actions/follow-button.tsx @@ -1,11 +1,5 @@ import * as React from 'react' -import * as Styles from '@/styles' -import WaitingButton from '@/common-adapters/waiting-button' - -const Kb = { - Styles, - WaitingButton, -} +import * as Kb from '@/common-adapters' type Props = { disabled?: boolean diff --git a/shared/profile/user/actions/index.tsx b/shared/profile/user/actions/index.tsx index eb061bd43022..06227bc59b13 100644 --- a/shared/profile/user/actions/index.tsx +++ b/shared/profile/user/actions/index.tsx @@ -19,37 +19,24 @@ type OwnProps = { username: string } -const Container = (ownProps: OwnProps) => { +const Actions = (ownProps: OwnProps) => { const {blocked, followThem, followsYou, guiID, hidFromFollowers, onReload, state, username} = ownProps const isBot = !!useFeaturedBot(username) - const _you = useCurrentUserState(s => s.username) + const you = useCurrentUserState(s => s.username) const navigateAppend = C.Router2.navigateAppend - const _onAddToTeam = (username: string) => navigateAppend({name: 'profileAddToTeam', params: {username}}) - const _onBrowsePublicFolder = (username: string) => - FS.navToPath(T.FS.stringToPath(`/keybase/public/${username}`)) - const _onEditProfile = () => navigateAppend({name: 'profileEdit', params: {}}) - const followUser = C.useRPC(T.RPCGen.identify3Identify3FollowUserRpcPromise) - const _onFollow = (follow: boolean) => { - followUser([{follow, guiID}, C.waitingKeyTracker], onReload, () => {}) - } - const _onInstallBot = (username: string) => { - navigateAppend({name: 'chatInstallBotPick', params: {botUsername: username}}) - } - const _onManageBlocking = (username: string) => - navigateAppend({name: 'chatBlockingModal', params: {username}}) - const _onOpenPrivateFolder = (myUsername: string, theirUsername: string) => - FS.navToPath(T.FS.stringToPath(`/keybase/private/${theirUsername},${myUsername}`)) - const onAccept = () => _onFollow(true) - const onAddToTeam = () => _onAddToTeam(username) - const onBrowsePublicFolder = () => _onBrowsePublicFolder(username) - const onEditProfile = _you === username ? _onEditProfile : undefined - const onFollow = () => _onFollow(true) - const onInstallBot = () => _onInstallBot(username) - const onManageBlocking = () => _onManageBlocking(username) - const onOpenPrivateFolder = () => _onOpenPrivateFolder(_you, username) - const onUnfollow = () => _onFollow(false) + const follow = (f: boolean) => followUser([{follow: f, guiID}, C.waitingKeyTracker], onReload, () => {}) + + const onAccept = () => follow(true) + const onAddToTeam = () => navigateAppend({name: 'profileAddToTeam', params: {username}}) + const onBrowsePublicFolder = () => FS.navToPath(T.FS.stringToPath(`/keybase/public/${username}`)) + const onEditProfile = you === username ? () => navigateAppend({name: 'profileEdit', params: {}}) : undefined + const onFollow = () => follow(true) + const onInstallBot = () => navigateAppend({name: 'chatInstallBotPick', params: {botUsername: username}}) + const onManageBlocking = () => navigateAppend({name: 'chatBlockingModal', params: {username}}) + const onOpenPrivateFolder = () => FS.navToPath(T.FS.stringToPath(`/keybase/private/${username},${you}`)) + const onUnfollow = () => follow(false) if (blocked) { return ( @@ -221,4 +208,4 @@ const styles = Kb.Styles.styleSheetCreate(() => ({ dropdownButton: {minWidth: undefined}, })) -export default Container +export default Actions diff --git a/shared/profile/user/friend.tsx b/shared/profile/user/friend.tsx index 72844c74b2cf..166dbb0742f7 100644 --- a/shared/profile/user/friend.tsx +++ b/shared/profile/user/friend.tsx @@ -12,7 +12,7 @@ const followSizeToStyle = { 64: {bottom: 0, left: 44, position: 'absolute'} as const, } -const Container = (ownProps: OwnProps) => { +const Friend = (ownProps: OwnProps) => { const {username: _username, width} = ownProps const _fullname = useUsersState(s => s.infoMap.get(ownProps.username)?.fullname ?? '') const fullname = _fullname || '' @@ -28,6 +28,7 @@ const Container = (ownProps: OwnProps) => { <Kb.ClickableBox3 direction="vertical" centerChildren={true} + noShrink={true} style={Kb.Styles.collapseStyles([styles.container, {width: width}])} onClick={onClick} > @@ -52,7 +53,6 @@ const Container = (ownProps: OwnProps) => { const styles = Kb.Styles.styleSheetCreate(() => ({ avatar: {marginBottom: Kb.Styles.globalMargins.xxtiny}, container: { - flexShrink: 0, height: 105, justifyContent: 'flex-start', minWidth: 0, @@ -66,4 +66,4 @@ const styles = Kb.Styles.styleSheetCreate(() => ({ }), })) -export default Container +export default Friend diff --git a/shared/profile/user/hooks.tsx b/shared/profile/user/hooks.tsx index 5f29715ed98a..03ec5ada78f1 100644 --- a/shared/profile/user/hooks.tsx +++ b/shared/profile/user/hooks.tsx @@ -24,13 +24,6 @@ const headerBackgroundColorType = ( } } -// const filterWebOfTrustEntries = memoize( -// ( -// webOfTrustEntries: ReadonlyArray<T.Tracker.WebOfTrustEntry> | undefined -// ): Array<T.Tracker.WebOfTrustEntry> => -// webOfTrustEntries ? webOfTrustEntries.filter(C.Tracker.showableWotEntry) : [] -// ) - const useUserData = (username: string) => { const myName = useCurrentUserState(s => s.username) const usernameKey = username.toLowerCase() @@ -120,18 +113,11 @@ const useUserData = (username: string) => { const followThem = useFollowerState(s => s.following.has(username)) const followsYou = useFollowerState(s => s.followers.has(username)) - // const mutualFollow = followThem && followsYou - const isDarkMode = useColorScheme() === 'dark' const stateProps = (() => { if (!notAUser) { // Keybase user - const {followersCount, followingCount, followers, following, reason /*, webOfTrustEntries = []*/} = d - - // const filteredWot = filterWebOfTrustEntries(webOfTrustEntries) - // const hasAlreadyVouched = filteredWot.some(entry => entry.attestingUser === myName) - // const vouchShowButton = mutualFollow && !hasAlreadyVouched - // const vouchDisableButton = !vouchShowButton || d.state !== 'valid' || d.resetBrokeTrack + const {followersCount, followingCount, followers, following, reason} = d return { ...commonProps, @@ -153,9 +139,6 @@ const useUserData = (username: string) => { sbsAvatarUrl: undefined, serviceIcon: undefined, title: username, - // vouchDisableButton, - // vouchShowButton, - // webOfTrustEntries: filteredWot, } } else { // SBS profile. But `nonUserDetails` might not have arrived yet, @@ -178,19 +161,11 @@ const useUserData = (username: string) => { service, serviceIcon: isDarkMode ? nonUserDetails.siteIconFullDarkmode : nonUserDetails.siteIconFull, title, - vouchDisableButton: true, - vouchShowButton: false, - webOfTrustEntries: [], } } })() const _onEditAvatar = editAvatar - // const _onIKnowThem = (username: string, guiID: string) => { - // dispatch( - // RouteTreeGen.createNavigateAppend({path: [{props: {guiID, username}, selected: 'profileWotAuthor'}]}) - // ) - // } const _onReload = (isYou: boolean, state: T.Tracker.DetailsState) => { if (state !== 'valid' && !isYou) { // Might be a Keybase user or not, launch non-user profile fetch. @@ -268,10 +243,6 @@ const useUserData = (username: string) => { onAddIdentity: allowOnAddIdentity ? onAddIdentity : undefined, onBack: onBack, onEditAvatar: stateProps.userIsYou ? _onEditAvatar : undefined, - // onIKnowThem: - // stateProps.vouchShowButton && !stateProps.vouchDisableButton - // ? () => _onIKnowThem(stateProps.username, stateProps.guiID) - // : undefined, onReload: () => _onReload(stateProps.userIsYou, stateProps.state), reason: stateProps.reason, sbsAvatarUrl: stateProps.sbsAvatarUrl, @@ -286,9 +257,6 @@ const useUserData = (username: string) => { title: stateProps.title, userIsYou: stateProps.userIsYou, username: stateProps.username, - // vouchDisableButton: stateProps.vouchDisableButton, - // vouchShowButton: stateProps.vouchShowButton, - // webOfTrustEntries: stateProps.webOfTrustEntries, } } diff --git a/shared/profile/user/index.tsx b/shared/profile/user/index.tsx index 8c0914460892..18d54ae8f16b 100644 --- a/shared/profile/user/index.tsx +++ b/shared/profile/user/index.tsx @@ -373,7 +373,7 @@ const BioTeamProofs = (props: BioTeamProofsProps) => { style={styles.bioAndProofs} > <BioLayout {...props} /> - <Kb.Box2 direction="vertical" style={styles.proofs}> + <Kb.Box2 direction="vertical" noShrink={true} style={styles.proofs}> <Kb.Text type="BodySmallSemibold" negative={true} center={true} style={styles.reason}> {props.reason} </Kb.Text> @@ -692,7 +692,6 @@ const styles = Kb.Styles.styleSheetCreate(() => ({ proofs: Kb.Styles.platformStyles({ isElectron: { alignSelf: 'flex-start', - flexShrink: 0, width: 350, }, isMobile: {width: '100%'}, diff --git a/shared/profile/user/teams/index.tsx b/shared/profile/user/teams/index.tsx index 46ad3d7ffc7d..63daf3753e9c 100644 --- a/shared/profile/user/teams/index.tsx +++ b/shared/profile/user/teams/index.tsx @@ -16,7 +16,7 @@ type OwnProps = { const noTeams = new Array<T.Tracker.TeamShowcase>() -const Container = (ownProps: OwnProps) => { +const Teams = (ownProps: OwnProps) => { const isYou = useCurrentUserState(s => s.username === ownProps.username) const {teams} = useTeamsList() const teamNameToID = React.useMemo(() => new Map(teams.map(team => [team.teamname, team.id] as const)), [teams]) @@ -72,14 +72,12 @@ const TeamShowcase = (props: TeamShowcaseProps) => { } const ShowcaseTeamsOffer = (p: {onEdit: () => void}) => ( - <Kb.Box2 direction="horizontal" gap="tiny" fullWidth={true}> - <Kb.ClickableBox3 direction="horizontal" gap="tiny" onClick={p.onEdit}> - <Kb.ImageIcon type="icon-team-placeholder-avatar-32" style={styles.placeholderTeam} /> - <Kb.Text style={styles.youFeatureTeam} type="BodyPrimaryLink"> - {"Feature the teams you're in"} - </Kb.Text> - </Kb.ClickableBox3> - </Kb.Box2> + <Kb.ClickableBox3 direction="horizontal" gap="tiny" fullWidth={true} onClick={p.onEdit}> + <Kb.ImageIcon type="icon-team-placeholder-avatar-32" style={styles.placeholderTeam} /> + <Kb.Text style={styles.youFeatureTeam} type="BodyPrimaryLink"> + {"Feature the teams you're in"} + </Kb.Text> + </Kb.ClickableBox3> ) const styles = Kb.Styles.styleSheetCreate( @@ -93,4 +91,4 @@ const styles = Kb.Styles.styleSheetCreate( }) as const ) -export default Container +export default Teams diff --git a/shared/profile/user/teams/openmeta.tsx b/shared/profile/user/teams/openmeta.tsx index 5bb767c8f804..a266eb80df85 100644 --- a/shared/profile/user/teams/openmeta.tsx +++ b/shared/profile/user/teams/openmeta.tsx @@ -1,17 +1,6 @@ -import Meta from '@/common-adapters/meta' -import * as Styles from '@/styles' +import * as Kb from '@/common-adapters' -const Kb = { - Meta, - Styles, -} - -type Props = { - isOpen: boolean - style?: Styles.StylesCrossPlatform -} - -const OpenMeta = ({isOpen}: Props) => +const OpenMeta = ({isOpen}: {isOpen: boolean}) => isOpen ? <Kb.Meta backgroundColor={Kb.Styles.globalColors.green} title="open" style={styles.meta} /> : null const styles = Kb.Styles.styleSheetCreate( diff --git a/shared/profile/user/teams/team-section.tsx b/shared/profile/user/teams/team-section.tsx index 6fe2abbe92d0..f14b878e241a 100644 --- a/shared/profile/user/teams/team-section.tsx +++ b/shared/profile/user/teams/team-section.tsx @@ -11,7 +11,7 @@ type Props = { } const TeamSection = ({children, right, title}: Props) => ( - <Kb.Box2 direction="vertical" gap="tiny" fullWidth={true} style={styles.container}> + <Kb.Box2 direction="vertical" gap="tiny" fullWidth={true} noShrink={true} style={styles.container}> <Kb.Box2 direction="horizontal" gap="tiny" fullWidth={true}> <Kb.Text type="BodySmallSemibold">{title}</Kb.Text> {right} @@ -29,7 +29,6 @@ const styles = Kb.Styles.styleSheetCreate(() => ({ common: { alignItems: 'flex-start', flex: 1, - flexShrink: 0, minWidth: 0, paddingBottom: Kb.Styles.globalMargins.small, paddingLeft: Kb.Styles.globalMargins.tiny, diff --git a/shared/profile/user/teams/teaminfo.tsx b/shared/profile/user/teams/teaminfo.tsx index 457b118d4fbc..4bbc7076315b 100644 --- a/shared/profile/user/teams/teaminfo.tsx +++ b/shared/profile/user/teams/teaminfo.tsx @@ -1,25 +1,9 @@ import * as React from 'react' -import * as Styles from '@/styles' +import * as Kb from '@/common-adapters' import * as C from '@/constants' import OpenMeta from './openmeta' -import FloatingMenu from '@/common-adapters/floating-menu' -import ConnectedUsernames from '@/common-adapters/usernames' -import {NameWithIcon} from '@/common-adapters/name-with-icon' -import Text from '@/common-adapters/text' -import {Box2} from '@/common-adapters/box' -import WaitingButton from '@/common-adapters/waiting-button' import type {MeasureRef} from '@/common-adapters/measure-ref' -const Kb = { - Box2, - ConnectedUsernames, - FloatingMenu, - NameWithIcon, - Styles, - Text, - WaitingButton, -} - export type Props = { attachTo?: React.RefObject<MeasureRef | null> description: string @@ -27,7 +11,7 @@ export type Props = { isOpen: boolean membersCount: number name: string - position?: Styles.Position + position?: Kb.Styles.Position onChat?: () => void onHidden: () => void onJoinTeam: (teamname: string) => void @@ -39,28 +23,8 @@ export type Props = { const TeamInfo = (props: Props) => { const [requested, setRequested] = React.useState(false) - const _isPrivate = () => { - return props.membersCount === 0 && props.description.length === 0 - } - - const _onJoinTeam = () => { - props.onJoinTeam(props.name) - setRequested(true) - } - - const _onViewTeam = () => { - props.onViewTeam() - props.onHidden() - } - - const _onChat = () => { - if (props.onChat) { - props.onChat() - props.onHidden() - } - } - - const memberText = _isPrivate() + const isPrivate = props.membersCount === 0 && props.description.length === 0 + const memberText = isPrivate ? 'This team is private. Admins will decide if they can let you in.' : `${props.membersCount} member${props.membersCount > 1 ? 's' : ''}` @@ -94,22 +58,21 @@ const TeamInfo = (props: Props) => { <Kb.WaitingButton waitingKey={C.waitingKeyTracker} label="Chat" - onClick={_onChat} + onClick={() => { props.onChat?.(); props.onHidden() }} mode="Secondary" /> )} - {/* With teamsRedesign we have external team page, always show view team button */} <Kb.WaitingButton waitingKey={C.waitingKeyTracker} label="View team" - onClick={_onViewTeam} + onClick={() => { props.onViewTeam(); props.onHidden() }} mode="Secondary" /> {!props.inTeam && ( <Kb.WaitingButton waitingKey={C.waitingKeyTracker} label={requested ? 'Requested!' : props.isOpen ? 'Join team' : 'Request to join'} - onClick={requested ? undefined : _onJoinTeam} + onClick={requested ? undefined : () => { props.onJoinTeam(props.name); setRequested(true) }} type={props.isOpen ? 'Success' : 'Default'} mode={requested ? 'Secondary' : 'Primary'} /> diff --git a/shared/provision/code-page/container.tsx b/shared/provision/code-page/container.tsx index 8e557c366c69..e7838bf8ab10 100644 --- a/shared/provision/code-page/container.tsx +++ b/shared/provision/code-page/container.tsx @@ -34,8 +34,7 @@ const CodePageContainer = () => { const iconNumber = T.Devices.deviceNumberToIconNumber(otherDevice.deviceNumberOfType) const waiting = C.Waiting.useAnyWaiting(C.waitingKeyProvision) - const navigateUp = C.Router2.navigateUp - const onBack = navigateUp + const onBack = C.Router2.navigateUp const _onSubmitTextCode = (code: string) => { if (!waiting) { @@ -75,12 +74,15 @@ const CodePageContainer = () => { const tab = tabState.defaultTab === defaultTab ? tabState.tab : defaultTab const setTab = (tab: Tab) => setTabState(state => ({...state, tab})) - const tabBackground = () => (tab === 'QR' ? Kb.Styles.globalColors.blueLight : Kb.Styles.globalColors.green) - const buttonType = () => (tab === 'QR' ? 'Default' as const : 'Success' as const) - const buttonLabelStyle = () => (tab === 'QR' ? styles.primaryOnBlueLabel : styles.primaryOnGreenLabel) + const tabBackground = tab === 'QR' ? Kb.Styles.globalColors.blueLight : Kb.Styles.globalColors.green + const buttonType = tab === 'QR' ? ('Default' as const) : ('Success' as const) + const buttonLabelStyle = tab === 'QR' ? styles.primaryOnBlueLabel : styles.primaryOnGreenLabel const onSubmitTextCode = () => _onSubmitTextCode(code) + // We're in a modal unless this is a desktop being newly provisioned. + const inModal = currentDeviceType !== 'desktop' || currentDeviceAlreadyProvisioned + const body = () => { let content: React.ReactNode = null switch (tab) { @@ -106,7 +108,7 @@ const CodePageContainer = () => { <Kb.Box2 direction="vertical" fullWidth={true} - style={Kb.Styles.collapseStyles([styles.codePageContainer, {backgroundColor: tabBackground()}])} + style={Kb.Styles.collapseStyles([styles.codePageContainer, {backgroundColor: tabBackground}])} > <Kb.Box2 direction="vertical" @@ -148,16 +150,12 @@ const CodePageContainer = () => { otherDevice={otherDevice} currentDeviceAlreadyProvisioned={currentDeviceAlreadyProvisioned} /> - {!inModal() && footer().content} + {!inModal && footer().content} </Kb.Box2> </Kb.Box2> </Kb.Box2> - {!inModal() && - currentDeviceType === 'desktop' && - currentDeviceType === otherDevice.type && - !currentDeviceAlreadyProvisioned && - heyWaitBanner()} - {!inModal() && troubleshooting && ( + {!inModal && otherDevice.type === 'desktop' && heyWaitBanner()} + {!inModal && troubleshooting && ( <Kb.Popup onHidden={() => setTroubleshooting(false)} propagateOutsideClicks={true}> {troubleshootingContent()} </Kb.Popup> @@ -183,33 +181,33 @@ const CodePageContainer = () => { {tab === 'enterText' && ( <Kb.WaitingButton fullWidth={true} - type={buttonType()} + type={buttonType} label="Continue" onClick={onSubmitTextCode} disabled={!code || waiting} style={Kb.Styles.collapseStyles([styles.enterTextButton, styles.primaryOnColor])} - labelStyle={buttonLabelStyle()} + labelStyle={buttonLabelStyle} waitingKey={C.waitingKeyProvision} /> )} - {tab !== 'enterText' && inModal() && !isMobile && ( + {tab !== 'enterText' && inModal && !isMobile && ( <Kb.WaitingButton fullWidth={true} - type={buttonType()} + type={buttonType} label="Close" onClick={onBack} onlyDisable={true} style={Kb.Styles.collapseStyles([styles.closeButton, styles.primaryOnColor])} - labelStyle={buttonLabelStyle()} + labelStyle={buttonLabelStyle} waitingKey={C.waitingKeyProvision} /> )} {showHeyWaitInFooter && heyWaitBanner()} </Kb.Box2> ), - hideBorder: !inModal() || currentDeviceType !== 'desktop', + hideBorder: !inModal || currentDeviceType !== 'desktop', style: { - backgroundColor: tabBackground(), + backgroundColor: tabBackground, ...Kb.Styles.padding(Kb.Styles.globalMargins.xsmall, 0, 0), }, } @@ -237,16 +235,13 @@ const CodePageContainer = () => { /> ) - // We're in a modal unless this is a desktop being newly provisioned. - const inModal = () => currentDeviceType !== 'desktop' || currentDeviceAlreadyProvisioned - - // Workaround for no modals while logged out: display just the troubleshooting modal if we're on mobile and it's open; - // When we're on desktop being newly provisioned, it's in this._body() + // Workaround for no modals while logged out: display just the troubleshooting content if we're on mobile and it's open; + // When we're on desktop being newly provisioned, it's rendered inside body() if (isMobile && troubleshooting) { return troubleshootingContent() } const content = body() - if (inModal()) { + if (inModal) { const f = footer() return ( <> @@ -295,7 +290,7 @@ const SwitchTab = (props: { } return ( - <Kb.Box2 direction="horizontal" gap="xtiny" style={styles.switchTabContainer}> + <Kb.Box2 direction="horizontal" gap="xtiny" alignItems="center"> <Kb.Text type="BodySmallPrimaryLink" negative={true} @@ -614,7 +609,6 @@ const styles = Kb.Styles.styleSheetCreate( marginBottom: Kb.Styles.globalMargins.xtiny, marginTop: Kb.Styles.globalMargins.tiny, }, - switchTabContainer: {alignItems: 'center'}, viewTextCode: Kb.Styles.platformStyles({ common: { ...Kb.Styles.globalStyles.fontTerminalSemibold, diff --git a/shared/provision/code-page/qr-scan/not-authorized.tsx b/shared/provision/code-page/qr-scan/not-authorized.tsx index ae7f31d0fb85..bcfa7205f7ea 100644 --- a/shared/provision/code-page/qr-scan/not-authorized.tsx +++ b/shared/provision/code-page/qr-scan/not-authorized.tsx @@ -3,7 +3,7 @@ import {openAppSettings} from '@/util/storeless-actions' const QRScanNotAuthorized = () => { return ( - <Kb.Box2 direction="vertical" justifyContent="center" flex={1} style={styles.container} gap="tiny"> + <Kb.Box2 direction="vertical" justifyContent="center" alignItems="center" flex={1} style={styles.container} gap="tiny"> <Kb.Icon type="iconfont-camera" color={Kb.Styles.globalColors.white_40} /> <Kb.Text center={true} type="BodyTiny" style={styles.text}> You need to allow access to the camera. @@ -19,7 +19,6 @@ const styles = Kb.Styles.styleSheetCreate( () => ({ container: { - alignItems: 'center', backgroundColor: Kb.Styles.globalColors.black, }, text: {color: Kb.Styles.globalColors.white_40}, diff --git a/shared/provision/error.tsx b/shared/provision/error.tsx index 9b7c58582938..87f4076c7b3a 100644 --- a/shared/provision/error.tsx +++ b/shared/provision/error.tsx @@ -8,7 +8,7 @@ import {type ProvisionRouteError, useProvisionState} from '@/stores/provision' import {startAccountReset} from '@/login/reset/account-reset' const Wrapper = (p: {onBack: () => void; children: React.ReactNode}) => ( - <LoginContainer onBack={p.onBack}> + <LoginContainer> <Kb.ImageIcon type="icon-illustration-zen-240-180" style={styles.icon} /> <Kb.Text type="Header" style={styles.header}> Oops, something went wrong. @@ -37,24 +37,13 @@ type Props = { } } -// Normally this would be a component but I want the children to be flat so i can use a Box2 as the parent and have nice gaps const RenderError = ({route}: Props) => { const error = route.params.error const username = useProvisionState(s => s.username) - const _onAccountReset = (username: string) => { - startAccountReset(false, username) - } - const navigateUp = C.Router2.navigateUp - const onBack = () => { - navigateUp() - } - const onKBHome = () => { - void openURL('https://keybase.io/') - } - const onPasswordReset = () => { - void openURL('https://keybase.io/#password-reset') - } - const onAccountReset = () => _onAccountReset(username) + const onBack = C.Router2.navigateUp + const onKBHome = () => void openURL('https://keybase.io/') + const onPasswordReset = () => void openURL('https://keybase.io/#password-reset') + const onAccountReset = () => startAccountReset(false, username) if (!error) { return ( diff --git a/shared/provision/forgot-username.tsx b/shared/provision/forgot-username.tsx index 3f653e34b2fd..5becf7630588 100644 --- a/shared/provision/forgot-username.tsx +++ b/shared/provision/forgot-username.tsx @@ -71,7 +71,7 @@ const ForgotUsername = () => { label: 'Recover username', onClick: onSubmit, type: 'Default', - waiting: waiting, + waiting, }, ]} onBack={onBack} diff --git a/shared/provision/paper-key.tsx b/shared/provision/paper-key.tsx index 1f3c039c9d06..824590cb4cac 100644 --- a/shared/provision/paper-key.tsx +++ b/shared/provision/paper-key.tsx @@ -8,19 +8,16 @@ const Container = () => { const error = useProvisionState(s => s.error) const hint = useProvisionState(s => `${s.codePageOtherDevice.name || ''}...`) const waiting = C.Waiting.useAnyWaiting(C.waitingKeyProvision) - const navigateUp = C.Router2.navigateUp - const onBack = () => { - navigateUp() - } const onSubmit = useProvisionState(s => s.dispatch.dynamic.setPassphrase) - const props = { - error: error, - hint: hint, - onBack: onBack, - onSubmit: (paperkey: string) => !waiting && onSubmit?.(paperkey), - waiting: waiting, - } - return <PaperKey {...props} /> + return ( + <PaperKey + error={error} + hint={hint} + onBack={C.Router2.navigateUp} + onSubmit={(paperkey: string) => !waiting && onSubmit?.(paperkey)} + waiting={waiting} + /> + ) } type Props = { @@ -33,10 +30,7 @@ type Props = { export const PaperKey = (props: Props) => { const [paperKey, setPaperKey] = React.useState('') - - const _onSubmit = () => { - props.onSubmit(paperKey) - } + const onSubmit = () => props.onSubmit(paperKey) return ( <SignupScreen @@ -46,7 +40,7 @@ export const PaperKey = (props: Props) => { { disabled: !paperKey, label: 'Continue', - onClick: _onSubmit, + onClick: onSubmit, type: 'Success', waiting: props.waiting, }, @@ -73,7 +67,7 @@ export const PaperKey = (props: Props) => { textType="Body" containerStyle={styles.container2} inputStyle={styles.inputText} - onEnterKeyDown={_onSubmit} + onEnterKeyDown={onSubmit} onChangeText={setPaperKey} value={paperKey} /> diff --git a/shared/provision/password.tsx b/shared/provision/password.tsx index b4ed96aa430e..1a684503bc19 100644 --- a/shared/provision/password.tsx +++ b/shared/provision/password.tsx @@ -10,18 +10,14 @@ const Password = () => { const error = useProvisionState(s => s.error) const username = useProvisionState(s => s.username) const waiting = C.Waiting.useAnyWaiting(C.waitingKeyProvision) - const navigateUp = C.Router2.navigateUp const [resetEmailSent, setResetEmailSent] = React.useState(false) - const _onForgotPassword = () => { + const onForgotPassword = () => { startRecoverPassword({abortProvisioning: true, onResetEmailSent: () => setResetEmailSent(true), username}) } - const onBack = () => { - navigateUp() - } - const _onSubmit = useProvisionState(s => s.dispatch.dynamic.setPassphrase) - const onSubmit = (password: string) => !waiting && _onSubmit?.(password) + const onBack = C.Router2.navigateUp + const setPassphrase = useProvisionState(s => s.dispatch.dynamic.setPassphrase) const [password, setPassword] = React.useState('') - const _onSubmitClick = () => onSubmit(password) + const onSubmit = () => !waiting && setPassphrase?.(password) return ( <SignupScreen @@ -43,7 +39,7 @@ const Password = () => { { disabled: !password, label: 'Continue', - onClick: _onSubmitClick, + onClick: onSubmit, type: 'Default', waiting, }, @@ -68,13 +64,13 @@ const Password = () => { <Kb.Input3 autoFocus={true} placeholder="Password" - onEnterKeyDown={_onSubmitClick} + onEnterKeyDown={onSubmit} onChangeText={setPassword} value={password} textType="BodySemibold" secureTextEntry={true} /> - <Kb.Text style={styles.forgotPassword} type="BodySmallSecondaryLink" onClick={_onForgotPassword}> + <Kb.Text style={styles.forgotPassword} type="BodySmallSecondaryLink" onClick={onForgotPassword}> Forgot password? </Kb.Text> </Kb.Box2> diff --git a/shared/provision/select-other-device-connected.tsx b/shared/provision/select-other-device-connected.tsx index 26ffeb3eeae1..8994e6739ed9 100644 --- a/shared/provision/select-other-device-connected.tsx +++ b/shared/provision/select-other-device-connected.tsx @@ -9,9 +9,7 @@ const SelectOtherDeviceContainer = () => { const submitDeviceSelect = useProvisionState(s => s.dispatch.dynamic.submitDeviceSelect) const username = useProvisionState(s => s.username) const waiting = C.Waiting.useAnyWaiting(C.waitingKeyProvision) - const navigateUp = C.Router2.navigateUp - const _onBack = navigateUp - const onBack = useSafeSubmit(_onBack, false) + const onBack = useSafeSubmit(C.Router2.navigateUp, false) const onResetAccount = () => { startAccountReset(false, username) diff --git a/shared/provision/set-public-name.tsx b/shared/provision/set-public-name.tsx index c135a5c02314..a3a07c29caab 100644 --- a/shared/provision/set-public-name.tsx +++ b/shared/provision/set-public-name.tsx @@ -11,14 +11,8 @@ const SetPublicName = () => { const devices = Provision.useProvisionState(s => s.devices) const error = Provision.useProvisionState(s => s.error) const waiting = C.Waiting.useAnyWaiting(C.waitingKeyProvision) - const navigateUp = C.Router2.navigateUp - const ponBack = useSafeSubmit(navigateUp, !!error) - const psetDeviceName = Provision.useProvisionState(s => s.dispatch.dynamic.setDeviceName) - const ponSubmit = (name: string) => { - if (!waiting) { - psetDeviceName?.(name) - } - } + const onBack = useSafeSubmit(C.Router2.navigateUp, !!error) + const submitDeviceName = Provision.useProvisionState(s => s.dispatch.dynamic.setDeviceName) const iconNumbers = T.Devices.nextDeviceIconNumbers(devices) const deviceIconNumber = isMobile ? iconNumbers.mobile : iconNumbers.desktop @@ -34,11 +28,11 @@ const SetPublicName = () => { Provision.badDeviceRE.test(cleanDeviceName) const showDisabled = disabled && !!cleanDeviceName && readyToShowError const onSubmit = () => { - ponSubmit(Provision.cleanDeviceName(cleanDeviceName)) + if (!waiting) submitDeviceName?.(Provision.cleanDeviceName(cleanDeviceName)) } - const _setDeviceName = (deviceName: string) => { + const onChangeDeviceName = (name: string) => { setReadyToShowError(false) - setDeviceName(deviceName.replace(Provision.badDeviceChars, '')) + setDeviceName(name.replace(Provision.badDeviceChars, '')) debouncedSetReadyToShowError(true) } @@ -64,10 +58,10 @@ const SetPublicName = () => { label: 'Continue', onClick: onSubmit, type: 'Success', - waiting: waiting, + waiting, }, ]} - onBack={ponBack} + onBack={onBack} title={isMobile ? 'Name this device' : 'Name this computer'} > <Kb.Box2 direction="vertical" style={styles.contents} centerChildren={true} gap="medium"> @@ -79,7 +73,7 @@ const SetPublicName = () => { maxLength={64} placeholder="Pick a device name" onEnterKeyDown={onSubmit} - onChangeText={_setDeviceName} + onChangeText={onChangeDeviceName} value={cleanDeviceName} containerStyle={styles.nameInput} /> diff --git a/shared/provision/troubleshooting.tsx b/shared/provision/troubleshooting.tsx index 297223df6c92..013507f39699 100644 --- a/shared/provision/troubleshooting.tsx +++ b/shared/provision/troubleshooting.tsx @@ -48,9 +48,8 @@ const BigButton = ({onClick, icon, mainText, subText, waiting}: BigButtonProps) const Troubleshooting = (props: Props) => { const onBack = props.onCancel - const navUpToScreen = C.Router2.navUpToScreen const onWayBack = () => { - navUpToScreen('login') + C.Router2.navUpToScreen('login') } const device = useProvisionState(s => s.codePageOtherDevice) diff --git a/shared/provision/username-or-email.tsx b/shared/provision/username-or-email.tsx index 32858cc6a75d..36a51cd6fab3 100644 --- a/shared/provision/username-or-email.tsx +++ b/shared/provision/username-or-email.tsx @@ -44,17 +44,10 @@ const UsernameOrEmailContainer = (op: OwnProps) => { const waiting = C.Waiting.useAnyWaiting(C.waitingKeyProvision) const hasError = !!error || !!inlineError || inlineSignUpLink - const navigateUp = C.Router2.navigateUp - const onBack = useSafeSubmit(navigateUp, hasError) - const navigateAppend = C.Router2.navigateAppend - const onForgotUsername = () => navigateAppend({name: 'forgotUsername', params: {}}) + const onBack = useSafeSubmit(C.Router2.navigateUp, hasError) + const onForgotUsername = () => C.Router2.navigateAppend({name: 'forgotUsername', params: {}}) const requestAutoInvite = useRequestAutoInvite() const _setUsername = useProvisionState(s => s.dispatch.dynamic.setUsername) - const _onSubmit = (username: string) => { - if (!waiting) { - _setUsername?.(username) - } - } const [username, setUsername] = React.useState(op.username ?? _username) React.useEffect(() => { if (op.username && op.username !== _username) { @@ -62,7 +55,7 @@ const UsernameOrEmailContainer = (op: OwnProps) => { } }, [op.username, _username, _setUsername]) const onSubmit = () => { - _onSubmit(username) + if (!waiting) _setUsername?.(username) } const onGoToSignup = () => { requestAutoInvite(username) diff --git a/shared/router-v2/account-switcher/index.tsx b/shared/router-v2/account-switcher/index.tsx index af0ad4b80414..02bcbf62edc2 100644 --- a/shared/router-v2/account-switcher/index.tsx +++ b/shared/router-v2/account-switcher/index.tsx @@ -14,7 +14,7 @@ const prepareAccountRows = <T extends {username: string; hasStoredSecret: boolea myUsername: string ): Array<T> => accountRows.filter(account => account.username !== myUsername) -const Container = () => { +const AccountSwitcher = () => { const _fullnames = useUsersState(s => s.infoMap) const _accountRows = useConfigState(s => s.configuredAccounts) const you = useCurrentUserState(s => s.username) @@ -202,7 +202,6 @@ const styles = Kb.Styles.styleSheetCreate(() => ({ common: {flexShrink: 1}, isElectron: {wordBreak: 'break-all'}, }), - signOut: {color: Kb.Styles.globalColors.red}, text2: {flexShrink: 0}, userBox: { ...Kb.Styles.paddingH(Kb.Styles.globalMargins.small), @@ -211,4 +210,4 @@ const styles = Kb.Styles.styleSheetCreate(() => ({ waiting: {opacity: 0.5}, })) -export default Container +export default AccountSwitcher diff --git a/shared/router-v2/common.tsx b/shared/router-v2/common.tsx index 6b331bdc0f00..0cd552849462 100644 --- a/shared/router-v2/common.tsx +++ b/shared/router-v2/common.tsx @@ -10,9 +10,7 @@ import Header from './header/index' export const headerDefaultStyle = isMobile ? { - get backgroundColor() { - return isIOS ? Kb.Styles.globalColors.white : Kb.Styles.globalColors.white - }, + backgroundColor: Kb.Styles.globalColors.white, borderBottomColor: Kb.Styles.globalColors.black_10, borderBottomWidth: Kb.Styles.hairlineWidth, height: 44, diff --git a/shared/router-v2/header/index.desktop.tsx b/shared/router-v2/header/index.desktop.tsx index 8083ba381b8c..e112e3e639c6 100644 --- a/shared/router-v2/header/index.desktop.tsx +++ b/shared/router-v2/header/index.desktop.tsx @@ -289,8 +289,6 @@ const styles = Kb.Styles.styleSheetCreate( ...Kb.Styles.desktopStyles.windowDraggingClickable, alignItems: 'center', borderRadius: Kb.Styles.borderRadius, - display: 'inline-block', - ...Kb.Styles.size(14), marginLeft: 4, marginRight: 6, padding: Kb.Styles.globalMargins.xtiny, diff --git a/shared/router-v2/linking.tsx b/shared/router-v2/linking.tsx index e33aab16ff99..8e747eebb456 100644 --- a/shared/router-v2/linking.tsx +++ b/shared/router-v2/linking.tsx @@ -233,74 +233,64 @@ export const createLinkingConfig = ( _fallbackHandler = handleAppLink return { getInitialURL: async () => { - // Compute the startup URL from saved state, push notifications, and deep links. - // This replaces the manual NavigationState construction that was in useInitialState. - const {loggedIn, startup, androidShare} = useConfigState.getState() - if (!loggedIn) return null - - const {tab: startupTab, followUser: startupFollowUser} = startup - let startupConversation = startup.conversation - if (!isValidConversationIDKey(startupConversation)) { - startupConversation = '' - } + const {loggedIn, startup, androidShare} = useConfigState.getState() + if (!loggedIn) return null - // Lazy-require to break require cycle: linking.tsx → push.native.tsx → linking.tsx - - const {usePushState} = require('@/stores/push') as typeof UsePushStateType - const pushState = usePushState.getState() - const showMonster = - !pushState.justSignedUp && pushState.showPushPrompt && !pushState.hasPermissions + const {tab: startupTab, followUser: startupFollowUser} = startup + let startupConversation = startup.conversation + if (!isValidConversationIDKey(startupConversation)) { + startupConversation = '' + } - // Check for an incoming deep link URL (native only) - let deepLinkUrl: string | null = null - if (isMobile) { - try { - deepLinkUrl = await Linking.getInitialURL() - } catch {} - } + // Lazy-require to break require cycle: linking.tsx → push.native.tsx → linking.tsx + const {usePushState} = require('@/stores/push') as typeof UsePushStateType + const pushState = usePushState.getState() + const showMonster = + !pushState.justSignedUp && pushState.showPushPrompt && !pushState.hasPermissions + + let deepLinkUrl: string | null = null + if (isMobile) { + try { + deepLinkUrl = await Linking.getInitialURL() + } catch {} + } - const haveSavedTab = !!(startupTab || startupConversation) + const haveSavedTab = !!(startupTab || startupConversation) - // Deep link URL takes priority - if (deepLinkUrl) { - const normalized = normalizeUrl(deepLinkUrl) - if (normalized) { - if (isHandledByLinkingConfig(normalized)) return normalized - // URL not handled by linking config; use imperative navigation as fallback - setTimeout(() => handleAppLink(normalized), 1) - return null + if (deepLinkUrl) { + const normalized = normalizeUrl(deepLinkUrl) + if (normalized) { + if (isHandledByLinkingConfig(normalized)) return normalized + // URL not handled by linking config; use imperative navigation as fallback + setTimeout(() => handleAppLink(normalized), 1) + return null + } } - } - // Push permission prompt (if no saved state to restore) - if (showMonster && !haveSavedTab) { - return 'keybase://settingsPushPrompt' - } + if (showMonster && !haveSavedTab) { + return 'keybase://settingsPushPrompt' + } - // Android share intent (if no saved state to restore) - if (androidShare && !haveSavedTab) { - return 'keybase://incoming-share' - } + if (androidShare && !haveSavedTab) { + return 'keybase://incoming-share' + } - // Push notification follow user - if (startupFollowUser && !startupConversation) { - _initialURLOnce = `keybase://profile/show/${startupFollowUser}` - return _initialURLOnce - } + if (startupFollowUser && !startupConversation) { + _initialURLOnce = `keybase://profile/show/${startupFollowUser}` + return _initialURLOnce + } - // Saved conversation from last session - if (startupConversation) { - _initialURLOnce = `keybase://convid/${startupConversation}` - return _initialURLOnce - } + if (startupConversation) { + _initialURLOnce = `keybase://convid/${startupConversation}` + return _initialURLOnce + } - // Saved tab from last session - if (startupTab) { - return `keybase://${startupTab}` - } + if (startupTab) { + return `keybase://${startupTab}` + } - return null - }, + return null + }, // Prevent React Navigation from updating window.location on Electron (file:// protocol). // On native this is a no-op since there's no browser URL to update. diff --git a/shared/router-v2/screen-layout-modal.desktop.tsx b/shared/router-v2/screen-layout-modal.desktop.tsx index a4d34e8a62de..e102c32e6bd2 100644 --- a/shared/router-v2/screen-layout-modal.desktop.tsx +++ b/shared/router-v2/screen-layout-modal.desktop.tsx @@ -13,7 +13,7 @@ type ModalHeaderProps = { const ModalHeader = (props: ModalHeaderProps) => ( <Kb.Box2 direction="vertical" fullWidth={true} style={styles.header}> - <Kb.Box2 direction="horizontal" alignItems="center" fullHeight={true} style={Kb.Styles.globalStyles.flexOne}> + <Kb.Box2 direction="horizontal" alignItems="center" fullHeight={true} flex={1}> <Kb.Box2 direction="horizontal" style={styles.headerLeft}> {!!props.leftButton && props.leftButton} </Kb.Box2> diff --git a/shared/settings/about.tsx b/shared/settings/about.tsx index 844431d49b93..3f3759b4c3d8 100644 --- a/shared/settings/about.tsx +++ b/shared/settings/about.tsx @@ -26,7 +26,7 @@ const About = () => { } return ( - <Kb.Box2 direction="vertical" fullWidth={true} fullHeight={true} justifyContent="center" style={styles.container}> + <Kb.Box2 direction="vertical" fullWidth={true} fullHeight={true} justifyContent="center" alignItems="center"> <Kb.ImageIcon type="icon-keybase-logo-64" /> <Kb.Box2 direction="vertical" alignItems="center" style={styles.version}> <Kb.Text center={true} type="Body"> @@ -46,9 +46,6 @@ const About = () => { ) } const styles = Kb.Styles.styleSheetCreate(() => ({ - container: { - alignItems: 'center', - }, terms: { marginBottom: Kb.Styles.globalMargins.tiny, }, diff --git a/shared/settings/account/email-phone-row.tsx b/shared/settings/account/email-phone-row.tsx index b5ce8c071c59..bb1b04c40ed3 100644 --- a/shared/settings/account/email-phone-row.tsx +++ b/shared/settings/account/email-phone-row.tsx @@ -134,7 +134,7 @@ const EmailPhoneRow = (p: {contactKey: string; onEmailVerificationSuccess: (emai return ( <Kb.Box2 direction="horizontal" alignItems="center" fullWidth={true} style={styles.container}> - <Kb.Box2 alignItems="flex-start" direction="vertical" style={{...Kb.Styles.globalStyles.flexOne}}> + <Kb.Box2 alignItems="flex-start" direction="vertical" flex={1}> <Kb.Text type="BodySemibold" selectable={true} lineClamp={1}> {address} </Kb.Text> diff --git a/shared/settings/advanced.tsx b/shared/settings/advanced.tsx index 019ad2837cbf..45d92f186240 100644 --- a/shared/settings/advanced.tsx +++ b/shared/settings/advanced.tsx @@ -108,7 +108,6 @@ const LockdownCheckbox = (p: { settingLockdownMode: boolean }) => { const {hasRandomPW, loaded, lockdownModeEnabled, setLockdownMode, settingLockdownMode} = p - const onChangeLockdownMode = setLockdownMode const readMoreUrlProps = Kb.useClickURL('https://keybase.io/docs/lockdown/index') const label = 'Enable account lockdown mode' + (hasRandomPW ? ' (you need to set a password first)' : '') const checked = hasRandomPW || !!lockdownModeEnabled @@ -117,7 +116,7 @@ const LockdownCheckbox = (p: { <Kb.Checkbox checked={checked} disabled={disabled} - onCheck={onChangeLockdownMode} + onCheck={setLockdownMode} labelComponent={ <Kb.Box2 direction="vertical" alignItems="flex-start" style={Kb.Styles.globalStyles.flexOne}> <Kb.Text type="Body">{label}</Kb.Text> @@ -234,7 +233,7 @@ const Advanced = () => { return ( <Kb.KeyboardAvoidingView2> - <Kb.ScrollView style={styles.scrollview}> + <Kb.ScrollView style={Kb.Styles.globalStyles.fullWidth}> <Kb.Box2 direction="vertical" fullWidth={true}> <Kb.Box2 direction="vertical" gap="tiny" fullWidth={true} style={styles.section}> {settingLockdownMode && <Kb.ProgressIndicator />} @@ -442,9 +441,6 @@ const styles = Kb.Styles.styleSheetCreate( marginTop: Kb.Styles.globalMargins.small, width: '100%', }, - scrollview: { - width: '100%', - }, section: Kb.Styles.platformStyles({ common: { ...Kb.Styles.padding( diff --git a/shared/settings/chat.tsx b/shared/settings/chat.tsx index fd0ac7bb0f7c..8c618ce1ca71 100644 --- a/shared/settings/chat.tsx +++ b/shared/settings/chat.tsx @@ -372,6 +372,7 @@ const Links = () => { <Kb.Box2 fullWidth={true} direction="horizontal" + justifyContent="space-between" style={Kb.Styles.collapseStyles([ styles.whitelistRowContainer, wlremoved ? {backgroundColor: Kb.Styles.globalColors.red_20} : undefined, @@ -491,37 +492,31 @@ const Misc = ({allowEdit, groups, toggle}: NotificationSettingsState) => { const Chat = () => { const notificationSettings = useNotificationSettings() return ( - <Kb.Box2 direction="vertical" fullWidth={true}> - <Kb.ScrollView> - <Kb.Box2 direction="vertical" fullHeight={true} gap="tiny" style={styles.container}> - <Security {...notificationSettings} /> - <Kb.Divider style={styles.divider} /> - <Links /> - <Sound {...notificationSettings} /> - <Misc {...notificationSettings} /> - </Kb.Box2> - </Kb.ScrollView> - </Kb.Box2> + <Kb.ScrollView> + <Kb.Box2 direction="vertical" fullHeight={true} gap="tiny" style={styles.container}> + <Security {...notificationSettings} /> + <Kb.Divider style={styles.divider} /> + <Links /> + <Sound {...notificationSettings} /> + <Misc {...notificationSettings} /> + </Kb.Box2> + </Kb.ScrollView> ) } const TeamRow = (p: {checked: boolean; isOpen: boolean; name: string; onCheck: (c: boolean) => void}) => { const {checked, isOpen, name, onCheck} = p return ( - <Kb.Box2 direction="vertical" fullWidth={true}> - <Kb.Box2 direction="horizontal" fullWidth={true} style={styles.teamRowContainer}> - <Kb.Checkbox checked={checked} onCheck={checked => onCheck(checked)} style={styles.teamCheckbox} /> - <Kb.Avatar isTeam={true} size={isMobile ? 32 : 24} teamname={name} /> - <Kb.Box2 direction="vertical" fullWidth={true} style={styles.teamNameContainer}> - <Kb.Box2 direction="horizontal" fullWidth={true} style={styles.teamText}> - <Kb.Text type="BodySemibold" lineClamp={1}> - {name} - </Kb.Text> - {isOpen && ( - <Kb.Meta title="open" style={styles.teamMeta} backgroundColor={Kb.Styles.globalColors.green} /> - )} - </Kb.Box2> - </Kb.Box2> + <Kb.Box2 direction="horizontal" fullWidth={true} style={styles.teamRowContainer}> + <Kb.Checkbox checked={checked} onCheck={checked => onCheck(checked)} style={styles.teamCheckbox} /> + <Kb.Avatar isTeam={true} size={isMobile ? 32 : 24} teamname={name} /> + <Kb.Box2 direction="horizontal" fullWidth={true} alignSelf="center" style={styles.teamNameContainer}> + <Kb.Text type="BodySemibold" lineClamp={1}> + {name} + </Kb.Text> + {isOpen && ( + <Kb.Meta title="open" style={styles.teamMeta} backgroundColor={Kb.Styles.globalColors.green} /> + )} </Kb.Box2> </Kb.Box2> ) @@ -536,7 +531,6 @@ const styles = Kb.Styles.styleSheetCreate(() => ({ container: Kb.Styles.platformStyles({ common: { ...Kb.Styles.paddingV(Kb.Styles.globalMargins.small), - width: '100%', }, }), divider: {marginBottom: Kb.Styles.globalMargins.small}, @@ -564,7 +558,6 @@ const styles = Kb.Styles.styleSheetCreate(() => ({ marginTop: 2, }, teamNameContainer: { - alignSelf: 'center', flexShrink: 1, marginLeft: Kb.Styles.globalMargins.tiny, marginRight: Kb.Styles.globalMargins.small, @@ -572,9 +565,6 @@ const styles = Kb.Styles.styleSheetCreate(() => ({ teamRowContainer: { ...Kb.Styles.padding(Kb.Styles.globalMargins.xtiny, Kb.Styles.globalMargins.small, Kb.Styles.globalMargins.xtiny, isMobile ? Kb.Styles.globalMargins.large : 48), }, - teamText: { - alignSelf: 'flex-start', - }, whitelist: Kb.Styles.platformStyles({ common: { alignSelf: 'flex-start', @@ -604,7 +594,6 @@ const styles = Kb.Styles.styleSheetCreate(() => ({ backgroundColor: Kb.Styles.globalColors.white, flexShrink: 0, height: 40, - justifyContent: 'space-between', marginLeft: Kb.Styles.globalMargins.tiny, padding: Kb.Styles.globalMargins.tiny, paddingRight: Kb.Styles.globalMargins.small, diff --git a/shared/settings/delete-confirm/index.tsx b/shared/settings/delete-confirm/index.tsx index 91acb1c0d897..e5ff763d5bb2 100644 --- a/shared/settings/delete-confirm/index.tsx +++ b/shared/settings/delete-confirm/index.tsx @@ -87,7 +87,7 @@ const DeleteConfirm = () => { header={ <> <Kb.Avatar username={username} size={64} /> - <Kb.ImageIcon type="icon-team-delete-28" style={{marginRight: -60, marginTop: -20, zIndex: 1}} /> + <Kb.ImageIcon type="icon-team-delete-28" style={styles.deleteIcon} /> </> } onCancel={onCancel} @@ -104,6 +104,7 @@ const styles = Kb.Styles.styleSheetCreate(() => ({ padding: Kb.Styles.globalMargins.mediumLarge, }, }), + deleteIcon: {marginRight: -60, marginTop: -20, zIndex: 1}, randomPWStatus: { padding: Kb.Styles.globalMargins.small, paddingBottom: 0, diff --git a/shared/settings/display.tsx b/shared/settings/display.tsx index 2a86baeeabd6..6ab48022dde2 100644 --- a/shared/settings/display.tsx +++ b/shared/settings/display.tsx @@ -28,7 +28,7 @@ const Display = () => { ) } return ( - <Kb.ScrollView style={styles.scrollview}> + <Kb.ScrollView style={Kb.Styles.globalStyles.fullWidth}> <Kb.Box2 direction="vertical" fullWidth={true} flex={1} style={styles.container}> <Kb.Box2 direction="vertical" fullWidth={true} gap="medium"> <Kb.Box2 direction="vertical" fullWidth={true} gap="tiny"> @@ -79,9 +79,6 @@ const styles = Kb.Styles.styleSheetCreate(() => ({ container: { padding: Kb.Styles.globalMargins.small, }, - scrollview: { - width: '100%', - }, })) export default Display diff --git a/shared/settings/feedback/container.shared.tsx b/shared/settings/feedback/container.shared.tsx deleted file mode 100644 index e983cc31075e..000000000000 --- a/shared/settings/feedback/container.shared.tsx +++ /dev/null @@ -1,4 +0,0 @@ -export type Props = { - heading?: string - feedback?: string -} diff --git a/shared/settings/feedback/container.tsx b/shared/settings/feedback/container.tsx index e732ddea195c..c86249656231 100644 --- a/shared/settings/feedback/container.tsx +++ b/shared/settings/feedback/container.tsx @@ -8,10 +8,11 @@ import logger from '@/logger' import {Platform} from 'react-native' import {getExtraChatLogsForLogSend, useSendFeedback} from './shared' import {version, pprofDir} from '@/constants/platform' -import type {Props as OwnProps} from './container.shared' import {usePushState} from '@/stores/push' import {appVersionName, appVersionCode, logSend} from 'react-native-kb' -export type {Props} from './container.shared' + +type OwnProps = {heading?: string; feedback?: string} +export type Props = OwnProps const mobileOsVersion = Platform.Version diff --git a/shared/settings/feedback/index.tsx b/shared/settings/feedback/index.tsx index 0b3497691f9e..93447f719008 100644 --- a/shared/settings/feedback/index.tsx +++ b/shared/settings/feedback/index.tsx @@ -45,18 +45,6 @@ const Feedback = (props: Props) => { lastSendErrorRef.current = sendError }, [sending, sendError, onFeedbackDone, feedback, showInternalSuccessBanner]) - const _onChangeFeedback = (feedback: string) => { - setFeedback(feedback) - } - - const _onChangeSendLogs = (sendLogs: boolean) => { - setSendLogs(sendLogs) - } - - const _onChangeEmail = (email: string) => { - setEmail(email) - } - const _sendMaxBytes = () => clickCount >= clickThreshold const _onSendFeedback = () => { @@ -83,7 +71,7 @@ const Feedback = (props: Props) => { containerStyle={styles.input} inputStyle={styles.inputResize} multiline={true} - onChangeText={_onChangeFeedback} + onChangeText={setFeedback} placeholder="Please tell us what you were doing, your experience, or anything else we should know. Thanks!" rowsMin={4} rowsMax={isMobile ? 4 : 10} @@ -101,7 +89,7 @@ const Feedback = (props: Props) => { label="Include your logs" labelSubtitle="This includes some private metadata info (e.g., file sizes, but not names or contents) but it will help the developers fix bugs more quickly." checked={sendLogs} - onCheck={_onChangeSendLogs} + onCheck={setSendLogs} /> </Kb.ClickableBox3> </Kb.Box2> @@ -110,7 +98,7 @@ const Feedback = (props: Props) => { <Kb.Input3 containerStyle={styles.input} placeholder="Your email address" - onChangeText={_onChangeEmail} + onChangeText={setEmail} /> </Kb.Box2> )} diff --git a/shared/settings/notifications/index.tsx b/shared/settings/notifications/index.tsx index a3f15e5903a1..e65e55a1c30f 100644 --- a/shared/settings/notifications/index.tsx +++ b/shared/settings/notifications/index.tsx @@ -9,40 +9,20 @@ import {usePushState} from '@/stores/push' const TurnOnNotifications = () => { const mobileHasPermissions = usePushState(s => s.hasPermissions) - const requestPermissions = usePushState(s => s.dispatch.requestPermissions) + const onEnable = usePushState(s => s.dispatch.requestPermissions) if (mobileHasPermissions) return null - const onEnable = requestPermissions return ( <Kb.Box2 direction="vertical" fullWidth={true} relative={true} overflow="hidden" - style={{backgroundColor: Kb.Styles.globalColors.red, height: 330}} + style={styles.turnOnOuter} > - <Kb.Box2 - direction="vertical" - style={{ - height: 270, - left: Kb.Styles.globalMargins.medium, - position: 'absolute', - top: -20, - width: 250, - }} - > + <Kb.Box2 direction="vertical" style={styles.turnOnIllustration}> <Kb.ImageIcon type="illustration-turn-on-notifications" /> </Kb.Box2> - <Kb.Text - type="BodySemibold" - center={true} - negative={true} - style={{ - bottom: Kb.Styles.globalMargins.medium, - left: Kb.Styles.globalMargins.small, - position: 'absolute', - right: Kb.Styles.globalMargins.small, - }} - > + <Kb.Text type="BodySemibold" center={true} negative={true} style={styles.turnOnText}> You turned off native notifications for Keybase. It's{' '} <Kb.Text type="BodySemiboldItalic" negative={true}> very @@ -86,7 +66,7 @@ const Notifications = () => { onReload={onReload} reloadOnMount={true} > - <Kb.ScrollView style={{...Kb.Styles.globalStyles.flexBoxColumn, flex: 1}}> + <Kb.ScrollView style={styles.scrollView}> <TurnOnNotifications /> <Render {...props} /> </Kb.ScrollView> @@ -94,4 +74,25 @@ const Notifications = () => { ) } +const styles = Kb.Styles.styleSheetCreate(() => ({ + scrollView: {...Kb.Styles.globalStyles.flexBoxColumn, flex: 1}, + turnOnIllustration: { + height: 270, + left: Kb.Styles.globalMargins.medium, + position: 'absolute', + top: -20, + width: 250, + }, + turnOnOuter: { + backgroundColor: Kb.Styles.globalColors.red, + height: 330, + }, + turnOnText: { + bottom: Kb.Styles.globalMargins.medium, + left: Kb.Styles.globalMargins.small, + position: 'absolute', + right: Kb.Styles.globalMargins.small, + }, +})) + export default Notifications diff --git a/shared/settings/notifications/render.tsx b/shared/settings/notifications/render.tsx index b2eff4958f95..ef74d509b490 100644 --- a/shared/settings/notifications/render.tsx +++ b/shared/settings/notifications/render.tsx @@ -52,7 +52,7 @@ const Notifications = (props: Props) => { const hasLoadedGroups = props.groups.size > 0 const emailGroup = props.groups.get('email') return !hasLoadedGroups ? ( - <Kb.Box2 direction="vertical" justifyContent="center" flex={1} style={styles.loading}> + <Kb.Box2 direction="vertical" justifyContent="center" alignItems="center" flex={1}> <Kb.ProgressIndicator type="Small" style={{width: Kb.Styles.globalMargins.medium}} /> </Kb.Box2> ) : ( @@ -89,7 +89,6 @@ const styles = Kb.Styles.styleSheetCreate( marginLeft: -Kb.Styles.globalMargins.small, marginTop: Kb.Styles.globalMargins.small, }, - loading: {alignItems: 'center'}, main: Kb.Styles.platformStyles({ common: {flex: 1, padding: Kb.Styles.globalMargins.small, paddingRight: 0}, isElectron: Kb.Styles.desktopStyles.scrollable, diff --git a/shared/settings/password.tsx b/shared/settings/password.tsx index 231928ed259a..881e036e1beb 100644 --- a/shared/settings/password.tsx +++ b/shared/settings/password.tsx @@ -15,6 +15,13 @@ type Props = { waitingForResponse?: boolean } +const errorSavingFunc = (password: string, passwordConfirm: string): string => { + if (password && passwordConfirm && password !== passwordConfirm) { + return 'Passwords must match.' + } + return '' +} + export const UpdatePassword = (props: Props) => { const [password, setPassword] = React.useState('') const [passwordConfirm, setPasswordConfirm] = React.useState('') @@ -31,13 +38,6 @@ export const UpdatePassword = (props: Props) => { setErrorSaving(errorSavingFunc(password, passwordConfirm)) } - const errorSavingFunc = (password: string, passwordConfirm: string): string => { - if (password && passwordConfirm && password !== passwordConfirm) { - return 'Passwords must match.' - } - return '' - } - const canSubmit = () => !errorSaving && password.length >= 8 && password === passwordConfirm const keyboardType = showTyping && isAndroid ? 'visible-password' : 'default' diff --git a/shared/settings/proxy.tsx b/shared/settings/proxy.tsx index b160e1b09ceb..867ae6b64098 100644 --- a/shared/settings/proxy.tsx +++ b/shared/settings/proxy.tsx @@ -236,14 +236,12 @@ const ProxySettingsComponent = (props: Props) => { const ProxySettingsPopup = (props: Props) => { return ( - <> - <Kb.Box2 direction="vertical" fullWidth={true} style={styles.popupBox}> - {!isMobile && <Kb.BackButton onClick={props.onBack} />} - <Kb.Box2 direction="vertical" fullWidth={true} style={styles.proxySettingPopupBox}> - <ProxySettingsComponent {...props} /> - </Kb.Box2> + <Kb.Box2 direction="vertical" fullWidth={true} style={styles.popupBox}> + {!isMobile && <Kb.BackButton onClick={props.onBack} />} + <Kb.Box2 direction="vertical" fullWidth={true} style={styles.proxySettingPopupBox}> + <ProxySettingsComponent {...props} /> </Kb.Box2> - </> + </Kb.Box2> ) } diff --git a/shared/settings/routes.tsx b/shared/settings/routes.tsx index 1736bdf966e8..9beeba0bdcba 100644 --- a/shared/settings/routes.tsx +++ b/shared/settings/routes.tsx @@ -8,7 +8,7 @@ import * as Settings from '@/constants/settings' import {defineRouteMap} from '@/constants/types/router' import {usePushState} from '@/stores/push' import {e164ToDisplay} from '@/util/phone-numbers' -import type {Props as FeedbackRouteParams} from './feedback/container.shared' +type FeedbackRouteParams = {heading?: string; feedback?: string} export type SettingsAccountRouteParams = { addedEmailBannerEmail?: string diff --git a/shared/settings/subheading.shared.tsx b/shared/settings/subheading.shared.tsx deleted file mode 100644 index a715c061e3ce..000000000000 --- a/shared/settings/subheading.shared.tsx +++ /dev/null @@ -1,5 +0,0 @@ -import type * as React from 'react' - -export type Props = { - children?: React.ReactNode -} diff --git a/shared/signup/common.tsx b/shared/signup/common.tsx index af92c6bbc008..f5e02511c918 100644 --- a/shared/signup/common.tsx +++ b/shared/signup/common.tsx @@ -5,6 +5,11 @@ import {type ButtonProps} from '@/common-adapters/button' import {openURL} from '@/util/misc' import {useConfigState} from '@/stores/config' +export const desktopInputWidth = Kb.Styles.platformStyles({ + isElectron: {width: 368}, + isTablet: {width: 368}, +}) + type InfoIconProps = { invisible?: boolean style?: Kb.Styles.StylesCrossPlatform @@ -60,7 +65,6 @@ type HeaderProps = { showInfoIconRow: boolean style: Kb.Styles.StylesCrossPlatform negative: boolean - rightActionComponent?: React.ReactNode rightActionLabel?: string onRightAction?: () => void } @@ -106,11 +110,6 @@ const Header = (props: HeaderProps) => ( style={styles.rightActionButton} /> )} - {props.rightActionComponent && ( - <Kb.Box2 direction="horizontal" style={styles.rightAction} justifyContent="center"> - {props.rightActionComponent} - </Kb.Box2> - )} </Kb.Box2> </Kb.Box2> ) @@ -138,11 +137,10 @@ type SignupScreenProps = { title?: string titleComponent?: React.ReactNode header?: React.ReactNode - rightActionComponent?: React.ReactNode rightActionLabel?: string onRightAction?: () => void - showHeaderInfoicon?: boolean - showHeaderInfoiconRow?: boolean + showHeaderInfoIcon?: boolean + showHeaderInfoIconRow?: boolean hideDesktopHeader?: boolean } @@ -163,14 +161,13 @@ export const SignupScreen = (props: SignupScreenProps) => { onBack={props.onBack} title={props.title} titleComponent={props.titleComponent} - showInfoIcon={!!props.showHeaderInfoicon} - showInfoIconRow={!!props.showHeaderInfoiconRow} + showInfoIcon={!!props.showHeaderInfoIcon} + showInfoIconRow={!!props.showHeaderInfoIconRow} style={Kb.Styles.collapseStyles([ props.noBackground && styles.whiteHeaderContainer, props.headerStyle, ])} negative={!!props.negativeHeader} - rightActionComponent={props.rightActionComponent} rightActionLabel={props.rightActionLabel} onRightAction={props.onRightAction} /> @@ -200,7 +197,7 @@ export const SignupScreen = (props: SignupScreenProps) => { {props.footer} </Kb.Box2> )} - {!!props.banners && <Kb.Box2 direction="vertical" style={styles.banners} children={props.banners} />} + {!!props.banners && <Kb.Box2 direction="vertical" style={styles.banners}>{props.banners}</Kb.Box2>} {!!props.buttons && ( <Kb.ButtonBar direction="column" @@ -304,18 +301,6 @@ const styles = Kb.Styles.styleSheetCreate( opacityNone: { opacity: 0, }, - rightAction: Kb.Styles.platformStyles({ - common: { - alignItems: 'center', - alignSelf: 'flex-end', - bottom: 0, - paddingRight: Kb.Styles.globalMargins.small, - position: 'absolute', - right: 0, - top: 0, - }, - isElectron: Kb.Styles.desktopStyles.windowDraggingClickable, - }), rightActionButton: Kb.Styles.platformStyles({ common: { position: 'absolute', diff --git a/shared/signup/device-name.tsx b/shared/signup/device-name.tsx index b007aa694959..c9d7f6da2204 100644 --- a/shared/signup/device-name.tsx +++ b/shared/signup/device-name.tsx @@ -1,7 +1,7 @@ import * as C from '@/constants' import * as Kb from '@/common-adapters' import * as React from 'react' -import {SignupScreen, errorBanner} from './common' +import {SignupScreen, errorBanner, desktopInputWidth} from './common' import * as Provision from '@/stores/provision' import {usePushState} from '@/stores/push' import * as T from '@/constants/types' @@ -140,7 +140,7 @@ const EnterDevicename = (props: EnterDevicenameProps) => { direction="vertical" gap={isMobile ? 'small' : 'medium'} fullWidth={true} - style={Kb.Styles.globalStyles.flexOne} + flex={1} > <Kb.ImageIcon type={ @@ -182,8 +182,5 @@ const styles = Kb.Styles.styleSheetCreate(() => ({ color: Kb.Styles.globalColors.redDark, marginLeft: 2, }, - input: Kb.Styles.platformStyles({ - isElectron: {width: 368}, - isTablet: {width: 368}, - }), + input: desktopInputWidth, })) diff --git a/shared/signup/email.tsx b/shared/signup/email.tsx index c3f0d49fd0ec..f33ad4f23303 100644 --- a/shared/signup/email.tsx +++ b/shared/signup/email.tsx @@ -1,7 +1,7 @@ import * as C from '@/constants' import * as React from 'react' import * as Kb from '@/common-adapters' -import {SignupScreen, errorBanner} from './common' +import {SignupScreen, errorBanner, desktopInputWidth} from './common' import {useAddEmail} from '@/settings/account/use-add-email' import {usePushState} from '@/stores/push' import {setSignupEmail} from '@/people/signup-email' @@ -11,12 +11,7 @@ const ConnectedEnterEmail = () => { const {error, submitEmail, waiting} = useAddEmail() const clearModals = C.Router2.clearModals const navigateAppend = C.Router2.navigateAppend - const _onSkip = () => { - setSignupEmail(C.noEmail) - } - - const onSkip = () => { - _onSkip() + const afterEmail = () => { if (_showPushPrompt) { navigateAppend({name: 'settingsPushPrompt', params: {}}, true) } else { @@ -24,14 +19,15 @@ const ConnectedEnterEmail = () => { } } + const onSkip = () => { + setSignupEmail(C.noEmail) + afterEmail() + } + const onCreate = (email: string, searchable: boolean) => { submitEmail(email, searchable, addedEmail => { setSignupEmail(addedEmail) - if (_showPushPrompt) { - navigateAppend({name: 'settingsPushPrompt', params: {}}, true) - } else { - clearModals() - } + afterEmail() }) } @@ -54,13 +50,13 @@ const ConnectedEnterEmail = () => { label: 'Finish', onClick: onContinue, type: 'Success', - waiting: waiting, + waiting, }, ]} rightActionLabel="Skip" onRightAction={onSkip} title="Your email address" - showHeaderInfoicon={true} + showHeaderInfoIcon={true} > <EnterEmailBody onChangeEmail={onChangeEmail} @@ -91,7 +87,7 @@ export const EnterEmailBody = (props: BodyProps) => ( direction="vertical" gap={isMobile ? 'small' : 'medium'} fullWidth={true} - style={Kb.Styles.globalStyles.flexOne} + flex={1} > <Kb.ImageIcon type={props.iconType} /> <Kb.Box2 direction="vertical" gap="tiny" style={styles.inputBox}> @@ -120,13 +116,12 @@ export const EnterEmailBody = (props: BodyProps) => ( const styles = Kb.Styles.styleSheetCreate(() => ({ checkbox: {width: '100%'}, - input: Kb.Styles.platformStyles({ - isElectron: {width: 368}, - }), + input: desktopInputWidth, inputBox: Kb.Styles.platformStyles({ // need to set width so subtext will wrap isElectron: {width: 368}, isMobile: {width: '100%'}, + isTablet: {width: 368}, }), })) diff --git a/shared/signup/feedback.tsx b/shared/signup/feedback.tsx index 098ce288a1c2..3e14912d841b 100644 --- a/shared/signup/feedback.tsx +++ b/shared/signup/feedback.tsx @@ -26,8 +26,7 @@ const SignupFeedback = () => { } title="Send feedback" onBack={C.Router2.navigateUp} - showHeaderInfoicon={false} - showHeaderInfoiconRow={!loggedOut} + showHeaderInfoIconRow={!loggedOut} > <FeedbackForm sendError="" diff --git a/shared/signup/phone-number/index.tsx b/shared/signup/phone-number/index.tsx index 63d105674233..49526a17bdb2 100644 --- a/shared/signup/phone-number/index.tsx +++ b/shared/signup/phone-number/index.tsx @@ -1,7 +1,7 @@ import * as C from '@/constants' import * as React from 'react' import * as Kb from '@/common-adapters' -import {SignupScreen, errorBanner} from '../common' +import {SignupScreen, errorBanner, desktopInputWidth} from '../common' import {useAddPhoneNumber} from './use-verification' import {useDefaultPhoneCountry} from '@/util/phone-numbers' @@ -21,6 +21,7 @@ export const EnterPhoneNumberBody = (props: BodyProps) => { <Kb.Box2 alignItems="center" direction="vertical" + flex={1} gap={isMobile ? 'small' : 'medium'} fullWidth={true} style={styles.container} @@ -52,7 +53,6 @@ export const EnterPhoneNumberBody = (props: BodyProps) => { const styles = Kb.Styles.styleSheetCreate(() => ({ checkbox: {width: '100%'}, container: Kb.Styles.platformStyles({ - common: Kb.Styles.globalStyles.flexOne, isTablet: {maxWidth: 386}, }), input: Kb.Styles.platformStyles({ @@ -65,10 +65,7 @@ const styles = Kb.Styles.styleSheetCreate(() => ({ width: '100%', }, }), - inputBox: Kb.Styles.platformStyles({ - // need to set width so subtext will wrap - isElectron: {width: 368}, - }), + inputBox: desktopInputWidth, })) const ConnectedEnterPhoneNumber = () => { @@ -90,13 +87,6 @@ const ConnectedEnterPhoneNumber = () => { navigateAppend({name: 'signupVerifyPhoneNumber', params: {phoneNumber: submittedPhoneNumber}}) }) } - const onChangeNumberCb = (phoneNumber: string, validity: boolean) => { - if (error) { - clearError() - } - onChangePhoneNumber(phoneNumber) - onChangeValidity(validity) - } return ( <SignupScreen buttons={[ @@ -104,20 +94,24 @@ const ConnectedEnterPhoneNumber = () => { disabled, label: 'Continue', onClick: onContinue, - type: 'Success' as const, - waiting: waiting, + type: 'Success', + waiting, }, ]} banners={errorBanner(error)} rightActionLabel="Skip" onRightAction={onSkip} title="Your phone number" - showHeaderInfoicon={true} + showHeaderInfoIcon={true} > <EnterPhoneNumberBody autoFocus={!isMobile} defaultCountry={defaultCountry} - onChangeNumber={onChangeNumberCb} + onChangeNumber={(phoneNumber, validity) => { + if (error) clearError() + onChangePhoneNumber(phoneNumber) + onChangeValidity(validity) + }} onContinue={onContinue} searchable={true} iconType={C.isLargeScreen ? 'icon-phone-number-add-96' : 'icon-phone-number-add-64'} diff --git a/shared/signup/phone-number/verify.tsx b/shared/signup/phone-number/verify.tsx index 934fcbcba3e3..7096be43ae87 100644 --- a/shared/signup/phone-number/verify.tsx +++ b/shared/signup/phone-number/verify.tsx @@ -8,7 +8,7 @@ import {usePhoneVerification} from './use-verification' type Props = {route: {params: {phoneNumber: string}}} -const Container = ({route}: Props) => { +const VerifyPhoneNumber = ({route}: Props) => { const {phoneNumber} = route.params const resendWaiting = C.Waiting.useAnyWaiting(C.waitingKeySettingsPhoneResendVerification) const verifyWaiting = C.Waiting.useAnyWaiting(C.waitingKeySettingsPhoneVerifyPhoneNumber) @@ -56,11 +56,11 @@ const Container = ({route}: Props) => { <Kb.Text type="BodyTinySemibold" style={styles.headerText} center={true}> {displayPhone} </Kb.Text> - <Kb.Box2 direction="horizontal" style={Kb.Styles.globalStyles.flexOne} /> + <Kb.Box2 direction="horizontal" flex={1} /> </Kb.Box2> } negativeHeader={true} - showHeaderInfoicon={true} + showHeaderInfoIcon={true} > <VerifyBody onChangeCode={onChangeCode} code={code} onResend={onResend} resendWaiting={resendWaiting} /> </SignupScreen> @@ -83,4 +83,4 @@ const styles = Kb.Styles.styleSheetCreate( }) as const ) -export default Container +export default VerifyPhoneNumber diff --git a/shared/signup/username.tsx b/shared/signup/username.tsx index bd8ae10411b5..1fe5d73c9d92 100644 --- a/shared/signup/username.tsx +++ b/shared/signup/username.tsx @@ -1,7 +1,7 @@ import * as C from '@/constants' import * as Kb from '@/common-adapters' import * as React from 'react' -import {SignupScreen, errorBanner} from './common' +import {SignupScreen, errorBanner, desktopInputWidth} from './common' import {useProvisionState} from '@/stores/provision' import * as T from '@/constants/types' import {RPCError} from '@/util/errors' @@ -88,7 +88,7 @@ const EnterUsername = (props: EnterUsernameProps) => { props.onContinue(usernameTrimmed) } const eulaLabel = ( - <Kb.Text type={isMobile ? 'BodySmall' : 'Body'} style={{alignSelf: 'center'}}> + <Kb.Text type={isMobile ? 'BodySmall' : 'Body'} style={styles.eulaText}> I accept the{' '} <Kb.Text type={isMobile ? 'BodySmallPrimaryLink' : 'BodyPrimaryLink'} @@ -125,7 +125,7 @@ const EnterUsername = (props: EnterUsernameProps) => { } buttons={[ { - disabled: disabled, + disabled, label: 'Continue', onClick: onContinue, type: 'Success', @@ -165,10 +165,8 @@ const EnterUsername = (props: EnterUsernameProps) => { } const styles = Kb.Styles.styleSheetCreate(() => ({ - input: Kb.Styles.platformStyles({ - isElectron: {width: 368}, - isTablet: {width: 368}, - }), + eulaText: {alignSelf: 'center' as const}, + input: desktopInputWidth, })) export default ConnectedEnterUsername diff --git a/shared/team-building/contact-restricted.tsx b/shared/team-building/contact-restricted.tsx index 35b78ee9dfb0..7ea1578a7dd2 100644 --- a/shared/team-building/contact-restricted.tsx +++ b/shared/team-building/contact-restricted.tsx @@ -63,11 +63,7 @@ export const ContactRestricted = (props: Props) => { type={isMobile ? 'Large' : 'Small'} icon={<Kb.Avatar size={isMobile ? 48 : 32} username={username} />} firstItem={idx === 0} - body={ - <Kb.Box2 direction="vertical" fullWidth={true}> - <Kb.Text type="BodySemibold">{username}</Kb.Text> - </Kb.Box2> - } + body={<Kb.Text type="BodySemibold">{username}</Kb.Text>} /> ))} </> @@ -114,12 +110,4 @@ const styles = Kb.Styles.styleSheetCreate(() => ({ }, })) -const ContactContainer = (ownProps: Props) => { - const props = { - source: ownProps.source, - usernames: ownProps.usernames, - } - return <ContactRestricted {...props} /> -} - -export default ContactContainer +export default ContactRestricted diff --git a/shared/team-building/continue-button.tsx b/shared/team-building/continue-button.tsx index afdcffb300f1..6dff0bc7d50b 100644 --- a/shared/team-building/continue-button.tsx +++ b/shared/team-building/continue-button.tsx @@ -1,4 +1,4 @@ -import * as Kb from '@/common-adapters/index' +import * as Kb from '@/common-adapters' export type Props = { label: string diff --git a/shared/team-building/email-search.tsx b/shared/team-building/email-search.tsx index 28a46928c6f6..0ab81a8168d0 100644 --- a/shared/team-building/email-search.tsx +++ b/shared/team-building/email-search.tsx @@ -23,15 +23,15 @@ const EmailSearch = ({continueLabel, namespace, search}: EmailSearchProps) => { const canSubmit = !!user && !waiting && isEmailValid const onChange = (_text: string) => { - // Remove leading or trailing whitespace - const text = _text.trim() - setEmailString(text) - const valid = validateEmailAddress(text) - setEmailValidity(valid) - if (valid) { - search(text, 'email') - } + // Remove leading or trailing whitespace + const text = _text.trim() + setEmailString(text) + const valid = validateEmailAddress(text) + setEmailValidity(valid) + if (valid) { + search(text, 'email') } + } const addUsersToTeamSoFar = TB.useTBContext(s => s.dispatch.addUsersToTeamSoFar) diff --git a/shared/team-building/go-button.tsx b/shared/team-building/go-button.tsx index ffb840e045a6..73f224922103 100644 --- a/shared/team-building/go-button.tsx +++ b/shared/team-building/go-button.tsx @@ -1,4 +1,4 @@ -import * as Kb from '@/common-adapters/index' +import * as Kb from '@/common-adapters' import type * as T from '@/constants/types' export type Props = { diff --git a/shared/team-building/index.tsx b/shared/team-building/index.tsx index e1c57a5f643f..75aabcfa989c 100644 --- a/shared/team-building/index.tsx +++ b/shared/team-building/index.tsx @@ -10,7 +10,7 @@ import TeamBox from './team-box' import logger from '@/logger' import {ContactsBanner} from './contacts' import {ListBody} from './list-body' -import {serviceIdToSearchPlaceholder} from './shared' +import {serviceIdToSearchPlaceholder, getSearchResults} from './shared' import {FilteredServiceTabBar} from './filtered-service-tab-bar' import {useSharedValue} from '@/common-adapters/reanimated' @@ -41,12 +41,6 @@ const deriveSelectedUsers = (teamSoFar: ReadonlySet<T.TB.User>): Array<T.TB.Sele } }) -const getUserResults = ( - searchResults: TB.State['searchResults'], - searchString: string, - selectedService: T.TB.ServiceIdWithContact -) => searchResults.get(searchString.trim())?.get(selectedService) - const findUserById = (users: ReadonlyArray<T.TB.User> | undefined, userId: string) => users?.find(user => user.id === userId) @@ -69,7 +63,7 @@ const useTeamBuildingData = (searchString: string, selectedService: T.TB.Service error, teamSoFar: deriveSelectedUsers(rawTeamSoFar), userRecs, - userResults: getUserResults(searchResults, searchString, selectedService), + userResults: getSearchResults(searchResults, searchString, selectedService), } } diff --git a/shared/team-building/input.tsx b/shared/team-building/input.tsx index e6750191791d..c8bbeb17d0c9 100644 --- a/shared/team-building/input.tsx +++ b/shared/team-building/input.tsx @@ -1,5 +1,5 @@ import * as React from 'react' -import * as Kb from '@/common-adapters/index' +import * as Kb from '@/common-adapters' type Props = { onChangeText: (newText: string) => void @@ -62,15 +62,15 @@ const Input = (props: Props) => { }, [focusCounter, prevFocusCounterRef]) const onKeyDown = (e: React.KeyboardEvent) => { - handleKeyDown( - () => e.preventDefault(), - e.ctrlKey, - e.key, - onUpArrowKeyDown, - onDownArrowKeyDown, - onEnterKeyDown - ) - } + handleKeyDown( + () => e.preventDefault(), + e.ctrlKey, + e.key, + onUpArrowKeyDown, + onDownArrowKeyDown, + onEnterKeyDown + ) + } return ( <Kb.Box2 direction="vertical" fullWidth={true} style={styles.container}> diff --git a/shared/team-building/list-body.tsx b/shared/team-building/list-body.tsx index ac07a184854f..208842ab1947 100644 --- a/shared/team-building/list-body.tsx +++ b/shared/team-building/list-body.tsx @@ -215,12 +215,6 @@ const sortAndSplitRecommendations = ( return sections.filter(section => section.data.length > 0) } -const getSearchResults = ( - searchResults: TB.State['searchResults'], - searchString: string, - selectedService: T.TB.ServiceIdWithContact -) => searchResults.get(searchString.trim())?.get(selectedService) - const getSelectableResults = ( showRecs: boolean, recommendations: ReadonlyArray<Types.SearchRecSection> | undefined, @@ -274,7 +268,7 @@ const useListBodyData = ({ following, preExistingTeamMembers ) - const userResults = getSearchResults(allSearchResults, searchString, selectedService) + const userResults = Shared.getSearchResults(allSearchResults, searchString, selectedService) const searchResults = deriveSearchResults( userResults, teamSoFar, diff --git a/shared/team-building/phone-search.tsx b/shared/team-building/phone-search.tsx index f802f7d251f7..fd4c6367f850 100644 --- a/shared/team-building/phone-search.tsx +++ b/shared/team-building/phone-search.tsx @@ -1,7 +1,7 @@ import * as C from '@/constants' import * as TB from '@/stores/team-building' import * as React from 'react' -import * as Kb from '@/common-adapters/index' +import * as Kb from '@/common-adapters' import type * as T from '@/constants/types' import ContinueButton from './continue-button' import {searchWaitingKey} from '@/constants/strings' diff --git a/shared/team-building/recs-and-recos.tsx b/shared/team-building/recs-and-recos.tsx index 7a7b344528bd..3292643d1cf9 100644 --- a/shared/team-building/recs-and-recos.tsx +++ b/shared/team-building/recs-and-recos.tsx @@ -31,7 +31,7 @@ export const numSectionLabel = '0-9' const SearchHintText = () => ( <Kb.Box2 direction="vertical" style={styles.searchHint}> - <Kb.Text type="BodySmall" style={{textAlign: 'center'}}> + <Kb.Text type="BodySmall" center={true}> Search anyone on Keybase by typing a username or a full name. </Kb.Text> </Kb.Box2> diff --git a/shared/team-building/search-result/common-result.tsx b/shared/team-building/search-result/common-result.tsx index c663681ae17f..81362c7014bf 100644 --- a/shared/team-building/search-result/common-result.tsx +++ b/shared/team-building/search-result/common-result.tsx @@ -353,6 +353,15 @@ const Username = (props: { } export const userResultHeight = isMobile ? Kb.Styles.globalMargins.xlarge : 48 + +// Shared row padding used by UserResult, YouResult, and HellobotResult +export const rowContainerWithLargePadding = Kb.Styles.padding( + Kb.Styles.globalMargins.tiny, + Kb.Styles.globalMargins.medium, + Kb.Styles.globalMargins.tiny, + Kb.Styles.globalMargins.xsmall +) + const styles = Kb.Styles.styleSheetCreate(() => ({ actionButtonsHighlighted: Kb.Styles.platformStyles({ isElectron: { diff --git a/shared/team-building/search-result/hellobot-result.tsx b/shared/team-building/search-result/hellobot-result.tsx index d266ca16c3eb..41a98e58fce6 100644 --- a/shared/team-building/search-result/hellobot-result.tsx +++ b/shared/team-building/search-result/hellobot-result.tsx @@ -2,7 +2,7 @@ import type * as React from 'react' import {previewConversation} from '@/constants/router' import {useTBContext} from '@/stores/team-building' import * as Kb from '@/common-adapters' -import CommonResult, {type ResultProps} from './common-result' +import CommonResult, {type ResultProps, rowContainerWithLargePadding} from './common-result' const HellobotResult = function HellobotResult(props: ResultProps) { const cancelTeamBuilding = useTBContext(s => s.dispatch.cancelTeamBuilding) @@ -14,18 +14,9 @@ const HellobotResult = function HellobotResult(props: ResultProps) { } const bottomRow: React.ReactNode = <Kb.Text type="BodySmall">Say hi, play puzzles, or ask for help</Kb.Text> - return <CommonResult {...props} onAdd={onSelfChat} rowStyle={styles.rowContainer} bottomRow={bottomRow} /> + return ( + <CommonResult {...props} onAdd={onSelfChat} rowStyle={rowContainerWithLargePadding} bottomRow={bottomRow} /> + ) } -const styles = Kb.Styles.styleSheetCreate(() => ({ - rowContainer: { - ...Kb.Styles.padding( - Kb.Styles.globalMargins.tiny, - Kb.Styles.globalMargins.medium, - Kb.Styles.globalMargins.tiny, - Kb.Styles.globalMargins.xsmall - ), - }, -})) - export default HellobotResult diff --git a/shared/team-building/search-result/people-result.tsx b/shared/team-building/search-result/people-result.tsx index afe14c80579f..4313b1103f95 100644 --- a/shared/team-building/search-result/people-result.tsx +++ b/shared/team-building/search-result/people-result.tsx @@ -143,11 +143,9 @@ const DropdownButton = (p: DropdownProps) => { ref={popupAnchor} direction="vertical" > - <Kb.Box2 direction="horizontal" fullWidth={true} gap="xsmall"> - <Kb.Button onClick={undefined} mode="Secondary" style={styles.dropdownButton} small={true}> - <Kb.Icon color={Kb.Styles.globalColors.blue} type="iconfont-ellipsis" /> - </Kb.Button> - </Kb.Box2> + <Kb.Button onClick={undefined} mode="Secondary" style={styles.dropdownButton} small={true}> + <Kb.Icon color={Kb.Styles.globalColors.blue} type="iconfont-ellipsis" /> + </Kb.Button> {popup} </Kb.ClickableBox3> ) diff --git a/shared/team-building/search-result/user-result.tsx b/shared/team-building/search-result/user-result.tsx index 52031d5ee9da..dc2434705d79 100644 --- a/shared/team-building/search-result/user-result.tsx +++ b/shared/team-building/search-result/user-result.tsx @@ -1,6 +1,6 @@ import type * as React from 'react' import * as Kb from '@/common-adapters' -import CommonResult, {type ResultProps} from './common-result' +import CommonResult, {type ResultProps, rowContainerWithLargePadding} from './common-result' import YouResult from './you-result' import HellobotResult from './hellobot-result' @@ -17,7 +17,7 @@ const UserResult = function UserResult(props: ResultProps) { return ( <CommonResult {...props} - rowStyle={styles.rowContainer} + rowStyle={rowContainerWithLargePadding} rightButtons={ !props.isPreExistingTeamMember && ( <ActionButton @@ -82,14 +82,6 @@ const styles = Kb.Styles.styleSheetCreate(() => ({ marginRight: Kb.Styles.globalMargins.tiny, }, }), - rowContainer: { - ...Kb.Styles.padding( - Kb.Styles.globalMargins.tiny, - Kb.Styles.globalMargins.medium, - Kb.Styles.globalMargins.tiny, - Kb.Styles.globalMargins.xsmall - ), - }, })) export default UserResult diff --git a/shared/team-building/search-result/you-result.tsx b/shared/team-building/search-result/you-result.tsx index a54bf528261b..4bcec9712fb6 100644 --- a/shared/team-building/search-result/you-result.tsx +++ b/shared/team-building/search-result/you-result.tsx @@ -2,7 +2,7 @@ import type * as React from 'react' import {previewConversation} from '@/constants/router' import {useTBContext} from '@/stores/team-building' import * as Kb from '@/common-adapters' -import CommonResult, {type ResultProps} from './common-result' +import CommonResult, {type ResultProps, rowContainerWithLargePadding} from './common-result' const YouResult = function YouResult(props: ResultProps) { const cancelTeamBuilding = useTBContext(s => s.dispatch.cancelTeamBuilding) @@ -32,18 +32,14 @@ const YouResult = function YouResult(props: ResultProps) { default: } - return <CommonResult {...props} {...onAddOverride} rowStyle={styles.rowContainer} bottomRow={bottomRow} /> + return ( + <CommonResult + {...props} + {...onAddOverride} + rowStyle={rowContainerWithLargePadding} + bottomRow={bottomRow} + /> + ) } -const styles = Kb.Styles.styleSheetCreate(() => ({ - rowContainer: { - ...Kb.Styles.padding( - Kb.Styles.globalMargins.tiny, - Kb.Styles.globalMargins.medium, - Kb.Styles.globalMargins.tiny, - Kb.Styles.globalMargins.xsmall - ), - }, -})) - export default YouResult diff --git a/shared/team-building/shared.tsx b/shared/team-building/shared.tsx index 817ede88ab0f..12ed0116b5b7 100644 --- a/shared/team-building/shared.tsx +++ b/shared/team-building/shared.tsx @@ -98,3 +98,9 @@ export const serviceIdToBadge = (service: T.TB.ServiceIdWithContact): boolean => export const serviceMapToArray = (services: T.TB.ServiceMap) => TeamBuilding.allServices.filter(x => x !== 'keybase' && x in services) + +export const getSearchResults = ( + searchResults: T.Immutable<T.TB.SearchResults>, + searchString: string, + selectedService: T.TB.ServiceIdWithContact +) => searchResults.get(searchString.trim())?.get(selectedService) diff --git a/shared/team-building/team-box.tsx b/shared/team-building/team-box.tsx index a275f91a592d..2708ac602698 100644 --- a/shared/team-building/team-box.tsx +++ b/shared/team-building/team-box.tsx @@ -72,17 +72,15 @@ const TeamBox = (props: Props) => { }, [prevLastRef, last]) return isMobile ? ( - <Kb.Box2 direction="horizontal" fullWidth={true}> - <Kb.Box2 direction="horizontal" fullWidth={true} style={styles.container}> - <Kb.ScrollView - horizontal={true} - alwaysBounceHorizontal={false} - ref={scrollViewRef} - contentContainerStyle={styles.scrollContent} - > - <UserBubbleCollection teamSoFar={props.teamSoFar} onRemove={props.onRemove} /> - </Kb.ScrollView> - </Kb.Box2> + <Kb.Box2 direction="horizontal" fullWidth={true} style={styles.container}> + <Kb.ScrollView + horizontal={true} + alwaysBounceHorizontal={false} + ref={scrollViewRef} + contentContainerStyle={styles.scrollContent} + > + <UserBubbleCollection teamSoFar={props.teamSoFar} onRemove={props.onRemove} /> + </Kb.ScrollView> </Kb.Box2> ) : ( <Kb.Box2 direction="horizontal" style={styles.container} fullWidth={true}> @@ -99,7 +97,7 @@ const TeamBox = (props: Props) => { </Kb.Box2> </Kb.ScrollView> </Kb.Box2> - <Kb.Box2 direction="horizontal" fullHeight={true} style={{marginLeft: 'auto'}}> + <Kb.Box2 direction="horizontal" fullHeight={true} style={styles.goButtonContainer}> {!!props.teamSoFar.length && ( <GoButton label={props.goButtonLabel ?? 'Start'} @@ -120,6 +118,7 @@ const styles = Kb.Styles.styleSheetCreate( overflow: 'hidden', }, }), + goButtonContainer: {marginLeft: 'auto' as const}, container: Kb.Styles.platformStyles({ common: { backgroundColor: Kb.Styles.globalColors.blueGrey, diff --git a/shared/teams/add-members-wizard/add-from-where.tsx b/shared/teams/add-members-wizard/add-from-where.tsx index 7abce6486120..60148b9b6cd1 100644 --- a/shared/teams/add-members-wizard/add-from-where.tsx +++ b/shared/teams/add-members-wizard/add-from-where.tsx @@ -45,30 +45,34 @@ const AddFromWhere = ({wizard}: Props) => { <Kb.Text type="Body"> {isNewTeam ? 'Where will your first team members come from?' : 'How would you like to add people?'} </Kb.Text> - <Kb.RichButton - icon="icon-teams-add-search-64" - title="From Keybase" - description="Search users by username." + <Kb.ListItem + type="Card" + firstItem={true} + icon={<Kb.IconAuto type="icon-teams-add-search-64" />} + body={<Kb.Box2 direction="vertical" fullWidth={true}><Kb.Text type="BodySemibold">From Keybase</Kb.Text><Kb.Text type="BodySmall">Search users by username.</Kb.Text></Kb.Box2>} onClick={onContinueKeybase} /> - <Kb.RichButton - icon="icon-teams-add-email-list-64" - title="A list of email addresses" - description="Enter one or multiple email addresses." + <Kb.ListItem + type="Card" + firstItem={true} + icon={<Kb.IconAuto type="icon-teams-add-email-list-64" />} + body={<Kb.Box2 direction="vertical" fullWidth={true}><Kb.Text type="BodySemibold">A list of email addresses</Kb.Text><Kb.Text type="BodySmall">Enter one or multiple email addresses.</Kb.Text></Kb.Box2>} onClick={onContinueEmail} /> {isMobile && ( - <Kb.RichButton - icon="icon-teams-add-phone-contacts-64" - title="From your contacts" - description="Add your friends, family, or colleagues." + <Kb.ListItem + type="Card" + firstItem={true} + icon={<Kb.IconAuto type="icon-teams-add-phone-contacts-64" />} + body={<Kb.Box2 direction="vertical" fullWidth={true}><Kb.Text type="BodySemibold">From your contacts</Kb.Text><Kb.Text type="BodySmall">Add your friends, family, or colleagues.</Kb.Text></Kb.Box2>} onClick={onContinueContacts} /> )} - <Kb.RichButton - icon="icon-teams-add-number-list-64" - title="A list of phone numbers" - description="Enter one or multiple phone numbers" + <Kb.ListItem + type="Card" + firstItem={true} + icon={<Kb.IconAuto type="icon-teams-add-number-list-64" />} + body={<Kb.Box2 direction="vertical" fullWidth={true}><Kb.Text type="BodySemibold">A list of phone numbers</Kb.Text><Kb.Text type="BodySmall">Enter one or multiple phone numbers</Kb.Text></Kb.Box2>} onClick={onContinuePhone} /> </Kb.Box2> diff --git a/shared/teams/common/activity.tsx b/shared/teams/common/activity.tsx index 61f0c99b330a..4cb0bb380e91 100644 --- a/shared/teams/common/activity.tsx +++ b/shared/teams/common/activity.tsx @@ -161,12 +161,10 @@ export const ModalTitle = ({title, teamID, newTeamWizard}: ModalTitleProps) => { imageOverrideUrl={isNewTeamWizard ? avatarFilepath : undefined} crop={isNewTeamWizard ? avatarCrop : undefined} /> - <Kb.Box2 direction="vertical" alignItems="center"> - <Kb.Text type="BodySmall" lineClamp={1}> - {displayTeamname} - </Kb.Text> - <Kb.Text type="Header">{title}</Kb.Text> - </Kb.Box2> + <Kb.Text type="BodySmall" lineClamp={1}> + {displayTeamname} + </Kb.Text> + <Kb.Text type="Header">{title}</Kb.Text> </Kb.Box2> ) } diff --git a/shared/teams/common/channels-widget.tsx b/shared/teams/common/channels-widget.tsx index f515aece6a08..7f6e4e94fd9e 100644 --- a/shared/teams/common/channels-widget.tsx +++ b/shared/teams/common/channels-widget.tsx @@ -52,21 +52,21 @@ const ChannelInputDesktop = (props: ChannelInputProps) => { const {channelMetas} = useAllChannelMetas(teamID) const channelItems = [...channelMetas.values()] - .filter( - c => - !selected.find(channel => channel.conversationIDKey === c.conversationIDKey) && - (!disableGeneral || c.channelname !== 'general') && - !disabledChannels?.some(dc => dc.conversationIDKey === c.conversationIDKey) - ) - .map(c => ({ - label: `#${c.channelname}`, - value: {channelname: c.channelname, conversationIDKey: c.conversationIDKey}, - })) + .filter( + c => + !selected.find(channel => channel.conversationIDKey === c.conversationIDKey) && + (!disableGeneral || c.channelname !== 'general') && + !disabledChannels?.some(dc => dc.conversationIDKey === c.conversationIDKey) + ) + .map(c => ({ + label: `#${c.channelname}`, + value: {channelname: c.channelname, conversationIDKey: c.conversationIDKey}, + })) const onSelect = (value: T.Unpacked<typeof channelItems>['value']) => { - onAdd([value]) - setFilter('') - } + onAdd([value]) + setFilter('') + } const {popup, popupAnchor, onKeyDown, showPopup, hidePopup} = useAutocompleter( channelItems, diff --git a/shared/teams/delete-team.tsx b/shared/teams/delete-team.tsx index cadb1286ad1c..f9031c70d91e 100644 --- a/shared/teams/delete-team.tsx +++ b/shared/teams/delete-team.tsx @@ -69,7 +69,7 @@ const DeleteTeamContainer = (op: OwnProps) => { return ( <Kb.ConfirmModal content={ - <Kb.Text type="Body" center={true} style={{marginTop: Kb.Styles.globalMargins.medium}}> + <Kb.Text type="Body" center={true} style={styles.subteamText}> Before you can delete <Kb.Text type="BodySemibold">{teamname}</Kb.Text>, delete its{' '} {subteamNames.length} {pluralize('subteam', subteamNames.length)}:{' '} <Kb.Text type="BodySemibold">{subteamNames.join(', ')}</Kb.Text>. @@ -113,7 +113,7 @@ const DeleteTeamContainer = (op: OwnProps) => { const Header = (props: {teamname: string}) => ( <> <Kb.Avatar teamname={props.teamname} size={64} /> - <Kb.ImageIcon type="icon-team-delete-28" style={{marginRight: -60, marginTop: -20, zIndex: 1}} /> + <Kb.ImageIcon type="icon-team-delete-28" style={styles.deleteIcon} /> </> ) @@ -146,4 +146,9 @@ const Checkboxes = (props: CheckboxesProps) => ( </Kb.Box2> ) +const styles = Kb.Styles.styleSheetCreate(() => ({ + deleteIcon: {marginRight: -60, marginTop: -20, zIndex: 1}, + subteamText: {marginTop: Kb.Styles.globalMargins.medium}, +})) + export default DeleteTeamContainer diff --git a/shared/teams/invite-by-email.tsx b/shared/teams/invite-by-email.tsx index 8472538e7728..a9234d7a5958 100644 --- a/shared/teams/invite-by-email.tsx +++ b/shared/teams/invite-by-email.tsx @@ -69,13 +69,13 @@ const Container = (ownProps: OwnProps) => { direction="vertical" alignItems="center" fullWidth={true} - style={{margin: Kb.Styles.globalMargins.medium}} + style={styles.outerBox} > <Kb.Text style={styles.header} type="Header"> Invite by email </Kb.Text> - <Kb.Box2 direction="horizontal" alignItems="center" style={{margin: Kb.Styles.globalMargins.tiny}}> - <Kb.Text style={{margin: Kb.Styles.globalMargins.tiny}} type="Body"> + <Kb.Box2 direction="horizontal" alignItems="center" style={styles.roleRow}> + <Kb.Text style={styles.addAsText} type="Body"> Add these team members to {teamname} as: </Kb.Text> <FloatingRolePicker @@ -89,7 +89,7 @@ const Container = (ownProps: OwnProps) => { <Kb.DropdownButton toggleOpen={onOpenRolePicker} selected={_makeDropdownItem(role)} - style={{width: 100}} + style={styles.dropdown} /> </FloatingRolePicker> </Kb.Box2> @@ -105,7 +105,7 @@ const Container = (ownProps: OwnProps) => { value={invitees} /> {!!errorMessage && ( - <Kb.Text type="BodySmall" style={{color: Kb.Styles.globalColors.redDark}}> + <Kb.Text type="BodySmall" style={styles.errorText}> {errorMessage} </Kb.Text> )} @@ -119,20 +119,19 @@ const Container = (ownProps: OwnProps) => { } const _makeDropdownItem = (item: string) => ( - <Kb.Box2 - key={item} - direction="horizontal" - alignItems="center" - style={{ - ...Kb.Styles.paddingH(Kb.Styles.globalMargins.small), - }} - > + <Kb.Box2 key={item} direction="horizontal" alignItems="center" style={styles.dropdownItem}> <Kb.Text type="BodyBig">{capitalize(item)}</Kb.Text> </Kb.Box2> ) const styles = Kb.Styles.styleSheetCreate(() => ({ + addAsText: {margin: Kb.Styles.globalMargins.tiny}, + dropdown: {width: 100}, + dropdownItem: {...Kb.Styles.paddingH(Kb.Styles.globalMargins.small)}, + errorText: {color: Kb.Styles.globalColors.redDark}, header: {padding: Kb.Styles.globalMargins.tiny}, + outerBox: {margin: Kb.Styles.globalMargins.medium}, + roleRow: {margin: Kb.Styles.globalMargins.tiny}, })) export default Container diff --git a/shared/teams/main/header.tsx b/shared/teams/main/header.tsx index 95a3e6fbd0ae..76706d1e761c 100644 --- a/shared/teams/main/header.tsx +++ b/shared/teams/main/header.tsx @@ -1,11 +1,5 @@ import * as Kb from '@/common-adapters' -export type HeaderButtonProps = { - iconType: Kb.IconType - label: string - onClick: () => void -} - export type Props = { onCreateTeam: () => void onJoinTeam: () => void diff --git a/shared/teams/main/index.tsx b/shared/teams/main/index.tsx index d5c064a2a347..9cde5cafc60d 100644 --- a/shared/teams/main/index.tsx +++ b/shared/teams/main/index.tsx @@ -62,30 +62,30 @@ const sortOrderToTitle = { } const SortHeader = ({onChangeSort, sortOrder}: {onChangeSort: Props['onChangeSort']; sortOrder: Props['sortOrder']}) => { const makePopup = (p: Kb.Popup2Parms) => { - const {attachTo, hidePopup} = p - return ( - <Kb.FloatingMenu - attachTo={attachTo} - items={[ - {icon: 'iconfont-team', onClick: () => onChangeSort('role'), title: sortOrderToTitle.role}, - { - icon: 'iconfont-campfire', - onClick: () => onChangeSort('activity'), - title: sortOrderToTitle.activity, - }, - { - icon: 'iconfont-sort-alpha', - onClick: () => onChangeSort('alphabetical'), - title: sortOrderToTitle.alphabetical, - }, - ]} - closeOnSelect={true} - onHidden={hidePopup} - visible={true} - position="bottom left" - /> - ) - } + const {attachTo, hidePopup} = p + return ( + <Kb.FloatingMenu + attachTo={attachTo} + items={[ + {icon: 'iconfont-team', onClick: () => onChangeSort('role'), title: sortOrderToTitle.role}, + { + icon: 'iconfont-campfire', + onClick: () => onChangeSort('activity'), + title: sortOrderToTitle.activity, + }, + { + icon: 'iconfont-sort-alpha', + onClick: () => onChangeSort('alphabetical'), + title: sortOrderToTitle.alphabetical, + }, + ]} + closeOnSelect={true} + onHidden={hidePopup} + visible={true} + position="bottom left" + /> + ) + } const {popup, showPopup, popupAnchor} = Kb.usePopup2(makePopup) return ( @@ -102,8 +102,6 @@ const SortHeader = ({onChangeSort, sortOrder}: {onChangeSort: Props['onChangeSor const teamRowHeight = isMobile ? 72 : 48 const teamRowItemHeight = {height: teamRowHeight, type: 'fixed' as const} -type TeamItem = TeamRowItem - const Teams = function Teams(p: Props) { const {deletedTeams, teams, onCreateTeam, onJoinTeam, onChangeSort, sortOrder} = p @@ -124,7 +122,7 @@ const {deletedTeams, teams, onCreateTeam, onJoinTeam, onChangeSort, sortOrder} = const listFooter = <TeamsFooter empty={teams.length === 0} /> - const renderItem = (_index: number, item: TeamItem) => { + const renderItem = (_index: number, item: TeamRowItem) => { return ( <PerfProfiler id="TeamRow"> <TeamRowNew showChat={!isMobile} {...item} /> diff --git a/shared/teams/main/team-row.tsx b/shared/teams/main/team-row.tsx index 119e14763419..2ac14a130891 100644 --- a/shared/teams/main/team-row.tsx +++ b/shared/teams/main/team-row.tsx @@ -36,9 +36,9 @@ const TeamRow = function TeamRow(props: Props) { const onChat = () => previewConversation({reason: 'teamRow', teamname: teamMeta.teamname}) const makePopup = (p: Kb.Popup2Parms) => { - const {attachTo, hidePopup} = p - return <TeamMenu teamID={teamID} attachTo={attachTo} onHidden={hidePopup} visible={true} /> - } + const {attachTo, hidePopup} = p + return <TeamMenu teamID={teamID} attachTo={attachTo} onHidden={hidePopup} visible={true} /> + } const {popup, popupAnchor, showPopup} = Kb.usePopup2(makePopup) const crownIconType: Kb.IconType | undefined = @@ -61,10 +61,10 @@ const TeamRow = function TeamRow(props: Props) { if (isMobile) { return ( <> - <Kb.ClickableBox3 onClick={onViewTeam} direction="horizontal" fullWidth={true} alignItems="center" style={Kb.Styles.collapseStyles([styles.clickableBox, styles.row])}> + <Kb.ClickableBox3 onClick={onViewTeam} direction="horizontal" fullWidth={true} alignItems="center" style={styles.rowStyle}> <Kb.Divider style={styles.divider} /> - <Kb.Box2 direction="vertical" centerChildren={true} style={styles.avatarContainer}> - <Kb.Box2 direction="vertical" style={styles.avatarInner} centerChildren={true}> + <Kb.Box2 direction="vertical" style={styles.avatarOuter} centerChildren={true}> + <Kb.Box2 direction="vertical" relative={true} style={styles.avatarRelative}> <Kb.Avatar size={32} teamname={teamMeta.teamname} isTeam={true} /> {!!badgeCount && <Kb.Badge badgeNumber={badgeCount} badgeStyle={styles.badge} />} {crownIcon} @@ -117,10 +117,10 @@ const TeamRow = function TeamRow(props: Props) { return ( <> - <Kb.ClickableBox3 onClick={onViewTeam} testID={TestIDs.TEAMS_ROW} className="teamRow" direction="horizontal" fullWidth={true} alignItems="center" style={Kb.Styles.collapseStyles([styles.clickableBox, styles.row])}> + <Kb.ClickableBox3 onClick={onViewTeam} testID={TestIDs.TEAMS_ROW} className="teamRow" direction="horizontal" fullWidth={true} alignItems="center" style={styles.rowStyle}> <Kb.Divider style={styles.divider} /> - <Kb.Box2 direction="vertical" centerChildren={true} style={styles.avatarContainer}> - <Kb.Box2 direction="vertical" style={styles.avatarInner} centerChildren={true}> + <Kb.Box2 direction="vertical" style={styles.avatarOuter} centerChildren={true}> + <Kb.Box2 direction="vertical" relative={true} style={styles.avatarRelative}> <Kb.Avatar size={32} teamname={teamMeta.teamname} isTeam={true} /> {!!badgeCount && <Kb.Badge badgeNumber={badgeCount} badgeStyle={styles.badge} />} {crownIcon} @@ -192,16 +192,15 @@ const styles = Kb.Styles.styleSheetCreate(() => ({ alignSelfCenter: { alignSelf: 'center', }, - avatarContainer: Kb.Styles.platformStyles({ + avatarOuter: Kb.Styles.platformStyles({ common: { minHeight: smallHeight, width: smallIconWidth, }, isPhone: {minHeight: 72}, }), - avatarInner: { + avatarRelative: { height: 32, - position: 'relative', width: 32, }, badge: { @@ -226,10 +225,11 @@ const styles = Kb.Styles.styleSheetCreate(() => ({ bodyRight: { flex: 0.7, }, - clickableBox: Kb.Styles.platformStyles({ + rowStyle: Kb.Styles.platformStyles({ common: { backgroundColor: Kb.Styles.globalColors.white, flexShrink: 0, + position: 'relative', }, isElectron: {minHeight: smallHeight}, isPhone: {minHeight: 72}, @@ -241,9 +241,9 @@ const styles = Kb.Styles.styleSheetCreate(() => ({ borderRadius: 100, ...Kb.Styles.size(17), position: 'absolute', + bottom: -5, + right: -5, }, - isElectron: {bottom: -5, right: -5}, - isMobile: {bottom: -5, right: -5}, }), divider: { left: 0, @@ -251,14 +251,7 @@ const styles = Kb.Styles.styleSheetCreate(() => ({ right: 0, top: 0, }, - row: Kb.Styles.platformStyles({ - common: { - backgroundColor: Kb.Styles.globalColors.white, - position: 'relative', - }, - isElectron: {minHeight: smallHeight}, - isPhone: {minHeight: 72}, - }), + }) as const) export default TeamRow diff --git a/shared/teams/new-team/wizard/make-big-team.tsx b/shared/teams/new-team/wizard/make-big-team.tsx index 82c6d82eea04..b7e5cf17b403 100644 --- a/shared/teams/new-team/wizard/make-big-team.tsx +++ b/shared/teams/new-team/wizard/make-big-team.tsx @@ -31,18 +31,19 @@ const MakeBigTeam = ({wizard: initialWizard}: Props) => { style={styles.body} gap={isMobile ? 'xsmall' : 'tiny'} > - <Kb.RichButton - description="With multiple roles and channels. Big team chats appear in the lower section in the inbox." - icon="icon-teams-size-big-64" + <Kb.ListItem + type="Card" + firstItem={true} + icon={<Kb.IconAuto type="icon-teams-size-big-64" />} + body={<Kb.Box2 direction="vertical" fullWidth={true}><Kb.Text type="BodySemibold">Yes, make it a big team</Kb.Text><Kb.Text type="BodySmall">With multiple roles and channels. Big team chats appear in the lower section in the inbox.</Kb.Text></Kb.Box2>} onClick={() => onSubmit(true)} - title="Yes, make it a big team" /> - - <Kb.RichButton - description="You can always make it a big team later." - icon="icon-teams-size-small-64" + <Kb.ListItem + type="Card" + firstItem={true} + icon={<Kb.IconAuto type="icon-teams-size-small-64" />} + body={<Kb.Box2 direction="vertical" fullWidth={true}><Kb.Text type="BodySemibold">No, keep it a simple conversation for now</Kb.Text><Kb.Text type="BodySmall">You can always make it a big team later.</Kb.Text></Kb.Box2>} onClick={() => onSubmit(false)} - title="No, keep it a simple conversation for now" /> </Kb.Box2> </> diff --git a/shared/teams/new-team/wizard/team-purpose.tsx b/shared/teams/new-team/wizard/team-purpose.tsx index 089d782e5bc3..8236073d10fc 100644 --- a/shared/teams/new-team/wizard/team-purpose.tsx +++ b/shared/teams/new-team/wizard/team-purpose.tsx @@ -27,32 +27,33 @@ const TeamPurpose = ({wizard: wizardParam}: Props) => { gap={isMobile ? 'xsmall' : 'tiny'} > <Kb.Text type="BodySemibold">What do you need a team for?</Kb.Text> - <Kb.RichButton - description="A small group of people, with no initial need for channels." - icon="icon-teams-type-squad-64" + <Kb.ListItem + type="Card" + firstItem={true} + icon={<Kb.IconAuto type="icon-teams-type-squad-64" />} + body={<Kb.Box2 direction="vertical" fullWidth={true}><Kb.Text type="BodySemibold">Friends, family, or squad</Kb.Text><Kb.Text type="BodySmall">A small group of people, with no initial need for channels.</Kb.Text></Kb.Box2>} onClick={() => onSubmit('friends')} - title="Friends, family, or squad" /> - - <Kb.RichButton - description="With multiple roles and channels." - icon="icon-teams-type-business-64" + <Kb.ListItem + type="Card" + firstItem={true} + icon={<Kb.IconAuto type="icon-teams-type-business-64" />} + body={<Kb.Box2 direction="vertical" fullWidth={true}><Kb.Text type="BodySemibold">A project, business or organization</Kb.Text><Kb.Text type="BodySmall">With multiple roles and channels.</Kb.Text></Kb.Box2>} onClick={() => onSubmit('project')} - title="A project, business or organization" /> - - <Kb.RichButton - description="A forum for people who share an interest or cause." - icon="icon-teams-type-community-64" + <Kb.ListItem + type="Card" + firstItem={true} + icon={<Kb.IconAuto type="icon-teams-type-community-64" />} + body={<Kb.Box2 direction="vertical" fullWidth={true}><Kb.Text type="BodySemibold">A community</Kb.Text><Kb.Text type="BodySmall">A forum for people who share an interest or cause.</Kb.Text></Kb.Box2>} onClick={() => onSubmit('community')} - title="A community" /> - - <Kb.RichButton - description="Start simple and go from there." - icon="icon-teams-type-notsure-64" + <Kb.ListItem + type="Card" + firstItem={true} + icon={<Kb.IconAuto type="icon-teams-type-notsure-64" />} + body={<Kb.Box2 direction="vertical" fullWidth={true}><Kb.Text type="BodySemibold">{"Other/You're not sure"}</Kb.Text><Kb.Text type="BodySmall">Start simple and go from there.</Kb.Text></Kb.Box2>} onClick={() => onSubmit('other')} - title="Other/You're not sure" /> </Kb.Box2> </> diff --git a/shared/teams/rename-team.tsx b/shared/teams/rename-team.tsx index 80d02e983acf..bc9e6f222fd7 100644 --- a/shared/teams/rename-team.tsx +++ b/shared/teams/rename-team.tsx @@ -35,8 +35,8 @@ const Container = (ownProps: OwnProps) => { lastWaitingRef.current = waiting }, [waiting, propError, navigateUp]) - const newFullName = () => [prefix, newName].join('.') - const disabled = () => newName.length < 2 + const newFullName = [prefix, newName].join('.') + const disabled = newName.length < 2 const validateTeamname = () => { if (newName.startsWith('_') || newName.includes('__')) { @@ -51,16 +51,16 @@ const Container = (ownProps: OwnProps) => { } const handleRename = () => { - if (waiting || disabled()) { + if (waiting || disabled) { return } - if (teamname === newFullName()) { + if (teamname === newFullName) { onCancel() return } setError('') if (validateTeamname()) { - onRename(newFullName()) + onRename(newFullName) } } @@ -124,7 +124,7 @@ const Container = (ownProps: OwnProps) => { label="Rename" onClick={handleRename} style={styles.button} - disabled={disabled()} + disabled={disabled} waiting={waiting} /> </Kb.ButtonBar> diff --git a/shared/teams/role-picker-utils.tsx b/shared/teams/role-picker-utils.tsx index 8d2d7ed7c156..c5b82d6557ab 100644 --- a/shared/teams/role-picker-utils.tsx +++ b/shared/teams/role-picker-utils.tsx @@ -1,30 +1,33 @@ import type * as T from '@/constants/types' +const msgOnlyOwnersCanChangeOwnerRole = "Only owners can change another owner's role" +const msgMustBeAdminToChangeRoles = 'You must be at least an admin to make role changes.' + const subteamsCannotHaveOwners = {owner: 'Subteams cannot have owners.'} const onlyOwnersCanTurnTeamMembersIntoOwners = {owner: 'Only owners can turn team members into owners.'} const roleChangeSub = { - admin: 'You must be at least an admin to make role changes.', + admin: msgMustBeAdminToChangeRoles, owner: 'Subteams cannot have owners.', - reader: 'You must be at least an admin to make role changes.', - writer: 'You must be at least an admin to make role changes.', + reader: msgMustBeAdminToChangeRoles, + writer: msgMustBeAdminToChangeRoles, } const roleChangeNotSub = { - admin: 'You must be at least an admin to make role changes.', - owner: 'You must be at least an admin to make role changes.', - reader: 'You must be at least an admin to make role changes.', - writer: 'You must be at least an admin to make role changes.', + admin: msgMustBeAdminToChangeRoles, + owner: msgMustBeAdminToChangeRoles, + reader: msgMustBeAdminToChangeRoles, + writer: msgMustBeAdminToChangeRoles, } const anotherRoleChangeSub = { - admin: `Only owners can change another owner's role`, + admin: msgOnlyOwnersCanChangeOwnerRole, owner: 'Subteams cannot have owners.', - reader: `Only owners can change another owner's role`, - writer: `Only owners can change another owner's role`, + reader: msgOnlyOwnersCanChangeOwnerRole, + writer: msgOnlyOwnersCanChangeOwnerRole, } const anotherRoleChangeNotSub = { - admin: `Only owners can change another owner's role`, - owner: `Only owners can change another owner's role`, - reader: `Only owners can change another owner's role`, - writer: `Only owners can change another owner's role`, + admin: msgOnlyOwnersCanChangeOwnerRole, + owner: msgOnlyOwnersCanChangeOwnerRole, + reader: msgOnlyOwnersCanChangeOwnerRole, + writer: msgOnlyOwnersCanChangeOwnerRole, } const notOwnerSub = {owner: 'Subteams cannot have owners.'} const notOwnerNotSub = {owner: `Only owners can turn members into owners`} diff --git a/shared/teams/role-picker.tsx b/shared/teams/role-picker.tsx index 87125e785422..28870a5a887e 100644 --- a/shared/teams/role-picker.tsx +++ b/shared/teams/role-picker.tsx @@ -72,7 +72,7 @@ const RoleRow = (p: RoleRowProps) => { </Kb.Text> </Kb.Box2> <Kb.Box2 - style={Kb.Styles.collapseStyles([styles.rowBody])} + style={styles.rowBody} direction="vertical" gap="xxtiny" gapStart={true} diff --git a/shared/teams/team/index.tsx b/shared/teams/team/index.tsx index 343674cd1caa..d6c19b31db75 100644 --- a/shared/teams/team/index.tsx +++ b/shared/teams/team/index.tsx @@ -241,7 +241,6 @@ const TeamBody = (props: Props) => { stickySectionHeadersEnabled={isMobile} sections={sections} contentContainerStyle={styles.listContentContainer} - style={styles.list} getItemHeight={() => 48} /> <SelectionPopup @@ -279,7 +278,6 @@ const styles = Kb.Styles.styleSheetCreate(() => ({ container: { backgroundColor: Kb.Styles.globalColors.blueGrey, }, - list: Kb.Styles.platformStyles({}), listContentContainer: Kb.Styles.platformStyles({ isMobile: { display: 'flex', diff --git a/shared/teams/team/member/index.new.tsx b/shared/teams/team/member/index.new.tsx index 905163693bb5..0a60582a188b 100644 --- a/shared/teams/team/member/index.new.tsx +++ b/shared/teams/team/member/index.new.tsx @@ -24,10 +24,6 @@ type Props = { teamID: T.Teams.TeamID username: string } -type OwnProps = { - teamID: T.Teams.TeamID - username: string -} type TeamTreeRowNotIn = { teamID: T.Teams.TeamID @@ -274,7 +270,7 @@ const useNavUpIfRemovedFromTeam = (teamID: T.Teams.TeamID, username: string) => type Item = {type: 'section-nodes'; tri: TeamTreeRowIn} | {type: 'section-add-nodes'; tni: TeamTreeRowNotIn} type Section = Kb.SectionType<Item> -const TeamMember = (props: OwnProps) => { +const TeamMember = (props: Props) => { const username = props.username const teamID = props.teamID const isMe = username === useCurrentUserState(s => s.username) diff --git a/shared/teams/team/rows/bot-row/bot.tsx b/shared/teams/team/rows/bot-row/bot.tsx index 89462c0b2cb0..eba0116eba35 100644 --- a/shared/teams/team/rows/bot-row/bot.tsx +++ b/shared/teams/team/rows/bot-row/bot.tsx @@ -79,8 +79,8 @@ export const TeamBotRow = (props: Props) => { onClick={props.onOpenProfile} /> <Kb.Box2 direction="vertical" style={styles.nameContainer}> - <Kb.Box2 direction="horizontal" fullWidth={true}>{usernameDisplay}</Kb.Box2> - <Kb.Box2 direction="horizontal" fullWidth={true} alignItems="center">{descriptionLabel}</Kb.Box2> + {usernameDisplay} + {descriptionLabel} </Kb.Box2> </Kb.Box2> <Kb.Box2 direction="vertical" style={styles.menuIconContainer} ref={popupAnchor}> diff --git a/shared/teams/team/rows/emoji-row/item.tsx b/shared/teams/team/rows/emoji-row/item.tsx index 2a6a6ebd77ea..09b6ac2b8a40 100644 --- a/shared/teams/team/rows/emoji-row/item.tsx +++ b/shared/teams/team/rows/emoji-row/item.tsx @@ -68,60 +68,59 @@ const ItemRow = ({conversationIDKey, emoji, firstItem, teamID}: OwnProps) => { const {showPopup, popup, popupAnchor} = Kb.usePopup2(makePopup) return ( - <Kb.Box2 direction="vertical" fullWidth={true} style={styles.outerContainer}> - <Kb.ListItem - type="Small" - body={ + <Kb.ListItem + type="Small" + body={ + <Kb.Box2 + direction="horizontal" + fullWidth={true} + alignItems="center" + justifyContent="flex-end" + gap="small" + > + <Kb.Emoji + emojiData={RPCToEmojiData(emoji, false)} + showTooltip={false} + size={isMobile ? 32 : 26} + /> + <Kb.Text type="Body" style={styles.alias}>{`:${emoji.alias}:`}</Kb.Text> + {!isMobile && emoji.creationInfo && ( + <Kb.Text type="Body" style={styles.date}> + {dateFns.format(emoji.creationInfo.time, 'EEE d MMM yyyy')} + </Kb.Text> + )} + {!isMobile && emoji.creationInfo && ( + <Kb.NameWithIcon + colorFollowing={true} + colorBroken={true} + horizontal={true} + username={emoji.creationInfo.username} + size="small" + avatarSize={16} + containerStyle={styles.username} + /> + )} <Kb.Box2 direction="horizontal" - fullWidth={true} - alignItems="center" - justifyContent="flex-end" - gap="small" + style={Kb.Styles.collapseStyles([!(doAddAlias || doRemove) ? {opacity: 0} : null])} > - <Kb.Emoji - emojiData={RPCToEmojiData(emoji, false)} - showTooltip={false} - size={isMobile ? 32 : 26} + {popup} + <Kb.IconButton + icon="iconfont-ellipsis" + mode="Secondary" + type="Dim" + onClick={showPopup} + ref={popupAnchor} + small={true} /> - <Kb.Text type="Body" style={styles.alias}>{`:${emoji.alias}:`}</Kb.Text> - {!isMobile && emoji.creationInfo && ( - <Kb.Text type="Body" style={styles.date}> - {dateFns.format(emoji.creationInfo.time, 'EEE d MMM yyyy')} - </Kb.Text> - )} - {!isMobile && emoji.creationInfo && ( - <Kb.NameWithIcon - colorFollowing={true} - colorBroken={true} - horizontal={true} - username={emoji.creationInfo.username} - size="small" - avatarSize={16} - containerStyle={styles.username} - /> - )} - <Kb.Box2 - direction="horizontal" - style={Kb.Styles.collapseStyles([!(doAddAlias || doRemove) ? {opacity: 0} : null])} - > - {popup} - <Kb.IconButton - icon="iconfont-ellipsis" - mode="Secondary" - type="Dim" - onClick={showPopup} - ref={popupAnchor} - small={true} - /> - </Kb.Box2> </Kb.Box2> - } - firstItem={firstItem} - fullDivider={true} - height={isMobile ? 48 : 42} - /> - </Kb.Box2> + </Kb.Box2> + } + firstItem={firstItem} + fullDivider={true} + height={isMobile ? 48 : 42} + style={styles.container} + /> ) } @@ -143,7 +142,7 @@ const styles = Kb.Styles.styleSheetCreate( maxWidth: 130, width: 130, }, - outerContainer: Kb.Styles.platformStyles({ + container: Kb.Styles.platformStyles({ common: {backgroundColor: Kb.Styles.globalColors.white}, isElectron: Kb.Styles.padding(0, Kb.Styles.globalMargins.small), }), diff --git a/shared/teams/team/rows/empty-row.tsx b/shared/teams/team/rows/empty-row.tsx index d9b344c83178..eadd25b09943 100644 --- a/shared/teams/team/rows/empty-row.tsx +++ b/shared/teams/team/rows/empty-row.tsx @@ -146,9 +146,7 @@ const EmptyRow = (props: Props) => { fullWidth={true} justifyContent="flex-start" > - <Kb.Box2 direction="horizontal"> - <Kb.ImageIcon type={icon[props.type]} style={styles.iconHeight} /> - </Kb.Box2> + <Kb.ImageIcon type={icon[props.type]} style={styles.iconHeight} /> <Kb.Text type="BodySmall" center={true} style={styles.text}> {getFirstText(props.type, teamOrChannel, teamOrChannelName, notIn)} </Kb.Text> diff --git a/shared/teams/team/rows/invite-row/invite.tsx b/shared/teams/team/rows/invite-row/invite.tsx index b3685834284e..7bc6b7260bfd 100644 --- a/shared/teams/team/rows/invite-row/invite.tsx +++ b/shared/teams/team/rows/invite-row/invite.tsx @@ -41,17 +41,17 @@ export const TeamInviteRow = (props: Props) => { const TeamInviteMenu = (props: {onCancelInvite?: () => void}) => { const {onCancelInvite} = props const makePopup = (p: Kb.Popup2Parms) => { - const {attachTo, hidePopup} = p - return ( - <Kb.FloatingMenu - items={[{danger: true, icon: 'iconfont-remove', onClick: onCancelInvite, title: 'Cancel invite'}]} - visible={true} - onHidden={hidePopup} - closeOnSelect={true} - attachTo={attachTo} - /> - ) - } + const {attachTo, hidePopup} = p + return ( + <Kb.FloatingMenu + items={[{danger: true, icon: 'iconfont-remove', onClick: onCancelInvite, title: 'Cancel invite'}]} + visible={true} + onHidden={hidePopup} + closeOnSelect={true} + attachTo={attachTo} + /> + ) + } const {showPopup, popup, popupAnchor} = Kb.usePopup2(makePopup) return ( <> diff --git a/shared/teams/team/rows/loading.tsx b/shared/teams/team/rows/loading.tsx index 0481a61e5a3a..b1fcc4f4226d 100644 --- a/shared/teams/team/rows/loading.tsx +++ b/shared/teams/team/rows/loading.tsx @@ -1,15 +1,9 @@ import * as Kb from '@/common-adapters' const LoadingRow = () => ( - <Kb.Box2 direction="horizontal" fullWidth={true} centerChildren={true} style={styles.container} gap="tiny"> + <Kb.Box2 direction="horizontal" fullWidth={true} centerChildren={true} padding="small" gap="tiny"> <Kb.ProgressIndicator /> <Kb.Text type="BodySmall">Loading...</Kb.Text> </Kb.Box2> ) export default LoadingRow - -const styles = Kb.Styles.styleSheetCreate(() => ({ - container: { - padding: Kb.Styles.globalMargins.small, - }, -})) diff --git a/shared/teams/team/settings-tab/index.tsx b/shared/teams/team/settings-tab/index.tsx index a6f9727328a9..d46024cd5ef7 100644 --- a/shared/teams/team/settings-tab/index.tsx +++ b/shared/teams/team/settings-tab/index.tsx @@ -280,19 +280,17 @@ export const Settings = (p: Props) => { )} {yourOperations.chat && ( <RetentionPicker - containerStyle={{marginTop: Kb.Styles.globalMargins.small}} + containerStyle={styles.retentionPicker} showSaveIndicator={false} teamID={teamID} entityType={isBigTeam ? 'big team' : 'small team'} /> )} - <Kb.Box2 direction="vertical" fullWidth={true} gap="medium" gapStart={true}> - {isBigTeam && ( - <Kb.Box2 direction="vertical" fullWidth={true}> - <DefaultChannels teamID={teamID} /> - </Kb.Box2> - )} - </Kb.Box2> + {isBigTeam && ( + <Kb.Box2 direction="vertical" fullWidth={true} gap="medium" gapStart={true}> + <DefaultChannels teamID={teamID} /> + </Kb.Box2> + )} </Kb.Box2> </Kb.Box2> ) @@ -300,6 +298,7 @@ export const Settings = (p: Props) => { const styles = Kb.Styles.styleSheetCreate(() => ({ grey: {color: Kb.Styles.globalColors.black_50}, + retentionPicker: {marginTop: Kb.Styles.globalMargins.small}, joinAs: Kb.Styles.platformStyles({ isElectron: {paddingRight: Kb.Styles.globalMargins.xtiny}, }), diff --git a/shared/teams/team/settings-tab/retention/index.tsx b/shared/teams/team/settings-tab/retention/index.tsx index 3c869609349d..df5cf98d7342 100644 --- a/shared/teams/team/settings-tab/retention/index.tsx +++ b/shared/teams/team/settings-tab/retention/index.tsx @@ -85,78 +85,78 @@ const RetentionPicker = (p: Props) => { const saving = !!pendingPolicy && !policyEquals(policy, pendingPolicy) const makePopup = (p: Kb.Popup2Parms) => { - const {attachTo, hidePopup} = p + const {attachTo, hidePopup} = p - const makeItems = () => { - const policies = Teams.baseRetentionPolicies.slice() - if (showInheritOption) { - policies.unshift(Teams.retentionPolicies.policyInherit) - } - return policies.reduce((arr, policy) => { - switch (policy.type) { - case 'retain': - case 'expire': - return [ - ...arr, - { - isSelected: isSelected(policy), - onClick: () => selectPolicy(policy), - title: policy.title, - } as const, - ] - case 'inherit': - if (teamPolicy) { - let title = '' - switch (teamPolicy.type) { - case 'retain': - title = 'Team default (Never)' - break - case 'expire': - case 'explode': - title = `Team default (${teamPolicy.title})` - break - default: - } - return [ - { - isSelected: isSelected(policy), - onClick: () => selectPolicy(policy), - title, - } as const, - 'Divider' as const, - ...arr, - ] - } else { - throw new Error(`Got policy of type 'inherit' without an inheritable parent policy`) + const makeItems = () => { + const policies = Teams.baseRetentionPolicies.slice() + if (showInheritOption) { + policies.unshift(Teams.retentionPolicies.policyInherit) + } + return policies.reduce((arr, policy) => { + switch (policy.type) { + case 'retain': + case 'expire': + return [ + ...arr, + { + isSelected: isSelected(policy), + onClick: () => selectPolicy(policy), + title: policy.title, + } as const, + ] + case 'inherit': + if (teamPolicy) { + let title = '' + switch (teamPolicy.type) { + case 'retain': + title = 'Team default (Never)' + break + case 'expire': + case 'explode': + title = `Team default (${teamPolicy.title})` + break + default: } - case 'explode': return [ - ...arr, { - icon: 'iconfont-timer', - iconIsVisible: true, isSelected: isSelected(policy), onClick: () => selectPolicy(policy), - title: policy.title, + title, } as const, + 'Divider' as const, + ...arr, ] - default: - return arr - } - }, new Array<Kb.MenuItems[0]>()) - } - const items = makeItems() - return ( - <Kb.FloatingMenu - attachTo={attachTo} - closeOnSelect={true} - visible={true} - onHidden={hidePopup} - items={items} - position="top center" - /> - ) + } else { + throw new Error(`Got policy of type 'inherit' without an inheritable parent policy`) + } + case 'explode': + return [ + ...arr, + { + icon: 'iconfont-timer', + iconIsVisible: true, + isSelected: isSelected(policy), + onClick: () => selectPolicy(policy), + title: policy.title, + } as const, + ] + default: + return arr + } + }, new Array<Kb.MenuItems[0]>()) } + const items = makeItems() + return ( + <Kb.FloatingMenu + attachTo={attachTo} + closeOnSelect={true} + visible={true} + onHidden={hidePopup} + items={items} + position="top center" + /> + ) + } const {showPopup, popup, popupAnchor} = Kb.usePopup2(makePopup) return ( diff --git a/shared/teams/team/tabs.tsx b/shared/teams/team/tabs.tsx index 5e7f20a3ea62..0a2e45b8007b 100644 --- a/shared/teams/team/tabs.tsx +++ b/shared/teams/team/tabs.tsx @@ -39,20 +39,18 @@ const TeamTabs = (props: TeamTabsProps) => { /> ) return ( - <Kb.Box2 direction="vertical" fullWidth={true}> - <Kb.Box2 direction="horizontal" fullWidth={true} style={styles.container}> - {isMobile ? ( - <Kb.ScrollView - horizontal={true} - contentContainerStyle={{minWidth: '100%'}} - alwaysBounceHorizontal={false} - > - {tabContent} - </Kb.ScrollView> - ) : ( - tabContent - )} - </Kb.Box2> + <Kb.Box2 direction="horizontal" fullWidth={true} style={styles.container}> + {isMobile ? ( + <Kb.ScrollView + horizontal={true} + contentContainerStyle={{minWidth: '100%'}} + alwaysBounceHorizontal={false} + > + {tabContent} + </Kb.ScrollView> + ) : ( + tabContent + )} </Kb.Box2> ) } diff --git a/shared/tracker/assertion.tsx b/shared/tracker/assertion.tsx index dd09f151610e..56efb5defba4 100644 --- a/shared/tracker/assertion.tsx +++ b/shared/tracker/assertion.tsx @@ -9,6 +9,7 @@ import {formatTimeForAssertionPopup} from '@/util/timestamp' import {useColorScheme} from 'react-native' import {navToProfile} from '@/constants/router' import {copyToClipboard} from '@/util/storeless-actions' +import {assertionColorToColor, assertionColorToTextColor, stateToIcon} from './model' type OwnProps = { assertion: T.Tracker.Assertion @@ -19,7 +20,7 @@ type OwnProps = { username: string } -const Container = (ownProps: OwnProps) => { +const Assertion = (ownProps: OwnProps) => { const isYours = useCurrentUserState(s => ownProps.username === s.username) const {assertion, isSuggestion = false, notAUser = false, onRefresh, stellarHidden = false} = ownProps const {color, metas: _metas, proofURL, sigID, siteIcon} = assertion @@ -184,6 +185,7 @@ const Container = (ownProps: OwnProps) => { className={notAUser ? undefined : 'hover-container'} ref={popupAnchor} direction="vertical" + noShrink={true} style={styles.container} fullWidth={true} > @@ -205,7 +207,7 @@ const Container = (ownProps: OwnProps) => { onShowProof={onShowProof} isSuggestion={isSuggestion} /> - <Kb.Text type="Body" style={styles.textContainer}> + <Kb.Text type="Body" style={styles.textAssertion}> <Value isSuggestion={isSuggestion} type={type} @@ -224,7 +226,7 @@ const Container = (ownProps: OwnProps) => { </Kb.Text> <Kb.ClickableBox3 onClick={items ? showPopup : onShowProof} - style={styles.statusContainer} + style={styles.statusAssertion} direction="horizontal" alignItems="center" gap="tiny" @@ -247,7 +249,7 @@ const Container = (ownProps: OwnProps) => { </Kb.ClickableBox3> </Kb.Box2> {!!metas.length && ( - <Kb.Box2 direction="horizontal" fullWidth={true} style={styles.metaContainer}> + <Kb.Box2 direction="horizontal" fullWidth={true} style={styles.metaAssertion}> {metas.map(m => ( <Kb.Meta key={m.label} backgroundColor={assertionColorToColor(m.color)} title={m.label} /> ))} @@ -267,23 +269,6 @@ const proofTypeToDesc = (proofType: string) => { } } -const stateToIcon = (state: T.Tracker.AssertionState) => { - switch (state) { - case 'checking': - return 'iconfont-proof-pending' - case 'valid': - return 'iconfont-proof-good' - case 'error': // fallthrough - case 'warning': - case 'revoked': - return 'iconfont-proof-broken' - case 'suggestion': - return 'iconfont-proof-placeholder' - default: - return 'iconfont-proof-pending' - } -} - // alternate versions of the ones from `stateToIcon` for the popup menu header const stateToDecorationIcon = (state: T.Tracker.AssertionState) => { switch (state) { @@ -316,44 +301,6 @@ const stateToValueTextStyle = (state: T.Tracker.AssertionState) => { } } -const assertionColorToTextColor = (c: T.Tracker.AssertionColor) => { - switch (c) { - case 'blue': - return Kb.Styles.globalColors.blueDark - case 'red': - return Kb.Styles.globalColors.redDark - case 'black': - return Kb.Styles.globalColors.black - case 'green': - return Kb.Styles.globalColors.greenDark - case 'gray': - return Kb.Styles.globalColors.black_50 - case 'yellow': // fallthrough - case 'orange': - default: - return Kb.Styles.globalColors.redDark - } -} - -const assertionColorToColor = (c: T.Tracker.AssertionColor) => { - switch (c) { - case 'blue': - return Kb.Styles.globalColors.blue - case 'red': - return Kb.Styles.globalColors.red - case 'black': - return Kb.Styles.globalColors.black - case 'green': - return Kb.Styles.globalColors.green - case 'gray': - return Kb.Styles.globalColors.black_50 - case 'yellow': // fallthrough - case 'orange': - default: - return Kb.Styles.globalColors.red - } -} - const StellarValue = (p: {value: string; color: T.Tracker.AssertionColor}) => { const {value, color} = p const onCopyAddress = () => { @@ -451,7 +398,7 @@ const Value = (p: { } const HoverOpacity = (p: {children: React.ReactNode}) => ( - <Kb.Box2 direction="vertical" className="hover-opacy inverted"> + <Kb.Box2 direction="vertical" className="hover-opacity inverted"> {p.children} </Kb.Box2> ) @@ -493,10 +440,18 @@ const AssertionSiteIcon = (p: SIProps) => { ) } +const popupHeaderTextBase = { + color: Kb.Styles.globalColors.white, + paddingBottom: Kb.Styles.globalMargins.tiny, + paddingLeft: Kb.Styles.globalMargins.small, + paddingRight: Kb.Styles.globalMargins.small, + paddingTop: Kb.Styles.globalMargins.tiny, +} as const + const styles = Kb.Styles.styleSheetCreate( () => ({ - container: {flexShrink: 0, paddingBottom: 4, paddingTop: 4}, + container: {paddingBottom: 4, paddingTop: 4}, crypto: Kb.Styles.platformStyles({ isElectron: {display: 'inline-block', fontSize: 11, wordBreak: 'break-all'}, }), @@ -512,30 +467,22 @@ const styles = Kb.Styles.styleSheetCreate( borderStyle: 'solid', padding: Kb.Styles.globalMargins.small, }, - metaContainer: {flexShrink: 0, paddingLeft: 20 + Kb.Styles.globalMargins.tiny * 2 - 4}, // icon spacing plus meta has 2 padding for some reason + metaAssertion: {flexShrink: 0, paddingLeft: 20 + Kb.Styles.globalMargins.tiny * 2 - 4}, // icon spacing plus meta has 2 padding for some reason popupHeaderTextBlue: { + ...popupHeaderTextBase, backgroundColor: Kb.Styles.globalColors.blue, - color: Kb.Styles.globalColors.white, - paddingBottom: Kb.Styles.globalMargins.tiny, - paddingLeft: Kb.Styles.globalMargins.small, - paddingRight: Kb.Styles.globalMargins.small, - paddingTop: Kb.Styles.globalMargins.tiny, }, popupHeaderTextRed: { + ...popupHeaderTextBase, backgroundColor: Kb.Styles.globalColors.red, - color: Kb.Styles.globalColors.white, - paddingBottom: Kb.Styles.globalMargins.tiny, - paddingLeft: Kb.Styles.globalMargins.small, - paddingRight: Kb.Styles.globalMargins.small, - paddingTop: Kb.Styles.globalMargins.tiny, }, site: {color: Kb.Styles.globalColors.black_20}, siteIconFullDecoration: {bottom: -8, position: 'absolute', right: -10}, - statusContainer: Kb.Styles.platformStyles({ + statusAssertion: Kb.Styles.platformStyles({ isMobile: {position: 'relative', top: -2}, }), strikeThrough: {textDecorationLine: 'line-through'}, - textContainer: Kb.Styles.platformStyles({ + textAssertion: Kb.Styles.platformStyles({ common: {flexGrow: 1, flexShrink: 1, marginTop: -1}, }), tooltip: Kb.Styles.platformStyles({isElectron: {display: 'inline-flex'}}), @@ -546,4 +493,4 @@ const styles = Kb.Styles.styleSheetCreate( }) as const ) -export default Container +export default Assertion diff --git a/shared/tracker/bio.tsx b/shared/tracker/bio.tsx index df77459d67e3..ffd39bf2b1cd 100644 --- a/shared/tracker/bio.tsx +++ b/shared/tracker/bio.tsx @@ -14,7 +14,7 @@ type Props = { username: string } -const Container = (props: Props) => { +const Bio = (props: Props) => { const { bio, blocked, @@ -30,12 +30,10 @@ const Container = (props: Props) => { username, } = props return ( - <Kb.Box2 direction="vertical" fullWidth={true} style={styles.container} centerChildren={true} gap="xtiny"> - <Kb.Box2 direction="horizontal" style={styles.fullNameContainer} gap="tiny"> - <Kb.Text center={true} type="BodyBig" lineClamp={inTracker ? 1 : undefined} selectable={true}> - {fullname} - </Kb.Text> - </Kb.Box2> + <Kb.Box2 direction="vertical" fullWidth={true} noShrink={true} style={styles.container} centerChildren={true} gap="xtiny"> + <Kb.Text center={true} type="BodyBig" lineClamp={inTracker ? 1 : undefined} selectable={true} style={styles.fullNameBio}> + {fullname} + </Kb.Text> <FollowText followThem={followThem} followsYou={followsYou} /> {followersCount !== undefined && ( <Kb.Text type="BodySmall"> @@ -137,8 +135,8 @@ const styles = Kb.Styles.styleSheetCreate( paddingTop: Kb.Styles.globalMargins.tiny, }, bold: {...Kb.Styles.globalStyles.fontBold}, - container: {backgroundColor: Kb.Styles.globalColors.white, flexShrink: 0}, - fullNameContainer: { + container: {backgroundColor: Kb.Styles.globalColors.white}, + fullNameBio: { ...Kb.Styles.paddingH(Kb.Styles.globalMargins.mediumLarge), }, text: Kb.Styles.platformStyles({ @@ -150,4 +148,4 @@ const styles = Kb.Styles.styleSheetCreate( }) as const ) -export default Container +export default Bio diff --git a/shared/tracker/index.desktop.tsx b/shared/tracker/index.desktop.tsx index 6c8f2d6771b8..a8087c7b65fd 100644 --- a/shared/tracker/index.desktop.tsx +++ b/shared/tracker/index.desktop.tsx @@ -2,6 +2,7 @@ import * as Kb from '@/common-adapters' import type * as T from '@/constants/types' import {openURL as openUrl} from '@/util/misc' import {useColorScheme} from 'react-native' +import {assertionColorToColor, assertionColorToTextColor, stateToIcon} from './model' export type Props = { assertions?: ReadonlyArray<T.Tracker.Assertion> @@ -102,7 +103,7 @@ const Bio = (props: { followText = 'FOLLOWS YOU' } return ( - <Kb.Box2 direction="vertical" fullWidth={true} style={styles.bioContainer} centerChildren={true} gap="xtiny"> + <Kb.Box2 direction="vertical" fullWidth={true} noShrink={true} style={styles.bioContainer} centerChildren={true} gap="xtiny"> <Kb.Box2 direction="horizontal" style={styles.fullNameContainer} gap="tiny"> <Kb.Text center={true} type="BodyBig" lineClamp={1} selectable={true}> {fullname} @@ -168,44 +169,6 @@ const sortAssertions = (a: T.Tracker.Assertion, b: T.Tracker.Assertion) => { return _scoreAssertionKey(b.type) - _scoreAssertionKey(a.type) } -const assertionColorToColor = (c: T.Tracker.AssertionColor) => { - switch (c) { - case 'blue': return Kb.Styles.globalColors.blue - case 'red': return Kb.Styles.globalColors.red - case 'black': return Kb.Styles.globalColors.black - case 'green': return Kb.Styles.globalColors.green - case 'gray': return Kb.Styles.globalColors.black_50 - case 'yellow': - case 'orange': - default: return Kb.Styles.globalColors.red - } -} - -const assertionColorToTextColor = (c: T.Tracker.AssertionColor) => { - switch (c) { - case 'blue': return Kb.Styles.globalColors.blueDark - case 'red': return Kb.Styles.globalColors.redDark - case 'black': return Kb.Styles.globalColors.black - case 'green': return Kb.Styles.globalColors.greenDark - case 'gray': return Kb.Styles.globalColors.black_50 - case 'yellow': - case 'orange': - default: return Kb.Styles.globalColors.redDark - } -} - -const stateToIcon = (state: T.Tracker.AssertionState) => { - switch (state) { - case 'checking': return 'iconfont-proof-pending' - case 'valid': return 'iconfont-proof-good' - case 'error': - case 'warning': - case 'revoked': return 'iconfont-proof-broken' - case 'suggestion': return 'iconfont-proof-placeholder' - default: return 'iconfont-proof-pending' - } -} - const siteIconToSrcSet = (set: T.Tracker.SiteIconSet) => set.map(i => `url("${i.path}")`).reverse().join(', ') @@ -215,7 +178,7 @@ const AssertionRow = (props: {assertion: T.Tracker.Assertion}) => { const isDarkMode = useColorScheme() === 'dark' const iconSet = isDarkMode ? a.siteIconDarkmode : a.siteIcon return ( - <Kb.Box2 direction="vertical" fullWidth={true} style={styles.assertionRow}> + <Kb.Box2 direction="vertical" fullWidth={true} noShrink={true} style={styles.assertionRow}> <Kb.Box2 alignItems="flex-start" direction="horizontal" gap="tiny" fullWidth={true} gapStart={true} gapEnd={true}> {iconSet.length > 0 && ( <Kb.Box2 @@ -302,21 +265,19 @@ const Tracker = (props: Props) => { <Kb.Text type="BodySmallSemibold" style={styles.reasonInvisible}> {props.reason} </Kb.Text> - <Kb.Box2 direction="vertical" fullWidth={true} relative={true} style={styles.avatarContainer}> + <Kb.Box2 direction="vertical" fullWidth={true} relative={true} noShrink={true}> <Kb.Box2 direction="vertical" style={styles.avatarBackground} /> - <Kb.Box2 direction="vertical" style={styles.nameWithIconContainer}> - <Kb.Box2 direction="vertical" centerChildren={true} gap="tiny"> - <img - src={avatarUrl(props.httpSrvAddress, props.httpSrvToken, props.trackerUsername, isDarkMode)} - width={96} - height={96} - style={styles.avatar} - loading="lazy" - /> - <Kb.Text type="BodyBig" selectable={true}> - {props.trackerUsername} - </Kb.Text> - </Kb.Box2> + <Kb.Box2 direction="vertical" centerChildren={true} gap="tiny" style={styles.nameWithIconContainer}> + <img + src={avatarUrl(props.httpSrvAddress, props.httpSrvToken, props.trackerUsername, isDarkMode)} + width={96} + height={96} + style={styles.avatar} + loading="lazy" + /> + <Kb.Text type="BodyBig" selectable={true}> + {props.trackerUsername} + </Kb.Text> </Kb.Box2> </Kb.Box2> <Bio @@ -342,7 +303,7 @@ const Tracker = (props: Props) => { {sortedAssertions?.map(a => <AssertionRow key={a.assertionKey} assertion={a} />)} </Kb.Box2> {!!buttons.length && ( - <Kb.Box2 fullWidth={true} direction="vertical" style={styles.spaceUnderButtons} /> + <Kb.Box2 fullWidth={true} direction="vertical" noShrink={true} style={styles.spaceUnderButtons} /> )} </Kb.Box2> </Kb.ScrollView> @@ -371,7 +332,7 @@ const reason = { const styles = Kb.Styles.styleSheetCreate( () => ({ - assertionRow: {flexShrink: 0, paddingBottom: 4, paddingTop: 4}, + assertionRow: {paddingBottom: 4, paddingTop: 4}, assertionSite: {color: Kb.Styles.globalColors.black_20}, assertionTextContainer: Kb.Styles.platformStyles({ common: {flexGrow: 1, flexShrink: 1, marginTop: -1}, @@ -396,8 +357,7 @@ const styles = Kb.Styles.styleSheetCreate( right: 0, top: avatarSize / 2, }, - avatarContainer: {flexShrink: 0}, - bioContainer: {backgroundColor: Kb.Styles.globalColors.white, flexShrink: 0}, + bioContainer: {backgroundColor: Kb.Styles.globalColors.white}, bioText: Kb.Styles.platformStyles({ common: { ...Kb.Styles.paddingH(Kb.Styles.globalMargins.mediumLarge), @@ -446,7 +406,7 @@ const styles = Kb.Styles.styleSheetCreate( zIndex: 9, }, metaContainer: {flexShrink: 0, paddingLeft: 20 + Kb.Styles.globalMargins.tiny * 2 - 4}, - nameWithIconContainer: {alignSelf: 'center'}, + nameWithIconContainer: {alignSelf: 'center' as const}, reason: Kb.Styles.platformStyles({ common: { ...reason, @@ -478,7 +438,6 @@ const styles = Kb.Styles.styleSheetCreate( }, }), spaceUnderButtons: { - flexShrink: 0, height: barHeight, }, strikeThrough: {textDecorationLine: 'line-through'}, diff --git a/shared/tracker/model.tsx b/shared/tracker/model.tsx index f0f754a87639..62bd509dd89b 100644 --- a/shared/tracker/model.tsx +++ b/shared/tracker/model.tsx @@ -1,4 +1,60 @@ import * as T from '@/constants/types' +import * as Kb from '@/common-adapters' + +export const assertionColorToColor = (c: T.Tracker.AssertionColor) => { + switch (c) { + case 'blue': + return Kb.Styles.globalColors.blue + case 'red': + return Kb.Styles.globalColors.red + case 'black': + return Kb.Styles.globalColors.black + case 'green': + return Kb.Styles.globalColors.green + case 'gray': + return Kb.Styles.globalColors.black_50 + case 'yellow': // fallthrough + case 'orange': + default: + return Kb.Styles.globalColors.red + } +} + +export const assertionColorToTextColor = (c: T.Tracker.AssertionColor) => { + switch (c) { + case 'blue': + return Kb.Styles.globalColors.blueDark + case 'red': + return Kb.Styles.globalColors.redDark + case 'black': + return Kb.Styles.globalColors.black + case 'green': + return Kb.Styles.globalColors.greenDark + case 'gray': + return Kb.Styles.globalColors.black_50 + case 'yellow': // fallthrough + case 'orange': + default: + return Kb.Styles.globalColors.redDark + } +} + +export const stateToIcon = (state: T.Tracker.AssertionState) => { + switch (state) { + case 'checking': + return 'iconfont-proof-pending' + case 'valid': + return 'iconfont-proof-good' + case 'error': // fallthrough + case 'warning': + case 'revoked': + return 'iconfont-proof-broken' + case 'suggestion': + return 'iconfont-proof-placeholder' + default: + return 'iconfont-proof-pending' + } +} export const noDetails: T.Tracker.Details = { assertions: new Map(), diff --git a/shared/tracker/use-profile.tsx b/shared/tracker/use-profile.tsx index 2e3deed93b7c..a341a2678fd3 100644 --- a/shared/tracker/use-profile.tsx +++ b/shared/tracker/use-profile.tsx @@ -24,12 +24,6 @@ type Options = { reloadOnFocus?: boolean } -const makeNonUserDetails = (): T.Tracker.NonUserDetails => ({...noNonUserDetails}) -type NonUserDetailsState = { - details: T.Tracker.NonUserDetails - username: string -} - export const useTrackerProfile = (username: string, options?: Options) => { const currentUser = useCurrentUserState( C.useShallow(s => ({ @@ -38,8 +32,8 @@ export const useTrackerProfile = (username: string, options?: Options) => { })) ) const [details, setDetails] = React.useState<T.Tracker.Details>(() => makeDetails(username)) - const [nonUserDetails, setNonUserDetails] = React.useState<NonUserDetailsState>(() => ({ - details: makeNonUserDetails(), + const [nonUserDetails, setNonUserDetails] = React.useState<{details: T.Tracker.NonUserDetails; username: string}>(() => ({ + details: {...noNonUserDetails}, username, })) const requestVersionRef = React.useRef(0) @@ -73,7 +67,7 @@ export const useTrackerProfile = (username: string, options?: Options) => { siteURL: '', } if (res.service) { - setNonUserDetails({details: {...makeNonUserDetails(), ...common, ...res.service}, username}) + setNonUserDetails({details: {...noNonUserDetails, ...common, ...res.service}, username}) } else { const {formatPhoneNumberInternational} = await import('@/util/phone-numbers') const formattedName = @@ -83,7 +77,7 @@ export const useTrackerProfile = (username: string, options?: Options) => { return } setNonUserDetails({ - details: {...makeNonUserDetails(), ...common, formattedName, fullName}, + details: {...noNonUserDetails, ...common, formattedName, fullName}, username, }) } @@ -278,7 +272,7 @@ export const useTrackerProfile = (username: string, options?: Options) => { const detailsForUsername = details.username === username ? details : makeDetails(username) const nonUserDetailsForUsername = - nonUserDetails.username === username ? nonUserDetails.details : makeNonUserDetails() + nonUserDetails.username === username ? nonUserDetails.details : {...noNonUserDetails} return { details: detailsForUsername, diff --git a/shared/unlock-folders/device-list.desktop.tsx b/shared/unlock-folders/device-list.desktop.tsx index 30069494cd7e..0b38667a9f39 100644 --- a/shared/unlock-folders/device-list.desktop.tsx +++ b/shared/unlock-folders/device-list.desktop.tsx @@ -16,48 +16,49 @@ const DeviceRow = ({device}: {device: UnlockFolderDevice}) => { )[device.type] return ( - <div style={{...Kb.Styles.globalStyles.flexBoxRow, marginBottom: 16}}> - <div style={styles.iconWrapper}> + <Kb.Box2 direction="horizontal" style={styles.deviceRow}> + <Kb.Box2 direction="horizontal" alignItems="center" justifyContent="center" style={styles.iconWrapper}> <Kb.ImageIcon type={icon} style={{height: 22}} /> - </div> - <Kb.Text type="BodySemibold" style={{marginLeft: 16}}> + </Kb.Box2> + <Kb.Text type="BodySemibold" style={styles.deviceName}> {device.name} </Kb.Text> - </div> + </Kb.Box2> ) } const DeviceList = (props: Props) => ( - <div style={{...Kb.Styles.globalStyles.flexBoxColumn, alignItems: 'center'}}> + <Kb.Box2 direction="vertical" alignItems="center"> <Kb.Text center={true} type="Body" style={styles.infoText}> This computer and possibly others are unable to read some of your folders. To avoid losing data forever, please turn on one of the devices below: </Kb.Text> - <div style={Kb.Styles.collapseStylesDesktop([styles.devicesContainer])}> + <Kb.Box2 direction="vertical" style={styles.devicesContainer}> {props.devices.map(d => ( <DeviceRow key={d.deviceID} device={d} /> ))} - </div> - <div style={styles.buttonsContainer}> + </Kb.Box2> + <Kb.Box2 direction="horizontal" style={styles.buttonsContainer}> <Kb.Button type="Dim" label="Enter a paper key instead" style={styles.enterPaperKey} onClick={props.toPaperKeyInput} /> - </div> - </div> + </Kb.Box2> + </Kb.Box2> ) const styles = Kb.Styles.styleSheetCreate( () => ({ buttonsContainer: { - ...Kb.Styles.globalStyles.flexBoxRow, alignSelf: 'center', marginRight: 30, marginTop: Kb.Styles.globalMargins.small, }, + deviceName: {marginLeft: 16}, + deviceRow: {marginBottom: 16}, devicesContainer: Kb.Styles.platformStyles({ isElectron: { alignSelf: 'center', @@ -75,8 +76,6 @@ const styles = Kb.Styles.styleSheetCreate( width: 236, }, iconWrapper: { - display: 'flex', - justifyContent: 'center', marginLeft: 33, width: 24, }, diff --git a/shared/unlock-folders/index.desktop.tsx b/shared/unlock-folders/index.desktop.tsx index 25982cd2766c..a8575e5054de 100644 --- a/shared/unlock-folders/index.desktop.tsx +++ b/shared/unlock-folders/index.desktop.tsx @@ -44,12 +44,12 @@ const UnlockFolders = (props: Props) => { } return ( - <div style={styles.container}> - <div style={styles.header}> + <Kb.Box2 direction="vertical" style={styles.container}> + <Kb.Box2 direction="vertical" style={styles.header}> <DragHeader icon={true} type="Default" title="" onClose={props.onClose} /> - </div> + </Kb.Box2> {innerComponent} - </div> + </Kb.Box2> ) } diff --git a/shared/unlock-folders/success.desktop.tsx b/shared/unlock-folders/success.desktop.tsx index 8ef9a9c90ffe..093d3ff96446 100644 --- a/shared/unlock-folders/success.desktop.tsx +++ b/shared/unlock-folders/success.desktop.tsx @@ -1,13 +1,13 @@ import * as Kb from '@/common-adapters' -const PaperKeyInput = ({onClose}: {onClose: () => void}) => ( - <div style={styles.container}> +const Success = ({onClose}: {onClose: () => void}) => ( + <Kb.Box2 direction="vertical" alignItems="center" justifyContent="space-between" style={styles.container}> <Kb.ImageIcon type="icon-folder-success-48" /> <Kb.Box2 direction="vertical"> <Kb.Text center={true} type="BodySemibold"> Success! </Kb.Text> - <Kb.Text center={true} style={{...Kb.Styles.paddingH(40)}} type="Body"> + <Kb.Text center={true} style={styles.body} type="Body"> Your paper key is now rekeying folders for this computer. It takes just a couple minutes but lasts forever, like the decision to have a child </Kb.Text> @@ -15,17 +15,15 @@ const PaperKeyInput = ({onClose}: {onClose: () => void}) => ( <Kb.ButtonBar> <Kb.Button label="Okay" onClick={onClose} /> </Kb.ButtonBar> - </div> + </Kb.Box2> ) const styles = Kb.Styles.styleSheetCreate( () => ({ + body: {...Kb.Styles.paddingH(40)}, container: { - ...Kb.Styles.globalStyles.flexBoxColumn, - alignItems: 'center', bottom: 30, - justifyContent: 'space-between', left: 0, position: 'absolute', right: 0, @@ -34,4 +32,4 @@ const styles = Kb.Styles.styleSheetCreate( }) as const ) -export default PaperKeyInput +export default Success diff --git a/shared/wallets/index.tsx b/shared/wallets/index.tsx index 633a22ef4946..ee515b3a77b5 100644 --- a/shared/wallets/index.tsx +++ b/shared/wallets/index.tsx @@ -110,7 +110,7 @@ const Row = (p: {account: Account}) => { ) } -const Container = () => { +const WalletsScreen = () => { const [accounts, setAccounts] = React.useState<Array<Account>>([]) const [acceptedDisclaimer, setAcceptedDisclaimer] = React.useState(false) const checkDisclaimer = C.useRPC(T.RPCStellar.localHasAcceptedDisclaimerLocalRpcPromise) @@ -144,7 +144,7 @@ const Container = () => { return ( <Kb.ScrollView style={styles.scroll}> - <Kb.Box2 direction="vertical" gap="small" fullWidth={true} style={styles.container}> + <Kb.Box2 direction="vertical" gap="small" fullWidth={true} padding="small"> {loading ? <Kb.ProgressIndicator /> : null} <Kb.Text type="BodyBig">Stellar Transactions Are No Longer Supported in the Keybase App</Kb.Text> {acceptedDisclaimer ? ( @@ -174,7 +174,6 @@ const styles = Kb.Styles.styleSheetCreate( accountID: Kb.Styles.platformStyles({ isElectron: {wordBreak: 'break-all'}, }), - container: {padding: Kb.Styles.globalMargins.small}, copyText: Kb.Styles.platformStyles({ isMobile: { flexShrink: 1, @@ -185,14 +184,12 @@ const styles = Kb.Styles.styleSheetCreate( alignSelf: 'flex-start', flexGrow: 1, maxWidth: isMobile ? undefined : 400, - width: '100%', }, idCopy: {height: 40}, label: {flexShrink: 0}, remove: {alignSelf: 'flex-end'}, reveal: { maxWidth: isMobile ? undefined : 400, - width: isMobile ? undefined : '100%', }, row: Kb.Styles.platformStyles({ common: { @@ -215,4 +212,4 @@ const styles = Kb.Styles.styleSheetCreate( }) as const ) -export default Container +export default WalletsScreen diff --git a/shared/wallets/really-remove-account.tsx b/shared/wallets/really-remove-account.tsx index 248cba243125..08f6bb9219fd 100644 --- a/shared/wallets/really-remove-account.tsx +++ b/shared/wallets/really-remove-account.tsx @@ -2,7 +2,7 @@ import * as C from '@/constants' import * as Kb from '@/common-adapters' import * as T from '@/constants/types' import * as React from 'react' -import WalletPopup from './wallet-popup' +import WalletPopup, {walletModalIconStyle} from './wallet-popup' import {loadAccountsWaitingKey} from '@/constants/strings' import {copyToClipboard} from '@/util/storeless-actions' @@ -78,22 +78,20 @@ const ReallyRemoveAccountPopup = (props: OwnProps) => { safeAreaViewTopStyle={styles.background} > <Kb.Box2 centerChildren={true} direction="vertical" flex={1} fullWidth={true}> - <Kb.ImageIcon + <Kb.IconAuto type={isMobile ? 'icon-wallet-secret-key-64' : 'icon-wallet-secret-key-48'} - style={styles.icon} + style={walletModalIconStyle} /> - <Kb.Box2 direction="vertical"> - <Kb.Text center={true} style={styles.warningText} type="Header"> - One last thing! Make sure you keep a copy of your secret key before removing{' '} - </Kb.Text> - <Kb.Text - center={true} - type="HeaderItalic" - style={Kb.Styles.collapseStyles([styles.warningText, styles.mainText] as const)} - > - {name}. - </Kb.Text> - </Kb.Box2> + <Kb.Text center={true} style={styles.warningText} type="Header"> + One last thing! Make sure you keep a copy of your secret key before removing{' '} + </Kb.Text> + <Kb.Text + center={true} + type="HeaderItalic" + style={Kb.Styles.collapseStyles([styles.warningText, styles.mainText] as const)} + > + {name}. + </Kb.Text> <Kb.Text center={true} type="BodySmall" style={styles.warningText}> If you save this secret key, you can use it in other wallets outside Keybase </Kb.Text> @@ -114,11 +112,6 @@ const styles = Kb.Styles.styleSheetCreate(() => ({ background: Kb.Styles.platformStyles({ common: {backgroundColor: Kb.Styles.globalColors.yellow}, }), - icon: Kb.Styles.platformStyles({ - common: {marginBottom: Kb.Styles.globalMargins.large}, - isElectron: {marginTop: Kb.Styles.globalMargins.medium}, - isMobile: {marginTop: Kb.Styles.globalMargins.xlarge}, - }), mainText: Kb.Styles.platformStyles({ common: {paddingBottom: Kb.Styles.globalMargins.small}, isElectron: {wordBreak: 'break-all'}, diff --git a/shared/wallets/remove-account.tsx b/shared/wallets/remove-account.tsx index e8288f98db6b..b673fcf9206b 100644 --- a/shared/wallets/remove-account.tsx +++ b/shared/wallets/remove-account.tsx @@ -1,6 +1,6 @@ import * as C from '@/constants' import * as Kb from '@/common-adapters' -import WalletPopup from './wallet-popup' +import WalletPopup, {walletModalIconStyle} from './wallet-popup' import {makeReallyRemoveAccountRouteParams} from './account-utils' type OwnProps = { @@ -9,7 +9,7 @@ type OwnProps = { name: string } -const Container = (ownProps: OwnProps) => { +const RemoveAccountPopup = (ownProps: OwnProps) => { const {accountID, balanceDescription, name} = ownProps const onDelete = () => { C.Router2.navigateAppend( @@ -36,7 +36,7 @@ const Container = (ownProps: OwnProps) => { <Kb.Box2 centerChildren={true} direction="vertical" flex={1} fullWidth={true}> <Kb.IconAuto type={isMobile ? 'icon-wallet-remove-64' : 'icon-wallet-remove-48'} - style={styles.icon} + style={walletModalIconStyle} /> <Kb.Text center={true} style={styles.warningText} type="Header"> This removes{' '} @@ -60,11 +60,6 @@ const Container = (ownProps: OwnProps) => { } const styles = Kb.Styles.styleSheetCreate(() => ({ - icon: Kb.Styles.platformStyles({ - common: {marginBottom: Kb.Styles.globalMargins.large}, - isElectron: {marginTop: Kb.Styles.globalMargins.medium}, - isMobile: {marginTop: Kb.Styles.globalMargins.xlarge}, - }), marginBottomTiny: {marginBottom: Kb.Styles.globalMargins.tiny}, warningText: Kb.Styles.platformStyles({ isElectron: {wordBreak: 'break-word'} as const, @@ -74,4 +69,4 @@ const styles = Kb.Styles.styleSheetCreate(() => ({ }), })) -export default Container +export default RemoveAccountPopup diff --git a/shared/wallets/wallet-popup.tsx b/shared/wallets/wallet-popup.tsx index 4e331ada17a8..9f5ea9c52481 100644 --- a/shared/wallets/wallet-popup.tsx +++ b/shared/wallets/wallet-popup.tsx @@ -97,4 +97,10 @@ const styles = Kb.Styles.styleSheetCreate(() => ({ scrollViewContentContainer: {...Kb.Styles.globalStyles.flexBoxColumn, flexGrow: 1}, })) +export const walletModalIconStyle = Kb.Styles.platformStyles({ + common: {marginBottom: Kb.Styles.globalMargins.large}, + isElectron: {marginTop: Kb.Styles.globalMargins.medium}, + isMobile: {marginTop: Kb.Styles.globalMargins.xlarge}, +}) + export default WalletPopup diff --git a/skill/simplify-ui-section/SKILL.md b/skill/simplify-ui-section/SKILL.md index e51d18c43994..13ff55c882d8 100644 --- a/skill/simplify-ui-section/SKILL.md +++ b/skill/simplify-ui-section/SKILL.md @@ -204,6 +204,14 @@ Go back to **Step 1** and re-read all files in scope. Then repeat Steps 2–5 wi **Never stop after the first pass.** The first pass removes the obvious problems. The second pass finds what those problems were hiding. The third pass is usually final. +## Revisiting Previously Simplified Directories + +**Re-running this skill on already-simplified code is intentional and by design.** Do not skip a directory just because it appears in recent git history as "already simplified." + +Each simplification pass changes the landscape. What looked acceptable before may now be a smell. New patterns emerge as nearby code changes. The second run almost always finds something the first missed. + +When asked to simplify a directory that was previously touched: proceed without hesitation. Read fresh, analyze fresh. + ## The Hard Line: No Unilateral Visual Changes **This skill is structural by default. Zero UX or behavior changes without explicit user sign-off.** @@ -245,3 +253,4 @@ This pattern generalises: use `common.tsx` as the name regardless of feature fol - Don't rename exports that have external consumers without confirming first - Don't collapse files that serve genuinely different concerns just because they're small - Don't put shared helpers in `index.tsx` — sub-views importing from the feature index creates backwards dependencies +- Don't rename `.tsx` files to `.ts` — JSX may be added later and the extension signals component-adjacent code