twterm 1.3.0 → 2.0.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (121) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +14 -18
  3. data/bin/twterm +1 -1
  4. data/lib/twterm/app.rb +120 -30
  5. data/lib/twterm/client.rb +10 -13
  6. data/lib/twterm/completion_mamanger.rb +11 -6
  7. data/lib/twterm/direct_message.rb +6 -28
  8. data/lib/twterm/direct_message_composer.rb +10 -5
  9. data/lib/twterm/direct_message_manager.rb +5 -6
  10. data/lib/twterm/event/notification/abstract_notification.rb +27 -0
  11. data/lib/twterm/event/notification/error.rb +13 -0
  12. data/lib/twterm/event/notification/info.rb +13 -0
  13. data/lib/twterm/event/notification/success.rb +13 -0
  14. data/lib/twterm/event/notification/warning.rb +13 -0
  15. data/lib/twterm/event_dispatcher.rb +1 -1
  16. data/lib/twterm/extensions/array.rb +5 -0
  17. data/lib/twterm/extensions/enumerator/lazy.rb +3 -0
  18. data/lib/twterm/extensions/string.rb +0 -4
  19. data/lib/twterm/friendship.rb +1 -85
  20. data/lib/twterm/image/between.rb +31 -0
  21. data/lib/twterm/image/blank_line.rb +21 -0
  22. data/lib/twterm/image/bold.rb +31 -0
  23. data/lib/twterm/image/brackets.rb +21 -0
  24. data/lib/twterm/image/color.rb +45 -0
  25. data/lib/twterm/image/empty.rb +21 -0
  26. data/lib/twterm/image/horizontal_sequential_image.rb +48 -0
  27. data/lib/twterm/image/parens.rb +21 -0
  28. data/lib/twterm/image/string_image.rb +38 -0
  29. data/lib/twterm/image/vertical_sequential_image.rb +43 -0
  30. data/lib/twterm/image.rb +107 -0
  31. data/lib/twterm/key_mapper/abstract_key_mapper.rb +51 -0
  32. data/lib/twterm/key_mapper/app_key_mapper.rb +13 -0
  33. data/lib/twterm/key_mapper/cursor_key_mapper.rb +13 -0
  34. data/lib/twterm/key_mapper/general_key_mapper.rb +18 -0
  35. data/lib/twterm/key_mapper/no_such_command.rb +20 -0
  36. data/lib/twterm/key_mapper/no_such_key.rb +16 -0
  37. data/lib/twterm/key_mapper/status_key_mapper.rb +18 -0
  38. data/lib/twterm/key_mapper/tab_key_mapper.rb +31 -0
  39. data/lib/twterm/key_mapper.rb +127 -0
  40. data/lib/twterm/list.rb +0 -31
  41. data/lib/twterm/notifier.rb +7 -7
  42. data/lib/twterm/repository/abstract_entity_repository.rb +41 -0
  43. data/lib/twterm/repository/abstract_expirable_entity_repository.rb +35 -0
  44. data/lib/twterm/repository/abstract_repository.rb +64 -0
  45. data/lib/twterm/repository/direct_message_repository.rb +14 -0
  46. data/lib/twterm/repository/friendship_repository.rb +108 -0
  47. data/lib/twterm/repository/hashtag_repository.rb +39 -0
  48. data/lib/twterm/repository/list_repository.rb +14 -0
  49. data/lib/twterm/repository/status_repository.rb +36 -0
  50. data/lib/twterm/repository/user_repository.rb +22 -0
  51. data/lib/twterm/rest_client.rb +107 -63
  52. data/lib/twterm/screen.rb +21 -15
  53. data/lib/twterm/search_query_window.rb +139 -0
  54. data/lib/twterm/status.rb +14 -108
  55. data/lib/twterm/streaming_client.rb +13 -12
  56. data/lib/twterm/tab/base.rb +48 -8
  57. data/lib/twterm/tab/direct_message/conversation.rb +53 -52
  58. data/lib/twterm/tab/direct_message/conversation_list.rb +46 -45
  59. data/lib/twterm/tab/dumpable.rb +3 -3
  60. data/lib/twterm/tab/key_assignments_cheatsheet.rb +58 -57
  61. data/lib/twterm/tab/loadable.rb +20 -0
  62. data/lib/twterm/tab/new/list.rb +32 -43
  63. data/lib/twterm/tab/new/search.rb +31 -44
  64. data/lib/twterm/tab/new/start.rb +44 -55
  65. data/lib/twterm/tab/new/user.rb +15 -12
  66. data/lib/twterm/tab/rate_limit_status.rb +84 -0
  67. data/lib/twterm/tab/scrollable.rb +39 -19
  68. data/lib/twterm/tab/searchable.rb +133 -0
  69. data/lib/twterm/tab/statuses/base.rb +139 -129
  70. data/lib/twterm/tab/statuses/conversation.rb +26 -15
  71. data/lib/twterm/tab/statuses/favorites.rb +10 -8
  72. data/lib/twterm/tab/statuses/home.rb +10 -9
  73. data/lib/twterm/tab/statuses/list_timeline.rb +12 -8
  74. data/lib/twterm/tab/statuses/mentions.rb +17 -11
  75. data/lib/twterm/tab/statuses/search.rb +8 -5
  76. data/lib/twterm/tab/statuses/user_timeline.rb +11 -8
  77. data/lib/twterm/tab/user_list_management.rb +109 -0
  78. data/lib/twterm/tab/user_tab.rb +125 -126
  79. data/lib/twterm/tab/users/base.rb +39 -41
  80. data/lib/twterm/tab/users/followers.rb +9 -6
  81. data/lib/twterm/tab/users/friends.rb +9 -6
  82. data/lib/twterm/tab_manager.rb +64 -40
  83. data/lib/twterm/tweetbox.rb +18 -13
  84. data/lib/twterm/uri_opener.rb +2 -1
  85. data/lib/twterm/user.rb +2 -110
  86. data/lib/twterm/version.rb +1 -1
  87. data/lib/twterm/view.rb +30 -0
  88. data/lib/twterm.rb +3 -9
  89. data/spec/fixtures/status.json +107 -0
  90. data/spec/fixtures/user.json +102 -0
  91. data/spec/spec_helper.rb +7 -0
  92. data/spec/supports/shared_examples/abstract_key_mapper.rb +17 -0
  93. data/spec/twterm/extension/enumerator/lazy_spec.rb +11 -0
  94. data/spec/twterm/friendship_spec.rb +0 -102
  95. data/spec/twterm/image/blank_line_spec.rb +11 -0
  96. data/spec/twterm/image/brackets_spec.rb +12 -0
  97. data/spec/twterm/image/color_spec.rb +22 -0
  98. data/spec/twterm/image/empry_spec.rb +11 -0
  99. data/spec/twterm/image/horizontal_sequential_image_spec.rb +15 -0
  100. data/spec/twterm/image/parens_spec.rb +12 -0
  101. data/spec/twterm/image/string_image_spec.rb +12 -0
  102. data/spec/twterm/image/vertical_sequential_image_spec.rb +14 -0
  103. data/spec/twterm/image_spec.rb +65 -0
  104. data/spec/twterm/key_mapper/abstract_key_mapper_spec.rb +21 -0
  105. data/spec/twterm/key_mapper/app_key_mapper_spec.rb +7 -0
  106. data/spec/twterm/key_mapper/status_key_mapper_spec.rb +7 -0
  107. data/spec/twterm/key_mapper/tab_key_mapper_spec.rb +7 -0
  108. data/spec/twterm/repository/friendship_repository_spec.rb +108 -0
  109. data/spec/twterm/status_spec.rb +58 -0
  110. data/spec/twterm/user_spec.rb +94 -0
  111. data/twterm.gemspec +13 -10
  112. metadata +129 -35
  113. data/lib/twterm/event/notification.rb +0 -33
  114. data/lib/twterm/extensions/integer.rb +0 -5
  115. data/lib/twterm/filter_query_window.rb +0 -91
  116. data/lib/twterm/filterable_list.rb +0 -41
  117. data/lib/twterm/history/base.rb +0 -21
  118. data/lib/twterm/history/hashtag.rb +0 -13
  119. data/lib/twterm/history/savable.rb +0 -37
  120. data/lib/twterm/history/screen_name.rb +0 -11
  121. data/lib/twterm/promise.rb +0 -143
@@ -1,18 +1,21 @@
1
+ require 'concurrent'
2
+
1
3
  require 'twterm/event/open_uri'
2
4
  require 'twterm/event/status/delete'
3
5
  require 'twterm/publisher'
4
6
  require 'twterm/subscriber'
5
7
  require 'twterm/tab/base'
8
+ require 'twterm/tab/loadable'
6
9
  require 'twterm/utils'
7
10
 
8
11
  module Twterm
9
12
  module Tab
10
13
  module Statuses
11
14
  class Base < Tab::Base
12
- include FilterableList
13
15
  include Publisher
14
- include Scrollable
16
+ include Searchable
15
17
  include Subscriber
18
+ include Loadable
16
19
  include Utils
17
20
 
18
21
  def append(status)
@@ -20,62 +23,81 @@ module Twterm
20
23
 
21
24
  return if @status_ids.include?(status.id)
22
25
 
23
- @status_ids.unshift(status.id)
26
+ @status_ids.push(status.id)
24
27
  status.split(window.maxx - 4)
25
- status.touch!
26
28
  scroller.item_appended!
27
- refresh
29
+ render
28
30
  end
29
31
 
30
32
  def delete(status_id)
31
- Status.delete(status_id)
32
- refresh
33
+ app.status_repository.delete(status_id)
34
+ render
33
35
  end
34
36
 
35
37
  def destroy_status
36
- status = highlighted_status
38
+ status = highlighted_original_status
37
39
 
38
- Client.current.destroy_status(status)
40
+ client.destroy_status(status)
39
41
  end
40
42
 
41
43
  def drawable_item_count
42
- statuses.reverse.drop(scroller.offset).lazy
44
+ statuses.drop(scroller.offset).lazy
43
45
  .map { |s| s.split(window.maxx - 4).count + 2 }
44
46
  .scan(0, :+)
45
- .select { |l| l < window.maxy }
47
+ .each_cons(2)
48
+ .select { |_, l| l < window.maxy }
46
49
  .count
47
50
  end
48
51
 
49
52
  def favorite
50
- return if highlighted_status.nil?
53
+ status = highlighted_original_status
54
+
55
+ return if status.nil?
51
56
 
52
- method_name = highlighted_status.favorited ? :unfavorite : :favorite
53
- Client.current.method(method_name).call(highlighted_status)
54
- .then { refresh }
57
+ if status.favorited?
58
+ client.unfavorite(status)
59
+ .then { status.unfavorite! }
60
+ else
61
+ client.favorite(status)
62
+ .then { status.favorite! }
63
+ end
64
+ .then { render }
55
65
  end
56
66
 
57
67
  def fetch
58
68
  fail NotImplementedError, 'fetch method must be implemented'
59
69
  end
60
70
 
61
- def initialize
62
- super
71
+ def initialize(app, client)
72
+ super(app, client)
63
73
 
64
- @status_ids = []
74
+ @status_ids = Concurrent::Array.new
65
75
 
66
76
  subscribe(Event::Status::Delete) { |e| delete(e.status_id) }
67
77
  end
68
78
 
69
79
  def items
70
- statuses.reverse
80
+ statuses
81
+ end
82
+
83
+ def matches?(status, query)
84
+ user = app.user_repository.find(status.user_id)
85
+
86
+ [
87
+ status.text,
88
+ user.screen_name,
89
+ user.name
90
+ ].any? { |x| x.downcase.include?(query.downcase) }
71
91
  end
72
92
 
73
93
  def open_link
74
- return if highlighted_status.nil?
94
+ status = highlighted_original_status
95
+
96
+ return if status.nil?
75
97
 
76
- status = highlighted_status
77
98
  urls = status.urls.map(&:expanded_url) + status.media.map(&:expanded_url)
78
99
  urls
100
+ .uniq
79
101
  .map { |url| Event::OpenURI.new(url) }
80
102
  .each { |e| publish(e) }
81
103
  end
@@ -85,42 +107,40 @@ module Twterm
85
107
 
86
108
  return if @status_ids.include?(status.id)
87
109
 
88
- @status_ids << status.id
110
+ @status_ids.unshift(status.id)
89
111
  status.split(window.maxx - 4)
90
- status.touch!
91
112
  scroller.item_prepended!
92
- refresh
113
+ render
93
114
  end
94
115
 
95
116
  def reply
96
117
  return if highlighted_status.nil?
97
- Tweetbox.instance.compose(highlighted_status)
118
+
119
+ app.tweetbox.compose(highlighted_original_status)
98
120
  end
99
121
 
100
122
  def respond_to_key(key)
101
123
  return true if scroller.respond_to_key(key)
102
124
 
125
+ k = KeyMapper.instance
126
+
103
127
  case key
104
- when ?c
128
+ when k[:status, :conversation]
105
129
  show_conversation
106
- when ?D
130
+ when k[:status, :destroy]
107
131
  destroy_status
108
- when ?F, ?L
132
+ when k[:status, :like]
109
133
  favorite
110
- when ?o
134
+ when k[:status, :open_link]
111
135
  open_link
112
- when ?r
136
+ when k[:status, :reply]
113
137
  reply
114
- when ?R
138
+ when k[:status, :retweet]
115
139
  retweet
116
- when 18
140
+ when k[:tab, :reload]
117
141
  fetch
118
- when ?U
142
+ when k[:status, :user]
119
143
  show_user
120
- when ?/
121
- filter
122
- when ?q
123
- reset_filter
124
144
  else
125
145
  return false
126
146
  end
@@ -128,120 +148,110 @@ module Twterm
128
148
  end
129
149
 
130
150
  def retweet
131
- return if highlighted_status.nil?
132
- Client.current.retweet(highlighted_status).then { refresh }
151
+ status = highlighted_original_status
152
+
153
+ return if status.nil?
154
+
155
+ if status.retweeted?
156
+ client.unretweet(status)
157
+ .then { status.unretweet! }
158
+ else
159
+ client.retweet(status)
160
+ .then { status.retweet! }
161
+ end
162
+ .then { render }
133
163
  end
134
164
 
135
165
  def show_conversation
136
- return if highlighted_status.nil?
137
- tab = Tab::Statuses::Conversation.new(highlighted_status.id)
138
- TabManager.instance.add_and_show(tab)
166
+ status = highlighted_original_status
167
+
168
+ return if status.nil?
169
+
170
+ tab = Tab::Statuses::Conversation.new(app, client, highlighted_original_status.id)
171
+ app.tab_manager.add_and_show(tab)
139
172
  end
140
173
 
141
174
  def show_user
142
- return if highlighted_status.nil?
143
- user = highlighted_status.user
144
- user_tab = Tab::UserTab.new(user.id)
145
- TabManager.instance.add_and_show(user_tab)
175
+ status = highlighted_original_status
176
+
177
+ return if status.nil?
178
+
179
+ user_id = status.user_id
180
+ user_tab = Tab::UserTab.new(app, client, user_id)
181
+ app.tab_manager.add_and_show(user_tab)
146
182
  end
147
183
 
148
184
  def statuses
149
- statuses = @status_ids.map { |id| Status.find(id) }.reject(&:nil?)
185
+ statuses = @status_ids.map { |id| app.status_repository.find(id) }.compact
150
186
  @status_ids = statuses.map(&:id)
151
187
 
152
- if filter_query.empty?
153
- statuses
154
- else
155
- statuses.select { |s| s.matches?(filter_query) }
156
- end
157
- end
158
-
159
- def touch_statuses
160
- statuses.reverse.take(100).each(&:touch!)
188
+ statuses
161
189
  end
162
190
 
163
191
  def total_item_count
164
- filter_query.empty? ? @status_ids.count : statuses.count
165
- end
166
-
167
- def update
168
- line = 0
169
-
170
- scroller.drawable_items.each.with_index(0) do |status, i|
171
- formatted_lines = status.split(window.maxx - 4).count
172
- window.with_color(:black, :magenta) do
173
- (formatted_lines + 1).times do |j|
174
- window.setpos(line + j, 0)
175
- window.addch(' ')
176
- end
177
- end if scroller.current_item?(i)
178
-
179
- window.setpos(line, 2)
180
-
181
- window.bold do
182
- window.with_color(status.user.color) do
183
- window.addstr(status.user.name)
184
- end
185
- end
186
-
187
- window.addstr(" (@#{status.user.screen_name}) [#{status.date}] ")
188
-
189
- unless status.retweeted_by.nil?
190
- window.addstr('(retweeted by ')
191
- window.bold do
192
- window.addstr("@#{status.retweeted_by.screen_name}")
193
- end
194
- window.addstr(') ')
195
- end
196
-
197
- if status.favorited?
198
- window.with_color(:black, :red) do
199
- window.addch(' ')
200
- end
201
-
202
- window.addch(' ')
203
- end
204
-
205
- if status.retweeted?
206
- window.with_color(:black, :green) do
207
- window.addch(' ')
208
- end
209
- window.addch(' ')
210
- end
211
-
212
- if status.favorite_count > 0
213
- window.with_color(:red) do
214
- window.addstr("#{status.favorite_count}like#{status.favorite_count > 1 ? 's' : ''}")
215
- end
216
- window.addch(' ')
217
- end
218
-
219
- if status.retweet_count > 0
220
- window.with_color(:green) do
221
- window.addstr("#{status.retweet_count}RT#{status.retweet_count > 1 ? 's' : ''}")
222
- end
223
- window.addch(' ')
224
- end
225
-
226
- status.split(window.maxx - 4).each do |str|
227
- line += 1
228
- window.setpos(line, 2)
229
- window.addstr(str)
230
- end
231
-
232
- line += 2
233
- end
192
+ search_query.empty? ? @status_ids.count : statuses.count
234
193
  end
235
194
 
236
195
  private
237
196
 
197
+ def highlighted_original_status
198
+ status = highlighted_status
199
+
200
+ status.retweet? ? app.status_repository.find(status.retweeted_status_id) : status
201
+ end
202
+
238
203
  def highlighted_status
239
- statuses[scroller.count - scroller.index - 1]
204
+ statuses[scroller.index]
205
+ end
206
+
207
+ def image
208
+ return Image.string(initially_loaded? ? 'No results found' : 'Loading...') if items.empty?
209
+
210
+ scroller.drawable_items.map.with_index(0) do |status, i|
211
+ original = status.retweet? ? app.status_repository.find(status.retweeted_status_id) : status
212
+ user = app.user_repository.find(original.user_id)
213
+ retweeted_by = app.user_repository.find(status.user_id)
214
+
215
+ header = [
216
+ !Image.string(user.name).color(user.color),
217
+ Image.string("@#{user.screen_name}").parens,
218
+ Image.string(original.date.to_s).brackets,
219
+ (Image.whitespace.color(:black, :red) if original.favorited?),
220
+ (Image.whitespace.color(:black, :green) if original.retweeted?),
221
+ ((Image.string('retweeted by ') - !Image.string("@#{retweeted_by.screen_name}")).parens if status.retweet?),
222
+ ((Image.number(original.favorite_count) - Image.plural(original.favorite_count, 'like')).color(:red) if original.favorite_count.positive?),
223
+ ((Image.number(original.retweet_count) - Image.plural(original.retweet_count, 'RT')).color(:green) if original.retweet_count.positive?),
224
+ ].compact.intersperse(Image.whitespace).reduce(Image.empty, :-)
225
+
226
+ body = original
227
+ .split(window.maxx - 4)
228
+ .map(&Image.method(:string))
229
+ .reduce(Image.empty, :|)
230
+
231
+ s = header | body
232
+
233
+ Image.cursor(s.height, scroller.current_index?(i)) - Image.whitespace - s
234
+ end
235
+ .intersperse(Image.blank_line)
236
+ .reduce(Image.empty, :|)
240
237
  end
241
238
 
242
239
  def sort
243
- @status_ids &= Status.all.map(&:id)
244
- @status_ids.sort_by! { |id| Status.find(id).appeared_at }
240
+ return if items.empty? || scroller.current_item.nil?
241
+
242
+ repo = app.status_repository
243
+
244
+ @status_ids &= repo.ids
245
+ @status_ids.sort_by! { |id| repo.find(id).created_at }.reverse!
246
+
247
+ formerly_selected_status_id = scroller.current_item.id
248
+
249
+ unless formerly_selected_status_id.nil?
250
+ new_index = @status_ids.index(formerly_selected_status_id)
251
+ scroller.move_to(new_index) unless new_index.nil?
252
+ end
253
+
254
+ self
245
255
  end
246
256
  end
247
257
  end
@@ -1,3 +1,5 @@
1
+ require 'concurrent'
2
+
1
3
  require 'twterm/tab/statuses/base'
2
4
 
3
5
  module Twterm
@@ -12,37 +14,46 @@ module Twterm
12
14
  other.is_a?(self.class) && status == other.status
13
15
  end
14
16
 
15
- def fetch_in_reply_to_status(status)
16
- status.in_reply_to_status.then do |in_reply_to|
17
- return if in_reply_to.nil?
18
- append(in_reply_to)
19
- sort
20
- Thread.new { fetch_in_reply_to_status(in_reply_to) }
17
+ def fetch_ancestor(status)
18
+ in_reply_to_status_id = status.in_reply_to_status_id
19
+
20
+ if in_reply_to_status_id.nil?
21
+ Concurrent::Promise.fulfill(nil)
22
+ elsif (instance = app.status_repository.find(in_reply_to_status_id))
23
+ Concurrent::Promise.fulfill(instance)
24
+ else
25
+ client.show_status(in_reply_to_status_id)
21
26
  end
27
+ .then do |in_reply_to|
28
+ next if in_reply_to.nil?
29
+ append(in_reply_to)
30
+ sort
31
+ fetch_ancestor(in_reply_to)
32
+ end
22
33
  end
23
34
 
24
- def fetch_replies(status)
25
- status.replies.each do |reply|
35
+ def find_descendants(status)
36
+ app.status_repository.find_replies_for(status.id).each do |reply|
26
37
  prepend(reply)
27
- sort
28
- Thread.new { fetch_replies(reply) }
38
+ find_descendants(reply)
29
39
  end
40
+ sort
30
41
  end
31
42
 
32
43
  def dump
33
44
  @status.id
34
45
  end
35
46
 
36
- def initialize(status_id)
37
- super()
47
+ def initialize(app, client, status_id)
48
+ super(app, client)
38
49
 
39
- Status.find_or_fetch(status_id).then do |status|
50
+ find_or_fetch_status(status_id).then do |status|
40
51
  @status = status
41
52
 
42
53
  append(status)
43
54
  scroller.move_to_top
44
- Thread.new { fetch_in_reply_to_status(status) }
45
- Thread.new { fetch_replies(status) }
55
+ fetch_ancestor(status)
56
+ find_descendants(status)
46
57
  end
47
58
  end
48
59
 
@@ -17,23 +17,25 @@ module Twterm
17
17
  end
18
18
 
19
19
  def fetch
20
- Client.current.favorites(@user.id).then do |statuses|
21
- statuses.reverse.each(&method(:prepend))
20
+ client.favorites(@user.id).then do |statuses|
21
+ statuses.each { |s| append(s) }
22
22
  sort
23
- yield if block_given?
24
23
  end
25
24
  end
26
25
 
27
- def initialize(user_id)
28
- super()
26
+ def initialize(app, client, user_id)
27
+ super(app, client)
29
28
 
30
29
  @user_id = user_id
31
30
 
32
- User.find_or_fetch(user_id).then do |user|
31
+ find_or_fetch_user(user_id).then do |user|
33
32
  @user = user
34
- TabManager.instance.refresh_window
33
+ app.tab_manager.refresh_window
35
34
 
36
- fetch { scroller.move_to_top }
35
+ fetch.then do
36
+ initially_loaded!
37
+ scroller.move_to_top
38
+ end
37
39
  end
38
40
  end
39
41
 
@@ -15,21 +15,22 @@ module Twterm
15
15
  end
16
16
 
17
17
  def fetch
18
- @client.home_timeline.then do |statuses|
19
- statuses.each(&method(:prepend))
18
+ client.home_timeline.then do |statuses|
19
+ statuses.each { |s| append(s) }
20
20
  sort
21
- yield if block_given?
22
21
  end
23
22
  end
24
23
 
25
- def initialize(client)
26
- check_type Client, client
24
+ def initialize(app, client)
25
+ super(app, client)
27
26
 
28
- super()
29
- @client = client
30
- subscribe(Event::Status::Timeline) { |e| prepend e.status }
27
+ subscribe(Event::Status::Timeline) { |e| prepend(e.status) }
28
+
29
+ fetch.then do
30
+ initially_loaded!
31
+ scroller.move_to_top
32
+ end
31
33
 
32
- fetch { scroller.move_to_top }
33
34
  @auto_reloader = Scheduler.new(180) { fetch }
34
35
  end
35
36
 
@@ -8,25 +8,29 @@ module Twterm
8
8
 
9
9
  attr_reader :list
10
10
 
11
- def initialize(list_id)
12
- super()
11
+ def initialize(app, client, list_id)
12
+ super(app, client)
13
13
 
14
14
  self.title = 'Loading...'.freeze
15
15
 
16
- List.find_or_fetch(list_id).then do |list|
16
+ find_or_fetch_list(list_id).then do |list|
17
17
  @list = list
18
18
  self.title = @list.full_name
19
- TabManager.instance.refresh_window
20
- fetch { scroller.move_to_top }
19
+ app.tab_manager.refresh_window
20
+
21
+ fetch.then do
22
+ initially_loaded!
23
+ scroller.move_to_top
24
+ end
25
+
21
26
  @auto_reloader = Scheduler.new(300) { fetch }
22
27
  end
23
28
  end
24
29
 
25
30
  def fetch
26
- Client.current.list_timeline(@list).then do |statuses|
27
- statuses.reverse.each(&method(:prepend))
31
+ client.list_timeline(@list).then do |statuses|
32
+ statuses.each { |s| append(s) }
28
33
  sort
29
- yield if block_given?
30
34
  end
31
35
  end
32
36
 
@@ -11,24 +11,30 @@ module Twterm
11
11
  end
12
12
 
13
13
  def fetch
14
- @client.mentions.then do |statuses|
15
- statuses.reverse.each(&method(:prepend))
16
- sort
17
- yield if block_given?
18
- end
14
+ client.mentions
19
15
  end
20
16
 
21
- def initialize(client)
17
+ def initialize(app, client)
22
18
  fail ArgumentError, 'argument must be an instance of Client class' unless client.is_a? Client
23
19
 
24
- super()
25
-
26
- @client = client
20
+ super(app, client)
27
21
 
28
22
  subscribe(Event::Status::Mention) { |e| prepend(e.status) }
29
23
 
30
- fetch { scroller.move_to_top }
31
- @auto_reloader = Scheduler.new(300) { fetch }
24
+ fetch.then do |statuses|
25
+ initially_loaded!
26
+ statuses.each { |s| append(s) }
27
+ scroller.move_to_top
28
+ end
29
+
30
+ @auto_reloader = Scheduler.new(300) { reload }
31
+ end
32
+
33
+ def reload
34
+ fetch.then do |statuses|
35
+ statuses.each { |s| append(s) }
36
+ sort
37
+ end
32
38
  end
33
39
 
34
40
  def title
@@ -22,20 +22,23 @@ module Twterm
22
22
  end
23
23
 
24
24
  def fetch
25
- Client.current.search(@query).then do |statuses|
25
+ client.search(@query).then do |statuses|
26
26
  statuses.each(&method(:append))
27
27
  sort
28
- yield if block_given?
29
28
  end
30
29
  end
31
30
 
32
- def initialize(query)
33
- super()
31
+ def initialize(app, client, query)
32
+ super(app, client)
34
33
 
35
34
  @query = query
36
35
  @title = "\"#{@query}\""
37
36
 
38
- fetch { scroller.move_to_top }
37
+ fetch.then do
38
+ initially_loaded!
39
+ scroller.move_to_top
40
+ end
41
+
39
42
  @auto_reloader = Scheduler.new(300) { fetch }
40
43
  end
41
44
  end
@@ -22,23 +22,26 @@ module Twterm
22
22
  end
23
23
 
24
24
  def fetch
25
- Client.current.user_timeline(@user.id).then do |statuses|
26
- statuses.reverse.each(&method(:prepend))
25
+ client.user_timeline(@user.id).then do |statuses|
26
+ statuses.each { |s| append(s) }
27
27
  sort
28
- yield if block_given?
29
28
  end
30
29
  end
31
30
 
32
- def initialize(user_id)
33
- super()
31
+ def initialize(app, client, user_id)
32
+ super(app, client)
34
33
 
35
34
  @user_id = user_id
36
35
 
37
- User.find_or_fetch(user_id).then do |user|
36
+ find_or_fetch_user(user_id).then do |user|
38
37
  @user = user
39
- TabManager.instance.refresh_window
38
+ app.tab_manager.refresh_window
39
+
40
+ fetch.then do
41
+ initially_loaded!
42
+ scroller.move_to_top
43
+ end
40
44
 
41
- fetch { scroller.move_to_top }
42
45
  @auto_reloader = Scheduler.new(120) { fetch }
43
46
  end
44
47
  end