Bluesky app fork with some witchin' additions 💫
0
fork

Configure Feed

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

Move menu controls into post footers and improve meta info rendering

+58 -53
+10 -8
src/view/com/post-thread/PostThreadItem.tsx
··· 222 222 <View style={[s.pl10, s.pb5]}> 223 223 <PostCtrls 224 224 big 225 + itemHref={itemHref} 226 + itemTitle={itemTitle} 227 + isAuthor={item.post.author.did === store.me.did} 225 228 isReposted={!!item.post.viewer.repost} 226 229 isUpvoted={!!item.post.viewer.upvote} 227 230 onPressReply={onPressReply} 228 231 onPressToggleRepost={onPressToggleRepost} 229 232 onPressToggleUpvote={onPressToggleUpvote} 233 + onCopyPostText={onCopyPostText} 234 + onDeletePost={onDeletePost} 230 235 /> 231 236 </View> 232 237 </View> ··· 276 281 </View> 277 282 <View style={styles.layoutContent}> 278 283 <PostMeta 279 - itemHref={itemHref} 280 - itemTitle={itemTitle} 281 284 authorHref={authorHref} 282 285 authorHandle={item.post.author.handle} 283 286 authorDisplayName={item.post.author.displayName} 284 287 timestamp={item.post.indexedAt} 285 - isAuthor={item.post.author.did === store.me.did} 286 - onCopyPostText={onCopyPostText} 287 - onDeletePost={onDeletePost} 288 288 /> 289 289 {item.post.author.viewer?.muted ? ( 290 290 <View style={[styles.mutedWarning, pal.btn]}> ··· 304 304 )} 305 305 <PostEmbeds embed={item.post.embed} style={{marginBottom: 10}} /> 306 306 <PostCtrls 307 - replyCount={item.post.replyCount} 308 - repostCount={item.post.repostCount} 309 - upvoteCount={item.post.upvoteCount} 307 + itemHref={itemHref} 308 + itemTitle={itemTitle} 309 + isAuthor={item.post.author.did === store.me.did} 310 310 isReposted={!!item.post.viewer.repost} 311 311 isUpvoted={!!item.post.viewer.upvote} 312 312 onPressReply={onPressReply} 313 313 onPressToggleRepost={onPressToggleRepost} 314 314 onPressToggleUpvote={onPressToggleUpvote} 315 + onCopyPostText={onCopyPostText} 316 + onDeletePost={onDeletePost} 315 317 /> 316 318 </View> 317 319 </View>
+5 -5
src/view/com/post/Post.tsx
··· 154 154 </View> 155 155 <View style={styles.layoutContent}> 156 156 <PostMeta 157 - itemHref={itemHref} 158 - itemTitle={itemTitle} 159 157 authorHref={authorHref} 160 158 authorHandle={item.post.author.handle} 161 159 authorDisplayName={item.post.author.displayName} 162 160 timestamp={item.post.indexedAt} 163 - isAuthor={item.post.author.did === store.me.did} 164 - onCopyPostText={onCopyPostText} 165 - onDeletePost={onDeletePost} 166 161 /> 167 162 {replyHref !== '' && ( 168 163 <View style={[s.flexRow, s.mb2, {alignItems: 'center'}]}> ··· 198 193 )} 199 194 <PostEmbeds embed={item.post.embed} style={{marginBottom: 10}} /> 200 195 <PostCtrls 196 + itemHref={itemHref} 197 + itemTitle={itemTitle} 198 + isAuthor={item.post.author.did === store.me.did} 201 199 replyCount={item.post.replyCount} 202 200 repostCount={item.post.repostCount} 203 201 upvoteCount={item.post.upvoteCount} ··· 206 204 onPressReply={onPressReply} 207 205 onPressToggleRepost={onPressToggleRepost} 208 206 onPressToggleUpvote={onPressToggleUpvote} 207 + onCopyPostText={onCopyPostText} 208 + onDeletePost={onDeletePost} 209 209 /> 210 210 </View> 211 211 </View>
+5 -5
src/view/com/posts/FeedItem.tsx
··· 177 177 </View> 178 178 <View style={styles.layoutContent}> 179 179 <PostMeta 180 - itemHref={itemHref} 181 - itemTitle={itemTitle} 182 180 authorHref={authorHref} 183 181 authorHandle={item.post.author.handle} 184 182 authorDisplayName={item.post.author.displayName} 185 183 timestamp={item.post.indexedAt} 186 - isAuthor={item.post.author.did === store.me.did} 187 - onCopyPostText={onCopyPostText} 188 - onDeletePost={onDeletePost} 189 184 /> 190 185 {!isChild && replyHref !== '' && ( 191 186 <View style={[s.flexRow, s.mb2, {alignItems: 'center'}]}> ··· 226 221 )} 227 222 <PostEmbeds embed={item.post.embed} style={styles.postEmbeds} /> 228 223 <PostCtrls 224 + itemHref={itemHref} 225 + itemTitle={itemTitle} 226 + isAuthor={item.post.author.did === store.me.did} 229 227 replyCount={item.post.replyCount} 230 228 repostCount={item.post.repostCount} 231 229 upvoteCount={item.post.upvoteCount} ··· 234 232 onPressReply={onPressReply} 235 233 onPressToggleRepost={onPressToggleRepost} 236 234 onPressToggleUpvote={onPressToggleUpvote} 235 + onCopyPostText={onCopyPostText} 236 + onDeletePost={onDeletePost} 237 237 /> 238 238 </View> 239 239 </View>
+23 -1
src/view/com/util/PostCtrls.tsx
··· 3 3 import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' 4 4 import ReactNativeHapticFeedback from 'react-native-haptic-feedback' 5 5 import {Text} from './text/Text' 6 + import {PostDropdownBtn} from './forms/DropdownButton' 6 7 import {UpIcon, UpIconSolid, CommentBottomArrow} from '../../lib/icons' 7 8 import {s, colors} from '../../lib/styles' 8 9 import {useAnimatedValue} from '../../lib/hooks/useAnimatedValue' 9 10 10 11 interface PostCtrlsOpts { 12 + itemHref: string 13 + itemTitle: string 14 + isAuthor: boolean 11 15 big?: boolean 12 16 replyCount?: number 13 17 repostCount?: number ··· 17 21 onPressReply: () => void 18 22 onPressToggleRepost: () => void 19 23 onPressToggleUpvote: () => void 24 + onCopyPostText: () => void 25 + onDeletePost: () => void 20 26 } 21 27 22 28 const redgray = '#7A6161' ··· 169 175 ) : undefined} 170 176 </TouchableOpacity> 171 177 </View> 172 - <View style={s.flex1}></View> 178 + <View style={s.flex1}> 179 + {opts.big ? undefined : ( 180 + <PostDropdownBtn 181 + style={styles.ctrl} 182 + itemHref={opts.itemHref} 183 + itemTitle={opts.itemTitle} 184 + isAuthor={opts.isAuthor} 185 + onCopyPostText={opts.onCopyPostText} 186 + onDeletePost={opts.onDeletePost}> 187 + <FontAwesomeIcon 188 + icon="ellipsis-h" 189 + size={16} 190 + style={[s.mt2, s.mr5, sRedgray]} 191 + /> 192 + </PostDropdownBtn> 193 + )} 194 + </View> 173 195 </View> 174 196 ) 175 197 }
+15 -34
src/view/com/util/PostMeta.tsx
··· 1 1 import React from 'react' 2 - import {StyleSheet, View} from 'react-native' 3 - import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' 2 + import {Platform, StyleSheet, View} from 'react-native' 4 3 import {Link} from '../util/Link' 5 4 import {Text} from './text/Text' 6 - import {PostDropdownBtn} from './forms/DropdownButton' 7 - import {s} from '../../lib/styles' 8 5 import {ago} from '../../../lib/strings' 9 - import {useTheme} from '../../lib/ThemeContext' 10 6 import {usePalette} from '../../lib/hooks/usePalette' 11 7 12 8 interface PostMetaOpts { 13 - itemHref: string 14 - itemTitle: string 15 9 authorHref: string 16 10 authorHandle: string 17 11 authorDisplayName: string | undefined 18 12 timestamp: string 19 - isAuthor: boolean 20 - onCopyPostText: () => void 21 - onDeletePost: () => void 22 13 } 23 14 24 15 export function PostMeta(opts: PostMetaOpts) { 25 - const theme = useTheme() 26 16 const pal = usePalette('default') 27 17 let displayName = opts.authorDisplayName || opts.authorHandle 28 18 let handle = opts.authorHandle ··· 31 21 // Android simply cannot handle the truncation case we need 32 22 // so we have to do it manually here 33 23 // -prf 34 - if (displayName.length + handle.length > 26) { 35 - if (displayName.length > 26) { 36 - displayName = displayName.slice(0, 23) + '...' 37 - } else { 38 - handle = handle.slice(0, 23 - displayName.length) + '...' 39 - if (handle.endsWith('....')) { 40 - handle = handle.slice(0, -4) + '...' 24 + if (Platform.OS === 'android') { 25 + if (displayName.length + handle.length > 26) { 26 + if (displayName.length > 26) { 27 + displayName = displayName.slice(0, 23) + '...' 28 + } else { 29 + handle = handle.slice(0, 23 - displayName.length) + '...' 30 + if (handle.endsWith('....')) { 31 + handle = handle.slice(0, -4) + '...' 32 + } 41 33 } 42 34 } 43 35 } ··· 45 37 return ( 46 38 <View style={styles.meta}> 47 39 <Link 48 - style={styles.metaItem} 40 + style={[styles.metaItem, styles.maxWidth]} 49 41 href={opts.authorHref} 50 42 title={opts.authorHandle}> 51 43 <Text type="h5" style={[pal.text]} numberOfLines={1}> ··· 60 52 <Text type="h6" style={[styles.metaItem, pal.textLight]}> 61 53 &middot; {ago(opts.timestamp)} 62 54 </Text> 63 - <View style={s.flex1} /> 64 - <PostDropdownBtn 65 - style={[styles.metaItem, s.pl5]} 66 - itemHref={opts.itemHref} 67 - itemTitle={opts.itemTitle} 68 - isAuthor={opts.isAuthor} 69 - onCopyPostText={opts.onCopyPostText} 70 - onDeletePost={opts.onDeletePost}> 71 - <FontAwesomeIcon 72 - icon="ellipsis-h" 73 - size={14} 74 - style={[s.mt2, s.mr5, pal.text]} 75 - /> 76 - </PostDropdownBtn> 77 55 </View> 78 56 ) 79 57 } ··· 81 59 const styles = StyleSheet.create({ 82 60 meta: { 83 61 flexDirection: 'row', 84 - alignItems: 'center', 62 + alignItems: 'baseline', 85 63 paddingTop: 0, 86 64 paddingBottom: 2, 87 65 }, 88 66 metaItem: { 89 67 paddingRight: 5, 68 + }, 69 + maxWidth: { 70 + maxWidth: '70%', 90 71 }, 91 72 })