Extract auto_update_ui
crate (#21008)
This PR extracts an `auto_update_ui` crate out of the `auto_update` crate. This allows `auto_update` to not depend on heavier crates like `editor`, which in turn allows other downstream crates to start building sooner. Release Notes: - N/A
This commit is contained in:
parent
841d3221b3
commit
f62ccf9c8a
11 changed files with 217 additions and 166 deletions
26
Cargo.lock
generated
26
Cargo.lock
generated
|
@ -1014,26 +1014,41 @@ dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"client",
|
"client",
|
||||||
"db",
|
"db",
|
||||||
"editor",
|
|
||||||
"gpui",
|
"gpui",
|
||||||
"http_client",
|
"http_client",
|
||||||
"log",
|
"log",
|
||||||
"markdown_preview",
|
|
||||||
"menu",
|
|
||||||
"paths",
|
"paths",
|
||||||
"release_channel",
|
"release_channel",
|
||||||
"schemars",
|
"schemars",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_derive",
|
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"settings",
|
"settings",
|
||||||
"smol",
|
"smol",
|
||||||
"tempfile",
|
"tempfile",
|
||||||
"util",
|
|
||||||
"which 6.0.3",
|
"which 6.0.3",
|
||||||
"workspace",
|
"workspace",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "auto_update_ui"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"auto_update",
|
||||||
|
"client",
|
||||||
|
"editor",
|
||||||
|
"gpui",
|
||||||
|
"http_client",
|
||||||
|
"markdown_preview",
|
||||||
|
"menu",
|
||||||
|
"release_channel",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"smol",
|
||||||
|
"util",
|
||||||
|
"workspace",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "autocfg"
|
name = "autocfg"
|
||||||
version = "1.4.0"
|
version = "1.4.0"
|
||||||
|
@ -15464,6 +15479,7 @@ dependencies = [
|
||||||
"async-watch",
|
"async-watch",
|
||||||
"audio",
|
"audio",
|
||||||
"auto_update",
|
"auto_update",
|
||||||
|
"auto_update_ui",
|
||||||
"backtrace",
|
"backtrace",
|
||||||
"breadcrumbs",
|
"breadcrumbs",
|
||||||
"call",
|
"call",
|
||||||
|
|
|
@ -9,6 +9,7 @@ members = [
|
||||||
"crates/assistant_tool",
|
"crates/assistant_tool",
|
||||||
"crates/audio",
|
"crates/audio",
|
||||||
"crates/auto_update",
|
"crates/auto_update",
|
||||||
|
"crates/auto_update_ui",
|
||||||
"crates/breadcrumbs",
|
"crates/breadcrumbs",
|
||||||
"crates/call",
|
"crates/call",
|
||||||
"crates/channel",
|
"crates/channel",
|
||||||
|
@ -187,6 +188,7 @@ assistant_slash_command = { path = "crates/assistant_slash_command" }
|
||||||
assistant_tool = { path = "crates/assistant_tool" }
|
assistant_tool = { path = "crates/assistant_tool" }
|
||||||
audio = { path = "crates/audio" }
|
audio = { path = "crates/audio" }
|
||||||
auto_update = { path = "crates/auto_update" }
|
auto_update = { path = "crates/auto_update" }
|
||||||
|
auto_update_ui = { path = "crates/auto_update_ui" }
|
||||||
breadcrumbs = { path = "crates/breadcrumbs" }
|
breadcrumbs = { path = "crates/breadcrumbs" }
|
||||||
call = { path = "crates/call" }
|
call = { path = "crates/call" }
|
||||||
channel = { path = "crates/channel" }
|
channel = { path = "crates/channel" }
|
||||||
|
|
|
@ -16,21 +16,16 @@ doctest = false
|
||||||
anyhow.workspace = true
|
anyhow.workspace = true
|
||||||
client.workspace = true
|
client.workspace = true
|
||||||
db.workspace = true
|
db.workspace = true
|
||||||
editor.workspace = true
|
|
||||||
gpui.workspace = true
|
gpui.workspace = true
|
||||||
http_client.workspace = true
|
http_client.workspace = true
|
||||||
log.workspace = true
|
log.workspace = true
|
||||||
markdown_preview.workspace = true
|
|
||||||
menu.workspace = true
|
|
||||||
paths.workspace = true
|
paths.workspace = true
|
||||||
release_channel.workspace = true
|
release_channel.workspace = true
|
||||||
schemars.workspace = true
|
schemars.workspace = true
|
||||||
serde.workspace = true
|
serde.workspace = true
|
||||||
serde_derive.workspace = true
|
|
||||||
serde_json.workspace = true
|
serde_json.workspace = true
|
||||||
settings.workspace = true
|
settings.workspace = true
|
||||||
smol.workspace = true
|
smol.workspace = true
|
||||||
tempfile.workspace = true
|
tempfile.workspace = true
|
||||||
util.workspace = true
|
|
||||||
which.workspace = true
|
which.workspace = true
|
||||||
workspace.workspace = true
|
workspace.workspace = true
|
||||||
|
|
|
@ -1,27 +1,19 @@
|
||||||
mod update_notification;
|
|
||||||
|
|
||||||
use anyhow::{anyhow, Context, Result};
|
use anyhow::{anyhow, Context, Result};
|
||||||
use client::{Client, TelemetrySettings};
|
use client::{Client, TelemetrySettings};
|
||||||
use db::kvp::KEY_VALUE_STORE;
|
use db::kvp::KEY_VALUE_STORE;
|
||||||
use db::RELEASE_CHANNEL;
|
use db::RELEASE_CHANNEL;
|
||||||
use editor::{Editor, MultiBuffer};
|
|
||||||
use gpui::{
|
use gpui::{
|
||||||
actions, AppContext, AsyncAppContext, Context as _, Global, Model, ModelContext,
|
actions, AppContext, AsyncAppContext, Context as _, Global, Model, ModelContext,
|
||||||
SemanticVersion, SharedString, Task, View, ViewContext, VisualContext, WindowContext,
|
SemanticVersion, Task, WindowContext,
|
||||||
};
|
};
|
||||||
|
|
||||||
use markdown_preview::markdown_preview_view::{MarkdownPreviewMode, MarkdownPreviewView};
|
|
||||||
use paths::remote_servers_dir;
|
|
||||||
use schemars::JsonSchema;
|
|
||||||
use serde::Deserialize;
|
|
||||||
use serde_derive::Serialize;
|
|
||||||
use smol::{fs, io::AsyncReadExt};
|
|
||||||
|
|
||||||
use settings::{Settings, SettingsSources, SettingsStore};
|
|
||||||
use smol::{fs::File, process::Command};
|
|
||||||
|
|
||||||
use http_client::{AsyncBody, HttpClient, HttpClientWithUrl};
|
use http_client::{AsyncBody, HttpClient, HttpClientWithUrl};
|
||||||
use release_channel::{AppCommitSha, AppVersion, ReleaseChannel};
|
use paths::remote_servers_dir;
|
||||||
|
use release_channel::{AppCommitSha, ReleaseChannel};
|
||||||
|
use schemars::JsonSchema;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use settings::{Settings, SettingsSources, SettingsStore};
|
||||||
|
use smol::{fs, io::AsyncReadExt};
|
||||||
|
use smol::{fs::File, process::Command};
|
||||||
use std::{
|
use std::{
|
||||||
env::{
|
env::{
|
||||||
self,
|
self,
|
||||||
|
@ -32,24 +24,13 @@ use std::{
|
||||||
sync::Arc,
|
sync::Arc,
|
||||||
time::Duration,
|
time::Duration,
|
||||||
};
|
};
|
||||||
use update_notification::UpdateNotification;
|
|
||||||
use util::ResultExt;
|
|
||||||
use which::which;
|
use which::which;
|
||||||
use workspace::notifications::NotificationId;
|
|
||||||
use workspace::Workspace;
|
use workspace::Workspace;
|
||||||
|
|
||||||
const SHOULD_SHOW_UPDATE_NOTIFICATION_KEY: &str = "auto-updater-should-show-updated-notification";
|
const SHOULD_SHOW_UPDATE_NOTIFICATION_KEY: &str = "auto-updater-should-show-updated-notification";
|
||||||
const POLL_INTERVAL: Duration = Duration::from_secs(60 * 60);
|
const POLL_INTERVAL: Duration = Duration::from_secs(60 * 60);
|
||||||
|
|
||||||
actions!(
|
actions!(auto_update, [Check, DismissErrorMessage, ViewReleaseNotes,]);
|
||||||
auto_update,
|
|
||||||
[
|
|
||||||
Check,
|
|
||||||
DismissErrorMessage,
|
|
||||||
ViewReleaseNotes,
|
|
||||||
ViewReleaseNotesLocally
|
|
||||||
]
|
|
||||||
);
|
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
struct UpdateRequestBody {
|
struct UpdateRequestBody {
|
||||||
|
@ -146,12 +127,6 @@ struct GlobalAutoUpdate(Option<Model<AutoUpdater>>);
|
||||||
|
|
||||||
impl Global for GlobalAutoUpdate {}
|
impl Global for GlobalAutoUpdate {}
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
|
||||||
struct ReleaseNotesBody {
|
|
||||||
title: String,
|
|
||||||
release_notes: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn init(http_client: Arc<HttpClientWithUrl>, cx: &mut AppContext) {
|
pub fn init(http_client: Arc<HttpClientWithUrl>, cx: &mut AppContext) {
|
||||||
AutoUpdateSetting::register(cx);
|
AutoUpdateSetting::register(cx);
|
||||||
|
|
||||||
|
@ -161,10 +136,6 @@ pub fn init(http_client: Arc<HttpClientWithUrl>, cx: &mut AppContext) {
|
||||||
workspace.register_action(|_, action, cx| {
|
workspace.register_action(|_, action, cx| {
|
||||||
view_release_notes(action, cx);
|
view_release_notes(action, cx);
|
||||||
});
|
});
|
||||||
|
|
||||||
workspace.register_action(|workspace, _: &ViewReleaseNotesLocally, cx| {
|
|
||||||
view_release_notes_locally(workspace, cx);
|
|
||||||
});
|
|
||||||
})
|
})
|
||||||
.detach();
|
.detach();
|
||||||
|
|
||||||
|
@ -264,121 +235,6 @@ pub fn view_release_notes(_: &ViewReleaseNotes, cx: &mut AppContext) -> Option<(
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn view_release_notes_locally(workspace: &mut Workspace, cx: &mut ViewContext<Workspace>) {
|
|
||||||
let release_channel = ReleaseChannel::global(cx);
|
|
||||||
|
|
||||||
let url = match release_channel {
|
|
||||||
ReleaseChannel::Nightly => Some("https://github.com/zed-industries/zed/commits/nightly/"),
|
|
||||||
ReleaseChannel::Dev => Some("https://github.com/zed-industries/zed/commits/main/"),
|
|
||||||
_ => None,
|
|
||||||
};
|
|
||||||
|
|
||||||
if let Some(url) = url {
|
|
||||||
cx.open_url(url);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let version = AppVersion::global(cx).to_string();
|
|
||||||
|
|
||||||
let client = client::Client::global(cx).http_client();
|
|
||||||
let url = client.build_url(&format!(
|
|
||||||
"/api/release_notes/v2/{}/{}",
|
|
||||||
release_channel.dev_name(),
|
|
||||||
version
|
|
||||||
));
|
|
||||||
|
|
||||||
let markdown = workspace
|
|
||||||
.app_state()
|
|
||||||
.languages
|
|
||||||
.language_for_name("Markdown");
|
|
||||||
|
|
||||||
workspace
|
|
||||||
.with_local_workspace(cx, move |_, cx| {
|
|
||||||
cx.spawn(|workspace, mut cx| async move {
|
|
||||||
let markdown = markdown.await.log_err();
|
|
||||||
let response = client.get(&url, Default::default(), true).await;
|
|
||||||
let Some(mut response) = response.log_err() else {
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut body = Vec::new();
|
|
||||||
response.body_mut().read_to_end(&mut body).await.ok();
|
|
||||||
|
|
||||||
let body: serde_json::Result<ReleaseNotesBody> =
|
|
||||||
serde_json::from_slice(body.as_slice());
|
|
||||||
|
|
||||||
if let Ok(body) = body {
|
|
||||||
workspace
|
|
||||||
.update(&mut cx, |workspace, cx| {
|
|
||||||
let project = workspace.project().clone();
|
|
||||||
let buffer = project.update(cx, |project, cx| {
|
|
||||||
project.create_local_buffer("", markdown, cx)
|
|
||||||
});
|
|
||||||
buffer.update(cx, |buffer, cx| {
|
|
||||||
buffer.edit([(0..0, body.release_notes)], None, cx)
|
|
||||||
});
|
|
||||||
let language_registry = project.read(cx).languages().clone();
|
|
||||||
|
|
||||||
let buffer = cx.new_model(|cx| MultiBuffer::singleton(buffer, cx));
|
|
||||||
|
|
||||||
let tab_description = SharedString::from(body.title.to_string());
|
|
||||||
let editor = cx.new_view(|cx| {
|
|
||||||
Editor::for_multibuffer(buffer, Some(project), true, cx)
|
|
||||||
});
|
|
||||||
let workspace_handle = workspace.weak_handle();
|
|
||||||
let view: View<MarkdownPreviewView> = MarkdownPreviewView::new(
|
|
||||||
MarkdownPreviewMode::Default,
|
|
||||||
editor,
|
|
||||||
workspace_handle,
|
|
||||||
language_registry,
|
|
||||||
Some(tab_description),
|
|
||||||
cx,
|
|
||||||
);
|
|
||||||
workspace.add_item_to_active_pane(
|
|
||||||
Box::new(view.clone()),
|
|
||||||
None,
|
|
||||||
true,
|
|
||||||
cx,
|
|
||||||
);
|
|
||||||
cx.notify();
|
|
||||||
})
|
|
||||||
.log_err();
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.detach();
|
|
||||||
})
|
|
||||||
.detach();
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn notify_of_any_new_update(cx: &mut ViewContext<Workspace>) -> Option<()> {
|
|
||||||
let updater = AutoUpdater::get(cx)?;
|
|
||||||
let version = updater.read(cx).current_version;
|
|
||||||
let should_show_notification = updater.read(cx).should_show_update_notification(cx);
|
|
||||||
|
|
||||||
cx.spawn(|workspace, mut cx| async move {
|
|
||||||
let should_show_notification = should_show_notification.await?;
|
|
||||||
if should_show_notification {
|
|
||||||
workspace.update(&mut cx, |workspace, cx| {
|
|
||||||
let workspace_handle = workspace.weak_handle();
|
|
||||||
workspace.show_notification(
|
|
||||||
NotificationId::unique::<UpdateNotification>(),
|
|
||||||
cx,
|
|
||||||
|cx| cx.new_view(|_| UpdateNotification::new(version, workspace_handle)),
|
|
||||||
);
|
|
||||||
updater.update(cx, |updater, cx| {
|
|
||||||
updater
|
|
||||||
.set_should_show_update_notification(false, cx)
|
|
||||||
.detach_and_log_err(cx);
|
|
||||||
});
|
|
||||||
})?;
|
|
||||||
}
|
|
||||||
anyhow::Ok(())
|
|
||||||
})
|
|
||||||
.detach();
|
|
||||||
|
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AutoUpdater {
|
impl AutoUpdater {
|
||||||
pub fn get(cx: &mut AppContext) -> Option<Model<Self>> {
|
pub fn get(cx: &mut AppContext) -> Option<Model<Self>> {
|
||||||
cx.default_global::<GlobalAutoUpdate>().0.clone()
|
cx.default_global::<GlobalAutoUpdate>().0.clone()
|
||||||
|
@ -423,6 +279,10 @@ impl AutoUpdater {
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn current_version(&self) -> SemanticVersion {
|
||||||
|
self.current_version
|
||||||
|
}
|
||||||
|
|
||||||
pub fn status(&self) -> AutoUpdateStatus {
|
pub fn status(&self) -> AutoUpdateStatus {
|
||||||
self.status.clone()
|
self.status.clone()
|
||||||
}
|
}
|
||||||
|
@ -646,7 +506,7 @@ impl AutoUpdater {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_should_show_update_notification(
|
pub fn set_should_show_update_notification(
|
||||||
&self,
|
&self,
|
||||||
should_show: bool,
|
should_show: bool,
|
||||||
cx: &AppContext,
|
cx: &AppContext,
|
||||||
|
@ -668,7 +528,7 @@ impl AutoUpdater {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn should_show_update_notification(&self, cx: &AppContext) -> Task<Result<bool>> {
|
pub fn should_show_update_notification(&self, cx: &AppContext) -> Task<Result<bool>> {
|
||||||
cx.background_executor().spawn(async move {
|
cx.background_executor().spawn(async move {
|
||||||
Ok(KEY_VALUE_STORE
|
Ok(KEY_VALUE_STORE
|
||||||
.read_kvp(SHOULD_SHOW_UPDATE_NOTIFICATION_KEY)?
|
.read_kvp(SHOULD_SHOW_UPDATE_NOTIFICATION_KEY)?
|
||||||
|
|
28
crates/auto_update_ui/Cargo.toml
Normal file
28
crates/auto_update_ui/Cargo.toml
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
[package]
|
||||||
|
name = "auto_update_ui"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
publish = false
|
||||||
|
license = "GPL-3.0-or-later"
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
path = "src/auto_update_ui.rs"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
anyhow.workspace = true
|
||||||
|
auto_update.workspace = true
|
||||||
|
client.workspace = true
|
||||||
|
editor.workspace = true
|
||||||
|
gpui.workspace = true
|
||||||
|
http_client.workspace = true
|
||||||
|
markdown_preview.workspace = true
|
||||||
|
menu.workspace = true
|
||||||
|
release_channel.workspace = true
|
||||||
|
serde.workspace = true
|
||||||
|
serde_json.workspace = true
|
||||||
|
smol.workspace = true
|
||||||
|
util.workspace = true
|
||||||
|
workspace.workspace = true
|
1
crates/auto_update_ui/LICENSE-GPL
Symbolic link
1
crates/auto_update_ui/LICENSE-GPL
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../../LICENSE-GPL
|
147
crates/auto_update_ui/src/auto_update_ui.rs
Normal file
147
crates/auto_update_ui/src/auto_update_ui.rs
Normal file
|
@ -0,0 +1,147 @@
|
||||||
|
mod update_notification;
|
||||||
|
|
||||||
|
use auto_update::AutoUpdater;
|
||||||
|
use editor::{Editor, MultiBuffer};
|
||||||
|
use gpui::{actions, prelude::*, AppContext, SharedString, View, ViewContext};
|
||||||
|
use http_client::HttpClient;
|
||||||
|
use markdown_preview::markdown_preview_view::{MarkdownPreviewMode, MarkdownPreviewView};
|
||||||
|
use release_channel::{AppVersion, ReleaseChannel};
|
||||||
|
use serde::Deserialize;
|
||||||
|
use smol::io::AsyncReadExt;
|
||||||
|
use util::ResultExt as _;
|
||||||
|
use workspace::notifications::NotificationId;
|
||||||
|
use workspace::Workspace;
|
||||||
|
|
||||||
|
use crate::update_notification::UpdateNotification;
|
||||||
|
|
||||||
|
actions!(auto_update, [ViewReleaseNotesLocally]);
|
||||||
|
|
||||||
|
pub fn init(cx: &mut AppContext) {
|
||||||
|
cx.observe_new_views(|workspace: &mut Workspace, _cx| {
|
||||||
|
workspace.register_action(|workspace, _: &ViewReleaseNotesLocally, cx| {
|
||||||
|
view_release_notes_locally(workspace, cx);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.detach();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
struct ReleaseNotesBody {
|
||||||
|
title: String,
|
||||||
|
release_notes: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn view_release_notes_locally(workspace: &mut Workspace, cx: &mut ViewContext<Workspace>) {
|
||||||
|
let release_channel = ReleaseChannel::global(cx);
|
||||||
|
|
||||||
|
let url = match release_channel {
|
||||||
|
ReleaseChannel::Nightly => Some("https://github.com/zed-industries/zed/commits/nightly/"),
|
||||||
|
ReleaseChannel::Dev => Some("https://github.com/zed-industries/zed/commits/main/"),
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(url) = url {
|
||||||
|
cx.open_url(url);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let version = AppVersion::global(cx).to_string();
|
||||||
|
|
||||||
|
let client = client::Client::global(cx).http_client();
|
||||||
|
let url = client.build_url(&format!(
|
||||||
|
"/api/release_notes/v2/{}/{}",
|
||||||
|
release_channel.dev_name(),
|
||||||
|
version
|
||||||
|
));
|
||||||
|
|
||||||
|
let markdown = workspace
|
||||||
|
.app_state()
|
||||||
|
.languages
|
||||||
|
.language_for_name("Markdown");
|
||||||
|
|
||||||
|
workspace
|
||||||
|
.with_local_workspace(cx, move |_, cx| {
|
||||||
|
cx.spawn(|workspace, mut cx| async move {
|
||||||
|
let markdown = markdown.await.log_err();
|
||||||
|
let response = client.get(&url, Default::default(), true).await;
|
||||||
|
let Some(mut response) = response.log_err() else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut body = Vec::new();
|
||||||
|
response.body_mut().read_to_end(&mut body).await.ok();
|
||||||
|
|
||||||
|
let body: serde_json::Result<ReleaseNotesBody> =
|
||||||
|
serde_json::from_slice(body.as_slice());
|
||||||
|
|
||||||
|
if let Ok(body) = body {
|
||||||
|
workspace
|
||||||
|
.update(&mut cx, |workspace, cx| {
|
||||||
|
let project = workspace.project().clone();
|
||||||
|
let buffer = project.update(cx, |project, cx| {
|
||||||
|
project.create_local_buffer("", markdown, cx)
|
||||||
|
});
|
||||||
|
buffer.update(cx, |buffer, cx| {
|
||||||
|
buffer.edit([(0..0, body.release_notes)], None, cx)
|
||||||
|
});
|
||||||
|
let language_registry = project.read(cx).languages().clone();
|
||||||
|
|
||||||
|
let buffer = cx.new_model(|cx| MultiBuffer::singleton(buffer, cx));
|
||||||
|
|
||||||
|
let tab_description = SharedString::from(body.title.to_string());
|
||||||
|
let editor = cx.new_view(|cx| {
|
||||||
|
Editor::for_multibuffer(buffer, Some(project), true, cx)
|
||||||
|
});
|
||||||
|
let workspace_handle = workspace.weak_handle();
|
||||||
|
let view: View<MarkdownPreviewView> = MarkdownPreviewView::new(
|
||||||
|
MarkdownPreviewMode::Default,
|
||||||
|
editor,
|
||||||
|
workspace_handle,
|
||||||
|
language_registry,
|
||||||
|
Some(tab_description),
|
||||||
|
cx,
|
||||||
|
);
|
||||||
|
workspace.add_item_to_active_pane(
|
||||||
|
Box::new(view.clone()),
|
||||||
|
None,
|
||||||
|
true,
|
||||||
|
cx,
|
||||||
|
);
|
||||||
|
cx.notify();
|
||||||
|
})
|
||||||
|
.log_err();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.detach();
|
||||||
|
})
|
||||||
|
.detach();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn notify_of_any_new_update(cx: &mut ViewContext<Workspace>) -> Option<()> {
|
||||||
|
let updater = AutoUpdater::get(cx)?;
|
||||||
|
let version = updater.read(cx).current_version();
|
||||||
|
let should_show_notification = updater.read(cx).should_show_update_notification(cx);
|
||||||
|
|
||||||
|
cx.spawn(|workspace, mut cx| async move {
|
||||||
|
let should_show_notification = should_show_notification.await?;
|
||||||
|
if should_show_notification {
|
||||||
|
workspace.update(&mut cx, |workspace, cx| {
|
||||||
|
let workspace_handle = workspace.weak_handle();
|
||||||
|
workspace.show_notification(
|
||||||
|
NotificationId::unique::<UpdateNotification>(),
|
||||||
|
cx,
|
||||||
|
|cx| cx.new_view(|_| UpdateNotification::new(version, workspace_handle)),
|
||||||
|
);
|
||||||
|
updater.update(cx, |updater, cx| {
|
||||||
|
updater
|
||||||
|
.set_should_show_update_notification(false, cx)
|
||||||
|
.detach_and_log_err(cx);
|
||||||
|
});
|
||||||
|
})?;
|
||||||
|
}
|
||||||
|
anyhow::Ok(())
|
||||||
|
})
|
||||||
|
.detach();
|
||||||
|
|
||||||
|
None
|
||||||
|
}
|
|
@ -23,6 +23,7 @@ assistant.workspace = true
|
||||||
async-watch.workspace = true
|
async-watch.workspace = true
|
||||||
audio.workspace = true
|
audio.workspace = true
|
||||||
auto_update.workspace = true
|
auto_update.workspace = true
|
||||||
|
auto_update_ui.workspace = true
|
||||||
backtrace = "0.3"
|
backtrace = "0.3"
|
||||||
breadcrumbs.workspace = true
|
breadcrumbs.workspace = true
|
||||||
call.workspace = true
|
call.workspace = true
|
||||||
|
|
|
@ -367,6 +367,7 @@ fn main() {
|
||||||
AppState::set_global(Arc::downgrade(&app_state), cx);
|
AppState::set_global(Arc::downgrade(&app_state), cx);
|
||||||
|
|
||||||
auto_update::init(client.http_client(), cx);
|
auto_update::init(client.http_client(), cx);
|
||||||
|
auto_update_ui::init(cx);
|
||||||
reliability::init(
|
reliability::init(
|
||||||
client.http_client(),
|
client.http_client(),
|
||||||
system_id.as_ref().map(|id| id.to_string()),
|
system_id.as_ref().map(|id| id.to_string()),
|
||||||
|
|
|
@ -223,7 +223,7 @@ pub fn initialize_workspace(
|
||||||
status_bar.add_right_item(cursor_position, cx);
|
status_bar.add_right_item(cursor_position, cx);
|
||||||
});
|
});
|
||||||
|
|
||||||
auto_update::notify_of_any_new_update(cx);
|
auto_update_ui::notify_of_any_new_update(cx);
|
||||||
|
|
||||||
let handle = cx.view().downgrade();
|
let handle = cx.view().downgrade();
|
||||||
cx.on_window_should_close(move |cx| {
|
cx.on_window_should_close(move |cx| {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue