this repo has no description
0
fork

Configure Feed

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

Handle case when too many sub-comments

For now, encourage clicking on status to see more replies instead of expanding the sub-comments
Feels "wasted" since the comments are already loaded but it's just too much scrolling

Also auto-open if the sub-comments are not a lot.

+74 -29
+10
src/app.css
··· 197 197 border-color: transparent transparent var(--comment-line-color) transparent; 198 198 transform: rotate(45deg); 199 199 } 200 + .timeline.contextual > li .replies-link { 201 + color: var(--text-insignificant-color); 202 + margin-left: 16px; 203 + margin-top: -12px; 204 + padding-bottom: 12px; 205 + font-size: 90%; 206 + } 207 + .timeline.contextual > li .replies-link * { 208 + vertical-align: middle; 209 + } 200 210 .timeline.contextual > li .replies { 201 211 margin-top: -12px; 202 212 }
+64 -29
src/pages/status.jsx
··· 12 12 import Icon from '../components/icon'; 13 13 import Loader from '../components/loader'; 14 14 import Status from '../components/status'; 15 + import htmlContentLength from '../utils/html-content-length'; 15 16 import shortenNumber from '../utils/shorten-number'; 16 17 import states from '../utils/states'; 17 18 import store from '../utils/store'; 18 19 import useTitle from '../utils/useTitle'; 20 + 21 + const LIMIT = 40; 19 22 20 23 function StatusPage({ id }) { 21 24 const snapStates = useSnapshot(states); ··· 215 218 }); 216 219 const closeLink = `#${prevRoute || '/'}`; 217 220 218 - const [limit, setLimit] = useState(40); 221 + const [limit, setLimit] = useState(LIMIT); 219 222 const showMore = useMemo(() => { 220 223 // return number of statuses to show 221 224 return statuses.length - limit; 222 225 }, [statuses.length, limit]); 223 226 224 - const hasManyStatuses = statuses.length > 40; 227 + const hasManyStatuses = statuses.length > LIMIT; 225 228 const hasDescendants = statuses.some((s) => s.descendant); 226 229 227 230 return ( ··· 286 289 withinContext 287 290 size={thread || ancestor ? 'm' : 's'} 288 291 /> 292 + {replies?.length > LIMIT && ( 293 + <div class="replies-link"> 294 + <Icon icon="comment" />{' '} 295 + <span title={replies.length}> 296 + {shortenNumber(replies.length)} 297 + </span> 298 + </div> 299 + )} 289 300 </Link> 290 301 )} 291 - {descendant && replies?.length > 0 && ( 292 - <details class="replies" open={!hasManyStatuses}> 293 - <summary hidden={!hasManyStatuses}> 294 - <span title={replies.length}> 295 - {shortenNumber(replies.length)} 296 - </span>{' '} 297 - repl{replies.length === 1 ? 'y' : 'ies'} 298 - </summary> 299 - <ul> 300 - {replies.map((replyID) => ( 301 - <li key={replyID}> 302 - <Link 303 - class="status-link" 304 - href={`#/s/${replyID}`} 305 - onClick={() => { 306 - userInitiated.current = true; 307 - }} 308 - > 309 - <Status statusID={replyID} withinContext size="s" /> 310 - </Link> 311 - </li> 312 - ))} 313 - </ul> 314 - </details> 315 - )} 302 + {descendant && 303 + replies?.length > 0 && 304 + replies?.length <= LIMIT && ( 305 + <SubComments 306 + hasManyStatuses={hasManyStatuses} 307 + replies={replies} 308 + /> 309 + )} 316 310 {uiState === 'loading' && 317 311 isHero && 318 312 !!heroStatus?.repliesCount && ··· 330 324 type="button" 331 325 class="plain block" 332 326 disabled={uiState === 'loading'} 333 - onClick={() => setLimit((l) => l + 40)} 327 + onClick={() => setLimit((l) => l + LIMIT)} 334 328 style={{ marginBlockEnd: '6em' }} 335 329 > 336 330 Show more&hellip;{' '} 337 - <span class="tag">{showMore > 40 ? '40+' : showMore}</span> 331 + <span class="tag"> 332 + {showMore > LIMIT ? `${LIMIT}+` : showMore} 333 + </span> 338 334 </button> 339 335 </li> 340 336 )} 341 337 </ul> 342 338 </div> 343 339 </div> 340 + ); 341 + } 342 + 343 + function SubComments({ hasManyStatuses, replies }) { 344 + // If less than or 2 replies and total number of characters of content from replies is less than 500 345 + let isBrief = false; 346 + if (replies.length <= 2) { 347 + let totalLength = replies.reduce((acc, reply) => { 348 + const { content } = reply; 349 + const length = htmlContentLength(content); 350 + return acc + length; 351 + }, 0); 352 + isBrief = totalLength < 500; 353 + } 354 + 355 + const open = isBrief || !hasManyStatuses; 356 + 357 + return ( 358 + <details class="replies" open={open}> 359 + <summary hidden={open}> 360 + <span title={replies.length}>{shortenNumber(replies.length)}</span> repl 361 + {replies.length === 1 ? 'y' : 'ies'} 362 + </summary> 363 + <ul> 364 + {replies.map((replyID) => ( 365 + <li key={replyID}> 366 + <Link 367 + class="status-link" 368 + href={`#/s/${replyID}`} 369 + onClick={() => { 370 + userInitiated.current = true; 371 + }} 372 + > 373 + <Status statusID={replyID} withinContext size="s" /> 374 + </Link> 375 + </li> 376 + ))} 377 + </ul> 378 + </details> 344 379 ); 345 380 } 346 381