@@ -93,6 +93,9 @@ pub struct VanityApp {
9393
9494 // 内嵌 logo 资源
9595 logo_handle : svg:: Handle ,
96+
97+ // 保存文件路径
98+ save_file_path : String ,
9699}
97100
98101impl 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