Calculate download checksums

This commit is contained in:
2026-05-07 22:15:56 -04:00
parent 4302d0817c
commit a6e1482648
8 changed files with 186 additions and 10 deletions
@@ -16,7 +16,7 @@ impl ElyShell {
cx: &mut Context<Self>,
) -> AnyElement {
div()
.w(px(64.0))
.w(px(96.0))
.flex()
.items_center()
.justify_end()
@@ -84,6 +84,7 @@ impl ElyShell {
|this| {
let open_id = entry.id().clone();
let reveal_id = entry.id().clone();
let checksum_id = entry.id().clone();
this.child(
download_action_button("open", index, IconName::ExternalLink, "Open File")
@@ -104,6 +105,20 @@ impl ElyShell {
}))
.into_any_element(),
)
.when(entry.checksum().is_none(), |this| {
this.child(
download_action_button(
"checksum",
index,
IconName::CircleCheck,
"Calculate SHA-256",
)
.on_click(cx.listener(move |shell, _, _, cx| {
shell.calculate_download_checksum(&checksum_id, cx);
}))
.into_any_element(),
)
})
},
)
.into_any_element()
@@ -1,6 +1,6 @@
use ely_browser_core::BrowserSnapshot;
use ely_design_system::colors;
use ely_domain::{DownloadEntry, DownloadSecurity};
use ely_domain::{DownloadChecksum, DownloadEntry, DownloadSecurity};
use gpui::prelude::FluentBuilder;
use gpui::{
AnyElement, Context, InteractiveElement, IntoElement, ParentElement, SharedString, Styled, div,
@@ -106,8 +106,8 @@ impl ElyShell {
),
),
)
.when_some(self.download_file_error.clone(), |this, message| {
this.child(render_download_file_error(message))
.when_some(self.download_action_error.clone(), |this, message| {
this.child(render_download_action_error(message))
})
.when(
self.download_clear_confirmation && !snapshot.download_entries.is_empty(),
@@ -259,6 +259,9 @@ impl ElyShell {
)
.when(entry.security().requires_prompt(), |this| {
this.child(render_security_prompt(entry.security()))
})
.when_some(entry.checksum(), |this, checksum| {
this.child(render_checksum_label(checksum))
}),
),
),
@@ -296,7 +299,7 @@ impl ElyShell {
}
}
fn render_download_file_error(message: String) -> AnyElement {
fn render_download_action_error(message: String) -> AnyElement {
div()
.rounded_md()
.border_1()
@@ -323,3 +326,18 @@ fn render_security_prompt(security: &DownloadSecurity) -> AnyElement {
.child(download_security_label(security))
.into_any_element()
}
fn render_checksum_label(checksum: &DownloadChecksum) -> AnyElement {
div()
.flex()
.items_center()
.gap_1()
.text_color(rgb(colors::SUCCESS))
.child(IconName::CircleCheck)
.child(format!("SHA-256 {}", short_checksum(checksum.value())))
.into_any_element()
}
fn short_checksum(value: &str) -> &str {
value.get(..12).unwrap_or(value)
}
+27 -5
View File
@@ -9,7 +9,10 @@ use gpui_component::input::{InputEvent, InputState, SelectAll};
use crate::{
CloseCurrentTab, FocusAddressBar, FocusCommandMode, OpenDownloads, OpenHistory, OpenNewTab,
OpenSettings, RestoreClosedTab, SelectNextTab, SelectPreviousTab, ToggleFavoriteTab,
TogglePinnedTab, services::download_files::DownloadFileAction,
TogglePinnedTab,
services::{
download_checksums::DownloadChecksumCalculator, download_files::DownloadFileAction,
},
};
enum ShellState {
@@ -22,7 +25,7 @@ pub struct ElyShell {
focus_handle: FocusHandle,
command_input: Entity<InputState>,
last_intent: Option<CommandIntent>,
download_file_error: Option<String>,
download_action_error: Option<String>,
download_clear_confirmation: bool,
_command_subscription: Subscription,
}
@@ -79,7 +82,7 @@ impl ElyShell {
focus_handle: cx.focus_handle(),
command_input,
last_intent: None,
download_file_error: None,
download_action_error: None,
download_clear_confirmation: false,
_command_subscription: command_subscription,
}
@@ -266,7 +269,26 @@ impl ElyShell {
core.clear_downloads_for_active_profile();
}
self.download_clear_confirmation = false;
self.download_file_error = None;
self.download_action_error = None;
cx.notify();
}
fn calculate_download_checksum(&mut self, download_id: &DownloadId, cx: &mut Context<Self>) {
let result = match &mut self.state {
ShellState::Ready(core) => core
.download_target_file_path(download_id)
.map_err(|error| error.to_string())
.and_then(|path| {
DownloadChecksumCalculator::sha256(&path).map_err(|error| error.to_string())
})
.and_then(|checksum| {
core.record_download_checksum(download_id, checksum)
.map_err(|error| error.to_string())
}),
ShellState::StartupError(message) => Err(message.clone()),
};
self.download_action_error = result.err();
cx.notify();
}
@@ -292,7 +314,7 @@ impl ElyShell {
ShellState::StartupError(message) => Err(message.clone()),
};
self.download_file_error = result.err();
self.download_action_error = result.err();
cx.notify();
}