twterm 2.2.0 → 2.3.0
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/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
|