3 Commits
7 changed files with 1163 additions and 816 deletions
Generated
+1 -1
View File
@@ -6372,7 +6372,7 @@ checksum = "e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e"
[[package]]
name = "zerosend"
version = "2.5.0"
version = "2.5.2"
dependencies = [
"arboard",
"axum",
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "zerosend"
version = "2.5.0"
version = "2.5.2"
edition = "2021"
description = "Fast, peer-to-peer file transfer designed for ZeroTier, Tailscale, Radmin VPN and LAN"
authors = ["RarDog"]
+9 -1
View File
@@ -32,6 +32,14 @@ fn get_default_device_name() -> String {
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
// Clean up any old binaries or temp files from previous self-updates
if let Ok(current_exe) = std::env::current_exe() {
if let Some(exe_dir) = current_exe.parent() {
let _ = std::fs::remove_file(exe_dir.join("zerosend.exe.old"));
let _ = std::fs::remove_file(exe_dir.join("zerosend_update.exe"));
}
}
let config = AppConfig::load();
let cli = Cli::parse();
@@ -298,7 +306,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
.with_inner_size([config.window_width, config.window_height])
.with_min_inner_size([780.0, 500.0])
.with_visible(!start_minimized)
.with_title("ZeroSend v2.5.0 - P2P Sharing for ZeroTier & VPN"),
.with_title(format!("ZeroSend v{} - P2P Sharing for ZeroTier & VPN", env!("CARGO_PKG_VERSION"))),
..Default::default()
};
+2 -1
View File
@@ -2330,7 +2330,7 @@ async fn handle_web_ui(State(state): State<Arc<ServerState>>) -> Html<String> {
<div class="toast" id="toast"></div>
<div class="footer">
ZeroSend v2.4.1 • Ultra-fast P2P File & Text Sharing • 🛡️ SHA-256 Verified
ZeroSend v{version} • Ultra-fast P2P File & Text Sharing • 🛡️ SHA-256 Verified
</div>
</div>
@@ -2766,6 +2766,7 @@ async fn handle_web_ui(State(state): State<Arc<ServerState>>) -> Html<String> {
</html>"###,
device_name = state.my_info.name,
net_type = state.my_info.net_type,
version = env!("CARGO_PKG_VERSION"),
);
Html(html)
+1114 -786
View File
File diff suppressed because it is too large Load Diff
+21 -21
View File
@@ -100,9 +100,9 @@ impl VimViewerModal {
self.is_command_mode = false;
self.is_dirty = false;
self.status_msg = Some(format!(
"Loaded {} lines • {}",
"Загружено {} строк • {}",
self.lines.len(),
if self.is_writable { "Writable [i: edit, :w: save]" } else { "Read-Only" }
if self.is_writable { "Доступна запись [i: правка, :w: сохранить]" } else { "Только чтение" }
));
self.last_g_press = None;
}
@@ -117,7 +117,7 @@ impl VimViewerModal {
pub fn trigger_save(&mut self) {
if !self.is_writable {
self.status_msg = Some("❌ Cannot save: folder is Read-Only".to_string());
self.status_msg = Some("❌ Невозможно сохранить: папка только для чтения".to_string());
return;
}
@@ -129,10 +129,10 @@ impl VimViewerModal {
self.buffer_content.clone(),
self.pin.clone(),
));
self.status_msg = Some("⏳ Saving changes to remote peer...".to_string());
self.status_msg = Some("⏳ Сохранение изменений на удаленном узле...".to_string());
self.is_dirty = false;
} else {
self.status_msg = Some("❌ No remote endpoint associated with this file".to_string());
self.status_msg = Some("❌ Нет удаленного подключения для этого файла".to_string());
}
}
@@ -361,14 +361,14 @@ impl VimViewerModal {
}
if self.is_writable {
ui.label(RichText::new("• [Writable]").color(Color32::from_rgb(34, 197, 94)).size(11.0));
ui.label(RichText::new("• [Доступна запись]").color(Color32::from_rgb(34, 197, 94)).size(11.0));
} else {
ui.label(RichText::new("• [Read-Only]").color(Color32::from_rgb(148, 163, 184)).size(11.0));
ui.label(RichText::new("• [Только чтение]").color(Color32::from_rgb(148, 163, 184)).size(11.0));
}
ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| {
if ui
.button(RichText::new("✕ Close (:q)").color(Color32::from_rgb(203, 213, 225)))
.button(RichText::new("✕ Закрыть (:q)").color(Color32::from_rgb(203, 213, 225)))
.clicked()
{
self.close();
@@ -376,7 +376,7 @@ impl VimViewerModal {
if self.is_writable {
let save_btn = egui::Button::new(
RichText::new("💾 Save (:w)")
RichText::new("💾 Сохранить (:w)")
.strong()
.color(Color32::WHITE),
)
@@ -387,7 +387,7 @@ impl VimViewerModal {
self.trigger_save();
}
let edit_label = if self.is_insert_mode { "👁 View Mode (Esc)" } else { "✏️ Edit (i)" };
let edit_label = if self.is_insert_mode { "👁 Просмотр (Esc)" } else { "✏️ Редактировать (i)" };
if ui.button(RichText::new(edit_label).color(Color32::from_rgb(226, 232, 240))).clicked() {
self.is_insert_mode = !self.is_insert_mode;
if !self.is_insert_mode {
@@ -398,7 +398,7 @@ impl VimViewerModal {
if self.file_name.to_lowercase().ends_with(".md") {
if ui
.selectable_label(self.is_markdown_view, "👁 Markdown Preview")
.selectable_label(self.is_markdown_view, "👁 Предпросмотр Markdown")
.clicked()
{
self.is_markdown_view = !self.is_markdown_view;
@@ -406,7 +406,7 @@ impl VimViewerModal {
}
ui.label(
RichText::new(format!("{} lines", self.lines.len()))
RichText::new(format!("{} строк", self.lines.len()))
.size(11.0)
.color(Color32::from_rgb(148, 163, 184)),
);
@@ -539,13 +539,13 @@ impl VimViewerModal {
ui.horizontal(|ui| {
// Mode Pill
let (mode_text, mode_bg, mode_fg) = if self.is_insert_mode {
("INSERT", Color32::from_rgb(34, 197, 94), Color32::BLACK)
("ВСТАВКА", Color32::from_rgb(34, 197, 94), Color32::BLACK)
} else if self.is_searching {
("SEARCH", Color32::from_rgb(217, 119, 6), Color32::WHITE)
("ПОИСК", Color32::from_rgb(217, 119, 6), Color32::WHITE)
} else if self.is_command_mode {
("COMMAND", Color32::from_rgb(147, 51, 234), Color32::WHITE)
("КОМАНДА", Color32::from_rgb(147, 51, 234), Color32::WHITE)
} else {
("NORMAL", Color32::from_rgb(37, 99, 235), Color32::WHITE)
("ОБЫЧНЫЙ", Color32::from_rgb(37, 99, 235), Color32::WHITE)
};
Frame::none()
@@ -559,16 +559,16 @@ impl VimViewerModal {
if self.is_searching {
ui.label(RichText::new("/").monospace().color(Color32::from_rgb(245, 158, 11)));
let edit = TextEdit::singleline(&mut self.search_query)
.hint_text("pattern (press Enter)...")
.hint_text("поиск (нажмите Enter)...")
.font(egui::TextStyle::Monospace)
.desired_width(200.0);
ui.add(edit).request_focus();
} else if self.is_command_mode {
ui.label(RichText::new(":").monospace().color(Color32::from_rgb(168, 85, 247)));
let edit = TextEdit::singleline(&mut self.command_input)
.hint_text("w (save) / q (quit) / line...")
.hint_text("w (сохранить) / q (выход) / номер...")
.font(egui::TextStyle::Monospace)
.desired_width(200.0);
.desired_width(220.0);
ui.add(edit).request_focus();
} else {
if let Some(msg) = &self.status_msg {
@@ -578,7 +578,7 @@ impl VimViewerModal {
ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| {
ui.label(
RichText::new("i: edit • Esc: normal • :w: save • :q: exit")
RichText::new("i: правка • Esc: обычный • :w: сохранить • :q: выход")
.size(10.0)
.color(Color32::from_rgb(100, 116, 139)),
);
@@ -586,7 +586,7 @@ impl VimViewerModal {
ui.separator();
ui.label(
RichText::new(format!("Ln {}, Col 1", self.cursor_line))
RichText::new(format!("Стр {}, Кол 1", self.cursor_line))
.size(11.0)
.monospace()
.color(Color32::from_rgb(148, 163, 184)),
+15 -5
View File
@@ -335,17 +335,27 @@ pub async fn perform_update_download(
info!("Update successfully installed to {:?}", current_exe);
let _ = progress_tx.send(UpdateProgress::Completed);
// Spawn background PowerShell cleanup script to delete old binary once this process terminates
let cleanup_script = format!(
"Start-Sleep -Seconds 1; Remove-Item -Force -ErrorAction SilentlyContinue '{}'",
old_backup_path.to_string_lossy()
);
let _ = std::process::Command::new("powershell")
.args(["-NoProfile", "-WindowStyle", "Hidden", "-Command", &cleanup_script])
.spawn();
// Spawn updated application and exit
let _ = std::process::Command::new(&current_exe).spawn();
std::thread::sleep(Duration::from_millis(500));
std::thread::sleep(Duration::from_millis(400));
std::process::exit(0);
} else {
// Fallback: Use PowerShell deferred replacement
// Fallback: Use PowerShell deferred replacement and cleanup
info!("Direct rename locked; triggering background PowerShell replacement...");
let script = format!(
"Start-Sleep -Milliseconds 600; Move-Item -Force '{temp}' '{target}'; Start-Process '{target}'",
"Start-Sleep -Milliseconds 600; Move-Item -Force '{temp}' '{target}'; Start-Sleep -Seconds 1; Remove-Item -Force -ErrorAction SilentlyContinue '{old}'; Start-Process '{target}'",
temp = temp_download_path.to_string_lossy(),
target = current_exe.to_string_lossy()
target = current_exe.to_string_lossy(),
old = old_backup_path.to_string_lossy()
);
let _ = std::process::Command::new("powershell")
@@ -353,7 +363,7 @@ pub async fn perform_update_download(
.spawn();
let _ = progress_tx.send(UpdateProgress::Completed);
std::thread::sleep(Duration::from_millis(500));
std::thread::sleep(Duration::from_millis(400));
std::process::exit(0);
}
}