diff options
author | Samuel Newman <mozzius@protonmail.com> | 2025-08-25 19:23:08 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-08-25 19:23:08 +0300 |
commit | 54f7af12ca963f4ec3f6a2899257f5f48eb30443 (patch) | |
tree | a3436f503a0a719e835bf2d5e716b571552f6fa7 | |
parent | ecb77a9b96500dac72b1b36f92e42bd899699445 (diff) | |
download | voidsky-54f7af12ca963f4ec3f6a2899257f5f48eb30443.tar.zst |
Update DM header to match new Layout style (#8846)
-rw-r--r-- | src/components/Layout/const.ts | 2 | ||||
-rw-r--r-- | src/components/dms/ConvoMenu.tsx | 40 | ||||
-rw-r--r-- | src/components/dms/MessagesListHeader.tsx | 171 |
3 files changed, 88 insertions, 125 deletions
diff --git a/src/components/Layout/const.ts b/src/components/Layout/const.ts index 2b5d3a1fc..2721bed21 100644 --- a/src/components/Layout/const.ts +++ b/src/components/Layout/const.ts @@ -13,7 +13,7 @@ export const BUTTON_VISUAL_ALIGNMENT_OFFSET = 3 /** * Corresponds to the width of a small square or round button */ -export const HEADER_SLOT_SIZE = 34 +export const HEADER_SLOT_SIZE = 33 /** * How far to shift the center column when in the tablet breakpoint diff --git a/src/components/dms/ConvoMenu.tsx b/src/components/dms/ConvoMenu.tsx index 8aa2335d0..1b1ebbcd5 100644 --- a/src/components/dms/ConvoMenu.tsx +++ b/src/components/dms/ConvoMenu.tsx @@ -1,12 +1,12 @@ import React, {useCallback} from 'react' -import {Keyboard, Pressable, View} from 'react-native' -import {ChatBskyConvoDefs, ModerationCause} from '@atproto/api' +import {Keyboard, View} from 'react-native' +import {type ChatBskyConvoDefs, type ModerationCause} from '@atproto/api' import {msg, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' import {useNavigation} from '@react-navigation/native' -import {NavigationProp} from '#/lib/routes/types' -import {Shadow} from '#/state/cache/types' +import {type NavigationProp} from '#/lib/routes/types' +import {type Shadow} from '#/state/cache/types' import { useConvoQuery, useMarkAsReadMutation, @@ -14,11 +14,15 @@ import { import {useMuteConvo} from '#/state/queries/messages/mute-conversation' import {useProfileBlockMutationQueue} from '#/state/queries/profile' import * as Toast from '#/view/com/util/Toast' -import {atoms as a, useTheme, ViewStyleProp} from '#/alf' +import {type ViewStyleProp} from '#/alf' +import {atoms as a} from '#/alf' +import {Button, ButtonIcon} from '#/components/Button' import {BlockedByListDialog} from '#/components/dms/BlockedByListDialog' import {LeaveConvoPrompt} from '#/components/dms/LeaveConvoPrompt' import {ReportConversationPrompt} from '#/components/dms/ReportConversationPrompt' +import {ReportDialog} from '#/components/dms/ReportDialog' import {ArrowBoxLeft_Stroke2_Corner0_Rounded as ArrowBoxLeft} from '#/components/icons/ArrowBoxLeft' +import {Bubble_Stroke2_Corner2_Rounded as Bubble} from '#/components/icons/Bubble' import {DotGrid_Stroke2_Corner0_Rounded as DotsHorizontal} from '#/components/icons/DotGrid' import {Flag_Stroke2_Corner0_Rounded as Flag} from '#/components/icons/Flag' import {Mute_Stroke2_Corner0_Rounded as Mute} from '#/components/icons/Mute' @@ -30,9 +34,7 @@ import { import {SpeakerVolumeFull_Stroke2_Corner0_Rounded as Unmute} from '#/components/icons/Speaker' import * as Menu from '#/components/Menu' import * as Prompt from '#/components/Prompt' -import * as bsky from '#/types/bsky' -import {Bubble_Stroke2_Corner2_Rounded as Bubble} from '../icons/Bubble' -import {ReportDialog} from './ReportDialog' +import type * as bsky from '#/types/bsky' let ConvoMenu = ({ convo, @@ -59,7 +61,6 @@ let ConvoMenu = ({ style?: ViewStyleProp['style'] }): React.ReactNode => { const {_} = useLingui() - const t = useTheme() const leaveConvoControl = Prompt.usePromptControl() const reportControl = Prompt.usePromptControl() @@ -73,22 +74,21 @@ let ConvoMenu = ({ {!hideTrigger && ( <View style={[style]}> <Menu.Trigger label={_(msg`Chat settings`)}> - {({props, state}) => ( - <Pressable + {({props}) => ( + <Button + label={props.accessibilityLabel} {...props} onPress={() => { Keyboard.dismiss() props.onPress() }} - style={[ - a.p_sm, - a.rounded_full, - (state.hovered || state.pressed) && t.atoms.bg_contrast_25, - // make sure pfp is in the middle - {marginLeft: -10}, - ]}> - <DotsHorizontal size="md" style={t.atoms.text} /> - </Pressable> + size="small" + color="secondary" + shape="round" + variant="ghost" + style={[a.bg_transparent]}> + <ButtonIcon icon={DotsHorizontal} size="md" /> + </Button> )} </Menu.Trigger> </View> diff --git a/src/components/dms/MessagesListHeader.tsx b/src/components/dms/MessagesListHeader.tsx index c8ed98f88..d37e4a34a 100644 --- a/src/components/dms/MessagesListHeader.tsx +++ b/src/components/dms/MessagesListHeader.tsx @@ -1,48 +1,42 @@ -import React, {useCallback} from 'react' -import {TouchableOpacity, View} from 'react-native' +import {useMemo} from 'react' +import {View} from 'react-native' import { type AppBskyActorDefs, type ModerationCause, type ModerationDecision, } from '@atproto/api' -import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' import {msg} from '@lingui/macro' import {useLingui} from '@lingui/react' -import {useNavigation} from '@react-navigation/native' -import {BACK_HITSLOP} from '#/lib/constants' import {makeProfileLink} from '#/lib/routes/links' -import {type NavigationProp} from '#/lib/routes/types' import {sanitizeDisplayName} from '#/lib/strings/display-names' import {isWeb} from '#/platform/detection' import {type Shadow} from '#/state/cache/profile-shadow' import {isConvoActive, useConvo} from '#/state/messages/convo' import {type ConvoItem} from '#/state/messages/convo/types' import {PreviewableUserAvatar} from '#/view/com/util/UserAvatar' -import {atoms as a, useBreakpoints, useTheme, web} from '#/alf' +import {atoms as a, useTheme, web} from '#/alf' import {ConvoMenu} from '#/components/dms/ConvoMenu' import {Bell2Off_Filled_Corner0_Rounded as BellStroke} from '#/components/icons/Bell2' +import * as Layout from '#/components/Layout' import {Link} from '#/components/Link' import {PostAlerts} from '#/components/moderation/PostAlerts' import {Text} from '#/components/Typography' import {useSimpleVerificationState} from '#/components/verification' import {VerificationCheck} from '#/components/verification/VerificationCheck' -const PFP_SIZE = isWeb ? 40 : 34 +const PFP_SIZE = isWeb ? 40 : Layout.HEADER_SLOT_SIZE -export let MessagesListHeader = ({ +export function MessagesListHeader({ profile, moderation, }: { profile?: Shadow<AppBskyActorDefs.ProfileViewDetailed> moderation?: ModerationDecision -}): React.ReactNode => { +}) { const t = useTheme() - const {_} = useLingui() - const {gtTablet} = useBreakpoints() - const navigation = useNavigation<NavigationProp>() - const blockInfo = React.useMemo(() => { + const blockInfo = useMemo(() => { if (!moderation) return const modui = moderation.ui('profileView') const blocks = modui.alerts.filter(alert => alert.type === 'blocking') @@ -54,87 +48,54 @@ export let MessagesListHeader = ({ } }, [moderation]) - const onPressBack = useCallback(() => { - if (navigation.canGoBack()) { - navigation.goBack() - } else { - navigation.navigate('Messages', {}) - } - }, [navigation]) - return ( - <View - style={[ - t.atoms.bg, - t.atoms.border_contrast_low, - a.border_b, - a.flex_row, - a.align_start, - a.gap_sm, - gtTablet ? a.pl_lg : a.pl_xl, - a.pr_lg, - a.py_sm, - ]}> - <TouchableOpacity - testID="conversationHeaderBackBtn" - onPress={onPressBack} - hitSlop={BACK_HITSLOP} - style={{width: 30, height: 30, marginTop: isWeb ? 6 : 4}} - accessibilityRole="button" - accessibilityLabel={_(msg`Back`)} - accessibilityHint=""> - <FontAwesomeIcon - size={18} - icon="angle-left" - style={{ - marginTop: 6, - }} - color={t.atoms.text.color} - /> - </TouchableOpacity> - - {profile && moderation && blockInfo ? ( - <HeaderReady - profile={profile} - moderation={moderation} - blockInfo={blockInfo} - /> - ) : ( - <> - <View style={[a.flex_row, a.align_center, a.gap_md, a.flex_1]}> - <View - style={[ - {width: PFP_SIZE, height: PFP_SIZE}, - a.rounded_full, - t.atoms.bg_contrast_25, - ]} - /> - <View style={a.gap_xs}> - <View - style={[ - {width: 120, height: 16}, - a.rounded_xs, - t.atoms.bg_contrast_25, - a.mt_xs, - ]} - /> + <Layout.Header.Outer> + <View style={[a.w_full, a.flex_row, a.gap_xs, a.align_start]}> + <View style={[{minHeight: PFP_SIZE}, a.justify_center]}> + <Layout.Header.BackButton /> + </View> + {profile && moderation && blockInfo ? ( + <HeaderReady + profile={profile} + moderation={moderation} + blockInfo={blockInfo} + /> + ) : ( + <> + <View style={[a.flex_row, a.align_center, a.gap_md, a.flex_1]}> <View style={[ - {width: 175, height: 12}, - a.rounded_xs, + {width: PFP_SIZE, height: PFP_SIZE}, + a.rounded_full, t.atoms.bg_contrast_25, ]} /> + <View style={a.gap_xs}> + <View + style={[ + {width: 120, height: 16}, + a.rounded_xs, + t.atoms.bg_contrast_25, + a.mt_xs, + ]} + /> + <View + style={[ + {width: 175, height: 12}, + a.rounded_xs, + t.atoms.bg_contrast_25, + ]} + /> + </View> </View> - </View> - <View style={{width: 30}} /> - </> - )} - </View> + <Layout.Header.Slot /> + </> + )} + </View> + </Layout.Header.Outer> ) } -MessagesListHeader = React.memo(MessagesListHeader) function HeaderReady({ profile, @@ -181,15 +142,13 @@ function HeaderReady({ label={_(msg`View ${displayName}'s profile`)} style={[a.flex_row, a.align_start, a.gap_md, a.flex_1, a.pr_md]} to={makeProfileLink(profile)}> - <View style={[a.pt_2xs]}> - <PreviewableUserAvatar - size={PFP_SIZE} - profile={profile} - moderation={moderation.ui('avatar')} - disableHoverCard={moderation.blocked} - /> - </View> - <View style={a.flex_1}> + <PreviewableUserAvatar + size={PFP_SIZE} + profile={profile} + moderation={moderation.ui('avatar')} + disableHoverCard={moderation.blocked} + /> + <View style={[a.flex_1]}> <View style={[a.flex_row, a.align_center]}> <Text emoji @@ -215,7 +174,7 @@ function HeaderReady({ <Text style={[ t.atoms.text_contrast_medium, - a.text_sm, + a.text_xs, web([a.leading_normal, {marginTop: -2}]), ]} numberOfLines={1}> @@ -235,15 +194,19 @@ function HeaderReady({ </View> </Link> - {isConvoActive(convoState) && ( - <ConvoMenu - convo={convoState.convo} - profile={profile} - currentScreen="conversation" - blockInfo={blockInfo} - latestReportableMessage={latestReportableMessage} - /> - )} + <View style={[{minHeight: PFP_SIZE}, a.justify_center]}> + <Layout.Header.Slot> + {isConvoActive(convoState) && ( + <ConvoMenu + convo={convoState.convo} + profile={profile} + currentScreen="conversation" + blockInfo={blockInfo} + latestReportableMessage={latestReportableMessage} + /> + )} + </Layout.Header.Slot> + </View> </View> <View |