Skip to content

Commit 184db3f

Browse files
committed
feat: add file path selection and fix save bug
- Add file path selector before starting (default to Desktop) - Display current save file path in UI - Remove 'Save Current' button (auto-save to selected file) - Fix: All vanity addresses now save to the same user-selected file - All chains (TRON/EVM/SOL) save to same file with chain label
1 parent cbc4592 commit 184db3f

2 files changed

Lines changed: 54 additions & 41 deletions

File tree

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ num_cpus = "1.16"
5151
# GUI - 使用 iced
5252
iced = { version = "0.12", features = ["debug", "tokio", "canvas", "svg"] }
5353
rfd = "0.14"
54+
dirs = "5.0"
5455

5556
# 系统监控
5657
sysinfo = "0.30"

src/gui.rs

Lines changed: 53 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,9 @@ pub struct VanityApp {
9393

9494
// 内嵌 logo 资源
9595
logo_handle: svg::Handle,
96+
97+
// 保存文件路径
98+
save_file_path: String,
9699
}
97100

98101
impl Default for VanityApp {
@@ -123,6 +126,17 @@ impl Default for VanityApp {
123126
vanity_cache: Arc::new(Mutex::new(None)),
124127
last_found: None,
125128
logo_handle: load_logo(),
129+
save_file_path: Self::default_save_path(),
130+
}
131+
}
132+
}
133+
134+
impl VanityApp {
135+
fn default_save_path() -> String {
136+
if let Some(home) = dirs::home_dir() {
137+
home.join("Desktop").join("vanity_addresses.txt").to_string_lossy().to_string()
138+
} else {
139+
"vanity_addresses.txt".to_string()
126140
}
127141
}
128142
}
@@ -133,11 +147,11 @@ pub enum Message {
133147
PatternsChanged(String),
134148
BatchSizeChanged(String),
135149
ThreadCountChanged(String),
150+
ChooseSaveFile,
151+
SaveFileSelected(Option<std::path::PathBuf>),
136152
StartPressed,
137153
PausePressed,
138154
StopPressed,
139-
SaveCurrent,
140-
SaveResult(String),
141155
Tick,
142156
VanityFound(String),
143157
}
@@ -162,6 +176,25 @@ impl Application for VanityApp {
162176
Message::PatternsChanged(input) => self.patterns_input = input,
163177
Message::BatchSizeChanged(input) => self.batch_size = input,
164178
Message::ThreadCountChanged(input) => self.thread_count = input,
179+
Message::ChooseSaveFile => {
180+
return Command::perform(
181+
async {
182+
rfd::AsyncFileDialog::new()
183+
.set_file_name("vanity_addresses.txt")
184+
.set_title("选择保存文件")
185+
.save_file()
186+
.await
187+
.map(|handle| handle.path().to_path_buf())
188+
},
189+
Message::SaveFileSelected,
190+
);
191+
}
192+
Message::SaveFileSelected(path) => {
193+
if let Some(path) = path {
194+
self.save_file_path = path.to_string_lossy().to_string();
195+
self.log_messages.push(format!("✓ 保存路径: {}", self.save_file_path));
196+
}
197+
}
165198
Message::StartPressed => {
166199
if !self.is_running {
167200
self.is_running = true;
@@ -211,7 +244,7 @@ impl Application for VanityApp {
211244
let vanity_cache = Arc::clone(&self.vanity_cache);
212245
let patterns_clone = patterns.clone();
213246
let chain_copy = chain;
214-
let filename = format!("{}_vanity.txt", chain_copy.label().to_lowercase());
247+
let save_path = self.save_file_path.clone();
215248

216249
thread::spawn(move || loop {
217250
if stop.load(Ordering::Relaxed) {
@@ -229,9 +262,9 @@ impl Application for VanityApp {
229262
patterns_clone.iter().map(|s| s.as_str()).collect();
230263
if is_vanity_address(&addr.address, &patterns_refs) {
231264
found.fetch_add(1, Ordering::Relaxed);
232-
// 保存到文件
233-
let _ = save_address_to_file(&filename, &addr, true);
234-
// 缓存靓号信息用于 UI 显示 / 手动保存
265+
// 保存到用户指定的文件
266+
let _ = save_address_to_file(&save_path, &addr, true);
267+
// 缓存靓号信息用于 UI 显示
235268
if let Ok(mut cache) = vanity_cache.lock() {
236269
*cache = Some(addr.clone());
237270
}
@@ -282,39 +315,6 @@ impl Application for VanityApp {
282315
}
283316
}
284317
}
285-
Message::SaveCurrent => {
286-
if let Some(addr) = self.last_found.clone() {
287-
return Command::perform(
288-
async move {
289-
let target = rfd::FileDialog::new()
290-
.set_title("保存靓号到文本")
291-
.set_file_name("vanity.txt")
292-
.save_file();
293-
294-
match target {
295-
Some(path) => {
296-
let res = save_address_to_file(
297-
path.to_string_lossy().as_ref(),
298-
&addr,
299-
true,
300-
);
301-
match res {
302-
Ok(_) => format!("✅ 已保存: {}", path.display()),
303-
Err(e) => format!("❌ 保存失败: {}", e),
304-
}
305-
}
306-
None => "已取消保存".to_string(),
307-
}
308-
},
309-
Message::SaveResult,
310-
);
311-
} else {
312-
self.log_messages.insert(0, "暂无可保存的靓号".to_string());
313-
}
314-
}
315-
Message::SaveResult(msg) => {
316-
self.log_messages.insert(0, msg);
317-
}
318318
Message::Tick => {
319319
let stats = self.monitor.get_stats();
320320
self.cpu_percent = stats.cpu_percent;
@@ -399,6 +399,19 @@ impl Application for VanityApp {
399399
]
400400
.spacing(8);
401401

402+
let file_path_row = column![
403+
row![
404+
text("保存路径:").size(14).style(iced::theme::Text::Color(accent())),
405+
ghost_button("选择文件", Message::ChooseSaveFile),
406+
]
407+
.spacing(12)
408+
.align_items(Alignment::Center),
409+
text(&self.save_file_path)
410+
.size(12)
411+
.style(iced::theme::Text::Color(Color::from_rgb8(160, 180, 200))),
412+
]
413+
.spacing(6);
414+
402415
let batch_threads_row = row![
403416
text("批处理大小").size(14).width(Length::Shrink),
404417
text_input("1000", &self.batch_size)
@@ -421,7 +434,6 @@ impl Application for VanityApp {
421434
Message::PausePressed
422435
),
423436
danger_button("停止", Message::StopPressed),
424-
ghost_button("保存当前靓号", Message::SaveCurrent),
425437
]
426438
.spacing(12);
427439

@@ -486,7 +498,7 @@ impl Application for VanityApp {
486498

487499
let layout = column![
488500
header,
489-
card(column![patterns_row, batch_threads_row].spacing(12)),
501+
card(column![file_path_row, patterns_row, batch_threads_row].spacing(12)),
490502
card(column![controls].spacing(8)),
491503
card(stat_cards),
492504
system_card,

0 commit comments

Comments
 (0)