add timeline paging for older messages

This commit is contained in:
2026-09-30 12:49:37 +07:00
parent de862637f3
commit d621b125a9
4 changed files with 164 additions and 6 deletions
+63 -3
View File
@@ -21,6 +21,7 @@ pub(crate) static LOCAL_KEYS: LazyLock<Keys> = LazyLock::new(Keys::generate);
const LIST_SUBSCRIPTION: &str = "nip29-list";
const GROUP_PREFIX: &str = "grp-";
const BROWSE_PREFIX: &str = "brw-";
const PAGE_PREFIX: &str = "pg-";
const BROWSE_LIMIT: usize = 500;
const BROWSE_TIMEOUT: Duration = Duration::from_secs(10);
@@ -67,9 +68,20 @@ fn browse_subscription(relay: &RelayUrl) -> SubscriptionId {
SubscriptionId::new(format!("{BROWSE_PREFIX}{:08x}", hasher.finish() as u32))
}
fn page_subscription(key: &GroupKey) -> SubscriptionId {
SubscriptionId::new(format!("{PAGE_PREFIX}{:08x}", key.uniq_id() as u32))
}
fn is_page(id: &SubscriptionId) -> bool {
id.as_str().starts_with(PAGE_PREFIX)
}
fn is_own_subscription(id: &SubscriptionId) -> bool {
let id = id.as_str();
id == LIST_SUBSCRIPTION || id.starts_with(GROUP_PREFIX) || id.starts_with(BROWSE_PREFIX)
id == LIST_SUBSCRIPTION
|| id.starts_with(GROUP_PREFIX)
|| id.starts_with(BROWSE_PREFIX)
|| id.starts_with(PAGE_PREFIX)
}
impl EventEmitter<GroupsEvent> for GroupsRegistry {}
@@ -259,6 +271,22 @@ impl GroupsRegistry {
self.browse.get(&browse_subscription(relay))
}
pub fn load_more(&mut self, key: &GroupKey, cx: &mut Context<Self>) {
let Some(group) = self.group(key, cx) else {
return;
};
if group.read(cx).loading_more() || group.read(cx).oldest().is_none() {
return;
}
self.routes.insert(page_subscription(key), key.clone());
group.update(cx, |group, cx| {
group.load_page(cx);
});
}
pub fn leave(&mut self, key: &GroupKey, cx: &mut Context<Self>) {
let Some(group) = self.group(key, cx) else {
return;
@@ -394,9 +422,11 @@ impl GroupsRegistry {
fn forget(&mut self, key: GroupKey, cx: &mut Context<Self>) {
let id = subscription_id(&key);
let page = page_subscription(&key);
let cache_tag = key.cache_tag();
self.routes.remove(&id);
self.routes.remove(&page);
self.observers.remove(&key);
self.groups.retain(|group| group.read(cx).key() != &key);
self.list.remove(&key);
@@ -405,8 +435,10 @@ impl GroupsRegistry {
let client = nostr.read(cx).client();
self.tasks.push(cx.background_spawn(async move {
if let Err(error) = client.unsubscribe(&id).await {
log::warn!("nip29: unsubscribing {id} failed: {error}");
for id in [id, page] {
if let Err(error) = client.unsubscribe(&id).await {
log::warn!("nip29: unsubscribing {id} failed: {error}");
}
}
let filter = Filter::new()
@@ -595,6 +627,18 @@ impl GroupsRegistry {
return;
};
if is_page(&id) {
self.routes.remove(&id);
if let Some(group) = self.group(&key, cx) {
group.update(cx, |group, cx| {
group.page_finished(cx);
});
}
return;
}
let Some(group) = self.group(&key, cx) else {
return;
};
@@ -620,6 +664,22 @@ impl GroupsRegistry {
return;
};
if is_page(&id) {
self.routes.remove(&id);
log::warn!(
"nip29: loading older messages in {} was refused: {reason}",
key.id()
);
if let Some(group) = self.group(&key, cx) {
group.update(cx, |group, cx| {
group.page_finished(cx);
});
}
return;
}
let Some(group) = self.group(&key, cx) else {
return;
};