ektoplayer 0.1.16 → 0.1.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1567475105c5b1d0e3a099a4324ca19cdd67efe8
4
- data.tar.gz: e48caa107e5f934866a720023a5cb86fbb9153a9
3
+ metadata.gz: 5e5ff8d4fa934d30ecd7374ab072cc6a4fe76fdc
4
+ data.tar.gz: 598356fac5e4260e419a967afb96d960c29f05d9
5
5
  SHA512:
6
- metadata.gz: f5b706485a36e6398a981314c93f244ad4c85e35afbe55cce4e2d211752059abd3cfe743316d5edc85011f01002ecf35b5895e0aab54551bff565e407b1e7db0
7
- data.tar.gz: 12636fee134acc3f234ddbb6f7637e6a2ca0186998d76929820eb1f5a36c347ed5ec6c86aab8f128be13cf7240b9d01ad8e68c68b3dd15ac8347c783cb765ead
6
+ metadata.gz: 8deb97e80245b3dcbb3fcdf9847b213781ed7148b10a55ea1e89cbe931bfbc0c2087adc03d21fc42f3d3797bd15efa0c6cc379a02f82a7bdaaa55a7f4ed66f5d
7
+ data.tar.gz: 96dec00f1913908bca31b7917889f298caf3480a224e006b93f55d6648e78848de26870a5539ac9e84bd55b711b287d88fd8f16171478e743de40baf84a4d371
@@ -10,7 +10,7 @@ require 'date'
10
10
 
11
11
  module Ektoplayer
12
12
  class Application
13
- VERSION = '0.1.16'.freeze
13
+ VERSION = '0.1.17'.freeze
14
14
  GITHUB_URL = 'https://github.com/braph/ektoplayer'.freeze
15
15
  EKTOPLAZM_URL = 'http://www.ektoplazm.com'.freeze
16
16
 
@@ -186,7 +186,10 @@ module Ektoplayer
186
186
  end
187
187
 
188
188
  if (n = Config[:playlist_load_newest]) > 0
189
- r = client.database.select(order_by: 'date desc,album,number', limit: n)
189
+ r = client.database.select(
190
+ order_by: 'date DESC,album,number',
191
+ limit: n
192
+ )
190
193
  playlist.add(*r)
191
194
  end
192
195
 
@@ -3,6 +3,12 @@ require_relative 'events'
3
3
 
4
4
  module Ektoplayer
5
5
  class Database
6
+ SELECT_DESCRIPTION = %q[
7
+ SELECT description
8
+ FROM albums
9
+ WHERE url = ?
10
+ ].squeeze(' ').freeze
11
+
6
12
  SELECT_ARCHIVES = %q[
7
13
  SELECT archive_url, archive_type
8
14
  FROM archive_urls
@@ -141,7 +147,7 @@ module Ektoplayer
141
147
  end
142
148
 
143
149
  def select(
144
- columns: ?*,
150
+ columns: 'number,artist,album,title,styles,date,year,rating,votes,download_count,bpm,album_url,url',
145
151
  filters: [],
146
152
  group_by: 'url',
147
153
  order_by: 'album,number',
@@ -187,6 +193,10 @@ module Ektoplayer
187
193
  execute(SELECT_ARCHIVES, [url])
188
194
  end
189
195
 
196
+ def get_description(album_url)
197
+ @db.get_first_value(SELECT_DESCRIPTION, [album_url])
198
+ end
199
+
190
200
  def track_count
191
201
  @db.get_first_value('SELECT COUNT(*) FROM tracks')
192
202
  end
@@ -39,7 +39,7 @@ module Ncurses
39
39
  end
40
40
 
41
41
  if $USING_CURSES == 'ncurses'
42
- ### FIX: 'attrset' in ncurses is broken!
42
+ ### FIX: 'attrset' in ncurses seems broken?
43
43
  def attrset(attributes)
44
44
  Ncurses.send(:wattr_get, @w, old_a=[], old_c=[], nil)
45
45
  Ncurses.send(:wattroff, @w, old_a[0] | old_c[0])
@@ -62,6 +62,11 @@ module ICurses
62
62
  def initscr; end # do nothing
63
63
  module_function :initscr
64
64
 
65
+ def stdscr
66
+ ICurses::IWindow.new Ncurses.stdscr
67
+ end
68
+ module_function :stdscr
69
+
65
70
  def newwin(*a)
66
71
  ICurses::IWindow.new( Ncurses.newwin(*a) )
67
72
  end
@@ -2,7 +2,8 @@ module ICurses
2
2
  class IMouseEvent
3
3
  attr_accessor :x, :y, :z, :bstate
4
4
 
5
- def initialize(mouse_event=nil)
5
+ def initialize(mouse_event=nil, bstate: 0, x: 0, y: 0, z: 0)
6
+ @x, @y, @z, @bstate = x, y, z, bstate
6
7
  from_mouse_event!(mouse_event)
7
8
  end
8
9
 
@@ -12,16 +13,16 @@ module ICurses
12
13
  def from_mouse_event!(m)
13
14
  @x, @y, @z, @bstate = m.x, m.y, m.z, m.bstate
14
15
  rescue
15
- @x, @y, @z, @bstate = m[:x], m[:y], m[:z], m[:bstate]
16
- rescue
17
- @x= @y= @z= @bstate = 0
16
+ begin @x, @y, @z, @bstate = m[:x], m[:y], m[:z], m[:bstate]
17
+ rescue
18
+ end
18
19
  end
19
20
 
20
21
  def update!(x: nil, y: nil, z: nil, bstate: nil)
21
22
  @x = x if x
22
23
  @y = y if y
23
24
  @z = z if z
24
- @bstate = (bstate or @bstate)
25
+ @bstate = bstate if bstate
25
26
  end
26
27
  end
27
28
  end
@@ -36,7 +37,6 @@ module ICurses
36
37
  method_missing(meth_up, *args)
37
38
  end
38
39
  )
39
-
40
40
  module_function(meth)
41
41
  elsif not respond_to? meth_up
42
42
  alias_method(meth_up, meth) rescue (
@@ -120,9 +120,7 @@ module Ektoplayer
120
120
  end
121
121
 
122
122
  def tracks(index)
123
- @database.select(
124
- order_by: 'album,' + CONTENTS[index].to_s + ",album,number"
125
- )
123
+ @database.select(order_by: 'album,' + CONTENTS[index].to_s + ',album,number')
126
124
  end
127
125
  end
128
126
  end
@@ -21,6 +21,10 @@ module Ektoplayer
21
21
 
22
22
  def track_count; @client.database.track_count end
23
23
  def album_count; @client.database.album_count end
24
+
25
+ def get_description(*a)
26
+ @client.database.get_description(*a)
27
+ end
24
28
 
25
29
  def updating?
26
30
  @update_thread and @update_thread.alive?
@@ -133,7 +133,7 @@ class MpgWrapperPlayer
133
133
  Thread.new do
134
134
  begin
135
135
  @mpg123_in, @mpg123_out, mpg123_err, @mpg123_thread =
136
- Open3.popen3('mpg123', '-o', 'jack,pulse,alsa,oss', '--fuzzy', '-b', '1024', '-R')
136
+ Open3.popen3('mpg123', '-o', 'alsa,jack,pulse,oss', '--fuzzy', '-R')
137
137
 
138
138
  while (line = @mpg123_out.readline)
139
139
  cmd, line = line.split(' ', 2)
@@ -0,0 +1,42 @@
1
+ require_relative '../icurses'
2
+
3
+ module UI
4
+ class EscapeSequenceTranslator
5
+ KEYS = {
6
+ ?\r => ICurses::KEY_ENTER,
7
+ ?\r.ord => ICurses::KEY_ENTER
8
+ }
9
+
10
+ def self.reg(key, fallback, curses_key)
11
+ code = `tput #{key} 2>/dev/null` rescue ''
12
+ code = fallback if code.empty?
13
+ KEYS[code] = curses_key if not code.empty?
14
+ end
15
+
16
+ self.reg('kcuu1', "\033[A", ICurses::KEY_UP)
17
+ self.reg('kcud1', "\033[B", ICurses::KEY_DOWN)
18
+ self.reg('kcuf1', "\033[C", ICurses::KEY_RIGHT)
19
+ self.reg('kcub1', "\033[D", ICurses::KEY_LEFT)
20
+ self.reg('khome', "\033[1~", ICurses::KEY_HOME)
21
+ self.reg('kich1', "\033[2~", ICurses::KEY_IC)
22
+ self.reg('kdch1', "\033[3~", ICurses::KEY_DC)
23
+ self.reg('kend', "\033[4~", ICurses::KEY_END)
24
+ self.reg('kpp', "\033[5~", ICurses::KEY_PPAGE)
25
+ self.reg('knp', "\033[6~", ICurses::KEY_NPAGE)
26
+ (0..60).each { |i| self.reg("kf#{i}", '', ICurses.const_get("KEY_F#{i}")) }
27
+
28
+ KEYS.freeze
29
+
30
+ def self.to_curses(key)
31
+ if KEYS.include? key
32
+ KEYS[key]
33
+ elsif key.is_a? Integer
34
+ key
35
+ elsif ((key.is_a? String or key.is_a? Array) and key[0] == 27.chr and key[1] == ?[ and key[2] == ?M)
36
+ ICurses::IMouseEvent.new(bstate: ICurses::BUTTON1_CLICKED, x: key[4].ord - 33, y: key[5].ord - 33)
37
+ elsif key.size == 1
38
+ key.ord rescue nil
39
+ end
40
+ end
41
+ end
42
+ end
@@ -191,7 +191,7 @@ module UI
191
191
 
192
192
  write_at(old_cursor); render(old_selected)
193
193
  write_at(new_cursor); render(@selected, selected: true)
194
- _check
194
+ #_check
195
195
  want_refresh
196
196
  elsif (new_cursor.between?(-(@size.height - 1), (2 * @size.height - 1)))
197
197
  # new selected item is max a half screen size away
@@ -206,7 +206,7 @@ module UI
206
206
 
207
207
  @win.insert_top; render(@selected, selected: true)
208
208
  @cursor = 0
209
- _check
209
+ #_check
210
210
  else
211
211
  if lines_before_cursor > (@selected - old_selected)
212
212
  write_at(old_cursor); render(old_selected)
@@ -218,14 +218,14 @@ module UI
218
218
 
219
219
  @win.append_bottom; render(@selected, selected: true)
220
220
  @cursor = cursor_max
221
- _check
221
+ #_check
222
222
  end
223
223
 
224
224
  want_refresh
225
225
  else
226
226
  #@selected = new_index
227
227
  @cursor = new_index.clamp(0, cursor_max) # todo new_index<>new_cursor? ne muess scho pasn
228
- _check
228
+ #_check
229
229
  want_redraw
230
230
  end
231
231
 
@@ -242,7 +242,7 @@ module UI
242
242
  with_lock do
243
243
  old_cursor, @cursor = @cursor, new_cursor
244
244
  old_selected, @selected = @selected, (@selected - (old_cursor - @cursor)).clamp(0, index_last)
245
- _check
245
+ #_check
246
246
 
247
247
  if @selection.started?
248
248
  want_redraw
@@ -290,12 +290,12 @@ module UI
290
290
 
291
291
  write_at(@cursor); render(@selected, selected: true)
292
292
 
293
- _check
293
+ #_check
294
294
  want_refresh
295
295
  else
296
296
  @selected -= n # TODO: move up?
297
297
  force_cursorpos(@cursor)
298
- _check # todo: move up
298
+ #_check # todo: move up
299
299
  want_redraw
300
300
  end
301
301
 
@@ -310,7 +310,7 @@ module UI
310
310
 
311
311
  if index_bottom == index_last
312
312
  select_from_cursorpos((@cursor + n).clamp(0, cursor_max))
313
- _check
313
+ #_check
314
314
  elsif n < @size.height
315
315
  old_index_bottom = index_bottom
316
316
  old_selected, @selected = @selected, @selected + n
@@ -325,24 +325,24 @@ module UI
325
325
 
326
326
  write_at(@cursor); render(@selected, selected: true)
327
327
 
328
- _check
328
+ #_check
329
329
  want_refresh
330
330
  else
331
331
  @selected += n
332
332
  force_cursorpos(@cursor)
333
- _check
333
+ #_check
334
334
  want_redraw
335
335
  end
336
336
 
337
337
  self.unlock
338
- _check
338
+ #_check
339
339
  end
340
340
 
341
341
  def draw
342
342
  @win.erase
343
343
  return if @list.empty?
344
344
  @selected = @selected.clamp(0, index_last)
345
- _check
345
+ #_check
346
346
 
347
347
  @cursor.times do |i|
348
348
  unless row = @list[@selected - (@cursor - i)]
@@ -353,7 +353,7 @@ module UI
353
353
  write_at(i); render(@selected - (@cursor - i))
354
354
  end
355
355
 
356
- _check
356
+ #_check
357
357
  write_at(@cursor); render(@selected, selected: true)
358
358
 
359
359
  (@cursor + 1).upto(@size.height - 1).each_with_index do |c, i|
@@ -361,7 +361,7 @@ module UI
361
361
  write_at(c); render(@selected + i + 1)
362
362
  end
363
363
 
364
- _check
364
+ #_check
365
365
  end
366
366
 
367
367
  def on_mouse_click(mevent, mevent_transformed)
@@ -373,7 +373,7 @@ module UI
373
373
 
374
374
  protected
375
375
 
376
- def write_at(pos) @win.line_start(pos).clrtoeol end
376
+ def write_at(pos) @win.move(pos, 0) end
377
377
 
378
378
  def index_first; 0 end
379
379
  def index_last; [@list.size, 1].max - 1 end
@@ -48,7 +48,7 @@ module UI
48
48
  layout;
49
49
  @want ^= WANT_LAYOUT
50
50
  end
51
- return if not visible?
51
+ return if not visible?
52
52
 
53
53
  if @want & WANT_REDRAW > 0
54
54
  draw
@@ -66,7 +66,7 @@ module UI
66
66
  layout;
67
67
  @want ^= WANT_LAYOUT
68
68
  end
69
- return if not visible?
69
+ return if not visible?
70
70
 
71
71
  if @want & WANT_REDRAW > 0 or force_redraw
72
72
  draw
@@ -120,7 +120,7 @@ module UI
120
120
  def mouse_click(mevent)
121
121
  if new_event = mouse_event_transform(mevent)
122
122
  trigger(@mouse, new_event)
123
- trigger(@mouse_event, new_event)
123
+ trigger(@mouse_section, new_event)
124
124
  end
125
125
  end
126
126
 
data/lib/ektoplayer/ui.rb CHANGED
@@ -1,35 +1,24 @@
1
- require_relative 'icurses'
2
1
  require 'readline'
3
2
  require 'io/console'
4
3
 
4
+ require_relative 'icurses'
5
5
  require_relative 'ui/colors'
6
+ require_relative 'ui/escapesequencetranslator'
6
7
  require_relative 'events'
7
8
 
8
9
  module UI
9
10
  class WidgetSizeError < Exception; end
10
11
 
11
12
  class Canvas
12
- extend ICurses
13
-
14
- def self.size
15
- UI::Size.new(height: ICurses.lines, width: ICurses.cols)
16
- end
17
-
18
- def self.cursor
19
- #UI::Point.new(y: ICurses.cury, x: ICurses.curx)
20
- end
21
-
22
- def self.pos
23
- UI::Point.new
24
- end
25
-
26
13
  def self.start
27
14
  @@widget = nil
15
+ @@want_resize = false
16
+ @@updating = Mutex.new
28
17
 
29
18
  %w(initscr cbreak noecho start_color use_default_colors).
30
19
  each(&ICurses.method(:send))
31
20
  ICurses.mousemask(ICurses::ALL_MOUSE_EVENTS | ICurses::REPORT_MOUSE_POSITION)
32
- ICurses.stdscr.keypad(true)
21
+ ICurses.stdscr.getch1(1) # first getch() clears screen?
33
22
  UI::Colors.start
34
23
 
35
24
  self.enable_resize_detection
@@ -39,21 +28,19 @@ module UI
39
28
  Signal.trap('WINCH') { @@want_resize = true }
40
29
  end
41
30
 
42
- def self.widget; @@widget end
43
- def self.widget=(w) @@widget = w end
44
- def self.stop; ICurses.endwin end
45
- def self.visible?; true end
46
- def self.inivsibile?; false end
31
+ def self.widget; @@widget end
32
+ def self.widget=(w) @@widget = w end
33
+ def self.stop; ICurses.endwin end
47
34
 
48
35
  def self.sub(cls, **opts)
49
- @@widget ||= (widget = cls.new(parent: self, **opts))
36
+ opts[:size] ||= UI::Size.new(height: ICurses.lines, width: ICurses.cols)
37
+ opts[:pos] ||= UI::Point.new
38
+ widget = cls.new(**opts)
39
+ @@widget ||= widget
50
40
  widget
51
41
  end
52
42
 
53
43
  def self.update_screen(force_redraw=false, force_resize=false)
54
- @@updating ||= Mutex.new
55
- @@want_resize ||= false
56
-
57
44
  if @@updating.try_lock
58
45
  begin
59
46
  if @@want_resize or force_resize
@@ -78,7 +65,7 @@ module UI
78
65
 
79
66
  def self.run
80
67
  self.start
81
- return yield
68
+ yield
82
69
  ensure
83
70
  self.stop
84
71
  end
@@ -87,51 +74,56 @@ module UI
87
74
  class Input
88
75
  KEYMAP_WORKAROUND = {
89
76
  13 => ICurses::KEY_ENTER,
90
- 127 => ICurses::KEY_BACKSPACE
77
+ 127 => ICurses::KEY_BACKSPACE,
91
78
  }
92
79
  KEYMAP_WORKAROUND.default_proc = proc { |h,k| k }
93
80
  KEYMAP_WORKAROUND.freeze
94
81
 
95
82
  def self.start_loop
96
83
  @@readline_obj ||= ReadlineWindow.new
97
- inactive = 0
98
84
 
99
85
  loop do
100
86
  unless @@readline_obj.active?
87
+ ICurses.stdscr.keypad(true)
101
88
  ICurses.curs_set(0)
102
89
  ICurses.nonl
103
90
 
104
- begin
105
- UI::Canvas.widget.win.keypad(true)
91
+ until @@readline_obj.active?
92
+ c = EscapeSequenceTranslator.to_curses(s = STDIN.readpartial(10))
93
+ #Ektoplayer::Application.log(self, s)
106
94
 
107
- if (c = (UI::Canvas.widget.win.getch1(500).ord rescue -1)) > -1
108
- inactive = 0
95
+ if c.is_a? ICurses::IMouseEvent
96
+ UI::Canvas.widget.mouse_click(c)
97
+ elsif c
98
+ UI::Canvas.widget.key_press(c)
99
+ end
109
100
 
110
- if c == ICurses::KEY_MOUSE
111
- if c = ICurses.getmouse
112
- UI::Canvas.widget.mouse_click(c)
101
+ inactivity_count = 0
102
+ until @@readline_obj.active? or inactivity_count > 10
103
+ if (c = (ICurses.stdscr.getch1(1000).ord rescue -1)) > -1
104
+ inactivity_count = 0
105
+
106
+ if c == ICurses::KEY_MOUSE
107
+ if (c = ICurses.getmouse)
108
+ UI::Canvas.widget.mouse_click(c)
109
+ end
110
+ else
111
+ UI::Canvas.widget.key_press(KEYMAP_WORKAROUND[c])
113
112
  end
114
113
  else
115
- UI::Canvas.widget.key_press(KEYMAP_WORKAROUND[c])
116
- end
117
- else
118
- if (inactive += 1) > 40
119
- s = STDIN.readpartial(10)
120
- ICurses.ungetch(s[0].ord) if s.size == 1
114
+ inactivity_count += 1
115
+ GC.start
121
116
  end
122
117
  end
123
-
124
- ICurses.doupdate
125
- end while !@@readline_obj.active?
118
+ end
126
119
  else
120
+ ICurses.stdscr.keypad(false)
127
121
  ICurses.curs_set(1)
128
122
  ICurses.nl
129
123
 
130
124
  begin
131
- win = UI::Canvas.widget.win
132
- win.keypad(false)
133
125
  @@readline_obj.redraw
134
- next unless (c = (win.getch1(100).ord rescue -1)) > -1
126
+ next unless (c = (ICurses.stdscr.getch1(100).ord rescue -1)) > -1
135
127
 
136
128
  if c == 10 or c == 4
137
129
  @@readline_obj.feed(?\n.ord)
@@ -139,10 +131,10 @@ module UI
139
131
  @@readline_obj.feed(c)
140
132
 
141
133
  if c == 27 # pass 3-character escape sequence
142
- win.timeout(5)
143
- if (c = (win.getch.ord rescue -1)) > -1
134
+ ICurses.stdscr.timeout(5)
135
+ if (c = (ICurses.stdscr.getch.ord rescue -1)) > -1
144
136
  @@readline_obj.feed(c)
145
- if (c = (win.getch.ord rescue -1)) > -1
137
+ if (c = (ICurses.stdscr.getch.ord rescue -1)) > -1
146
138
  @@readline_obj.feed(c)
147
139
  end
148
140
  end
@@ -168,7 +160,7 @@ module UI
168
160
  @thread = nil
169
161
  end
170
162
 
171
- def active?; @thread; end
163
+ def active?; !@thread.nil? end
172
164
 
173
165
  def redraw
174
166
  @window.resize(@size.height, @size.width)
@@ -245,8 +237,8 @@ module UI
245
237
  Size.new(width: (width or @width), height: (height or @height))
246
238
  end
247
239
 
248
- def calc(height: 0, width: 0)
249
- Size.new(height: @height + height, width: @width + width)
240
+ def calc(width: 0, height: 0)
241
+ Size.new(width: @width + width, height: @height + height)
250
242
  end
251
243
 
252
244
  def ==(s) s.height == @height and s.width == @width end
@@ -300,7 +292,6 @@ module ICurses
300
292
  class IWindow
301
293
  alias :height :maxy
302
294
  alias :width :maxx
303
- alias :clear_line :clrtoeol
304
295
 
305
296
  def cursor; UI::Point.new(y: cury, x: curx) end
306
297
  def pos; UI::Point.new(y: begy, x: begx) end
@@ -331,7 +322,6 @@ module ICurses
331
322
  def on_column(n) move(cury, n) ;self;end
332
323
  def next_line; move(cury + 1, 0) ;self;end
333
324
  def mv_left(n) move(cury, curx - 1) ;self;end
334
- def line_start(l=0) move(l, 0) ;self;end
335
325
  def from_left(size) move(cury, size) ;self;end
336
326
  def from_right(size) move(cury, (maxx - size)) ;self;end
337
327
  def center(size) move(cury, (maxx / 2) - (size / 2)) ;self;end
@@ -363,11 +353,7 @@ module ICurses
363
353
  end
364
354
 
365
355
  def to_s
366
- name = ICurses.constants.
367
- select { |c| c =~ /^BUTTON_/ }.
368
- select { |c| ICurses.const_get(c) & @bstate > 0 }[0]
369
- name ||= @button
370
- "[(IMouseEvent) button=#{name}, x=#{x}, y=#{y}, z=#{z}]"
356
+ "[(IMouseEvent) bstate=#{bstate}, x=#{x}, y=#{y}, z=#{z}]"
371
357
  end
372
358
  end
373
359
  end
@@ -111,11 +111,12 @@ module Ektoplayer
111
111
 
112
112
  # -- description
113
113
  draw_heading('Description')
114
+ description = @database.get_description(@track['album_url'])
114
115
  line_length = START_TAG
115
116
  wrap_length = @size.width.clamp(1, LINE_WRAP)
116
117
  @win.move(@win.cury + 1, START_TAG)
117
118
 
118
- Nokogiri::HTML("<p>#{@track['description']}</p>").css(?p).each do |p|
119
+ Nokogiri::HTML("<p>#{description}</p>").css(?p).each do |p|
119
120
  p.children.each do |element|
120
121
  if element['href']
121
122
  if (line_length += element.text.size) > wrap_length
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ektoplayer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.16
4
+ version: 0.1.17
5
5
  platform: ruby
6
6
  authors:
7
7
  - Benjamin Abendroth
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-03-31 00:00:00.000000000 Z
11
+ date: 2017-04-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sqlite3
@@ -91,6 +91,7 @@ files:
91
91
  - lib/ektoplayer/trackloader.rb
92
92
  - lib/ektoplayer/ui.rb
93
93
  - lib/ektoplayer/ui/colors.rb
94
+ - lib/ektoplayer/ui/escapesequencetranslator.rb
94
95
  - lib/ektoplayer/ui/widgets.rb
95
96
  - lib/ektoplayer/ui/widgets/container.rb
96
97
  - lib/ektoplayer/ui/widgets/labelwidget.rb