Bluesky app fork with some witchin' additions ๐Ÿ’ซ
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

[๐Ÿด] Adjust messages list styles (#3945)

* some initial tweaks

* tweaks

* more tweaks

* tweak chat header

* properly align placeholders

* tweak web header

* one more...

* remove extra loading states from chat

* limit line count for display name

* Tweaks styles (#3949)

* Adjust sizing

* Consistent font size

* Adjust header

* oops

* fix accessibility in list

* don't use `identifier` for notifications, use `dates` instead

---------

Co-authored-by: Eric Bailey <git@esb.lol>

authored by

Hailey
Eric Bailey
and committed by
GitHub
e729647c 1a904260

+133 -100
+3 -3
src/lib/hooks/useNotificationHandler.ts
··· 58 58 const closeAllActiveElements = useCloseAllActiveElements() 59 59 60 60 // Safety to prevent double handling of the same notification 61 - const prevIdentifier = React.useRef('') 61 + const prevDate = React.useRef(0) 62 62 63 63 React.useEffect(() => { 64 64 const handleNotification = (payload?: NotificationPayload) => { ··· 161 161 162 162 const responseReceivedListener = 163 163 Notifications.addNotificationResponseReceivedListener(e => { 164 - if (e.notification.request.identifier === prevIdentifier.current) { 164 + if (e.notification.date === prevDate.current) { 165 165 return 166 166 } 167 - prevIdentifier.current = e.notification.request.identifier 167 + prevDate.current = e.notification.date 168 168 169 169 logger.debug( 170 170 'Notifications: response received',
+3 -5
src/screens/Messages/Conversation/index.tsx
··· 160 160 a.gap_lg, 161 161 a.pl_xl, 162 162 a.pr_lg, 163 - a.py_sm, 163 + a.py_md, 164 164 ]}> 165 165 {!gtTablet ? ( 166 166 <TouchableOpacity ··· 188 188 <View style={[a.align_center]}> 189 189 <PreviewableUserAvatar size={32} profile={profile} /> 190 190 <Text 191 - style={[a.text_lg, a.font_bold, isWeb ? a.mt_md : a.mt_sm]} 191 + style={[a.text_lg, a.font_bold, a.pt_sm, a.pb_2xs]} 192 192 numberOfLines={1}> 193 193 {profile.displayName} 194 194 </Text> 195 - <Text 196 - style={[t.atoms.text_contrast_medium, {fontSize: 15}]} 197 - numberOfLines={1}> 195 + <Text style={[t.atoms.text_contrast_medium]} numberOfLines={1}> 198 196 @{profile.handle} 199 197 </Text> 200 198 </View>
+127 -92
src/screens/Messages/List/index.tsx
··· 1 - /* eslint-disable react/prop-types */ 2 - 3 1 import React, {useCallback, useMemo, useState} from 'react' 4 2 import {View} from 'react-native' 5 3 import {ChatBskyConvoDefs} from '@atproto-labs/api' ··· 40 38 import {useDmServiceUrlStorage} from '../Temp/useDmServiceUrlStorage' 41 39 42 40 type Props = NativeStackScreenProps<MessagesTabNavigatorParams, 'Messages'> 41 + 42 + function renderItem({ 43 + item, 44 + index, 45 + }: { 46 + item: ChatBskyConvoDefs.ConvoView 47 + index: number 48 + }) { 49 + return <ChatListItem convo={item} index={index} /> 50 + } 51 + 52 + function keyExtractor(item: ChatBskyConvoDefs.ConvoView) { 53 + return item.id 54 + } 55 + 43 56 export function MessagesScreen({navigation, route}: Props) { 44 57 const {_} = useLingui() 45 58 const t = useTheme() ··· 135 148 navigation.navigate('MessagesSettings') 136 149 }, [navigation]) 137 150 138 - const renderItem = useCallback( 139 - ({item}: {item: ChatBskyConvoDefs.ConvoView}) => { 140 - return <ChatListItem key={item.id} convo={item} /> 141 - }, 142 - [], 143 - ) 144 - 145 151 const gate = useGate() 146 152 if (!gate('dms')) return <ClipClopGate /> 147 153 ··· 213 219 <ViewHeader 214 220 title={_(msg`Messages`)} 215 221 renderButton={renderButton} 216 - showBorder 222 + showBorder={false} 217 223 canGoBack={false} 218 224 /> 219 225 )} ··· 221 227 <List 222 228 data={conversations} 223 229 renderItem={renderItem} 224 - keyExtractor={item => item.id} 230 + keyExtractor={keyExtractor} 225 231 refreshing={isPTRing} 226 232 onRefresh={onRefresh} 227 233 onEndReached={onEndReached} ··· 249 255 ) 250 256 } 251 257 252 - function ChatListItem({convo}: {convo: ChatBskyConvoDefs.ConvoView}) { 258 + function ChatListItem({ 259 + convo, 260 + index, 261 + }: { 262 + convo: ChatBskyConvoDefs.ConvoView 263 + index: number 264 + }) { 253 265 const t = useTheme() 254 266 const {_} = useLingui() 255 267 const {currentAccount} = useSession() ··· 301 313 } 302 314 303 315 return ( 304 - <Button 305 - label={otherUser.displayName || otherUser.handle} 306 - onPress={onPress} 307 - style={a.flex_1} 308 - onLongPress={isNative ? menuControl.open : undefined} 316 + <View 309 317 // @ts-expect-error web only 310 318 onMouseEnter={onMouseEnter} 311 319 onMouseLeave={onMouseLeave} 312 320 onFocus={onFocus} 313 321 onBlur={onMouseLeave}> 314 - {({hovered, pressed}) => ( 315 - <View 316 - style={[ 317 - a.flex_row, 318 - a.flex_1, 319 - a.pl_md, 320 - a.py_sm, 321 - a.gap_md, 322 - a.pr_xl, 323 - (hovered || pressed) && t.atoms.bg_contrast_25, 324 - ]}> 325 - <View pointerEvents="none"> 326 - <UserAvatar avatar={otherUser?.avatar} size={42} /> 327 - </View> 328 - <View style={[a.flex_1]}> 329 - <Text 330 - numberOfLines={1} 331 - style={[a.text_md, web([a.leading_normal, {marginTop: -4}])]}> 332 - <Text 333 - style={[t.atoms.text, convo.unreadCount > 0 && a.font_bold]}> 334 - {otherUser.displayName || otherUser.handle} 335 - </Text>{' '} 336 - {lastMessageSentAt ? ( 337 - <TimeElapsed timestamp={lastMessageSentAt}> 338 - {({timeElapsed}) => ( 339 - <Text style={t.atoms.text_contrast_medium}> 340 - @{otherUser.handle} &middot; {timeElapsed} 322 + <Button 323 + label={otherUser.displayName || otherUser.handle} 324 + onPress={onPress} 325 + style={a.flex_1} 326 + onLongPress={isNative ? menuControl.open : undefined}> 327 + {({hovered, pressed}) => ( 328 + <View 329 + style={[ 330 + a.flex_row, 331 + a.flex_1, 332 + a.px_lg, 333 + a.py_md, 334 + a.gap_md, 335 + (hovered || pressed) && t.atoms.bg_contrast_25, 336 + index === 0 && [a.border_t, a.pt_lg], 337 + t.atoms.border_contrast_low, 338 + ]}> 339 + <UserAvatar avatar={otherUser?.avatar} size={52} /> 340 + <View style={[a.flex_1, a.flex_row, a.align_center]}> 341 + <View style={[a.flex_1]}> 342 + <View 343 + style={[ 344 + a.flex_1, 345 + a.flex_row, 346 + a.align_end, 347 + a.pb_2xs, 348 + web([{marginTop: -2}]), 349 + ]}> 350 + <Text 351 + numberOfLines={1} 352 + style={[{maxWidth: '85%'}, web([a.leading_normal])]}> 353 + <Text style={[a.text_md, t.atoms.text, a.font_bold]}> 354 + {otherUser.displayName || otherUser.handle} 341 355 </Text> 356 + </Text> 357 + {lastMessageSentAt && ( 358 + <TimeElapsed timestamp={lastMessageSentAt}> 359 + {({timeElapsed}) => ( 360 + <Text 361 + style={[ 362 + a.text_sm, 363 + web([a.leading_normal]), 364 + t.atoms.text_contrast_medium, 365 + ]}> 366 + {' '} 367 + &middot; {timeElapsed} 368 + </Text> 369 + )} 370 + </TimeElapsed> 342 371 )} 343 - </TimeElapsed> 344 - ) : ( 345 - <Text style={t.atoms.text_contrast_medium}> 372 + </View> 373 + <Text 374 + numberOfLines={1} 375 + style={[a.text_sm, t.atoms.text_contrast_medium, a.pb_xs]}> 346 376 @{otherUser.handle} 347 377 </Text> 378 + <Text 379 + numberOfLines={2} 380 + style={[ 381 + a.text_sm, 382 + a.leading_snug, 383 + convo.unreadCount > 0 384 + ? a.font_bold 385 + : t.atoms.text_contrast_high, 386 + ]}> 387 + {lastMessage} 388 + </Text> 389 + </View> 390 + {convo.unreadCount > 0 && ( 391 + <View 392 + style={[ 393 + a.absolute, 394 + a.rounded_full, 395 + { 396 + backgroundColor: convo.muted 397 + ? t.palette.contrast_200 398 + : t.palette.primary_500, 399 + height: 7, 400 + width: 7, 401 + }, 402 + isNative 403 + ? { 404 + top: 15, 405 + right: 12, 406 + } 407 + : { 408 + top: 0, 409 + right: 0, 410 + }, 411 + ]} 412 + /> 348 413 )} 349 - </Text> 350 - <Text 351 - numberOfLines={2} 352 - style={[ 353 - a.text_sm, 354 - a.leading_snug, 355 - convo.unreadCount > 0 356 - ? a.font_bold 357 - : t.atoms.text_contrast_medium, 358 - ]}> 359 - {lastMessage} 360 - </Text> 414 + <ConvoMenu 415 + convo={convo} 416 + profile={otherUser} 417 + control={menuControl} 418 + currentScreen="list" 419 + showMarkAsRead={convo.unreadCount > 0} 420 + hideTrigger={isNative} 421 + triggerOpacity={ 422 + !gtMobile || showActions || menuControl.isOpen ? 1 : 0 423 + } 424 + /> 425 + </View> 361 426 </View> 362 - {convo.unreadCount > 0 && ( 363 - <View 364 - style={[ 365 - a.flex_0, 366 - a.ml_md, 367 - a.mt_sm, 368 - a.rounded_full, 369 - { 370 - backgroundColor: convo.muted 371 - ? t.palette.contrast_200 372 - : t.palette.primary_500, 373 - height: 7, 374 - width: 7, 375 - }, 376 - ]} 377 - /> 378 - )} 379 - <ConvoMenu 380 - convo={convo} 381 - profile={otherUser} 382 - control={menuControl} 383 - currentScreen="list" 384 - showMarkAsRead={convo.unreadCount > 0} 385 - hideTrigger={isNative} 386 - triggerOpacity={ 387 - !gtMobile || showActions || menuControl.isOpen ? 1 : 0 388 - } 389 - /> 390 - </View> 391 - )} 392 - </Button> 427 + )} 428 + </Button> 429 + </View> 393 430 ) 394 431 } 395 432 ··· 412 449 <View 413 450 style={[ 414 451 t.atoms.bg, 415 - t.atoms.border_contrast_low, 416 - a.border_b, 417 452 a.flex_row, 418 453 a.align_center, 419 454 a.justify_between,