vc=32: subs feed — dates, watched filter, infinite scroll, avatar fallback
Subscription feed is now actually a feed instead of a teaser.
Rust (strawcore wrapper)
Added upload_date_relative and uploader_avatar to SearchItem so
Kotlin can see both. strawcore-core already extracts upload_date
relative ("2 days ago") on every StreamInfoItem and uploader_avatars
on most — we were just throwing them away in from_core. Fixed.
StreamItem
uploadDateRelative + uploaderAvatar fields added. Every construction
site (search/channel/detail/feed) plumbs them through.
SubscriptionFeedViewModel
Per-channel cap 5 → 30. With 30 subs that's up to 900 items in
memory; ConcurrentHashMap entries are small enough.
Sort by parsed relative recency (RECENCY_RE on the "N <unit> ago"
string, signed seconds-ago, tied items break by viewCount).
Opportunistic avatar backfill: every successful channelInfo fetch
updates the stored ChannelRef.avatar via Subscriptions.updateAvatar
when strawcore returns a non-null avatar — fixes the "I just subbed
to a channel and the chip has no icon" case where the channel header
parser missed the avatar at subscribe time but the feed-fetch
layout returns one.
SubsPane (StrawHome)
Hide-watched FilterChip (session-sticky). Cross-references
History.watches by 11-char YT video ID; filters out anything you've
already watched. "All caught up — nothing unwatched" empty state.
Infinite scroll: PAGE_SIZE = 20. derivedStateOf-gated snapshotFlow
watches the LazyListState's lastVisibleItem index; when within 5
items of the bottom, bumps visibleCount by 20. "Loading more..."
spinner at the bottom while there's more to show.
Visible-count resets to PAGE_SIZE when the underlying list shrinks
(refresh dropped items, filter just engaged).
FeedRow now shows: uploader · views · "3 days ago".
SubChip
Lettered fallback when ch.avatar is null. PrimaryContainer-tinted
circle with the first letter — no more broken-image placeholder
while the feed-fetch backfills the real avatar.
SubscriptionsStore
updateAvatar(url, avatar) for the backfill path. Atomic via
updateAndGet, persists to SharedPreferences.
This commit is contained in:
parent
9aafc003cb
commit
544035b30c
8 changed files with 244 additions and 26 deletions
|
|
@ -15,11 +15,16 @@ pub struct SearchItem {
|
|||
pub title: String,
|
||||
pub uploader: String,
|
||||
pub uploader_url: Option<String>,
|
||||
pub uploader_avatar: Option<String>,
|
||||
pub thumbnail: Option<String>,
|
||||
/// Duration in seconds. 0 = live/unknown.
|
||||
pub duration_seconds: i64,
|
||||
/// Reported view count. 0 = unknown.
|
||||
pub view_count: i64,
|
||||
/// Relative upload date as YT renders it ("2 days ago", "3 weeks
|
||||
/// ago"). Empty if not extracted. Strawcore-core already populates
|
||||
/// this on StreamInfoItem; we just pass it through.
|
||||
pub upload_date_relative: String,
|
||||
}
|
||||
|
||||
pub(crate) fn from_core(item: StreamInfoItem) -> SearchItem {
|
||||
|
|
@ -32,11 +37,16 @@ pub(crate) fn from_core(item: StreamInfoItem) -> SearchItem {
|
|||
.thumbnails
|
||||
.last()
|
||||
.map(|i| i.url().to_string());
|
||||
let uploader_avatar = item
|
||||
.uploader_avatars
|
||||
.last()
|
||||
.map(|i| i.url().to_string());
|
||||
SearchItem {
|
||||
url: item.url,
|
||||
title: item.name,
|
||||
uploader: item.uploader_name,
|
||||
uploader_url,
|
||||
uploader_avatar,
|
||||
thumbnail,
|
||||
duration_seconds: item.duration_seconds,
|
||||
view_count: if item.view_count < 0 {
|
||||
|
|
@ -44,6 +54,7 @@ pub(crate) fn from_core(item: StreamInfoItem) -> SearchItem {
|
|||
} else {
|
||||
item.view_count
|
||||
},
|
||||
upload_date_relative: item.upload_date_relative,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue