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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bce2d4276a631793204a44044b38afaa43f02d2c16bcc6daf68653288d1c5e12
4
- data.tar.gz: e1307f6b9623eb96f2659406377888283d5a912fd30caf0d20737852a62e9b9c
3
+ metadata.gz: d251a92afa7b450c2da0556f66fe431d6db851633b739601e0c47cb5ad45baa5
4
+ data.tar.gz: a014a40ac7b5d15859880b157375ebe372e011a4a76153fc93b66075ad3a594c
5
5
  SHA512:
6
- metadata.gz: 43c9cce69344a7e7cc8107793bc79f133ffe1ff134ec422eacbae4ae449661c0b57e7f6b15a241bb5d69db4c58d6bc22065badc9b85f1203bc29e130d8711fb9
7
- data.tar.gz: fdad1dfb3aff8e7f66a94d00db63e5bd3d1e274072c17664e23ebb3de0a38dc26ebc2f9229f8172b14e84c1d71971cea05aba7ca9133eb7f537f03c33dbc8508
6
+ metadata.gz: 5dc37cf71fa46b22cb7e69efc5a3ad09c2fd0a65ba8c77869e6d2a494159aace7691653fe0b001952edef57153a39f5be1715ca0447fc1aa04712130aabc40f5
7
+ data.tar.gz: de94a92f370e94e509063132cd69a8525df015d9825393e7570ba7d55c99466042aaab7d4261ac1e6559b4518703792ead41433a8c2ad1817115e01a7c3e7da3
data/bin/twterm CHANGED
@@ -1,5 +1,9 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
+ if RUBY_VERSION >= '2.5.0'
4
+ Thread.report_on_exception = false
5
+ end
6
+
3
7
  if ARGV.count == 1 && (%w(-v --version).include?(ARGV.first))
4
8
  require 'twterm/version'
5
9
  puts 'twterm version %s' % Twterm::VERSION
data/lib/twterm/app.rb CHANGED
@@ -129,7 +129,7 @@ module Twterm
129
129
 
130
130
  status_repository.before_create do |tweet|
131
131
  tweet.hashtags.each do |hashtag|
132
- hashtag_repository.create(hashtag.text)
132
+ hashtag_repository.create(hashtag)
133
133
  end
134
134
  end
135
135
 
@@ -6,7 +6,7 @@ module Twterm
6
6
  def complete(query)
7
7
  if query.start_with?('#')
8
8
  app.hashtag_repository.all
9
- .map { |tag| "##{tag}" }
9
+ .map { |tag| "##{tag.text}" }
10
10
  .select { |tag| tag.start_with?(query) }
11
11
  elsif query.start_with?('@')
12
12
  app.user_repository.all
@@ -14,7 +14,7 @@ module Twterm
14
14
  operators
15
15
  elsif q.start_with?('#')
16
16
  app.hashtag_repository.all
17
- .map { |tag| "##{tag} " }
17
+ .map { |tag| "##{tag.text} " }
18
18
  .select { |tag| tag.start_with?(q) }
19
19
  elsif q.start_with?('@')
20
20
  app.user_repository.all
@@ -0,0 +1,9 @@
1
+ module Twterm
2
+ class Hashtag
3
+ attr_reader :text
4
+
5
+ def initialize(hashtag)
6
+ @text = hashtag.text
7
+ end
8
+ end
9
+ end
data/lib/twterm/image.rb CHANGED
@@ -36,8 +36,8 @@ class Twterm::Image
36
36
  BlankLine.new
37
37
  end
38
38
 
39
- def bold
40
- Bold.new(self)
39
+ def bold(on = true)
40
+ on ? Bold.new(self) : self
41
41
  end
42
42
 
43
43
  def brackets
@@ -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
@@ -1,3 +1,4 @@
1
+ require 'twterm/hashtag'
1
2
  require 'twterm/repository/abstract_repository'
2
3
 
3
4
  module Twterm
@@ -32,7 +33,7 @@ module Twterm
32
33
  end
33
34
 
34
35
  def type
35
- String
36
+ Hashtag
36
37
  end
37
38
  end
38
39
  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
- !Image.string(sender.name).color(sender.color),
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
- !Image.string(collocutor.name).color(collocutor.color),
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
 
@@ -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
- cursor = Image.cursor(2, scroller.current_index?(i))
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
- Image.cursor(1, scroller.current_index?(i)) - Image.whitespace - Image.string(query)
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
  ]
@@ -55,7 +55,8 @@ module Twterm
55
55
  def image
56
56
  drawable_items
57
57
  .map.with_index(0) { |item, i|
58
- cursor = Image.cursor(1, scroller.current_index?(i))
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
- cursor = Image.cursor(1, scroller.current_index?(i))
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
- cursor = Image.cursor(1, scroller.current_index?(i))
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
- !Image.string(user.name).color(user.color),
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
- cursor = Image.cursor(2, scroller.current_index?(i))
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)
@@ -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 = !Image.string(user.name) - Image.whitespace - Image.string("@#{user.screen_name}").parens
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
- foo = drawable_items.map.with_index(0) do |item, i|
268
- Image.cursor(1, scroller.current_index?(i)) - Image.whitespace -
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, foo]
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
- !Image.string(user.name).color(user.color),
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, :-)
@@ -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', '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 :color, :description, :favorites_count, :followers_count,
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)
@@ -1,3 +1,3 @@
1
1
  module Twterm
2
- VERSION = '2.2.0'
2
+ VERSION = '2.3.0'
3
3
  end
@@ -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
@@ -32,4 +32,5 @@ Gem::Specification.new do |spec|
32
32
  spec.add_development_dependency 'rake', '~> 12.0'
33
33
  spec.add_development_dependency 'rspec', '~> 3.7.0'
34
34
  spec.add_development_dependency 'rubocop', '~> 0.51.0'
35
+ spec.add_development_dependency 'yard', '~> 0.9.12'
35
36
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: twterm
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.0
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-01-20 00:00:00.000000000 Z
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.4
407
+ rubygems_version: 2.7.6
390
408
  signing_key:
391
409
  specification_version: 4
392
410
  summary: A full-featured TUI Twitter client