aboutsummaryrefslogtreecommitdiffstats
path: root/src/features/messages.js
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2026-10-19 12:50:06 -0700
committerAdam Soltys <[email protected]>2026-10-19 12:50:06 -0700
commit762bdcb558af94b540801a89cd16cd419d3a27d5 (patch)
tree5a876c3caceb61c0cc7c9748557dfc471d1d22ca /src/features/messages.js
parente889fa6ef8eec38311646eec30b2498fd488e890 (diff)
downloadcoinosv3-762bdcb558af94b540801a89cd16cd419d3a27d5.tar.gz
coinosv3-762bdcb558af94b540801a89cd16cd419d3a27d5.zip
Profiles: past streams move off the top into a Streams tab (beside Posts and Replies, shown once they've streamed), as the Live chip's grid of tiles.
Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_013ZDf1cyCQLkfjftYhymZAg
Diffstat (limited to 'src/features/messages.js')
-rw-r--r--src/features/messages.js20
1 files changed, 9 insertions, 11 deletions
diff --git a/src/features/messages.js b/src/features/messages.js
index eecdb79..0974839 100644
--- a/src/features/messages.js
+++ b/src/features/messages.js
@@ -8835,13 +8835,9 @@ export function messagesFeature(ctx) {
h('div', { class: 'live-tile-title' }, liveTitle(ev) || t('liveUntitled')),
h('div', { class: 'row gap6 live-tile-host' }, avatar(host, 'chat-avatar mini', false), h('span', { class: 'small muted' }, displayName(host))));
}
- // a profile's past streams, a row to scroll through
+ // a profile's Streams tab: their past streams, as the Live chip's tiles
function pastStreams(pk) {
- const past = pastOf(pk).slice(0, 20);
- if (!past.length) return null;
- return h('div', { class: 'col', style: 'gap:6px', 'data-key': 'live-past-of:' + pk },
- h('div', { class: 'small muted' }, t('livePast')),
- h('div', { class: 'live-past-row' }, ...past.map(liveTile)));
+ return h('div', { class: 'live-grid live-past', 'data-key': 'live-past-of:' + pk }, ...pastOf(pk).slice(0, 60).map(liveTile));
}
// a profile's "on now" line
function liveBanner(pk) {
@@ -12752,7 +12748,6 @@ export function messagesFeature(ctx) {
// the hat pitch lives beside the avatar it decorates
mine ? hook('hatShopEntry') : null)),
ui.profEdit ? null : liveBanner(pk),
- ui.profEdit ? null : pastStreams(pk),
mine && !ui.profEdit && canGoLive() && !liveNowOf(pk) ? h('button', { class: 'btn-sm go-live-btn', style: 'align-self:flex-start', onClick: openGoLive },
h('span', { class: 'go-live-dot' }), t('goLive')) : null,
// no spinner while the kind 0 loads — prefetch keeps this rare, and
@@ -12942,7 +12937,9 @@ export function messagesFeature(ctx) {
const c = notesFor(pk);
// Posts | Replies: the replies are their side of other people's
// conversations, apart from what they posted themselves
- const tab = profTab(pk);
+ // Streams joins the tabs once they've streamed
+ const streamed = pastOf(pk).length > 0;
+ const tab = profTab(pk) === 'streams' && !streamed ? 'posts' : profTab(pk);
const shown = c.notes.filter((e) => (tab === 'replies') === replyish(e));
// a tab that holds only a few of the pages fetched so far (someone
// who mostly replies, or mostly posts) asks for older ones by itself:
@@ -12950,15 +12947,16 @@ export function messagesFeature(ctx) {
// (five pages at most per tab: someone who never replies must not
// have their whole history paged through looking for one)
const fill = c.autoFill && c.autoFill.tab === tab ? c.autoFill : (c.autoFill = { tab, n: 0 });
- if (c.status === 'ready' && shown.length < 12 && !c.end && !c.loadingMore && fill.n < 5) {
+ if (tab !== 'streams' && c.status === 'ready' && shown.length < 12 && !c.end && !c.loadingMore && fill.n < 5) {
fill.n++;
queueMicrotask(() => loadOlderNotes(pk).catch(() => {}));
}
const tabs = h('div', { class: 'seg prof-tabs', style: 'display:flex;width:100%' },
- ...['posts', 'replies'].map((k) => h('button', {
+ ...['posts', 'replies', ...(streamed ? ['streams'] : [])].map((k) => h('button', {
type: 'button', class: (tab === k ? 'active ' : '') + 'grow', 'data-tab': k,
onClick: () => { if (tab === k) return; ui.profTab = { pk, tab: k }; c.win = null; render(); },
- }, t(k === 'posts' ? 'profTabPosts' : 'profTabReplies'))));
+ }, t(k === 'posts' ? 'profTabPosts' : k === 'replies' ? 'profTabReplies' : 'profTabStreams'))));
+ if (tab === 'streams') return h('div', { class: 'col', style: 'gap:8px' }, tabs, pastStreams(pk));
// while loading with nothing to show: an invisible copy of the
// empty-state line holds the height, so the page doesn't jump when
// the answer lands (no spinner). With posts already in hand — from