my fork of the bluesky client

Merge branch 'main' of https://github.com/haideralipunjabi/social-app into main

+64 -5
+1
src/lib/constants.ts
··· 147 147 export const HITSLOP_20 = createHitslop(20) 148 148 export const HITSLOP_30 = createHitslop(30) 149 149 export const BACK_HITSLOP = HITSLOP_30 150 + export const MAX_POST_LINES = 25
+5
src/lib/strings/helpers.ts
··· 32 32 33 33 return 4294967296 * (2097151 & h2) + (h1 >>> 0) 34 34 } 35 + 36 + export function countLines(str: string | undefined): number { 37 + if (!str) return 0 38 + return str.match(/\n/g)?.length ?? 0 39 + }
+19 -2
src/view/com/post-thread/PostThreadItem.tsx
··· 8 8 FontAwesomeIconStyle, 9 9 } from '@fortawesome/react-native-fontawesome' 10 10 import {PostThreadItemModel} from 'state/models/content/post-thread-item' 11 - import {Link} from '../util/Link' 11 + import {Link, TextLink} from '../util/Link' 12 12 import {RichText} from '../util/text/RichText' 13 13 import {Text} from '../util/text/Text' 14 14 import {PostDropdownBtn} from '../util/forms/PostDropdownBtn' ··· 18 18 import {niceDate} from 'lib/strings/time' 19 19 import {sanitizeDisplayName} from 'lib/strings/display-names' 20 20 import {sanitizeHandle} from 'lib/strings/handles' 21 - import {pluralize} from 'lib/strings/helpers' 21 + import {countLines, pluralize} from 'lib/strings/helpers' 22 22 import {isEmbedByEmbedder} from 'lib/embeds' 23 23 import {getTranslatorLink, isPostInLanguage} from '../../../locale/helpers' 24 24 import {useStores} from 'state/index' ··· 35 35 import {TimeElapsed} from 'view/com/util/TimeElapsed' 36 36 import {makeProfileLink} from 'lib/routes/links' 37 37 import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries' 38 + import {MAX_POST_LINES} from 'lib/constants' 38 39 39 40 export const PostThreadItem = observer(function PostThreadItem({ 40 41 item, ··· 50 51 const pal = usePalette('default') 51 52 const store = useStores() 52 53 const [deleted, setDeleted] = React.useState(false) 54 + const [limitLines, setLimitLines] = React.useState( 55 + countLines(item.richText?.text) >= MAX_POST_LINES, 56 + ) 53 57 const styles = useStyles() 54 58 const record = item.postRecord 55 59 const hasEngagement = item.post.likeCount || item.post.repostCount ··· 150 154 }, 151 155 ) 152 156 }, [item, store]) 157 + 158 + const onPressShowMore = React.useCallback(() => { 159 + setLimitLines(false) 160 + }, [setLimitLines]) 153 161 154 162 if (!record) { 155 163 return <ErrorMessage message="Invalid or unsupported post record" /> ··· 489 497 richText={item.richText} 490 498 style={[pal.text, s.flex1]} 491 499 lineHeight={1.3} 500 + numberOfLines={limitLines ? MAX_POST_LINES : undefined} 492 501 /> 493 502 </View> 503 + ) : undefined} 504 + {limitLines ? ( 505 + <TextLink 506 + text="Show More" 507 + style={pal.link} 508 + onPress={onPressShowMore} 509 + href="#" 510 + /> 494 511 ) : undefined} 495 512 {item.post.embed && ( 496 513 <ContentHider
+19 -2
src/view/com/post/Post.tsx
··· 14 14 import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' 15 15 import {PostThreadModel} from 'state/models/content/post-thread' 16 16 import {PostThreadItemModel} from 'state/models/content/post-thread-item' 17 - import {Link} from '../util/Link' 17 + import {Link, TextLink} from '../util/Link' 18 18 import {UserInfoText} from '../util/UserInfoText' 19 19 import {PostMeta} from '../util/PostMeta' 20 20 import {PostEmbeds} from '../util/post-embeds' ··· 30 30 import {usePalette} from 'lib/hooks/usePalette' 31 31 import {getTranslatorLink} from '../../../locale/helpers' 32 32 import {makeProfileLink} from 'lib/routes/links' 33 + import {MAX_POST_LINES} from 'lib/constants' 34 + import {countLines} from 'lib/strings/helpers' 33 35 34 36 export const Post = observer(function PostImpl({ 35 37 view, ··· 103 105 }) { 104 106 const pal = usePalette('default') 105 107 const store = useStores() 106 - 108 + const [limitLines, setLimitLines] = React.useState( 109 + countLines(item.richText?.text) >= MAX_POST_LINES, 110 + ) 107 111 const itemUri = item.post.uri 108 112 const itemCid = item.post.cid 109 113 const itemUrip = new AtUri(item.post.uri) ··· 182 186 ) 183 187 }, [item, setDeleted, store]) 184 188 189 + const onPressShowMore = React.useCallback(() => { 190 + setLimitLines(false) 191 + }, [setLimitLines]) 192 + 185 193 return ( 186 194 <Link href={itemHref} style={[styles.outer, pal.view, pal.border, style]}> 187 195 {showReplyLine && <View style={styles.replyLine} />} ··· 239 247 type="post-text" 240 248 richText={item.richText} 241 249 lineHeight={1.3} 250 + numberOfLines={limitLines ? MAX_POST_LINES : undefined} 242 251 style={s.flex1} 243 252 /> 244 253 </View> 254 + ) : undefined} 255 + {limitLines ? ( 256 + <TextLink 257 + text="Show More" 258 + style={pal.link} 259 + onPress={onPressShowMore} 260 + href="#" 261 + /> 245 262 ) : undefined} 246 263 {item.post.embed ? ( 247 264 <ContentHider
+19 -1
src/view/com/posts/FeedItem.tsx
··· 9 9 } from '@fortawesome/react-native-fontawesome' 10 10 import {PostsFeedItemModel} from 'state/models/feeds/post' 11 11 import {FeedSourceInfo} from 'lib/api/feed/types' 12 - import {Link, TextLinkOnWebOnly} from '../util/Link' 12 + import {Link, TextLinkOnWebOnly, TextLink} from '../util/Link' 13 13 import {Text} from '../util/text/Text' 14 14 import {UserInfoText} from '../util/UserInfoText' 15 15 import {PostMeta} from '../util/PostMeta' ··· 30 30 import {getTranslatorLink} from '../../../locale/helpers' 31 31 import {makeProfileLink} from 'lib/routes/links' 32 32 import {isEmbedByEmbedder} from 'lib/embeds' 33 + import {MAX_POST_LINES} from 'lib/constants' 34 + import {countLines} from 'lib/strings/helpers' 33 35 34 36 export const FeedItem = observer(function FeedItemImpl({ 35 37 item, ··· 49 51 const pal = usePalette('default') 50 52 const {track} = useAnalytics() 51 53 const [deleted, setDeleted] = useState(false) 54 + const [limitLines, setLimitLines] = useState( 55 + countLines(item.richText?.text) >= MAX_POST_LINES, 56 + ) 52 57 const record = item.postRecord 53 58 const itemUri = item.post.uri 54 59 const itemCid = item.post.cid ··· 135 140 }, 136 141 ) 137 142 }, [track, item, setDeleted, store]) 143 + 144 + const onPressShowMore = React.useCallback(() => { 145 + setLimitLines(false) 146 + }, [setLimitLines]) 138 147 139 148 const outerStyles = [ 140 149 styles.outer, ··· 307 316 type="post-text" 308 317 richText={item.richText} 309 318 lineHeight={1.3} 319 + numberOfLines={limitLines ? MAX_POST_LINES : undefined} 310 320 style={s.flex1} 311 321 /> 312 322 </View> 323 + ) : undefined} 324 + {limitLines ? ( 325 + <TextLink 326 + text="Show More" 327 + style={pal.link} 328 + onPress={onPressShowMore} 329 + href="#" 330 + /> 313 331 ) : undefined} 314 332 {item.post.embed ? ( 315 333 <ContentHider
+1
src/view/com/util/text/RichText.tsx
··· 52 52 testID={testID} 53 53 type={type} 54 54 style={[style, pal.text, lineHeightStyle]} 55 + numberOfLines={numberOfLines} 55 56 // @ts-ignore web only -prf 56 57 dataSet={WORD_WRAP}> 57 58 {text}