update repo list

This commit is contained in:
2026-08-30 09:18:38 +07:00
parent 8829bc5bc1
commit 729e15e27e
3 changed files with 55 additions and 5 deletions
+10
View File
@@ -37,6 +37,11 @@ pub fn init(db_path: impl AsRef<Path>, cx: &mut App) -> Entity<Backend> {
ProfileStore::set_global(cx.new(ProfileStore::new), cx);
// Start the explore list from the local database before the first
// window opens; relay syncs continue in the background, so the list
// never waits for them.
RepoListStore::set_global(cx.new(|cx| RepoListStore::new(None, cx)), cx);
// The clone cache is only meaningful on native platforms; the wasm
// build registers an empty store so `GitStore::global` still works.
GitStore::set_global(PathBuf::new(), cx);
@@ -54,6 +59,11 @@ pub fn init(cx: &mut App) -> Entity<Backend> {
ProfileStore::set_global(cx.new(ProfileStore::new), cx);
// Start the explore list from the local database before the first
// window opens; relay syncs continue in the background, so the list
// never waits for them.
RepoListStore::set_global(cx.new(|cx| RepoListStore::new(None, cx)), cx);
GitStore::set_global(PathBuf::new(), cx);
entity
+34 -2
View File
@@ -3,7 +3,7 @@ use std::sync::Arc;
use std::time::Duration;
use anyhow::Error;
use gpui::{AppContext, Context, Subscription, Task};
use gpui::{App, AppContext, Context, Entity, Global, Subscription, Task};
use nostr_sdk::prelude::*;
use signed_core::{Announcement, Deletions, RepoAddr, filters, repo_addr};
@@ -16,7 +16,15 @@ const REFRESH_DEBOUNCE: Duration = Duration::from_millis(300);
/// How far back activity events count toward a repository's last activity.
const ACTIVITY_WINDOW: Duration = Duration::from_secs(90 * 86_400);
struct GlobalRepoListStore(Entity<RepoListStore>);
impl Global for GlobalRepoListStore {}
/// Store listing repository announcements (global discovery or per-author).
///
/// The all-repos store (`author: None`) is created at startup by
/// [`crate::init`] and installed as a global, so the explore panel renders
/// what's in the local database without waiting for relays.
pub struct RepoListStore {
/// Shared so views can clone the list per frame without a deep copy.
pub announcements: Arc<Vec<Announcement>>,
@@ -33,6 +41,16 @@ pub struct RepoListStore {
}
impl RepoListStore {
/// Retrieve the global explore store (all announcements, created at
/// startup by [`crate::init`]).
pub fn global(cx: &App) -> Entity<Self> {
cx.global::<GlobalRepoListStore>().0.clone()
}
pub(crate) fn set_global(entity: Entity<Self>, cx: &mut App) {
cx.set_global(GlobalRepoListStore(entity));
}
/// Create a store. If `author` is `None`, all announcements are listed.
pub fn new(author: Option<PublicKey>, cx: &mut Context<Self>) -> Self {
let backend = Backend::global(cx);
@@ -79,7 +97,9 @@ impl RepoListStore {
};
store.subscribe_remote(cx);
store.refresh(cx);
// Query the local database right away; the list never waits for the
// relay syncs started above to finish.
store.refresh_initial(cx);
store
}
@@ -107,6 +127,18 @@ impl RepoListStore {
});
}
/// One-shot initial load: query the local database immediately (no
/// debounce), so stored announcements appear as soon as the app opens.
/// Only called from [`Self::new`], before any refresh can be pending.
fn refresh_initial(&mut self, cx: &mut Context<Self>) {
debug_assert!(!self.debouncing);
if self.refreshing {
self.refresh_dirty = true;
return;
}
self.run_refresh(cx);
}
/// Re-query the local database. Latest announcement per repository wins.
///
/// Debounced: a short delay collapses bursts of requests (e.g. sync