twterm 2.2.0 → 2.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/twterm +4 -0
- data/lib/twterm/app.rb +1 -1
- data/lib/twterm/completer/default_completer.rb +1 -1
- data/lib/twterm/completer/search_query_completer.rb +1 -1
- data/lib/twterm/hashtag.rb +9 -0
- data/lib/twterm/image.rb +2 -2
- data/lib/twterm/image_builder/user_name_image_builder.rb +28 -0
- data/lib/twterm/repository/hashtag_repository.rb +2 -1
- data/lib/twterm/status.rb +6 -2
- data/lib/twterm/tab/direct_message/conversation.rb +2 -2
- data/lib/twterm/tab/direct_message/conversation_list.rb +2 -2
- data/lib/twterm/tab/new/list.rb +3 -2
- data/lib/twterm/tab/new/search.rb +2 -1
- data/lib/twterm/tab/new/start.rb +3 -2
- data/lib/twterm/tab/preferences/index.rb +3 -2
- data/lib/twterm/tab/preferences/notification_backend.rb +3 -2
- data/lib/twterm/tab/status_tab.rb +226 -0
- data/lib/twterm/tab/statuses/base.rb +14 -2
- data/lib/twterm/tab/user_list_management.rb +3 -2
- data/lib/twterm/tab/user_tab.rb +7 -4
- data/lib/twterm/tab/users/base.rb +2 -2
- data/lib/twterm/tab_manager.rb +1 -1
- data/lib/twterm/user.rb +1 -4
- data/lib/twterm/version.rb +1 -1
- data/spec/twterm/image_builder/user_name_image_builder_spec.rb +28 -0
- data/twterm.gemspec +1 -0
- metadata +21 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d251a92afa7b450c2da0556f66fe431d6db851633b739601e0c47cb5ad45baa5
|
4
|
+
data.tar.gz: a014a40ac7b5d15859880b157375ebe372e011a4a76153fc93b66075ad3a594c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5dc37cf71fa46b22cb7e69efc5a3ad09c2fd0a65ba8c77869e6d2a494159aace7691653fe0b001952edef57153a39f5be1715ca0447fc1aa04712130aabc40f5
|
7
|
+
data.tar.gz: de94a92f370e94e509063132cd69a8525df015d9825393e7570ba7d55c99466042aaab7d4261ac1e6559b4518703792ead41433a8c2ad1817115e01a7c3e7da3
|
data/bin/twterm
CHANGED
data/lib/twterm/app.rb
CHANGED
data/lib/twterm/image.rb
CHANGED
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'twterm/image'
|
2
|
+
|
3
|
+
module Twterm
|
4
|
+
module ImageBuilder
|
5
|
+
class UserNameImageBuilder
|
6
|
+
COLORS = [:red, :blue, :green, :cyan, :yellow, :magenta].freeze
|
7
|
+
|
8
|
+
# @param user [Twterm::User] user
|
9
|
+
def initialize(user)
|
10
|
+
@user = user
|
11
|
+
end
|
12
|
+
|
13
|
+
# @return [Twterm::Image] image for the given user
|
14
|
+
def build
|
15
|
+
!Image.string(user.name).color(color) - Image.whitespace - Image.string("@#{user.screen_name}").parens
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
attr_reader :user
|
21
|
+
|
22
|
+
# @return [Symbol] color for user
|
23
|
+
def color
|
24
|
+
COLORS[user.id % 6]
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/lib/twterm/status.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
require 'concurrent'
|
2
2
|
|
3
|
+
require 'twterm/hashtag'
|
4
|
+
|
3
5
|
class Twitter::Tweet
|
4
6
|
attr_reader :quoted_status_id
|
5
7
|
|
@@ -11,9 +13,9 @@ end
|
|
11
13
|
|
12
14
|
module Twterm
|
13
15
|
class Status
|
14
|
-
attr_reader :created_at, :favorite_count, :favorited, :id,
|
16
|
+
attr_reader :created_at, :favorite_count, :favorited, :hashtags, :id,
|
15
17
|
:in_reply_to_status_id, :media, :retweet_count, :retweeted,
|
16
|
-
:quoted_status_id, :retweeted_status_id, :text, :url, :urls, :user_id
|
18
|
+
:quoted_status_id, :retweeted_status_id, :text, :url, :urls, :user_id, :user_mentions
|
17
19
|
alias_method :favorited?, :favorited
|
18
20
|
alias_method :retweeted?, :retweeted
|
19
21
|
|
@@ -50,7 +52,9 @@ module Twterm
|
|
50
52
|
update!(tweet, is_retweeted_status)
|
51
53
|
|
52
54
|
@media = tweet.media
|
55
|
+
@hashtags = tweet.hashtags.map { |tag| Hashtag.new(tag) }
|
53
56
|
@urls = tweet.urls
|
57
|
+
@user_mentions = tweet.user_mentions
|
54
58
|
|
55
59
|
@user_id = tweet.user.id
|
56
60
|
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'twterm/direct_message_composer'
|
2
2
|
require 'twterm/event/direct_message/fetched'
|
3
|
+
require 'twterm/image_builder/user_name_image_builder'
|
3
4
|
require 'twterm/subscriber'
|
4
5
|
require 'twterm/tab/base'
|
5
6
|
require 'twterm/tab/loadable'
|
@@ -29,8 +30,7 @@ module Twterm
|
|
29
30
|
sender = app.user_repository.find(message.sender_id)
|
30
31
|
|
31
32
|
header = [
|
32
|
-
|
33
|
-
Image.string("@#{sender.screen_name}").parens,
|
33
|
+
ImageBuilder::UserNameImageBuilder.new(sender).build,
|
34
34
|
Image.string(message.date.to_s).brackets,
|
35
35
|
].intersperse(Image.whitespace).reduce(Image.empty, :-)
|
36
36
|
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'twterm/direct_message_composer'
|
2
2
|
require 'twterm/event/direct_message/fetched'
|
3
|
+
require 'twterm/image_builder/user_name_image_builder'
|
3
4
|
require 'twterm/subscriber'
|
4
5
|
require 'twterm/tab/base'
|
5
6
|
require 'twterm/tab/loadable'
|
@@ -26,8 +27,7 @@ module Twterm
|
|
26
27
|
collocutor = app.user_repository.find(conversation.collocutor_id)
|
27
28
|
|
28
29
|
header = [
|
29
|
-
|
30
|
-
Image.string("@#{collocutor.screen_name}").parens,
|
30
|
+
ImageBuilder::UserNameImageBuilder.new(collocutor).build,
|
31
31
|
Image.string(conversation.updated_at.to_s).brackets,
|
32
32
|
].intersperse(Image.whitespace).reduce(Image.empty, :-)
|
33
33
|
|
data/lib/twterm/tab/new/list.rb
CHANGED
@@ -73,9 +73,10 @@ module Twterm
|
|
73
73
|
return Image.string(initially_loaded? ? 'No results found' : 'Loading...') if items.empty?
|
74
74
|
|
75
75
|
drawable_items.map.with_index(0) do |list, i|
|
76
|
-
|
76
|
+
curr = scroller.current_index?(i)
|
77
|
+
cursor = Image.cursor(2, curr)
|
77
78
|
|
78
|
-
summary = Image.string("#{list.full_name} (#{list.member_count} members / #{list.subscriber_count} subscribers)")
|
79
|
+
summary = Image.string("#{list.full_name} (#{list.member_count} members / #{list.subscriber_count} subscribers)").bold(curr)
|
79
80
|
desc = Image.string(' ') - Image.string(list.description)
|
80
81
|
|
81
82
|
cursor - Image.whitespace - (summary | desc)
|
@@ -100,7 +100,8 @@ module Twterm
|
|
100
100
|
[
|
101
101
|
*drawable_items
|
102
102
|
.map.with_index(0) { |query, i|
|
103
|
-
|
103
|
+
curr = scroller.current_index?(i)
|
104
|
+
Image.cursor(1, curr) - Image.whitespace - Image.string(query).bold(curr)
|
104
105
|
},
|
105
106
|
(Image.string(' Loading saved searches...') unless initially_loaded?),
|
106
107
|
]
|
data/lib/twterm/tab/new/start.rb
CHANGED
@@ -55,7 +55,8 @@ module Twterm
|
|
55
55
|
def image
|
56
56
|
drawable_items
|
57
57
|
.map.with_index(0) { |item, i|
|
58
|
-
|
58
|
+
curr = scroller.current_index?(i)
|
59
|
+
cursor = Image.cursor(1, curr)
|
59
60
|
|
60
61
|
desc =
|
61
62
|
case item
|
@@ -75,7 +76,7 @@ module Twterm
|
|
75
76
|
'Preferences'
|
76
77
|
end
|
77
78
|
|
78
|
-
cursor - Image.whitespace - Image.string(desc)
|
79
|
+
cursor - Image.whitespace - Image.string(desc).bold(curr)
|
79
80
|
}
|
80
81
|
.intersperse(Image.blank_line)
|
81
82
|
.reduce(Image.empty, :|)
|
@@ -21,14 +21,15 @@ module Twterm
|
|
21
21
|
|
22
22
|
def image
|
23
23
|
drawable_items.map.with_index do |item, i|
|
24
|
-
|
24
|
+
curr = scroller.current_index?(i)
|
25
|
+
cursor = Image.cursor(1, curr)
|
25
26
|
desc =
|
26
27
|
case item
|
27
28
|
when :notification_backend
|
28
29
|
'Notification backend preferences'
|
29
30
|
end
|
30
31
|
|
31
|
-
cursor - Image.whitespace - Image.string(desc)
|
32
|
+
cursor - Image.whitespace - Image.string(desc).bold(curr)
|
32
33
|
end
|
33
34
|
.intersperse(Image.blank_line)
|
34
35
|
.reduce(Image.empty) { |acc, x| acc | x }
|
@@ -17,7 +17,8 @@ module Twterm
|
|
17
17
|
|
18
18
|
def image
|
19
19
|
drawable_items.map.with_index do |item, i|
|
20
|
-
|
20
|
+
curr = scroller.current_index?(i)
|
21
|
+
cursor = Image.cursor(1, curr)
|
21
22
|
checkbox = Image.checkbox(app.preferences[:notification_backend, item])
|
22
23
|
desc =
|
23
24
|
case item
|
@@ -29,7 +30,7 @@ module Twterm
|
|
29
30
|
'Terminal Notifier backend'
|
30
31
|
end
|
31
32
|
|
32
|
-
cursor - Image.whitespace - checkbox - Image.whitespace - Image.string(desc)
|
33
|
+
cursor - Image.whitespace - checkbox - Image.whitespace - Image.string(desc).bold(curr)
|
33
34
|
end
|
34
35
|
.intersperse(Image.blank_line)
|
35
36
|
.reduce(Image.empty) { |acc, x| acc | x }
|
@@ -0,0 +1,226 @@
|
|
1
|
+
require 'addressable/uri'
|
2
|
+
|
3
|
+
require 'twterm/event/open_uri'
|
4
|
+
require 'twterm/hashtag'
|
5
|
+
require 'twterm/image'
|
6
|
+
require 'twterm/image_builder/user_name_image_builder'
|
7
|
+
require 'twterm/publisher'
|
8
|
+
require 'twterm/tab/base'
|
9
|
+
require 'twterm/tab/dumpable'
|
10
|
+
require 'twterm/tab/loadable'
|
11
|
+
require 'twterm/tab/scrollable'
|
12
|
+
|
13
|
+
module Twterm
|
14
|
+
module Tab
|
15
|
+
class StatusTab < Tab::Base
|
16
|
+
include Dumpable
|
17
|
+
include Publisher
|
18
|
+
include Tab::Scrollable
|
19
|
+
|
20
|
+
def initialize(app, client, status_id)
|
21
|
+
super(app, client)
|
22
|
+
|
23
|
+
@status_id = status_id
|
24
|
+
end
|
25
|
+
|
26
|
+
def drawable_item_count
|
27
|
+
(window.maxy - status.text.split_by_width(window.maxx - 4).count - 6).div(2)
|
28
|
+
end
|
29
|
+
|
30
|
+
def dump
|
31
|
+
status_id
|
32
|
+
end
|
33
|
+
|
34
|
+
def image
|
35
|
+
if status.nil?
|
36
|
+
find_or_fetch_status(status_id).then { render }
|
37
|
+
return Image.string('Loading...')
|
38
|
+
end
|
39
|
+
|
40
|
+
if user.nil?
|
41
|
+
find_or_fetch_user(status.user_id).then { render }
|
42
|
+
return Image.string('Loading...')
|
43
|
+
end
|
44
|
+
|
45
|
+
header = [
|
46
|
+
ImageBuilder::UserNameImageBuilder.new(user).build,
|
47
|
+
Image.string(status.date.to_s).brackets,
|
48
|
+
(Image.whitespace.color(:black, :red) if status.favorited?),
|
49
|
+
(Image.whitespace.color(:black, :green) if status.retweeted?),
|
50
|
+
((Image.number(status.favorite_count) - Image.plural(status.favorite_count, 'like')).color(:red) if status.favorite_count.positive?),
|
51
|
+
((Image.number(status.retweet_count) - Image.plural(status.retweet_count, 'RT')).color(:green) if status.retweet_count.positive?),
|
52
|
+
].compact.intersperse(Image.whitespace).reduce(Image.empty, :-)
|
53
|
+
|
54
|
+
[
|
55
|
+
header,
|
56
|
+
Image.blank_line,
|
57
|
+
*status.text.split_by_width(window.maxx - 4).map { |x| Image.string(x) },
|
58
|
+
Image.blank_line,
|
59
|
+
Image.blank_line,
|
60
|
+
*drawable_items.flat_map.with_index do |item, i|
|
61
|
+
curr = scroller.current_index?(i)
|
62
|
+
Image.cursor(1, curr) - Image.whitespace - image_for_item(item).bold(curr)
|
63
|
+
end.intersperse(Image.blank_line),
|
64
|
+
].reduce(Image.empty) { |acc, x| acc | x }
|
65
|
+
end
|
66
|
+
|
67
|
+
def items
|
68
|
+
[
|
69
|
+
:reply,
|
70
|
+
:favorite,
|
71
|
+
:retweet,
|
72
|
+
:quote,
|
73
|
+
(:destroy if user.id == client.user_id),
|
74
|
+
:show_user,
|
75
|
+
:open_in_browser,
|
76
|
+
*status.media,
|
77
|
+
*status.urls,
|
78
|
+
*status.hashtags,
|
79
|
+
*status.user_mentions,
|
80
|
+
].compact
|
81
|
+
end
|
82
|
+
|
83
|
+
def respond_to_key(key)
|
84
|
+
return true if scroller.respond_to_key(key)
|
85
|
+
|
86
|
+
case key
|
87
|
+
when 10
|
88
|
+
perform_selected_action
|
89
|
+
else
|
90
|
+
return false
|
91
|
+
end
|
92
|
+
|
93
|
+
true
|
94
|
+
end
|
95
|
+
|
96
|
+
def title
|
97
|
+
user.nil? ? 'Loading...' : "@#{user.screen_name}'s tweet"
|
98
|
+
end
|
99
|
+
|
100
|
+
private
|
101
|
+
|
102
|
+
attr_reader :status_id
|
103
|
+
|
104
|
+
def destroy!
|
105
|
+
client
|
106
|
+
.destroy_status(status)
|
107
|
+
.then { app.tab_manager.close }
|
108
|
+
end
|
109
|
+
|
110
|
+
def favorite!
|
111
|
+
if status.favorited?
|
112
|
+
client.unfavorite(status).then { status.unfavorite! }
|
113
|
+
else
|
114
|
+
client.favorite(status).then { status.favorite! }
|
115
|
+
end
|
116
|
+
.then { render }
|
117
|
+
end
|
118
|
+
|
119
|
+
def highlight_with_entity(text, entity)
|
120
|
+
starts, ends = entity.indices
|
121
|
+
Image.string(text[0...starts]) - Image.string(text[starts...ends]).bold - Image.string(text[y...text.length])
|
122
|
+
end
|
123
|
+
|
124
|
+
# @return [Twterm::Image]
|
125
|
+
def image_for_item(item)
|
126
|
+
case item
|
127
|
+
when :reply
|
128
|
+
Image.string('Reply to this tweet')
|
129
|
+
when :favorite
|
130
|
+
Image.string(status.favorited? ? 'Unlike this tweet' : 'Like this tweet')
|
131
|
+
when :retweet
|
132
|
+
Image.string(status.retweeted? ? 'Unretweet this tweet' : 'Retweet this tweet')
|
133
|
+
when :quote
|
134
|
+
Image.string('Quote this tweet')
|
135
|
+
when :destroy
|
136
|
+
Image.string('Delete this tweet')
|
137
|
+
when :show_user
|
138
|
+
Image.string("Show user (@#{user.screen_name})")
|
139
|
+
when :open_in_browser
|
140
|
+
Image.string("Open this tweet in browser (#{status.url})")
|
141
|
+
when Addressable::URI
|
142
|
+
Image.string(item.to_s)
|
143
|
+
when Hashtag
|
144
|
+
Image.string("[Hashtag] ##{item.text}")
|
145
|
+
when Twitter::Entity::UserMention
|
146
|
+
Image.string("[User] #{item.name} (@#{item.screen_name})")
|
147
|
+
when Twitter::Entity::URI
|
148
|
+
Image.string("[URL] #{item.expanded_url}")
|
149
|
+
when Twitter::Media::AnimatedGif
|
150
|
+
url = item.video_info.variants.max { |v| v.bitrate }.url
|
151
|
+
Image.string("[GIF] #{url}")
|
152
|
+
when Twitter::Media::Photo
|
153
|
+
Image.string("[Photo] #{item.media_url_https}")
|
154
|
+
when Twitter::Media::Video
|
155
|
+
url = item.video_info.variants.max { |v| v.bitrate }.url
|
156
|
+
Image.string("[Video] #{url}")
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
def perform_selected_action
|
161
|
+
item = scroller.current_item
|
162
|
+
|
163
|
+
case item
|
164
|
+
when :reply
|
165
|
+
reply!
|
166
|
+
when :favorite
|
167
|
+
favorite!
|
168
|
+
when :retweet
|
169
|
+
retweet!
|
170
|
+
when :quote
|
171
|
+
quote!
|
172
|
+
when :destroy
|
173
|
+
destroy!
|
174
|
+
when :show_user
|
175
|
+
show_user!
|
176
|
+
when :open_in_browser
|
177
|
+
publish(Event::OpenURI.new(status.url))
|
178
|
+
when Hashtag
|
179
|
+
tab = Tab::Statuses::Search.new(app, client, "##{item.text}")
|
180
|
+
app.tab_manager.add_and_show(tab)
|
181
|
+
when Twitter::Entity::UserMention
|
182
|
+
tab = Tab::UserTab.new(app, client, item.id)
|
183
|
+
app.tab_manager.add_and_show(tab)
|
184
|
+
when Twitter::Entity::URI
|
185
|
+
publish(Event::OpenURI.new(item.expanded_url))
|
186
|
+
when Twitter::Media::Photo
|
187
|
+
publish(Event::OpenURI.new(item.media_url_https))
|
188
|
+
when Twitter::Media::AnimatedGif, Twitter::Media::Video
|
189
|
+
url = item.video_info.variants.max { |v| v.bitrate }.url
|
190
|
+
publish(Event::OpenURI.new(url))
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
def quote!
|
195
|
+
app.tweetbox.quote(status)
|
196
|
+
end
|
197
|
+
|
198
|
+
def reply!
|
199
|
+
app.tweetbox.reply(status)
|
200
|
+
end
|
201
|
+
|
202
|
+
def retweet!
|
203
|
+
if status.retweeted?
|
204
|
+
client.unretweet(status).then { status.unretweet! }
|
205
|
+
else
|
206
|
+
client.retweet(status).then { status.retweet! }
|
207
|
+
end
|
208
|
+
.then { render }
|
209
|
+
end
|
210
|
+
|
211
|
+
def show_user!
|
212
|
+
user_id = status.user_id
|
213
|
+
user_tab = Tab::UserTab.new(app, client, user_id)
|
214
|
+
app.tab_manager.add_and_show(user_tab)
|
215
|
+
end
|
216
|
+
|
217
|
+
def status
|
218
|
+
app.status_repository.find(status_id)
|
219
|
+
end
|
220
|
+
|
221
|
+
def user
|
222
|
+
status.nil? ? nil : app.user_repository.find(status.user_id)
|
223
|
+
end
|
224
|
+
end
|
225
|
+
end
|
226
|
+
end
|
@@ -3,10 +3,12 @@ require 'concurrent'
|
|
3
3
|
require 'twterm/event/open_uri'
|
4
4
|
require 'twterm/event/status/delete'
|
5
5
|
require 'twterm/event/status_garbage_collected'
|
6
|
+
require 'twterm/image_builder/user_name_image_builder'
|
6
7
|
require 'twterm/publisher'
|
7
8
|
require 'twterm/subscriber'
|
8
9
|
require 'twterm/tab/base'
|
9
10
|
require 'twterm/tab/loadable'
|
11
|
+
require 'twterm/tab/status_tab'
|
10
12
|
require 'twterm/utils'
|
11
13
|
|
12
14
|
module Twterm
|
@@ -134,6 +136,8 @@ module Twterm
|
|
134
136
|
k = KeyMapper.instance
|
135
137
|
|
136
138
|
case key
|
139
|
+
when 10
|
140
|
+
open_status_tab
|
137
141
|
when k[:status, :conversation]
|
138
142
|
show_conversation
|
139
143
|
when k[:status, :destroy]
|
@@ -221,8 +225,7 @@ module Twterm
|
|
221
225
|
retweeted_by = app.user_repository.find(status.user_id)
|
222
226
|
|
223
227
|
header = [
|
224
|
-
|
225
|
-
Image.string("@#{user.screen_name}").parens,
|
228
|
+
ImageBuilder::UserNameImageBuilder.new(user).build,
|
226
229
|
Image.string(original.date.to_s).brackets,
|
227
230
|
(Image.whitespace.color(:black, :red) if original.favorited?),
|
228
231
|
(Image.whitespace.color(:black, :green) if original.retweeted?),
|
@@ -244,6 +247,15 @@ module Twterm
|
|
244
247
|
.reduce(Image.empty, :|)
|
245
248
|
end
|
246
249
|
|
250
|
+
def open_status_tab
|
251
|
+
status = highlighted_original_status
|
252
|
+
|
253
|
+
return if status.nil?
|
254
|
+
|
255
|
+
tab = Tab::StatusTab.new(app, client, highlighted_original_status.id)
|
256
|
+
app.tab_manager.add_and_show(tab)
|
257
|
+
end
|
258
|
+
|
247
259
|
def reload
|
248
260
|
fetch.then do |statuses|
|
249
261
|
statuses.each { |s| append(s) }
|
@@ -46,9 +46,10 @@ module Twterm
|
|
46
46
|
return Image.string(initially_loaded? ? 'No lists found' : 'Loading...') if items.empty?
|
47
47
|
|
48
48
|
drawable_items.map.with_index do |list, i|
|
49
|
-
|
49
|
+
curr = scroller.current_index?(i)
|
50
|
+
cursor = Image.cursor(2, curr)
|
50
51
|
|
51
|
-
summary = Image.checkbox(@list_ids.include?(list.id)) - Image.whitespace - Image.string(list.full_name)
|
52
|
+
summary = Image.checkbox(@list_ids.include?(list.id)) - Image.whitespace - Image.string(list.full_name).bold(curr)
|
52
53
|
description = Image.string(' ') - Image.string(list.description)
|
53
54
|
|
54
55
|
cursor - Image.whitespace - (summary | description)
|
data/lib/twterm/tab/user_tab.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'twterm/event/open_uri'
|
2
2
|
require 'twterm/publisher'
|
3
|
+
require 'twterm/image_builder/user_name_image_builder'
|
3
4
|
require 'twterm/tab/base'
|
4
5
|
require 'twterm/tab/user_list_management'
|
5
6
|
|
@@ -233,7 +234,7 @@ module Twterm
|
|
233
234
|
return Image.empty
|
234
235
|
end
|
235
236
|
|
236
|
-
name =
|
237
|
+
name = ImageBuilder::UserNameImageBuilder.new(user).build
|
237
238
|
|
238
239
|
badges = [
|
239
240
|
(Image.string('protected').brackets.color(:yellow) if user.protected?),
|
@@ -264,8 +265,9 @@ module Twterm
|
|
264
265
|
|
265
266
|
location = Image.string("Location: #{user.location}")
|
266
267
|
|
267
|
-
|
268
|
-
|
268
|
+
actions = drawable_items.map.with_index(0) do |item, i|
|
269
|
+
curr = scroller.current_index?(i)
|
270
|
+
Image.cursor(1, curr) - Image.whitespace -
|
269
271
|
case item
|
270
272
|
when :compose_direct_message
|
271
273
|
Image.string('Compose direct message')
|
@@ -302,11 +304,12 @@ module Twterm
|
|
302
304
|
when :manage_lists
|
303
305
|
Image.string('Add to / Remove from lists')
|
304
306
|
end
|
307
|
+
.bold(curr)
|
305
308
|
end
|
306
309
|
.intersperse(Image.blank_line)
|
307
310
|
.reduce(Image.empty, :|)
|
308
311
|
|
309
|
-
[name, badges, status, description, location,
|
312
|
+
[name, badges, status, description, location, Image.blank_line | actions]
|
310
313
|
.compact
|
311
314
|
.intersperse(Image.blank_line)
|
312
315
|
.reduce(Image.empty, :|)
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'concurrent'
|
2
2
|
|
3
3
|
require 'twterm/event/user_garbage_collected'
|
4
|
+
require 'twterm/image_builder/user_name_image_builder'
|
4
5
|
require 'twterm/tab/base'
|
5
6
|
require 'twterm/tab/loadable'
|
6
7
|
|
@@ -74,8 +75,7 @@ module Twterm
|
|
74
75
|
cursor = Image.cursor(2, scroller.current_index?(i))
|
75
76
|
|
76
77
|
header = [
|
77
|
-
|
78
|
-
Image.string("@#{user.screen_name}"),
|
78
|
+
ImageBuilder::UserNameImageBuilder.new(user).build,
|
79
79
|
(Image.string('protected').brackets.color(:yellow) if user.protected?),
|
80
80
|
(Image.string('verified').brackets.color(:cyan) if user.verified?),
|
81
81
|
].compact.intersperse(Image.whitespace).reduce(Image.empty, :-)
|
data/lib/twterm/tab_manager.rb
CHANGED
@@ -45,7 +45,7 @@ module Twterm
|
|
45
45
|
current_tab.render
|
46
46
|
refresh_window
|
47
47
|
rescue Tab::NotClosableError
|
48
|
-
publish(Event::Message::Warning.new('this tab cannot be closed'
|
48
|
+
publish(Event::Message::Warning.new('this tab cannot be closed'))
|
49
49
|
end
|
50
50
|
|
51
51
|
def current_tab
|
data/lib/twterm/user.rb
CHANGED
@@ -1,17 +1,14 @@
|
|
1
1
|
module Twterm
|
2
2
|
class User
|
3
|
-
attr_reader :
|
3
|
+
attr_reader :description, :favorites_count, :followers_count,
|
4
4
|
:friends_count, :id, :location, :name, :protected,
|
5
5
|
:screen_name, :statuses_count, :url, :verified, :website
|
6
6
|
alias_method :protected?, :protected
|
7
7
|
alias_method :verified?, :verified
|
8
8
|
|
9
|
-
COLORS = [:red, :blue, :green, :cyan, :yellow, :magenta]
|
10
|
-
|
11
9
|
def initialize(user)
|
12
10
|
@id = user.id
|
13
11
|
update!(user)
|
14
|
-
@color = COLORS[@id % 6]
|
15
12
|
end
|
16
13
|
|
17
14
|
def update!(user)
|
data/lib/twterm/version.rb
CHANGED
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'twterm/image_builder/user_name_image_builder'
|
2
|
+
|
3
|
+
RSpec.describe Twterm::ImageBuilder::UserNameImageBuilder do
|
4
|
+
|
5
|
+
describe '#build' do
|
6
|
+
let(:json) {
|
7
|
+
json = JSON.parse(fixture('user.json'), symbolize_names: true)
|
8
|
+
|
9
|
+
json[:screen_name] = screen_name
|
10
|
+
json[:name] = name
|
11
|
+
|
12
|
+
json
|
13
|
+
}
|
14
|
+
let(:user) { Twterm::User.new(Twitter::User.new(json)) }
|
15
|
+
let(:builder) { described_class.new(user) }
|
16
|
+
let(:image) { builder.build }
|
17
|
+
let(:screen_name) { 'alice42' }
|
18
|
+
let(:name) { 'Alice' }
|
19
|
+
|
20
|
+
it "builds an image containing user's screen name" do
|
21
|
+
expect(image.to_s).to include screen_name
|
22
|
+
end
|
23
|
+
|
24
|
+
it "builds an image containing user's name" do
|
25
|
+
expect(image.to_s).to include name
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/twterm.gemspec
CHANGED
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: 2.
|
4
|
+
version: 2.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryota Kameoka
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-04-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: curses
|
@@ -192,6 +192,20 @@ dependencies:
|
|
192
192
|
- - "~>"
|
193
193
|
- !ruby/object:Gem::Version
|
194
194
|
version: 0.51.0
|
195
|
+
- !ruby/object:Gem::Dependency
|
196
|
+
name: yard
|
197
|
+
requirement: !ruby/object:Gem::Requirement
|
198
|
+
requirements:
|
199
|
+
- - "~>"
|
200
|
+
- !ruby/object:Gem::Version
|
201
|
+
version: 0.9.12
|
202
|
+
type: :development
|
203
|
+
prerelease: false
|
204
|
+
version_requirements: !ruby/object:Gem::Requirement
|
205
|
+
requirements:
|
206
|
+
- - "~>"
|
207
|
+
- !ruby/object:Gem::Version
|
208
|
+
version: 0.9.12
|
195
209
|
description: A full-featured TUI Twitter client
|
196
210
|
email:
|
197
211
|
- kameoka.ryota@gmail.com
|
@@ -253,6 +267,7 @@ files:
|
|
253
267
|
- lib/twterm/extensions/enumerator/lazy.rb
|
254
268
|
- lib/twterm/extensions/string.rb
|
255
269
|
- lib/twterm/friendship.rb
|
270
|
+
- lib/twterm/hashtag.rb
|
256
271
|
- lib/twterm/image.rb
|
257
272
|
- lib/twterm/image/between.rb
|
258
273
|
- lib/twterm/image/blank_line.rb
|
@@ -264,6 +279,7 @@ files:
|
|
264
279
|
- lib/twterm/image/parens.rb
|
265
280
|
- lib/twterm/image/string_image.rb
|
266
281
|
- lib/twterm/image/vertical_sequential_image.rb
|
282
|
+
- lib/twterm/image_builder/user_name_image_builder.rb
|
267
283
|
- lib/twterm/key_mapper.rb
|
268
284
|
- lib/twterm/key_mapper/abstract_key_mapper.rb
|
269
285
|
- lib/twterm/key_mapper/app_key_mapper.rb
|
@@ -316,6 +332,7 @@ files:
|
|
316
332
|
- lib/twterm/tab/rate_limit_status.rb
|
317
333
|
- lib/twterm/tab/scrollable.rb
|
318
334
|
- lib/twterm/tab/searchable.rb
|
335
|
+
- lib/twterm/tab/status_tab.rb
|
319
336
|
- lib/twterm/tab/statuses/base.rb
|
320
337
|
- lib/twterm/tab/statuses/cacheable.rb
|
321
338
|
- lib/twterm/tab/statuses/conversation.rb
|
@@ -357,6 +374,7 @@ files:
|
|
357
374
|
- spec/twterm/image/parens_spec.rb
|
358
375
|
- spec/twterm/image/string_image_spec.rb
|
359
376
|
- spec/twterm/image/vertical_sequential_image_spec.rb
|
377
|
+
- spec/twterm/image_builder/user_name_image_builder_spec.rb
|
360
378
|
- spec/twterm/image_spec.rb
|
361
379
|
- spec/twterm/key_mapper/abstract_key_mapper_spec.rb
|
362
380
|
- spec/twterm/key_mapper/app_key_mapper_spec.rb
|
@@ -386,7 +404,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
386
404
|
version: '0'
|
387
405
|
requirements: []
|
388
406
|
rubyforge_project:
|
389
|
-
rubygems_version: 2.7.
|
407
|
+
rubygems_version: 2.7.6
|
390
408
|
signing_key:
|
391
409
|
specification_version: 4
|
392
410
|
summary: A full-featured TUI Twitter client
|