Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
35e590c718 | ||
|
|
9f9044646f |
Generated
+1
-1
@@ -6372,7 +6372,7 @@ checksum = "e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e"
|
||||
|
||||
[[package]]
|
||||
name = "zerosend"
|
||||
version = "2.5.1"
|
||||
version = "2.5.2"
|
||||
dependencies = [
|
||||
"arboard",
|
||||
"axum",
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "zerosend"
|
||||
version = "2.5.1"
|
||||
version = "2.5.2"
|
||||
edition = "2021"
|
||||
description = "Fast, peer-to-peer file transfer designed for ZeroTier, Tailscale, Radmin VPN and LAN"
|
||||
authors = ["RarDog"]
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
+914
-652
File diff suppressed because it is too large
Load Diff
+21
-21
@@ -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
@@ -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(¤t_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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user