twterm 1.0.10 → 1.0.11

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: 8d067153f4c632aeba6108ea07201aff1db4790c
4
- data.tar.gz: d6ddac0119221c40646bae8bd53bf19081ddab1b
3
+ metadata.gz: 2572d3668fe0048eb79fa55c0b881a39fe130c7a
4
+ data.tar.gz: 8fc15104af2e69ee71861a1e903a056f3dda1f57
5
5
  SHA512:
6
- metadata.gz: dcd02ff35df547ca1383dfe70ac5a097c4ca0d91448ec0a79a4557084a84a14b24961c190697d30f428b1053db710fcd4030fcb9350a0a12111dd1c6eeec0dba
7
- data.tar.gz: d37de57e07ad39327df4864b961a141e146a00d6956f43391c2e9cf4843e5d4d80a78d4666204edfeb32c4fbc7dd0ab73692a6e847a3d060bb4a57271629848c
6
+ metadata.gz: c7f0770b2c858fee53746e64ee194218b565ff16d88d06fd336b5c3ad304716df9dc57e5a8fbd1f8eba5b377ba9ada1d97aaf580f9d68355090924de4a595451
7
+ data.tar.gz: 7ed7a151ce86516110461ea3426e742f271713d6b87038d5c331c78d4f06ed8995ed39b98d96257a2aab5d1eaff99e54ff3a106ff76699002df426ac8594519a
data/lib/twterm.rb CHANGED
@@ -20,6 +20,7 @@ require 'twterm/color_manager'
20
20
  require 'twterm/completion_mamanger'
21
21
  require 'twterm/config'
22
22
  require 'twterm/extensions/curses/window'
23
+ require 'twterm/extensions/enumerator/lazy'
23
24
  require 'twterm/extensions/integer'
24
25
  require 'twterm/extensions/string'
25
26
  require 'twterm/history/base'
@@ -37,7 +38,7 @@ require 'twterm/tab_manager'
37
38
  require 'twterm/tab/base'
38
39
  require 'twterm/tab/dumpable'
39
40
  require 'twterm/tab/exceptions'
40
- require 'twterm/tab/scroll_manager'
41
+ require 'twterm/tab/scrollable'
41
42
  require 'twterm/tab/statuses_tab'
42
43
  require 'twterm/tab/conversation_tab'
43
44
  require 'twterm/tab/key_assignments_cheatsheet'
@@ -57,6 +58,6 @@ require 'twterm/version'
57
58
 
58
59
  module Twterm
59
60
  class Conf
60
- REQUIRE_VERSION = '1.0.10'
61
+ REQUIRE_VERSION = '1.0.11'
61
62
  end
62
63
  end
data/lib/twterm/client.rb CHANGED
@@ -175,6 +175,12 @@ module Twterm
175
175
  end
176
176
  end
177
177
 
178
+ def saved_search
179
+ send_request do
180
+ yield rest_client.saved_searches
181
+ end
182
+ end
183
+
178
184
  def search(query)
179
185
  send_request do
180
186
  statuses = rest_client
@@ -0,0 +1,12 @@
1
+ class Enumerator
2
+ class Lazy
3
+ def scan(initial, sym = nil)
4
+ acc = initial
5
+
6
+ Enumerator::Lazy.new(self) do |y, x|
7
+ acc = sym.nil? ? yield(acc, x) : sym.to_proc.call(acc, x)
8
+ y << acc
9
+ end
10
+ end
11
+ end
12
+ end
@@ -39,7 +39,7 @@ module Twterm
39
39
  @status = status
40
40
 
41
41
  append(status)
42
- scroll_manager.move_to_top
42
+ scroller.move_to_top
43
43
  Thread.new { fetch_in_reply_to_status(status) }
44
44
  Thread.new { fetch_replies(status) }
45
45
  end
@@ -2,6 +2,7 @@ module Twterm
2
2
  module Tab
3
3
  class KeyAssignmentsCheatsheet
4
4
  include Base
5
+ include Scrollable
5
6
 
6
7
  def ==(other)
7
8
  other.is_a?(self.class)
@@ -38,20 +39,29 @@ module Twterm
38
39
  }
39
40
  }
40
41
 
42
+ def drawable_item_count
43
+ window.maxy - 3
44
+ end
45
+
46
+ def initialize
47
+ super
48
+ scroller.set_cursor_free!
49
+ end
50
+
41
51
  def respond_to_key(key)
42
52
  case key
43
53
  when ?d, 4
44
- 10.times { scroll_manager.move_down }
54
+ 10.times { scroller.move_down }
45
55
  when ?g
46
- scroll_manager.move_to_top
56
+ scroller.move_to_top
47
57
  when ?G
48
- scroll_manager.move_to_bottom
58
+ scroller.move_to_bottom
49
59
  when ?j, 14, Curses::Key::DOWN
50
- scroll_manager.move_down
60
+ scroller.move_down
51
61
  when ?k, 16, Curses::Key::UP
52
- scroll_manager.move_up
62
+ scroller.move_up
53
63
  when ?u, 21
54
- 10.times { scroll_manager.move_up }
64
+ 10.times { scroller.move_up }
55
65
  else
56
66
  return false
57
67
  end
@@ -63,51 +73,34 @@ module Twterm
63
73
  'Key assignments'.freeze
64
74
  end
65
75
 
66
- def update
67
- top = 2 # begin drawing from line 2
68
- draw_cond = -> line { top <= line && line <= window.maxy - top }
76
+ def total_item_count
77
+ @count ||= SHORTCUTS.count * 4 + SHORTCUTS.values.map(&:count).reduce(0, :+) + 1
78
+ end
69
79
 
70
- current_line = top - scroll_manager.offset
80
+ def update
81
+ offset = scroller.offset
82
+ line = 0
71
83
 
72
- window.setpos(current_line, 3)
73
- window.bold { window.addstr('Key assignments') } if draw_cond[current_line]
84
+ window.setpos(line - offset + 2, 3)
85
+ window.bold { window.addstr('Key assignments') } if scroller.nth_item_drawable?(line)
74
86
 
75
87
  SHORTCUTS.each do |category, shortcuts|
76
- current_line += 3
77
- window.setpos(current_line, 5)
78
- window.bold { window.addstr("<#{category}>") } if draw_cond[current_line]
79
- current_line += 1
88
+ line += 3
89
+ window.setpos(line - offset + 2, 5)
90
+ window.bold { window.addstr("<#{category}>") } if scroller.nth_item_drawable?(line)
91
+ line += 1
80
92
 
81
93
  shortcuts.each do |key, description|
82
- current_line += 1
83
- next unless draw_cond[current_line]
94
+ line += 1
95
+ next unless scroller.nth_item_drawable?(line)
84
96
 
85
- window.setpos(current_line, 7)
97
+ window.setpos(line - offset + 2, 7)
86
98
  window.bold { window.addstr(key.rjust(17)) }
87
- window.setpos(current_line, 25)
99
+ window.setpos(line - offset + 2, 25)
88
100
  window.addstr(": #{description}")
89
101
  end
90
102
  end
91
103
  end
92
-
93
- private
94
-
95
- def count
96
- @count ||= SHORTCUTS.count * 4 + SHORTCUTS.map(&:count).reduce(0, :+) + 1
97
- end
98
-
99
- def offset_from_bottom
100
- 0
101
- end
102
-
103
- def scroll_manager
104
- return @scroll_manager unless @scroll_manager.nil?
105
-
106
- @scroll_manager = ScrollManager.new
107
- @scroll_manager.delegate = self
108
- @scroll_manager.after_move { refresh }
109
- @scroll_manager
110
- end
111
104
  end
112
105
  end
113
106
  end
@@ -13,7 +13,7 @@ module Twterm
13
13
  @list = list
14
14
  @title = @list.full_name
15
15
  TabManager.instance.refresh_window
16
- fetch { scroll_manager.move_to_top }
16
+ fetch { scroller.move_to_top }
17
17
  @auto_reloader = Scheduler.new(300) { fetch }
18
18
  end
19
19
  end
@@ -28,7 +28,7 @@ module Twterm
28
28
 
29
29
  @title = 'Mentions'
30
30
 
31
- fetch { scroll_manager.move_to_top }
31
+ fetch { scroller.move_to_top }
32
32
  @auto_reloader = Scheduler.new(300) { fetch }
33
33
  end
34
34
  end
@@ -3,6 +3,7 @@ module Twterm
3
3
  module New
4
4
  class List
5
5
  include Base
6
+ include Scrollable
6
7
 
7
8
  @@lists = nil
8
9
 
@@ -10,6 +11,10 @@ module Twterm
10
11
  other.is_a?(self.class)
11
12
  end
12
13
 
14
+ def drawable_item_count
15
+ (window.maxy - 2).div(3)
16
+ end
17
+
13
18
  def initialize
14
19
  super
15
20
 
@@ -17,50 +22,52 @@ module Twterm
17
22
  refresh
18
23
  end
19
24
 
25
+ def items
26
+ @@lists
27
+ end
28
+
20
29
  def respond_to_key(key)
21
30
  case key
22
31
  when ?g
23
- scroll_manager.move_to_top
32
+ scroller.move_to_top
24
33
  when ?G
25
- scroll_manager.move_to_bottom
34
+ scroller.move_to_bottom
26
35
  when ?j, 14, Curses::Key::DOWN
27
- scroll_manager.move_down
36
+ scroller.move_down
28
37
  when 10
29
38
  return true if current_list.nil?
30
39
  list_tab = Tab::ListTab.new(current_list.id)
31
40
  TabManager.instance.switch(list_tab)
32
41
  when ?k, 16, Curses::Key::UP
33
- scroll_manager.move_up
42
+ scroller.move_up
34
43
  else
35
44
  return false
36
45
  end
37
46
  true
38
47
  end
39
48
 
40
- private
41
-
42
- def count
49
+ def total_item_count
43
50
  @@lists.nil? ? 0 : @@lists.count
44
51
  end
45
52
 
46
- def current_list
47
- @@lists.nil? ? nil : @@lists[scroll_manager.index]
48
- end
53
+ private
49
54
 
50
- def offset_from_bottom
51
- 0
55
+ def current_list
56
+ @@lists.nil? ? nil : @@lists[scroller.index]
52
57
  end
53
58
 
54
59
  def show_lists
55
60
  return if @@lists.nil?
56
61
 
57
- @@lists.each.with_index(0) do |list, i|
62
+ index, offset = scroller.index, scroller.offset
63
+
64
+ drawable_items.each.with_index(0) do |list, i|
58
65
  window.with_color(:black, :magenta) do
59
66
  window.setpos(i * 3 + 5, 4)
60
67
  window.addstr(' ')
61
68
  window.setpos(i * 3 + 6, 4)
62
69
  window.addstr(' ')
63
- end if i == scroll_manager.index
70
+ end if scroller.current_item?(i)
64
71
 
65
72
  window.setpos(i * 3 + 5, 6)
66
73
  window.addstr("#{list.full_name} (#{list.member_count} members / #{list.subscriber_count} subscribers)")
@@ -69,15 +76,6 @@ module Twterm
69
76
  end
70
77
  end
71
78
 
72
- def scroll_manager
73
- return @scroll_manager unless @scroll_manager.nil?
74
-
75
- @scroll_manager = ScrollManager.new
76
- @scroll_manager.delegate = self
77
- @scroll_manager.after_move { refresh }
78
- @scroll_manager
79
- end
80
-
81
79
  def update
82
80
  window.setpos(2, 3)
83
81
  window.bold { window.addstr('Open list tab') }
@@ -4,15 +4,24 @@ module Twterm
4
4
  class Search
5
5
  include Base
6
6
  include Readline
7
+ include Scrollable
8
+
9
+ @@queries = []
7
10
 
8
11
  def ==(other)
9
12
  other.is_a?(self.class)
10
13
  end
11
14
 
15
+ def drawable_item_count
16
+ (window.maxy - 2).div(3)
17
+ end
18
+
12
19
  def initialize
13
20
  super
14
21
 
15
22
  @title = 'New tab'
23
+
24
+ update_saved_search
16
25
  end
17
26
 
18
27
  def invoke_input
@@ -29,27 +38,96 @@ module Twterm
29
38
  query = (readline('> ') || '').strip
30
39
  resetter.call
31
40
 
32
- tab = query.nil? || query.empty? ? Tab::New::Start.new : Tab::SearchTab.new(query)
41
+ tab = query.nil? || query.empty? ? Tab::New::Search.new : Tab::SearchTab.new(query)
33
42
  TabManager.instance.switch(tab)
34
43
  end
35
44
 
36
45
  App.instance.register_interruption_handler do
37
46
  input_thread.kill
38
47
  resetter.call
39
- tab = Tab::New::Start.new
48
+ tab = Tab::New::Search.new
40
49
  TabManager.instance.switch(tab)
41
50
  end
42
51
 
43
52
  input_thread.join
44
53
  end
45
54
 
46
- def respond_to_key(_)
47
- false
55
+ def items
56
+ ['<Input search query>'] + @@queries
57
+ end
58
+
59
+ def respond_to_key(key)
60
+ case key
61
+ when ?d, 4
62
+ 10.times { scroller.move_down }
63
+ when ?g
64
+ scroller.move_to_top
65
+ when ?G
66
+ scroller.move_to_bottom
67
+ when 10
68
+ open_search_tab_with_current_query
69
+ when ?j, 14, Curses::Key::DOWN
70
+ scroller.move_down
71
+ when ?k, 16, Curses::Key::UP
72
+ scroller.move_up
73
+ when ?u, 21
74
+ 10.times { scroller.move_up }
75
+ else
76
+ return false
77
+ end
78
+
79
+ true
80
+ end
81
+
82
+ def total_item_count
83
+ @@queries.count + 1
48
84
  end
49
85
 
50
86
  private
51
87
 
52
- def update; end
88
+ alias_method :count, :total_item_count
89
+
90
+ def open_search_tab_with_current_query
91
+ index = scroller.index
92
+
93
+ if index == 0
94
+ invoke_input
95
+ else
96
+ query = @@queries[index - 1]
97
+ tab = Tab::SearchTab.new(query)
98
+ TabManager.instance.switch(tab)
99
+ end
100
+ end
101
+
102
+ def update
103
+ offset = scroller.offset
104
+
105
+ window.setpos(2, 3)
106
+ window.bold { window.addstr('Open search tab') }
107
+
108
+ drawable_items.each.with_index(0) do |query, i|
109
+ line = 3 * i + 5
110
+
111
+ window.with_color(:black, :magenta) do
112
+ window.setpos(line, 4)
113
+ window.addstr(' ')
114
+ window.setpos(line + 1, 4)
115
+ window.addstr(' ')
116
+ end if scroller.current_item?(i)
117
+
118
+ window.setpos(line, 6)
119
+ window.addstr(query)
120
+ end
121
+ end
122
+
123
+ def update_saved_search
124
+ return unless @@queries.empty?
125
+
126
+ Client.current.saved_search do |searches|
127
+ @@queries = searches.map(&:query)
128
+ refresh
129
+ end
130
+ end
53
131
  end
54
132
  end
55
133
  end
@@ -22,15 +22,10 @@ module Twterm
22
22
  when 'S'
23
23
  tab = Tab::New::Search.new
24
24
  TabManager.instance.switch(tab)
25
- tab.invoke_input
26
25
  when 'U'
27
26
  tab = Tab::New::User.new
28
27
  TabManager.instance.switch(tab)
29
28
  tab.invoke_input
30
- when 'x'
31
- tab = Tab::New::Track.new
32
- TabManager.instance.switch(tab)
33
- tab.invoke_input
34
29
  else
35
30
  return false
36
31
  end
@@ -0,0 +1,138 @@
1
+ module Twterm
2
+ module Tab
3
+ module Scrollable
4
+ extend Forwardable
5
+
6
+ attr_reader :scroller
7
+ def_delegators :scroller, :drawable_items
8
+
9
+ def scroller
10
+ return @scroller unless @scroller.nil?
11
+
12
+ @scroller = Scroller.new
13
+ @scroller.delegate = self
14
+ @scroller.after_move { refresh }
15
+ @scroller
16
+ end
17
+
18
+ private
19
+
20
+ class Scroller
21
+ extend Forwardable
22
+
23
+ attr_reader :index, :offset
24
+
25
+ attr_accessor :delegate
26
+ def_delegators :delegate, :items, :total_item_count, :drawable_item_count
27
+
28
+ def after_move(&block)
29
+ add_hook(:after_move, &block)
30
+ end
31
+
32
+ def current_item?(i)
33
+ index == offset + i
34
+ end
35
+
36
+ def cursor_free?
37
+ !!@cursor_free
38
+ end
39
+
40
+ def initialize
41
+ @index = 0
42
+ @offset = 0
43
+ @cursor_free_mode = false
44
+ end
45
+
46
+ def drawable_items
47
+ items.drop(offset).take(drawable_item_count)
48
+ end
49
+
50
+ def item_appended!
51
+ @index -= 1
52
+ @offset -= 1 if @offset > 0
53
+ end
54
+
55
+ def item_prepended!
56
+ @index += 1
57
+ @offset += 1
58
+ end
59
+
60
+ def move_down
61
+ return if count == 0 || index == count - 1
62
+ # return when there are no items or cursor is at the bottom
63
+
64
+ @index += 1
65
+ @offset += 1 if (cursor_free? || cursor_on_the_downside?) && !last_item_shown?
66
+
67
+ hook :after_move
68
+ end
69
+
70
+ def move_to_bottom
71
+ return if count == 0 || index == count - 1
72
+
73
+ @index = count - 1
74
+ @offset = [count - drawable_item_count + 1, 0].max
75
+
76
+ @offset += 1 until last_item_shown?
77
+
78
+ hook :after_move
79
+ end
80
+
81
+ def move_to_top
82
+ return if count.zero? || index.zero?
83
+
84
+ @index = 0
85
+ @offset = 0
86
+
87
+ hook :after_move
88
+ end
89
+
90
+ def move_up
91
+ return if count.zero? || index.zero?
92
+
93
+ @index -= 1
94
+ @offset -= 1 if cursor_on_the_upside? && !first_item_shown?
95
+
96
+ hook :after_move
97
+ end
98
+
99
+ def nth_item_drawable?(n)
100
+ n.between?(offset, offset + drawable_item_count)
101
+ end
102
+
103
+ def set_cursor_free!
104
+ @cursor_free = true
105
+ end
106
+
107
+ private
108
+
109
+ alias_method :count, :total_item_count
110
+
111
+ def add_hook(name, &block)
112
+ @hooks ||= {}
113
+ @hooks[name] = block
114
+ end
115
+
116
+ def cursor_on_the_downside?
117
+ drawable_item_count + offset - index < 4
118
+ end
119
+
120
+ def cursor_on_the_upside?
121
+ index - offset < 4
122
+ end
123
+
124
+ def first_item_shown?
125
+ offset.zero?
126
+ end
127
+
128
+ def last_item_shown?
129
+ total_item_count <= offset + drawable_item_count
130
+ end
131
+
132
+ def hook(name)
133
+ @hooks[name].call unless @hooks[name].nil?
134
+ end
135
+ end
136
+ end
137
+ end
138
+ end
@@ -32,7 +32,7 @@ module Twterm
32
32
  @query = query
33
33
  @title = "\"#{@query}\""
34
34
 
35
- fetch { scroll_manager.move_to_top }
35
+ fetch { scroller.move_to_top }
36
36
  @auto_reloader = Scheduler.new(300) { fetch }
37
37
  end
38
38
  end
@@ -2,6 +2,7 @@ module Twterm
2
2
  module Tab
3
3
  module StatusesTab
4
4
  include Base
5
+ include Scrollable
5
6
 
6
7
  def append(status)
7
8
  fail ArgumentError,
@@ -12,14 +13,10 @@ module Twterm
12
13
  @status_ids.unshift(status.id)
13
14
  status.split(window.maxx - 4)
14
15
  status.touch!
15
- scroll_manager.item_appended!
16
+ scroller.item_appended!
16
17
  refresh
17
18
  end
18
19
 
19
- def count
20
- grep_query.empty? ? @status_ids.count : statuses.count
21
- end
22
-
23
20
  def delete(status_id)
24
21
  @status_ids.delete(status_id)
25
22
  refresh
@@ -34,6 +31,14 @@ module Twterm
34
31
  end
35
32
  end
36
33
 
34
+ def drawable_item_count
35
+ statuses.reverse.drop(scroller.offset).lazy
36
+ .map { |s| s.split(window.maxx - 4).count + 2 }
37
+ .scan(0, :+)
38
+ .select { |l| l < window.maxy }
39
+ .count
40
+ end
41
+
37
42
  def favorite
38
43
  return if highlighted_status.nil?
39
44
 
@@ -56,26 +61,26 @@ module Twterm
56
61
 
57
62
  if grep_query.empty?
58
63
  reset_grep
59
- elsif count == 0
64
+ elsif total_item_count == 0
60
65
  Notifier.instance.show_error "No matches found: \"#{grep_query}\""
61
66
  reset_grep
62
67
  else
63
- Notifier.instance.show_message "#{count} statuses found: \"#{grep_query}\""
64
- scroll_manager.move_to_top
68
+ Notifier.instance.show_message "#{total_item_count} statuses found: \"#{grep_query}\""
69
+ scroller.move_to_top
65
70
  refresh
66
71
  end
67
72
  end
68
73
 
69
- def grep_query
70
- @grep_query || ''
71
- end
72
-
73
74
  def initialize
74
75
  super
75
76
 
76
77
  @status_ids = []
77
78
  end
78
79
 
80
+ def items
81
+ statuses.reverse
82
+ end
83
+
79
84
  def open_link
80
85
  return if highlighted_status.nil?
81
86
 
@@ -92,7 +97,7 @@ module Twterm
92
97
  @status_ids << status.id
93
98
  status.split(window.maxx - 4)
94
99
  status.touch!
95
- scroll_manager.item_prepended!
100
+ scroller.item_prepended!
96
101
  refresh
97
102
  end
98
103
 
@@ -115,19 +120,19 @@ module Twterm
115
120
  when ?c
116
121
  show_conversation
117
122
  when ?d, 4
118
- 10.times { scroll_manager.move_down }
123
+ 10.times { scroller.move_down }
119
124
  when ?D
120
125
  destroy_status
121
126
  when ?F
122
127
  favorite
123
128
  when ?g
124
- scroll_manager.move_to_top
129
+ scroller.move_to_top
125
130
  when ?G
126
- scroll_manager.move_to_bottom
131
+ scroller.move_to_bottom
127
132
  when ?j, 14, Curses::Key::DOWN
128
- scroll_manager.move_down
133
+ scroller.move_down
129
134
  when ?k, 16, Curses::Key::UP
130
- scroll_manager.move_up
135
+ scroller.move_up
131
136
  when ?o
132
137
  open_link
133
138
  when ?r
@@ -137,7 +142,7 @@ module Twterm
137
142
  when 18
138
143
  fetch
139
144
  when ?u, 21
140
- 10.times { scroll_manager.move_up }
145
+ 10.times { scroller.move_up }
141
146
  when ?U
142
147
  show_user
143
148
  when ?/
@@ -185,33 +190,23 @@ module Twterm
185
190
  statuses.reverse.take(100).each(&:touch!)
186
191
  end
187
192
 
188
- def update
189
- current_line = 0
190
-
191
- offset = scroll_manager.offset
192
- index = scroll_manager.index
193
+ def total_item_count
194
+ grep_query.empty? ? @status_ids.count : statuses.count
195
+ end
193
196
 
194
- return if offset < 0
197
+ def update
198
+ line = 0
195
199
 
196
- statuses.reverse.drop(offset).each.with_index(offset) do |status, i|
200
+ scroller.drawable_items.each.with_index(0) do |status, i|
197
201
  formatted_lines = status.split(window.maxx - 4).count
198
- if current_line + formatted_lines + 2 > window.maxy
199
- scroll_manager.last = i
200
- break
201
- end
202
-
203
- posy = current_line
204
-
205
- if index == i
206
- window.with_color(:black, :magenta) do
207
- (formatted_lines + 1).times do |j|
208
- window.setpos(posy + j, 0)
209
- window.addch(' ')
210
- end
202
+ window.with_color(:black, :magenta) do
203
+ (formatted_lines + 1).times do |j|
204
+ window.setpos(line + j, 0)
205
+ window.addch(' ')
211
206
  end
212
- end
207
+ end if scroller.current_item?(i)
213
208
 
214
- window.setpos(current_line, 2)
209
+ window.setpos(line, 2)
215
210
 
216
211
  window.bold do
217
212
  window.with_color(status.user.color) do
@@ -258,46 +253,24 @@ module Twterm
258
253
  window.addch(' ')
259
254
  end
260
255
 
261
- status.split(window.maxx - 4).each do |line|
262
- current_line += 1
263
- window.setpos(current_line, 2)
264
- window.addstr(line)
256
+ status.split(window.maxx - 4).each do |str|
257
+ line += 1
258
+ window.setpos(line, 2)
259
+ window.addstr(str)
265
260
  end
266
261
 
267
- current_line += 2
262
+ line += 2
268
263
  end
269
-
270
- UserWindow.instance.update(highlighted_status.user) unless highlighted_status.nil?
271
264
  end
272
265
 
273
266
  private
274
267
 
275
- def highlighted_status
276
- id = @status_ids[scroll_manager.count - scroll_manager.index - 1]
277
- Status.find(id)
278
- end
279
-
280
- def offset_from_bottom
281
- return @offset_from_bottom unless @offset_from_bottom.nil?
282
-
283
- height = 0
284
- statuses.each.with_index(-1) do |status, i|
285
- height += status.split(window.maxx - 4).count + 2
286
- if height >= window.maxy
287
- @offset_from_bottom = i
288
- return i
289
- end
290
- end
291
- count
268
+ def grep_query
269
+ @grep_query || ''
292
270
  end
293
271
 
294
- def scroll_manager
295
- return @scroll_manager unless @scroll_manager.nil?
296
-
297
- @scroll_manager = ScrollManager.new
298
- @scroll_manager.delegate = self
299
- @scroll_manager.after_move { refresh }
300
- @scroll_manager
272
+ def highlighted_status
273
+ statuses[scroller.count - scroller.index - 1]
301
274
  end
302
275
 
303
276
  def sort
@@ -23,7 +23,7 @@ module Twterm
23
23
  @client.on_timeline_status(&method(:prepend))
24
24
  @title = 'Timeline'
25
25
 
26
- fetch { scroll_manager.move_to_top }
26
+ fetch { scroller.move_to_top }
27
27
  @auto_reloader = Scheduler.new(180) { fetch }
28
28
  end
29
29
  end
@@ -35,7 +35,7 @@ module Twterm
35
35
  @title = "@#{@user.screen_name}"
36
36
  TabManager.instance.refresh_window
37
37
 
38
- fetch { scroll_manager.move_to_top }
38
+ fetch { scroller.move_to_top }
39
39
  @auto_reloader = Scheduler.new(120) { fetch }
40
40
  end
41
41
  end
@@ -1,3 +1,3 @@
1
1
  module Twterm
2
- VERSION = '1.0.10'
2
+ VERSION = '1.0.11'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: twterm
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.10
4
+ version: 1.0.11
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryota Kameoka
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-07-07 00:00:00.000000000 Z
11
+ date: 2015-07-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: curses
@@ -159,6 +159,7 @@ files:
159
159
  - lib/twterm/completion_mamanger.rb
160
160
  - lib/twterm/config.rb
161
161
  - lib/twterm/extensions/curses/window.rb
162
+ - lib/twterm/extensions/enumerator/lazy.rb
162
163
  - lib/twterm/extensions/integer.rb
163
164
  - lib/twterm/extensions/string.rb
164
165
  - lib/twterm/history/base.rb
@@ -184,7 +185,7 @@ files:
184
185
  - lib/twterm/tab/new/search.rb
185
186
  - lib/twterm/tab/new/start.rb
186
187
  - lib/twterm/tab/new/user.rb
187
- - lib/twterm/tab/scroll_manager.rb
188
+ - lib/twterm/tab/scrollable.rb
188
189
  - lib/twterm/tab/search_tab.rb
189
190
  - lib/twterm/tab/statuses_tab.rb
190
191
  - lib/twterm/tab/timeline_tab.rb
@@ -1,84 +0,0 @@
1
- module Twterm
2
- module Tab
3
- class ScrollManager
4
- extend Forwardable
5
-
6
- attr_reader :index, :offset
7
- attr_accessor :last
8
-
9
- attr_accessor :delegate
10
- def_delegators :delegate, :count, :offset_from_bottom
11
-
12
- def after_move(&block)
13
- add_hook(:after_move, &block)
14
- end
15
-
16
- def initialize
17
- @index = 0
18
- @offset = 0
19
- @last = 0
20
- end
21
-
22
- def item_appended!
23
- @index -= 1
24
- @offset -= 1 if @offset > 0
25
- end
26
-
27
- def item_prepended!
28
- @index += 1
29
- @offset += 1
30
- end
31
-
32
- def move_down
33
- return if count == 0 || index == count - 1
34
-
35
- @index = [index + 1, count - 1].min
36
- @offset = [
37
- offset + 1,
38
- count - 1,
39
- count - offset_from_bottom
40
- ].min if index > last - 4
41
-
42
- hook :after_move
43
- end
44
-
45
- def move_to_bottom
46
- return if count == 0 || index == count - 1
47
-
48
- @index = count - 1
49
- @offset = count - 1 - offset_from_bottom
50
-
51
- hook :after_move
52
- end
53
-
54
- def move_to_top
55
- return if count == 0 || index == 0
56
-
57
- @index = 0
58
- @offset = 0
59
-
60
- hook :after_move
61
- end
62
-
63
- def move_up
64
- return if count == 0 || index == 0
65
-
66
- @index = [index - 1, 0].max
67
- @offset = [offset - 1, 0].max if index - 4 < offset
68
-
69
- hook :after_move
70
- end
71
-
72
- private
73
-
74
- def add_hook(name, &block)
75
- @hooks ||= {}
76
- @hooks[name] = block
77
- end
78
-
79
- def hook(name)
80
- @hooks[name].call unless @hooks[name].nil?
81
- end
82
- end
83
- end
84
- end