twterm 1.3.0 → 2.0.0.beta1
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 +4 -4
- data/README.md +14 -18
- data/bin/twterm +1 -1
- data/lib/twterm/app.rb +120 -30
- data/lib/twterm/client.rb +10 -13
- data/lib/twterm/completion_mamanger.rb +11 -6
- data/lib/twterm/direct_message.rb +6 -28
- data/lib/twterm/direct_message_composer.rb +10 -5
- data/lib/twterm/direct_message_manager.rb +5 -6
- data/lib/twterm/event/notification/abstract_notification.rb +27 -0
- data/lib/twterm/event/notification/error.rb +13 -0
- data/lib/twterm/event/notification/info.rb +13 -0
- data/lib/twterm/event/notification/success.rb +13 -0
- data/lib/twterm/event/notification/warning.rb +13 -0
- data/lib/twterm/event_dispatcher.rb +1 -1
- data/lib/twterm/extensions/array.rb +5 -0
- data/lib/twterm/extensions/enumerator/lazy.rb +3 -0
- data/lib/twterm/extensions/string.rb +0 -4
- data/lib/twterm/friendship.rb +1 -85
- data/lib/twterm/image/between.rb +31 -0
- data/lib/twterm/image/blank_line.rb +21 -0
- data/lib/twterm/image/bold.rb +31 -0
- data/lib/twterm/image/brackets.rb +21 -0
- data/lib/twterm/image/color.rb +45 -0
- data/lib/twterm/image/empty.rb +21 -0
- data/lib/twterm/image/horizontal_sequential_image.rb +48 -0
- data/lib/twterm/image/parens.rb +21 -0
- data/lib/twterm/image/string_image.rb +38 -0
- data/lib/twterm/image/vertical_sequential_image.rb +43 -0
- data/lib/twterm/image.rb +107 -0
- data/lib/twterm/key_mapper/abstract_key_mapper.rb +51 -0
- data/lib/twterm/key_mapper/app_key_mapper.rb +13 -0
- data/lib/twterm/key_mapper/cursor_key_mapper.rb +13 -0
- data/lib/twterm/key_mapper/general_key_mapper.rb +18 -0
- data/lib/twterm/key_mapper/no_such_command.rb +20 -0
- data/lib/twterm/key_mapper/no_such_key.rb +16 -0
- data/lib/twterm/key_mapper/status_key_mapper.rb +18 -0
- data/lib/twterm/key_mapper/tab_key_mapper.rb +31 -0
- data/lib/twterm/key_mapper.rb +127 -0
- data/lib/twterm/list.rb +0 -31
- data/lib/twterm/notifier.rb +7 -7
- data/lib/twterm/repository/abstract_entity_repository.rb +41 -0
- data/lib/twterm/repository/abstract_expirable_entity_repository.rb +35 -0
- data/lib/twterm/repository/abstract_repository.rb +64 -0
- data/lib/twterm/repository/direct_message_repository.rb +14 -0
- data/lib/twterm/repository/friendship_repository.rb +108 -0
- data/lib/twterm/repository/hashtag_repository.rb +39 -0
- data/lib/twterm/repository/list_repository.rb +14 -0
- data/lib/twterm/repository/status_repository.rb +36 -0
- data/lib/twterm/repository/user_repository.rb +22 -0
- data/lib/twterm/rest_client.rb +107 -63
- data/lib/twterm/screen.rb +21 -15
- data/lib/twterm/search_query_window.rb +139 -0
- data/lib/twterm/status.rb +14 -108
- data/lib/twterm/streaming_client.rb +13 -12
- data/lib/twterm/tab/base.rb +48 -8
- data/lib/twterm/tab/direct_message/conversation.rb +53 -52
- data/lib/twterm/tab/direct_message/conversation_list.rb +46 -45
- data/lib/twterm/tab/dumpable.rb +3 -3
- data/lib/twterm/tab/key_assignments_cheatsheet.rb +58 -57
- data/lib/twterm/tab/loadable.rb +20 -0
- data/lib/twterm/tab/new/list.rb +32 -43
- data/lib/twterm/tab/new/search.rb +31 -44
- data/lib/twterm/tab/new/start.rb +44 -55
- data/lib/twterm/tab/new/user.rb +15 -12
- data/lib/twterm/tab/rate_limit_status.rb +84 -0
- data/lib/twterm/tab/scrollable.rb +39 -19
- data/lib/twterm/tab/searchable.rb +133 -0
- data/lib/twterm/tab/statuses/base.rb +139 -129
- data/lib/twterm/tab/statuses/conversation.rb +26 -15
- data/lib/twterm/tab/statuses/favorites.rb +10 -8
- data/lib/twterm/tab/statuses/home.rb +10 -9
- data/lib/twterm/tab/statuses/list_timeline.rb +12 -8
- data/lib/twterm/tab/statuses/mentions.rb +17 -11
- data/lib/twterm/tab/statuses/search.rb +8 -5
- data/lib/twterm/tab/statuses/user_timeline.rb +11 -8
- data/lib/twterm/tab/user_list_management.rb +109 -0
- data/lib/twterm/tab/user_tab.rb +125 -126
- data/lib/twterm/tab/users/base.rb +39 -41
- data/lib/twterm/tab/users/followers.rb +9 -6
- data/lib/twterm/tab/users/friends.rb +9 -6
- data/lib/twterm/tab_manager.rb +64 -40
- data/lib/twterm/tweetbox.rb +18 -13
- data/lib/twterm/uri_opener.rb +2 -1
- data/lib/twterm/user.rb +2 -110
- data/lib/twterm/version.rb +1 -1
- data/lib/twterm/view.rb +30 -0
- data/lib/twterm.rb +3 -9
- data/spec/fixtures/status.json +107 -0
- data/spec/fixtures/user.json +102 -0
- data/spec/spec_helper.rb +7 -0
- data/spec/supports/shared_examples/abstract_key_mapper.rb +17 -0
- data/spec/twterm/extension/enumerator/lazy_spec.rb +11 -0
- data/spec/twterm/friendship_spec.rb +0 -102
- data/spec/twterm/image/blank_line_spec.rb +11 -0
- data/spec/twterm/image/brackets_spec.rb +12 -0
- data/spec/twterm/image/color_spec.rb +22 -0
- data/spec/twterm/image/empry_spec.rb +11 -0
- data/spec/twterm/image/horizontal_sequential_image_spec.rb +15 -0
- data/spec/twterm/image/parens_spec.rb +12 -0
- data/spec/twterm/image/string_image_spec.rb +12 -0
- data/spec/twterm/image/vertical_sequential_image_spec.rb +14 -0
- data/spec/twterm/image_spec.rb +65 -0
- data/spec/twterm/key_mapper/abstract_key_mapper_spec.rb +21 -0
- data/spec/twterm/key_mapper/app_key_mapper_spec.rb +7 -0
- data/spec/twterm/key_mapper/status_key_mapper_spec.rb +7 -0
- data/spec/twterm/key_mapper/tab_key_mapper_spec.rb +7 -0
- data/spec/twterm/repository/friendship_repository_spec.rb +108 -0
- data/spec/twterm/status_spec.rb +58 -0
- data/spec/twterm/user_spec.rb +94 -0
- data/twterm.gemspec +13 -10
- metadata +129 -35
- data/lib/twterm/event/notification.rb +0 -33
- data/lib/twterm/extensions/integer.rb +0 -5
- data/lib/twterm/filter_query_window.rb +0 -91
- data/lib/twterm/filterable_list.rb +0 -41
- data/lib/twterm/history/base.rb +0 -21
- data/lib/twterm/history/hashtag.rb +0 -13
- data/lib/twterm/history/savable.rb +0 -37
- data/lib/twterm/history/screen_name.rb +0 -11
- 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
|
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.
|
26
|
+
@status_ids.push(status.id)
|
24
27
|
status.split(window.maxx - 4)
|
25
|
-
status.touch!
|
26
28
|
scroller.item_appended!
|
27
|
-
|
29
|
+
render
|
28
30
|
end
|
29
31
|
|
30
32
|
def delete(status_id)
|
31
|
-
|
32
|
-
|
33
|
+
app.status_repository.delete(status_id)
|
34
|
+
render
|
33
35
|
end
|
34
36
|
|
35
37
|
def destroy_status
|
36
|
-
status =
|
38
|
+
status = highlighted_original_status
|
37
39
|
|
38
|
-
|
40
|
+
client.destroy_status(status)
|
39
41
|
end
|
40
42
|
|
41
43
|
def drawable_item_count
|
42
|
-
statuses.
|
44
|
+
statuses.drop(scroller.offset).lazy
|
43
45
|
.map { |s| s.split(window.maxx - 4).count + 2 }
|
44
46
|
.scan(0, :+)
|
45
|
-
.
|
47
|
+
.each_cons(2)
|
48
|
+
.select { |_, l| l < window.maxy }
|
46
49
|
.count
|
47
50
|
end
|
48
51
|
|
49
52
|
def favorite
|
50
|
-
|
53
|
+
status = highlighted_original_status
|
54
|
+
|
55
|
+
return if status.nil?
|
51
56
|
|
52
|
-
|
53
|
-
|
54
|
-
|
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
|
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
|
-
|
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
|
110
|
+
@status_ids.unshift(status.id)
|
89
111
|
status.split(window.maxx - 4)
|
90
|
-
status.touch!
|
91
112
|
scroller.item_prepended!
|
92
|
-
|
113
|
+
render
|
93
114
|
end
|
94
115
|
|
95
116
|
def reply
|
96
117
|
return if highlighted_status.nil?
|
97
|
-
|
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
|
128
|
+
when k[:status, :conversation]
|
105
129
|
show_conversation
|
106
|
-
when
|
130
|
+
when k[:status, :destroy]
|
107
131
|
destroy_status
|
108
|
-
when
|
132
|
+
when k[:status, :like]
|
109
133
|
favorite
|
110
|
-
when
|
134
|
+
when k[:status, :open_link]
|
111
135
|
open_link
|
112
|
-
when
|
136
|
+
when k[:status, :reply]
|
113
137
|
reply
|
114
|
-
when
|
138
|
+
when k[:status, :retweet]
|
115
139
|
retweet
|
116
|
-
when
|
140
|
+
when k[:tab, :reload]
|
117
141
|
fetch
|
118
|
-
when
|
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
|
-
|
132
|
-
|
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
|
-
|
137
|
-
|
138
|
-
|
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
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
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|
|
185
|
+
statuses = @status_ids.map { |id| app.status_repository.find(id) }.compact
|
150
186
|
@status_ids = statuses.map(&:id)
|
151
187
|
|
152
|
-
|
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
|
-
|
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.
|
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
|
-
|
244
|
-
|
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
|
16
|
-
status.
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
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
|
25
|
-
status.
|
35
|
+
def find_descendants(status)
|
36
|
+
app.status_repository.find_replies_for(status.id).each do |reply|
|
26
37
|
prepend(reply)
|
27
|
-
|
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
|
-
|
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
|
-
|
45
|
-
|
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
|
-
|
21
|
-
statuses.
|
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
|
-
|
31
|
+
find_or_fetch_user(user_id).then do |user|
|
33
32
|
@user = user
|
34
|
-
|
33
|
+
app.tab_manager.refresh_window
|
35
34
|
|
36
|
-
fetch
|
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
|
-
|
19
|
-
statuses.each(
|
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
|
-
|
24
|
+
def initialize(app, client)
|
25
|
+
super(app, client)
|
27
26
|
|
28
|
-
|
29
|
-
|
30
|
-
|
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
|
-
|
16
|
+
find_or_fetch_list(list_id).then do |list|
|
17
17
|
@list = list
|
18
18
|
self.title = @list.full_name
|
19
|
-
|
20
|
-
|
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
|
-
|
27
|
-
statuses.
|
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
|
-
|
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
|
31
|
-
|
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
|
-
|
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
|
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
|
-
|
26
|
-
statuses.
|
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
|
-
|
36
|
+
find_or_fetch_user(user_id).then do |user|
|
38
37
|
@user = user
|
39
|
-
|
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
|