1
Fork 0
mirror of https://github.com/thegeneralist01/archivr synced 2026-07-22 03:05:32 +02:00

feat: tweet/article preview quality pass

HTML entities: decode > < & etc. on sliced segments only
(entity offsets index the stored string; decoding before slicing shifts them)

Image lightbox: click any tweet/thread/article image to open full-screen
viewer; cmd+click follows <a> to open in new tab; arrow-key + ‹ › nav;
Escape closes; 1/N counter; ↗ open-in-new-tab link

Multi-image grid: 2 photos → side-by-side (180px rows); 3 → left spans
both rows; 4 → 2×2 (140px rows); single image unchanged

Empty media grid ghost: build photos/videoItems arrays first, render
.mediaGrid div only when at least one item resolved (advisory: never gate
on raw media.length when map items can all return null)

QT indicator: ↻ QT badge on tweet.is_quote_status === true entries

Modal shrinks for short content: height: 88vh → max-height: 88vh;
.preview-modal-body gets max-height: calc(88vh - 52px) so long threads
still scroll (advisory: don't rely on flex:1 once parent has no fixed height)

Video scrollbar leak: .preview-modal-body overflow: auto → hidden; each
child (tweet-wrap, video-wrap, iframe) manages its own scroll surface

Styled thin scrollbar on .preview-tweet-wrap (matches workspace rail)

ArticleRenderer: cover image and body images are lightbox-clickable;
opts thread through renderBlocksJSX → renderBlockJSX → renderAtomicJSX
This commit is contained in:
TheGeneralist 2026-07-12 14:04:41 +02:00
parent 060dcfb531
commit e7f58bb7ad
Signed by: thegeneralist01
SSH key fingerprint: SHA256:pp9qddbCNmVNoSjevdvQvM5z0DHN7LTa8qBMbcMq/R4
5 changed files with 378 additions and 101 deletions

View file

@ -2014,6 +2014,22 @@ select {
overflow-y: auto;
padding: 12px 16px;
background: var(--paper-2);
/* styled scrollbar matching the workspace rail */
scrollbar-width: thin;
scrollbar-color: var(--line) transparent;
}
.preview-tweet-wrap::-webkit-scrollbar { width: 8px; }
.preview-tweet-wrap::-webkit-scrollbar-track { background: transparent; }
.preview-tweet-wrap::-webkit-scrollbar-thumb {
background: var(--line);
border-radius: 999px;
border: 2px solid transparent;
background-clip: padding-box;
}
.preview-tweet-wrap::-webkit-scrollbar-thumb:hover {
background: var(--muted-2);
background-clip: padding-box;
border: 2px solid transparent;
}
/* ── Tweet card ───────────────────────────────────────────────────── */
@ -2340,7 +2356,7 @@ select {
box-shadow: 0 24px 80px rgba(0, 0, 0, 0.28);
width: 90vw;
max-width: 1100px;
height: 88vh;
max-height: 88vh;
display: flex;
flex-direction: column;
overflow: hidden;
@ -2383,9 +2399,15 @@ select {
.preview-modal-body {
flex: 1;
min-height: 0;
overflow: auto;
/* overflow: hidden each child (tweet-wrap, video-wrap, iframe, image)
manages its own scroll. This also prevents the spurious scrollbar that
appears when a video's native controls briefly expand the layout. */
overflow: hidden;
display: flex;
flex-direction: column;
/* Cap so long threads/articles stay scrollable even when modal has no
fixed height (shrinks for short tweets). 52px header padding+border. */
max-height: calc(88vh - 52px);
}
/* Preview button in context rail */
.rail-preview-btn {