refactor
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
use std::borrow::Cow;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::path::PathBuf;
|
||||
use std::time::Duration;
|
||||
|
||||
use anyhow::{Error, bail};
|
||||
use bitcoin_hashes::sha1::Hash as Sha1Hash;
|
||||
@@ -22,9 +21,6 @@ use crate::git_store::GitStore;
|
||||
use crate::refresh::{RefreshGate, RefreshRequest};
|
||||
use crate::repos::RepoListStore;
|
||||
|
||||
/// Delay between a refresh request and the actual re-query.
|
||||
const REFRESH_DEBOUNCE: Duration = Duration::from_millis(300);
|
||||
|
||||
/// Maximum size of one patch event.
|
||||
///
|
||||
/// NIP-34 suggests patches when each event is under 60kb.
|
||||
@@ -37,6 +33,10 @@ const MAX_PATCH_EVENT_BYTES: usize = 60 * 1024;
|
||||
pub struct RepoStore {
|
||||
addr: RepoAddr,
|
||||
pub announcement: Option<Announcement>,
|
||||
/// The first local pass has been applied.
|
||||
///
|
||||
/// Views distinguish "no data yet" from a genuinely empty repository with it.
|
||||
pub loaded: bool,
|
||||
/// Branch pointed to by `HEAD` in the latest state announcement.
|
||||
pub head: Option<String>,
|
||||
pub issues: Vec<Event>,
|
||||
@@ -143,6 +143,7 @@ impl RepoStore {
|
||||
Self {
|
||||
addr,
|
||||
announcement: None,
|
||||
loaded: false,
|
||||
head: None,
|
||||
issues: Vec::new(),
|
||||
patches: Vec::new(),
|
||||
@@ -228,17 +229,15 @@ impl RepoStore {
|
||||
}
|
||||
|
||||
/// Re-query the local database and update all fields.
|
||||
///
|
||||
/// Runs immediately. The backend pump already batches the relay events that
|
||||
/// trigger a refresh, so no per-store debounce is needed.
|
||||
pub fn refresh(&mut self, cx: &mut Context<Self>) {
|
||||
if self.refresh.request() != RefreshRequest::Schedule {
|
||||
return;
|
||||
}
|
||||
|
||||
cx.spawn(async move |this, cx| {
|
||||
cx.background_executor().timer(REFRESH_DEBOUNCE).await;
|
||||
|
||||
this.update(cx, |this, cx| this.run_refresh(cx))
|
||||
})
|
||||
.detach();
|
||||
self.run_refresh(cx);
|
||||
}
|
||||
|
||||
fn run_refresh(&mut self, cx: &mut Context<Self>) {
|
||||
@@ -402,10 +401,16 @@ impl RepoStore {
|
||||
// is polled in bursts while a sync is in flight; notifying on
|
||||
// every identical pass would re-render the repository panel
|
||||
// several times for no visible change.
|
||||
//
|
||||
// The first pass is the exception: it must notify even when it
|
||||
// found nothing, so views can leave their loading state and show
|
||||
// the empty result.
|
||||
let first_pass = !this.loaded;
|
||||
let head_changed = state
|
||||
.as_ref()
|
||||
.is_some_and(|(_, head)| this.head.as_deref() != head.as_deref());
|
||||
let changed = this.announcement != announcement
|
||||
let changed = first_pass
|
||||
|| this.announcement != announcement
|
||||
|| head_changed
|
||||
|| this.issues != issues
|
||||
|| this.patches != patches
|
||||
@@ -435,6 +440,7 @@ impl RepoStore {
|
||||
this.status_by_root = status_by_root;
|
||||
this.open_issue_count = open_issue_count;
|
||||
this.open_pr_count = open_pr_count;
|
||||
this.loaded = true;
|
||||
this.version = this.version.wrapping_add(1);
|
||||
|
||||
// Comments and statuses without an `a` tag.
|
||||
|
||||
@@ -117,11 +117,6 @@ impl LocalReposStore {
|
||||
}
|
||||
}
|
||||
|
||||
/// Delay between a refresh request and the actual re-query.
|
||||
///
|
||||
/// Bursts of events, e.g. sync progress ticks, collapse into one query.
|
||||
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);
|
||||
|
||||
@@ -220,7 +215,7 @@ impl RepoListStore {
|
||||
cx.defer(move |cx| {
|
||||
weak.update(cx, |this, cx| {
|
||||
this.subscribe_remote(cx);
|
||||
this.refresh_initial(cx);
|
||||
this.refresh(cx);
|
||||
})
|
||||
.ok();
|
||||
});
|
||||
@@ -254,33 +249,19 @@ impl RepoListStore {
|
||||
});
|
||||
}
|
||||
|
||||
/// One-shot initial load.
|
||||
///
|
||||
/// Query the local database immediately, no debounce.
|
||||
/// Stored announcements appear as soon as the app opens.
|
||||
fn refresh_initial(&mut self, cx: &mut Context<Self>) {
|
||||
debug_assert!(!self.refresh.debouncing());
|
||||
if self.refresh.running() {
|
||||
self.refresh.request();
|
||||
return;
|
||||
}
|
||||
self.run_refresh(cx);
|
||||
}
|
||||
|
||||
/// Re-query the local database.
|
||||
///
|
||||
/// Runs immediately. The backend pump already batches the relay events that
|
||||
/// trigger a refresh, so no per-store debounce is needed.
|
||||
pub fn refresh(&mut self, cx: &mut Context<Self>) {
|
||||
if self.refresh.request() != RefreshRequest::Schedule {
|
||||
return;
|
||||
}
|
||||
|
||||
cx.spawn(async move |this, cx| {
|
||||
cx.background_executor().timer(REFRESH_DEBOUNCE).await;
|
||||
this.update(cx, |this, cx| this.run_refresh(cx))
|
||||
})
|
||||
.detach();
|
||||
self.run_refresh(cx);
|
||||
}
|
||||
|
||||
/// One query and apply cycle, the debounced entry point.
|
||||
/// One query and apply cycle, the refresh entry point.
|
||||
fn run_refresh(&mut self, cx: &mut Context<Self>) {
|
||||
self.refresh.begin();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user