Class: Supermicro::Spinner

Inherits:
Object
  • Object
show all
Defined in:
lib/supermicro/spinner.rb

Constant Summary collapse

SPINNERS =
{
  dots: {
    frames: ['', '', '', '', '', '', '', '', '', ''],
    interval: 0.08
  },
  line: {
    frames: ['-', '\\', '|', '/'],
    interval: 0.1
  },
  arrow: {
    frames: ['', '', '', '', '', '', '', ''],
    interval: 0.1
  },
  bounce: {
    frames: ['', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ''],
    interval: 0.08
  },
  bar: {
    frames: ['', '', '', '', '', '', '', '', '', '', '', '', '', ''],
    interval: 0.08
  }
}

Instance Method Summary collapse

Constructor Details

#initialize(message = "Working", type: :dots, color: :cyan) ⇒ Spinner

Returns a new instance of Spinner.



28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/supermicro/spinner.rb', line 28

def initialize(message = "Working", type: :dots, color: :cyan)
  @message = message
  @type = type
  @color = color
  @running = false
  @thread = nil
  @current_frame = 0
  @spinner_config = SPINNERS[@type] || SPINNERS[:dots]
  @start_time = nil
  @last_update = nil
  @max_width = 0  # Track the maximum width we've printed
end

Instance Method Details

#startObject



41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/supermicro/spinner.rb', line 41

def start
  return if @running
  @running = true
  @start_time = Time.now
  @current_frame = 0
  
  @thread = Thread.new do
    while @running
      render
      sleep @spinner_config[:interval]
      @current_frame = (@current_frame + 1) % @spinner_config[:frames].length
    end
  end
end

#stop(final_message = nil, success: true) ⇒ Object



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/supermicro/spinner.rb', line 63

def stop(final_message = nil, success: true)
  return unless @running
  @running = false
  @thread&.join
  
  # Clear the spinner line completely
  print "\r\033[2K"
  
  if final_message
    icon = success ? "".green : "".red
    elapsed = Time.now - @start_time
    time_str = elapsed > 1 ? " (#{elapsed.round(1)}s)" : ""
    puts "#{icon} #{final_message}#{time_str}"
  end
end

#update(message) ⇒ Object



56
57
58
59
60
61
# File 'lib/supermicro/spinner.rb', line 56

def update(message)
  @message = message
  @last_update = Time.now
  # Immediately render to show the update
  render if @running
end

#with_spinnerObject



79
80
81
82
83
84
85
86
# File 'lib/supermicro/spinner.rb', line 79

def with_spinner
  start
  begin
    yield self
  ensure
    stop
  end
end