Bluesky app fork with some witchin' additions 💫 witchsky.app
bluesky fork client
122
fork

Configure Feed

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

Fix notification descriptions and render images for your own posts in notifs

+63 -13
+22 -11
src/view/com/notifications/FeedItem.tsx
··· 11 11 import {UpIconSolid} from '../../lib/icons' 12 12 import {Text} from '../util/text/Text' 13 13 import {UserAvatar} from '../util/UserAvatar' 14 + import {ImageHorzList} from '../util/images/ImageHorzList' 14 15 import {ErrorMessage} from '../util/error/ErrorMessage' 15 16 import {Post} from '../post/Post' 16 17 import {Link} from '../util/Link' ··· 181 182 </Text> 182 183 </> 183 184 ) : undefined} 185 + <Text style={[styles.metaItem, pal.text]}>{action}</Text> 184 186 <Text style={[styles.metaItem, pal.textLight]}> 185 187 {ago(item.indexedAt)} 186 188 </Text> ··· 208 210 if (additionalPost.error) { 209 211 return <ErrorMessage message={additionalPost.error} /> 210 212 } 211 - const record = additionalPost.thread?.postRecord 212 - let text = record.text 213 - if ( 214 - AppBskyEmbedImages.isMain(record.embed) && 215 - AppBskyEmbedImages.validateMain(record.embed).success 216 - ) { 217 - for (let i = 0; i < record.embed.images.length; i++) { 218 - text += ` [${record.embed.images[i].alt || `image${i + 1}`}]` 219 - } 220 - } 221 - return <Text style={pal.textLight}>{text}</Text> 213 + const text = additionalPost.thread?.postRecord.text 214 + const images = ( 215 + additionalPost.thread.post.embed as AppBskyEmbedImages.Presented 216 + )?.images 217 + return ( 218 + <> 219 + {text?.length > 0 && <Text style={pal.textLight}>{text}</Text>} 220 + {images && images?.length > 0 && ( 221 + <ImageHorzList 222 + uris={images?.map(img => img.thumb)} 223 + style={styles.additionalPostImages} 224 + /> 225 + )} 226 + </> 227 + ) 222 228 } 223 229 224 230 const styles = StyleSheet.create({ ··· 263 269 postText: { 264 270 paddingBottom: 5, 265 271 color: colors.black, 272 + }, 273 + additionalPostImages: { 274 + marginTop: 5, 275 + marginLeft: 2, 276 + opacity: 0.8, 266 277 }, 267 278 268 279 addedContainer: {
+39
src/view/com/util/images/ImageHorzList.tsx
··· 1 + import React from 'react' 2 + import { 3 + Image, 4 + StyleProp, 5 + StyleSheet, 6 + TouchableWithoutFeedback, 7 + View, 8 + ViewStyle, 9 + } from 'react-native' 10 + 11 + export function ImageHorzList({ 12 + uris, 13 + onPress, 14 + style, 15 + }: { 16 + uris: string[] 17 + onPress?: (index: number) => void 18 + style?: StyleProp<ViewStyle> 19 + }) { 20 + return ( 21 + <View style={[styles.flexRow, style]}> 22 + {uris.map((uri, i) => ( 23 + <TouchableWithoutFeedback key={i} onPress={() => onPress?.(i)}> 24 + <Image source={{uri}} style={styles.image} /> 25 + </TouchableWithoutFeedback> 26 + ))} 27 + </View> 28 + ) 29 + } 30 + 31 + const styles = StyleSheet.create({ 32 + flexRow: {flexDirection: 'row'}, 33 + image: { 34 + width: 100, 35 + height: 100, 36 + borderRadius: 4, 37 + marginRight: 5, 38 + }, 39 + })
+2 -2
src/view/com/util/images/ImageLayoutGrid.tsx
··· 24 24 style, 25 25 }: { 26 26 type: ImageLayoutGridType 27 - uris: string 27 + uris: string[] 28 28 onPress?: (index: number) => void 29 29 style?: StyleProp<ViewStyle> 30 30 }) { ··· 58 58 containerInfo, 59 59 }: { 60 60 type: ImageLayoutGridType 61 - uris: string 61 + uris: string[] 62 62 onPress?: (index: number) => void 63 63 containerInfo: Dim 64 64 }) {