At RustConf we were demo'ing zed, and it continually popped open the chat panel. We're usually inured to this because the Chat panel doesn't open unless a Guest is in the channel, but it made me sad that we were showing a long stream of vacuous comments and unresponded to questions on every demo screen. We may bring chat back in the future, but we need more thought on the UX, and we need to rebuild the backend to not use the existing collab server that we're trying to move off of. Release Notes: - Removed the chat feature from Zed (Sorry to the 5 of you who use this on the regular!)
183 lines
6.7 KiB
Rust
183 lines
6.7 KiB
Rust
use auto_update::AutoUpdater;
|
|
use editor::{Editor, MultiBuffer};
|
|
use gpui::{App, Context, DismissEvent, Entity, Window, actions, prelude::*};
|
|
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::Workspace;
|
|
use workspace::notifications::simple_message_notification::MessageNotification;
|
|
use workspace::notifications::{NotificationId, show_app_notification};
|
|
|
|
actions!(
|
|
auto_update,
|
|
[
|
|
/// Opens the release notes for the current version in a new tab.
|
|
ViewReleaseNotesLocally
|
|
]
|
|
);
|
|
|
|
pub fn init(cx: &mut App) {
|
|
notify_if_app_was_updated(cx);
|
|
cx.observe_new(|workspace: &mut Workspace, _window, _cx| {
|
|
workspace.register_action(|workspace, _: &ViewReleaseNotesLocally, window, cx| {
|
|
view_release_notes_locally(workspace, window, cx);
|
|
});
|
|
})
|
|
.detach();
|
|
}
|
|
|
|
#[derive(Deserialize)]
|
|
struct ReleaseNotesBody {
|
|
title: String,
|
|
release_notes: String,
|
|
}
|
|
|
|
fn view_release_notes_locally(
|
|
workspace: &mut Workspace,
|
|
window: &mut Window,
|
|
cx: &mut Context<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(window, cx, move |_, window, cx| {
|
|
cx.spawn_in(window, async move |workspace, cx| {
|
|
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_in(cx, |workspace, window, cx| {
|
|
let project = workspace.project().clone();
|
|
let buffer = project.update(cx, |project, cx| {
|
|
project.create_local_buffer("", markdown, false, 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(|cx| MultiBuffer::singleton(buffer, cx));
|
|
|
|
let editor = cx.new(|cx| {
|
|
Editor::for_multibuffer(buffer, Some(project), window, cx)
|
|
});
|
|
let workspace_handle = workspace.weak_handle();
|
|
let markdown_preview: Entity<MarkdownPreviewView> =
|
|
MarkdownPreviewView::new(
|
|
MarkdownPreviewMode::Default,
|
|
editor,
|
|
workspace_handle,
|
|
language_registry,
|
|
window,
|
|
cx,
|
|
);
|
|
workspace.add_item_to_active_pane(
|
|
Box::new(markdown_preview),
|
|
None,
|
|
true,
|
|
window,
|
|
cx,
|
|
);
|
|
cx.notify();
|
|
})
|
|
.log_err();
|
|
}
|
|
})
|
|
.detach();
|
|
})
|
|
.detach();
|
|
}
|
|
|
|
/// Shows a notification across all workspaces if an update was previously automatically installed
|
|
/// and this notification had not yet been shown.
|
|
pub fn notify_if_app_was_updated(cx: &mut App) {
|
|
let Some(updater) = AutoUpdater::get(cx) else {
|
|
return;
|
|
};
|
|
|
|
if let ReleaseChannel::Nightly = ReleaseChannel::global(cx) {
|
|
return;
|
|
}
|
|
|
|
struct UpdateNotification;
|
|
|
|
let should_show_notification = updater.read(cx).should_show_update_notification(cx);
|
|
cx.spawn(async move |cx| {
|
|
let should_show_notification = should_show_notification.await?;
|
|
if should_show_notification {
|
|
cx.update(|cx| {
|
|
let version = updater.read(cx).current_version();
|
|
let app_name = ReleaseChannel::global(cx).display_name();
|
|
show_app_notification(
|
|
NotificationId::unique::<UpdateNotification>(),
|
|
cx,
|
|
move |cx| {
|
|
let workspace_handle = cx.entity().downgrade();
|
|
cx.new(|cx| {
|
|
MessageNotification::new(
|
|
format!("Updated to {app_name} {}", version),
|
|
cx,
|
|
)
|
|
.primary_message("View Release Notes")
|
|
.primary_on_click(move |window, cx| {
|
|
if let Some(workspace) = workspace_handle.upgrade() {
|
|
workspace.update(cx, |workspace, cx| {
|
|
crate::view_release_notes_locally(workspace, window, cx);
|
|
})
|
|
}
|
|
cx.emit(DismissEvent);
|
|
})
|
|
.show_suppress_button(false)
|
|
})
|
|
},
|
|
);
|
|
updater.update(cx, |updater, cx| {
|
|
updater
|
|
.set_should_show_update_notification(false, cx)
|
|
.detach_and_log_err(cx);
|
|
})
|
|
})?;
|
|
}
|
|
anyhow::Ok(())
|
|
})
|
|
.detach();
|
|
}
|