fix(desktop): identify stale hosted catalog results

This commit is contained in:
2026-09-06 08:15:36 +03:00
parent 980934bf63
commit a337dd4bf0
4 changed files with 232 additions and 9 deletions
+39 -4
View File
@@ -255,19 +255,26 @@ impl App {
self.hosted.base = base;
self.hosted.connection = None;
self.hosted.catalog.clear();
self.hosted.next = None;
self.hosted.invalidate_catalog();
self.hosted.selected = None;
}
Event::Token(token) => {
self.hosted.token = token;
self.hosted.connection = None;
self.hosted.catalog.clear();
self.hosted.selected = None;
self.hosted.invalidate_catalog();
}
Event::Query(query) => {
self.hosted.query = query;
self.hosted.next = None;
if self.hosted.query != query {
self.hosted.query = query;
self.hosted.selected = None;
self.hosted.invalidate_catalog();
}
}
Event::Connect => match Connection::new(&self.hosted.base, self.hosted.token.clone()) {
Ok(connection) => {
self.hosted.invalidate_catalog();
return self.hosted_start(Operation::Catalog(false), connection, None);
}
Err(error) => {
@@ -276,7 +283,8 @@ impl App {
}
},
Event::More => {
if self.hosted.next.is_some()
if !self.hosted.catalog_stale
&& self.hosted.next.is_some()
&& let Some(connection) = &self.hosted.connection
{
return self.hosted_start(Operation::Catalog(true), connection.clone(), None);
@@ -382,6 +390,32 @@ impl App {
}
let request = self.hosted.request.take().expect("matching request");
self.busy = false;
// A catalog is a read snapshot, never a live mirror. Known or
// uncertain writes and observed newer revisions invalidate only
// the service whose results are currently displayed.
let catalog_changed = match &result {
Ok(Outcome::Remote(remote)) => {
matches!(request.operation, Operation::Publish | Operation::Save)
|| self.hosted.catalog.iter().any(|item| {
item.resource_id == remote.resource_id
&& item.revision != remote.revision
})
}
Err(error) => {
matches!(request.operation, Operation::Publish | Operation::Save)
&& (error.uncertain || error.status == Some(412))
}
Ok(Outcome::Catalog(_)) => false,
};
if catalog_changed
&& self
.hosted
.connection
.as_ref()
.is_some_and(|connection| connection.base() == request.connection.base())
{
self.hosted.invalidate_catalog();
}
match result {
Err(error) => {
let conflict =
@@ -435,6 +469,7 @@ impl App {
}
}
self.hosted.next = catalog.next_after;
self.hosted.catalog_stale = false;
if !self
.hosted
.catalog