@@ -355,7 +355,8 @@ func (a *App) executeDirect(config DirectConfig) error {
355355 ctx , cancel := context .WithTimeout (context .Background (), a .inputTimeout )
356356 defer cancel ()
357357
358- resultText , err := withSpinner ("Abfrage" , func () string {
358+ resultText , err := withSpinner ("Abfrage" , func (frame int ) string {
359+ _ = frame
359360 return "Server wird abgefragt"
360361 }, 120 * time .Millisecond , func () (string , error ) {
361362 result , err := ping .Execute (ctx , config .Edition , config .Host , config .Port )
@@ -376,17 +377,11 @@ func (a *App) executeLookup(config LookupConfig) error {
376377 ctx := context .Background ()
377378
378379 var current atomic.Value
379- current .Store ("Domains werden überprüft" )
380- formatProgress := func (subdomain , ending string ) string {
381- sub := subdomain
382- if sub == "" {
383- sub = "(keine)"
384- }
385- return fmt .Sprintf ("Subdomain: %s | Endung: %s" , sub , ending )
386- }
380+ current .Store (ping.LookupProgress {})
387381
388- resultText , err := withSpinner ("IP Lookup" , func () string {
389- return current .Load ().(string )
382+ resultText , err := withSpinner ("IP Lookup" , func (frame int ) string {
383+ progress := current .Load ().(ping.LookupProgress )
384+ return formatLookupProgress (progress , frame )
390385 }, 120 * time .Millisecond , func () (string , error ) {
391386 result , lookupErr := ping .LookupDomains (ctx , ping.LookupConfig {
392387 Edition : config .Edition ,
@@ -395,8 +390,8 @@ func (a *App) executeLookup(config LookupConfig) error {
395390 Subdomains : config .Subdomains ,
396391 DomainEndings : config .Endings ,
397392 Concurrency : 24 ,
398- Progress : func (subdomain , ending string ) {
399- current .Store (formatProgress ( subdomain , ending ) )
393+ Progress : func (progress ping. LookupProgress ) {
394+ current .Store (progress )
400395 },
401396 })
402397 if lookupErr != nil {
@@ -412,6 +407,53 @@ func (a *App) executeLookup(config LookupConfig) error {
412407 return nil
413408}
414409
410+ func formatLookupProgress (progress ping.LookupProgress , frame int ) string {
411+ if progress .Total == 0 {
412+ return "Domains werden überprüft"
413+ }
414+ subdomain := progress .Subdomain
415+ if subdomain == "" {
416+ subdomain = "(keine)"
417+ }
418+ bar := buildProgressBar (progress .Completed , progress .Total , frame , 20 )
419+ percent := (float64 (progress .Completed ) / float64 (progress .Total )) * 100
420+ return fmt .Sprintf (
421+ "%s %d/%d (%.0f%%) | Subdomain: %s | Endung: %s | Host: %s" ,
422+ bar ,
423+ progress .Completed ,
424+ progress .Total ,
425+ percent ,
426+ subdomain ,
427+ progress .Ending ,
428+ progress .Host ,
429+ )
430+ }
431+
432+ func buildProgressBar (completed , total , frame , width int ) string {
433+ if total <= 0 || width <= 0 {
434+ return "[--------------------]"
435+ }
436+ if completed > total {
437+ completed = total
438+ }
439+ filled := (completed * width ) / total
440+ if filled > width {
441+ filled = width
442+ }
443+ bar := make ([]rune , width )
444+ for i := 0 ; i < width ; i ++ {
445+ bar [i ] = '░'
446+ }
447+ for i := 0 ; i < filled ; i ++ {
448+ bar [i ] = '█'
449+ }
450+ if completed < total && filled < width {
451+ animation := []rune {'▏' , '▎' , '▍' , '▌' , '▋' , '▊' , '▉' }
452+ bar [filled ] = animation [frame % len (animation )]
453+ }
454+ return fmt .Sprintf ("[%s]" , string (bar ))
455+ }
456+
415457func (a * App ) askAgain () (bool , error ) {
416458 index , err := selectOption ("Nächster Schritt" , []string {"Neue Abfrage" , "Beenden" })
417459 if err != nil {
0 commit comments