update
This commit is contained in:
1
Cargo.lock
generated
1
Cargo.lock
generated
@@ -9117,6 +9117,7 @@ name = "workspace"
|
||||
version = "1.0.0-beta5"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"auto_update",
|
||||
"browser-signer-proxy",
|
||||
"chat",
|
||||
"chat_ui",
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#![cfg(not(target_arch = "wasm32"))]
|
||||
|
||||
use gpui::{App, AppContext, Context, Entity, Global, Subscription, Window};
|
||||
use gpui::{App, AppContext, Context, Entity, Global, SharedString, Subscription, Window};
|
||||
use gpui_updater::{EngineConfig, GitHubSource, UpdateStatus, Updater, Version};
|
||||
use instant::Duration;
|
||||
use instant::{Duration, Instant};
|
||||
|
||||
const COOP_UPDATE_EXPLANATION: &str = "COOP_UPDATE_EXPLANATION";
|
||||
|
||||
@@ -52,6 +52,8 @@ pub struct AutoUpdater {
|
||||
pub version: Version,
|
||||
/// Keeps the observer subscription alive.
|
||||
_subscription: Subscription,
|
||||
/// When the last error was recorded, so we can reset to idle after 5s.
|
||||
error_time: Option<Instant>,
|
||||
}
|
||||
|
||||
impl AutoUpdater {
|
||||
@@ -83,11 +85,24 @@ impl AutoUpdater {
|
||||
// When an update becomes available, automatically download and install it.
|
||||
let subscription = cx.observe(&updater, |this: &mut AutoUpdater, _updater, cx| {
|
||||
let status = this.updater.read(cx).status().clone();
|
||||
|
||||
if matches!(status, UpdateStatus::Available(_)) {
|
||||
this.updater.update(cx, |updater, cx| {
|
||||
updater.download_and_install(cx);
|
||||
});
|
||||
}
|
||||
|
||||
if matches!(status, UpdateStatus::Errored(_)) {
|
||||
this.error_time = Some(Instant::now());
|
||||
cx.spawn(async move |this, cx| {
|
||||
cx.background_executor().timer(Duration::from_secs(5)).await;
|
||||
this.update(cx, |_this, cx| cx.notify()).ok();
|
||||
})
|
||||
.detach();
|
||||
} else {
|
||||
this.error_time = None;
|
||||
}
|
||||
|
||||
cx.notify();
|
||||
});
|
||||
|
||||
@@ -111,6 +126,55 @@ impl AutoUpdater {
|
||||
updater,
|
||||
version,
|
||||
_subscription: subscription,
|
||||
error_time: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn idle(&self, cx: &App) -> bool {
|
||||
let status = self.updater.read(cx).status();
|
||||
if status == &UpdateStatus::Idle {
|
||||
return true;
|
||||
}
|
||||
if matches!(status, UpdateStatus::Errored(_))
|
||||
&& self
|
||||
.error_time
|
||||
.is_some_and(|t| t.elapsed() >= Duration::from_secs(5))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
pub fn status(&self, cx: &App) -> SharedString {
|
||||
let status = self.updater.read(cx).status();
|
||||
|
||||
match status {
|
||||
UpdateStatus::Idle => "Up to date".into(),
|
||||
UpdateStatus::Checking => "Checking for updates…".into(),
|
||||
UpdateStatus::UpToDate => "Up to date".into(),
|
||||
UpdateStatus::Available(version) => format!("Version {version} available").into(),
|
||||
UpdateStatus::Downloading { downloaded, total } => {
|
||||
let total_mb = total.map(|t| t as f64 / 1_048_576.0);
|
||||
let downloaded_mb = *downloaded as f64 / 1_048_576.0;
|
||||
match total_mb {
|
||||
Some(t) => format!("Downloading {downloaded_mb:.1} / {t:.1} MB").into(),
|
||||
None => format!("Downloading {downloaded_mb:.1} MB").into(),
|
||||
}
|
||||
}
|
||||
UpdateStatus::Installing => "Installing update…".into(),
|
||||
UpdateStatus::Staged(version) => {
|
||||
format!("Version {version} ready — restart to apply").into()
|
||||
}
|
||||
UpdateStatus::Errored(msg) => {
|
||||
if self
|
||||
.error_time
|
||||
.is_some_and(|t| t.elapsed() >= Duration::from_secs(5))
|
||||
{
|
||||
"Up to date".into()
|
||||
} else {
|
||||
format!("Update failed: {msg}").into()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -164,12 +164,8 @@
|
||||
</head>
|
||||
<body>
|
||||
<div class="card">
|
||||
<div class="logo">
|
||||
<div class="logo__mark">C</div>
|
||||
<span class="logo__text">Coop</span>
|
||||
</div>
|
||||
|
||||
<h1 class="heading">Web Signer</h1>
|
||||
|
||||
<p class="subtitle">
|
||||
This page connects the app to your Nostr Web Signer extension so you can sign in and use Coop securely.
|
||||
</p>
|
||||
|
||||
@@ -14,6 +14,7 @@ chat = { path = "../chat" }
|
||||
chat_ui = { path = "../chat_ui" }
|
||||
settings = { path = "../settings" }
|
||||
person = { path = "../person" }
|
||||
auto_update = { path = "../auto_update" }
|
||||
|
||||
gpui.workspace = true
|
||||
nostr-sdk.workspace = true
|
||||
|
||||
@@ -2,6 +2,7 @@ use std::sync::Arc;
|
||||
|
||||
use ::settings::AppSettings;
|
||||
use anyhow::Error;
|
||||
use auto_update::AutoUpdater;
|
||||
use chat::{ChatEvent, ChatRegistry};
|
||||
use common::{CoopImageCache, download_dir};
|
||||
use device::{DeviceEvent, DeviceRegistry};
|
||||
@@ -379,7 +380,12 @@ impl Workspace {
|
||||
self.import_encryption(window, cx);
|
||||
}
|
||||
Command::Update => {
|
||||
//
|
||||
let auto_updater = AutoUpdater::global(cx);
|
||||
auto_updater.update(cx, |this, cx| {
|
||||
this.updater.update(cx, |updater, cx| {
|
||||
updater.check(cx);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -604,6 +610,7 @@ impl Workspace {
|
||||
}
|
||||
|
||||
fn titlebar_right(&mut self, cx: &mut Context<Self>) -> impl IntoElement {
|
||||
let updater = AutoUpdater::global(cx);
|
||||
let chat = ChatRegistry::global(cx);
|
||||
let nip4e_enabled = AppSettings::get_nip4e(cx);
|
||||
let nostr = NostrRegistry::global(cx);
|
||||
@@ -615,10 +622,15 @@ impl Workspace {
|
||||
let persons = PersonRegistry::global(cx);
|
||||
let profile = persons.read(cx).get(&public_key, cx);
|
||||
let announcement = profile.announcement();
|
||||
let updater_idle = updater.read(cx).idle(cx);
|
||||
|
||||
h_flex()
|
||||
.when(!cx.theme().platform.is_mac(), |this| this.pr_2())
|
||||
.gap_2()
|
||||
.when(!updater_idle, |this| {
|
||||
let status = updater.read(cx).status(cx);
|
||||
this.child(div().text_xs().italic().child(status))
|
||||
})
|
||||
.when(nip4e_enabled, |this| {
|
||||
this.child(
|
||||
Button::new("key")
|
||||
|
||||
Reference in New Issue
Block a user