twterm 2.5.0 → 2.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +62 -0
  3. data/.gitignore +1 -0
  4. data/Makefile +18 -0
  5. data/README.md +30 -4
  6. data/bin/twterm +1 -3
  7. data/default.nix +21 -0
  8. data/gemset.nix +5130 -0
  9. data/lib/twterm/app.rb +0 -18
  10. data/lib/twterm/client.rb +1 -6
  11. data/lib/twterm/color_manager.rb +8 -9
  12. data/lib/twterm/image.rb +26 -0
  13. data/lib/twterm/image/underlined.rb +31 -0
  14. data/lib/twterm/image_builder/user_name_image_builder.rb +1 -0
  15. data/lib/twterm/key_mapper.rb +6 -8
  16. data/lib/twterm/key_mapper/abstract_key_mapper.rb +2 -2
  17. data/lib/twterm/list.rb +36 -1
  18. data/lib/twterm/message_window.rb +4 -5
  19. data/lib/twterm/persistable_configuration_proxy.rb +6 -6
  20. data/lib/twterm/preferences.rb +8 -1
  21. data/lib/twterm/rest_client.rb +0 -33
  22. data/lib/twterm/screen.rb +54 -14
  23. data/lib/twterm/search_query_window.rb +4 -5
  24. data/lib/twterm/status.rb +10 -0
  25. data/lib/twterm/tab/abstract_tab.rb +33 -8
  26. data/lib/twterm/tab/new/index.rb +0 -10
  27. data/lib/twterm/tab/new/list.rb +3 -3
  28. data/lib/twterm/tab/new/search.rb +2 -2
  29. data/lib/twterm/tab/new/user.rb +2 -2
  30. data/lib/twterm/tab/preferences/control.rb +77 -0
  31. data/lib/twterm/tab/preferences/index.rb +6 -0
  32. data/lib/twterm/tab/status_tab.rb +10 -0
  33. data/lib/twterm/tab/statuses/abstract_statuses_tab.rb +4 -4
  34. data/lib/twterm/tab/statuses/home.rb +0 -3
  35. data/lib/twterm/tab/statuses/mentions.rb +1 -0
  36. data/lib/twterm/tab/user_tab.rb +0 -9
  37. data/lib/twterm/tab_manager.rb +77 -5
  38. data/lib/twterm/tweetbox.rb +2 -3
  39. data/lib/twterm/user.rb +1 -0
  40. data/lib/twterm/version.rb +1 -1
  41. data/nix/Gemfile +3 -0
  42. data/nix/Gemfile.lock +70 -0
  43. data/nix/gemset.nix +283 -0
  44. data/shell.nix +40 -0
  45. data/twterm.gemspec +13 -13
  46. metadata +42 -44
  47. data/.travis.yml +0 -12
  48. data/lib/twterm/direct_message.rb +0 -60
  49. data/lib/twterm/direct_message_composer.rb +0 -80
  50. data/lib/twterm/direct_message_manager.rb +0 -51
  51. data/lib/twterm/event/direct_message/fetched.rb +0 -10
  52. data/lib/twterm/event/notification/direct_message.rb +0 -30
  53. data/lib/twterm/event/status/timeline.rb +0 -10
  54. data/lib/twterm/repository/direct_message_repository.rb +0 -14
  55. data/lib/twterm/streaming_client.rb +0 -146
  56. data/lib/twterm/tab/direct_message/conversation.rb +0 -104
  57. data/lib/twterm/tab/direct_message/conversation_list.rb +0 -100
@@ -1,4 +1,5 @@
1
1
  require 'twterm/image'
2
+ require 'twterm/tab/preferences/control'
2
3
  require 'twterm/tab/preferences/notification_backend'
3
4
  require 'twterm/tab/preferences/photo_viewer_backend'
4
5
  require 'twterm/preferences'
@@ -26,6 +27,8 @@ module Twterm
26
27
  cursor = Image.cursor(1, curr)
27
28
  desc =
28
29
  case item
30
+ when :control
31
+ 'Control preferences'
29
32
  when :notification_backend
30
33
  'Notification backend preferences'
31
34
  when :photo_viewer_backend
@@ -40,6 +43,7 @@ module Twterm
40
43
 
41
44
  def items
42
45
  [
46
+ :control,
43
47
  :notification_backend,
44
48
  :photo_viewer_backend,
45
49
  ]
@@ -67,6 +71,8 @@ module Twterm
67
71
  def open
68
72
  tab =
69
73
  case scroller.current_item
74
+ when :control
75
+ Tab::Preferences::Control.new(app, client)
70
76
  when :notification_backend
71
77
  Tab::Preferences::NotificationBackend.new(app, client)
72
78
  when :photo_viewer_backend
@@ -67,6 +67,7 @@ module Twterm
67
67
 
68
68
  def items
69
69
  [
70
+ :show_conversation,
70
71
  :reply,
71
72
  :favorite,
72
73
  :retweet,
@@ -135,6 +136,8 @@ module Twterm
135
136
  Image.string('Quote this tweet')
136
137
  when :destroy
137
138
  Image.string('Delete this tweet')
139
+ when :show_conversation
140
+ Image.string("Show conversation")
138
141
  when :show_user
139
142
  Image.string("Show user (@#{user.screen_name})")
140
143
  when :open_in_browser
@@ -172,6 +175,8 @@ module Twterm
172
175
  quote!
173
176
  when :destroy
174
177
  destroy!
178
+ when :show_conversation
179
+ show_conversation!
175
180
  when :show_user
176
181
  show_user!
177
182
  when :open_in_browser
@@ -209,6 +214,11 @@ module Twterm
209
214
  .then { render }
210
215
  end
211
216
 
217
+ def show_conversation!
218
+ tab = Tab::Statuses::Conversation.new(app, client, status_id)
219
+ app.tab_manager.add_and_show(tab)
220
+ end
221
+
212
222
  def show_user!
213
223
  user_id = status.user_id
214
224
  user_tab = Tab::UserTab.new(app, client, user_id)
@@ -27,7 +27,7 @@ module Twterm
27
27
  return if @status_ids.include?(status.id)
28
28
 
29
29
  @status_ids.push(status.id)
30
- status.split(window.maxx - 4)
30
+ status.split(window.maxx - 2)
31
31
  scroller.item_appended!
32
32
  render
33
33
  end
@@ -46,7 +46,7 @@ module Twterm
46
46
 
47
47
  def drawable_item_count
48
48
  statuses.drop(scroller.offset).lazy
49
- .map { |s| s.split(window.maxx - 4).count + 2 }
49
+ .map { |s| s.split(window.maxx - 2).count + 2 }
50
50
  .scan(0, :+)
51
51
  .each_cons(2)
52
52
  .select { |_, l| l < window.maxy }
@@ -113,7 +113,7 @@ module Twterm
113
113
  return if @status_ids.include?(status.id)
114
114
 
115
115
  @status_ids.unshift(status.id)
116
- status.split(window.maxx - 4)
116
+ status.split(window.maxx - 2)
117
117
  scroller.item_prepended!
118
118
  render
119
119
  end
@@ -235,7 +235,7 @@ module Twterm
235
235
  ].compact.intersperse(Image.whitespace).reduce(Image.empty, :-)
236
236
 
237
237
  body = original
238
- .split(window.maxx - 4)
238
+ .split(window.maxx - 2)
239
239
  .map(&Image.method(:string))
240
240
  .reduce(Image.empty, :|)
241
241
 
@@ -1,5 +1,4 @@
1
1
  require 'twterm/subscriber'
2
- require 'twterm/event/status/timeline'
3
2
  require 'twterm/tab/statuses/abstract_statuses_tab'
4
3
  require 'twterm/utils'
5
4
 
@@ -21,8 +20,6 @@ module Twterm
21
20
  def initialize(app, client)
22
21
  super(app, client)
23
22
 
24
- subscribe(Event::Status::Timeline) { |e| prepend(e.status) }
25
-
26
23
  reload.then do
27
24
  initially_loaded!
28
25
  scroller.move_to_top
@@ -1,4 +1,5 @@
1
1
  require 'twterm/tab/statuses/abstract_statuses_tab'
2
+ require 'twterm/event/status/mention'
2
3
 
3
4
  module Twterm
4
5
  module Tab
@@ -53,7 +53,6 @@ module Twterm
53
53
  :profile_image,
54
54
  (:profile_background_image unless user.profile_background_image.nil?),
55
55
  :manage_lists,
56
- (:compose_direct_message unless myself?),
57
56
  (:open_website unless user.website.nil?),
58
57
  (:toggle_follow unless myself?),
59
58
  (:toggle_mute unless myself?),
@@ -96,10 +95,6 @@ module Twterm
96
95
  app.friendship_repository.blocking?(client.user_id, user_id)
97
96
  end
98
97
 
99
- def compose_direct_message
100
- app.direct_message_composer.compose(user)
101
- end
102
-
103
98
  def follow
104
99
  client.follow(user_id).then do |users|
105
100
  render
@@ -176,8 +171,6 @@ module Twterm
176
171
 
177
172
  def perform_selected_action
178
173
  case scroller.current_item
179
- when :compose_direct_message
180
- compose_direct_message
181
174
  when :manage_lists
182
175
  open_list_management_tab
183
176
  when :open_in_browser
@@ -294,8 +287,6 @@ module Twterm
294
287
  curr = scroller.current_index?(i)
295
288
  Image.cursor(1, curr) - Image.whitespace -
296
289
  case item
297
- when :compose_direct_message
298
- Image.string('Compose direct message')
299
290
  when :toggle_block
300
291
  if blocking?
301
292
  Image.string('Unblock this user')
@@ -6,7 +6,6 @@ require 'twterm/view'
6
6
 
7
7
  module Twterm
8
8
  class TabManager
9
- include Curses
10
9
  include Publisher
11
10
  include Subscriber
12
11
  include Utils
@@ -69,6 +68,20 @@ module Twterm
69
68
  end
70
69
  end
71
70
 
71
+ # Returns if the given coordinate is enclosed by the window
72
+ #
73
+ # @param x [Integer]
74
+ # @param y [Integer]
75
+ # @return [Boolean]
76
+ def enclose?(x, y)
77
+ left = @window.begx
78
+ top = @window.begy
79
+ right = left + @window.maxx
80
+ bottom = top + @window.maxy
81
+
82
+ left <= x && x < right && top <= y && y < bottom
83
+ end
84
+
72
85
  def initialize(app, client)
73
86
  @app, @client = app, client
74
87
 
@@ -76,11 +89,50 @@ module Twterm
76
89
  @index = 0
77
90
  @history = []
78
91
 
79
- @window = stdscr.subwin(3, stdscr.maxx, 0, 0)
92
+ @window = Curses.stdscr.subwin(1, Curses.stdscr.maxx, 0, 0)
80
93
 
81
94
  subscribe(Event::Screen::Resize, :resize)
82
95
  end
83
96
 
97
+ # Open the clicked tab
98
+ #
99
+ # @param x [Integer]
100
+ # @param _y [Integer]
101
+ #
102
+ # @return [nil]
103
+ def handle_left_click(x, _y)
104
+ n = find_tab_index_on_x(x)
105
+ return if n.nil?
106
+
107
+ show_nth_tab(n)
108
+
109
+ nil
110
+ end
111
+
112
+ # Open next tab
113
+ #
114
+ # @param _x [Integer]
115
+ # @param _y [Integer]
116
+ #
117
+ # @return [nil]
118
+ def handle_scroll_down(_x, _y)
119
+ show_next
120
+
121
+ nil
122
+ end
123
+
124
+ # Open previous tab
125
+ #
126
+ # @param _x [Integer]
127
+ # @param _y [Integer]
128
+ #
129
+ # @return [nil]
130
+ def handle_scroll_up(_x, _y)
131
+ show_previous
132
+
133
+ nil
134
+ end
135
+
84
136
  def open_my_profile
85
137
  current_user_id = client.user_id
86
138
  tab = Tab::UserTab.new(app, client, current_user_id)
@@ -120,10 +172,10 @@ module Twterm
120
172
 
121
173
  image = @tabs
122
174
  .map { |t| [t, Image.string(t.title)] }
123
- .map { |t, r| t.equal?(current_tab) ? !r : r }
175
+ .map { |t, r| t.equal?(current_tab) ? !r._ : r }
124
176
  .reduce(pipe) { |acc, x| acc - wss - x - wss - pipe }
125
177
 
126
- View.new(@window, image).at(1, 1)
178
+ View.new(@window, image)
127
179
  end
128
180
 
129
181
  def respond_to_key(key)
@@ -195,8 +247,28 @@ module Twterm
195
247
 
196
248
  attr_reader :app, :client
197
249
 
250
+ # @param x [Integer]
251
+ #
252
+ # @return [Integer, nil]
253
+ def find_tab_index_on_x(x)
254
+ pos = 0
255
+
256
+ @tabs.each.with_index do |tab, index|
257
+ title = tab.title
258
+ len = title.length
259
+ left = pos + 1
260
+ right = left + len + 4 # each tab has 2 whitespaces on the both side
261
+
262
+ return index if left <= x && x < right
263
+
264
+ pos = right
265
+ end
266
+
267
+ nil
268
+ end
269
+
198
270
  def resize(_event)
199
- @window.resize(3, stdscr.maxx)
271
+ @window.resize(1, Curses.stdscr.maxx)
200
272
  @window.move(0, 0)
201
273
  end
202
274
  end
@@ -16,7 +16,6 @@ module Twterm
16
16
  end
17
17
 
18
18
  include Readline
19
- include Curses
20
19
  include Publisher
21
20
 
22
21
  def initialize(app, client)
@@ -104,7 +103,7 @@ module Twterm
104
103
  end
105
104
 
106
105
  def ask_and_post(leading_text, prompt, postprocessor, options = {})
107
- close_screen
106
+ Curses.close_screen
108
107
  puts "\e[H\e[2J#{leading_text}\n\n"
109
108
  ask(prompt, postprocessor) { |text| client.post(postprocessor.call(text), options) }
110
109
  end
@@ -120,7 +119,7 @@ module Twterm
120
119
  end
121
120
 
122
121
  def reset
123
- reset_prog_mode
122
+ Curses.reset_prog_mode
124
123
  sleep 0.1
125
124
  publish(Event::Screen::Refresh.new)
126
125
  end
data/lib/twterm/user.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  module Twterm
2
+ # A Twitter user
2
3
  class User
3
4
  attr_reader :description, :favorites_count, :followers_count,
4
5
  :friends_count, :id, :location, :name, :protected, :profile_image,
@@ -1,3 +1,3 @@
1
1
  module Twterm
2
- VERSION = '2.5.0'
2
+ VERSION = '2.9.0'
3
3
  end
data/nix/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'twterm'
data/nix/Gemfile.lock ADDED
@@ -0,0 +1,70 @@
1
+ GEM
2
+ remote: https://rubygems.org/
3
+ specs:
4
+ addressable (2.7.0)
5
+ public_suffix (>= 2.0.2, < 5.0)
6
+ buftok (0.2.0)
7
+ citrus (3.0.2)
8
+ concurrent-ruby (1.0.5)
9
+ curses (1.3.2)
10
+ domain_name (0.5.20190701)
11
+ unf (>= 0.0.5, < 1.0.0)
12
+ equalizer (0.0.11)
13
+ http (3.3.0)
14
+ addressable (~> 2.3)
15
+ http-cookie (~> 1.0)
16
+ http-form_data (~> 2.0)
17
+ http_parser.rb (~> 0.6.0)
18
+ http-cookie (1.0.3)
19
+ domain_name (~> 0.5)
20
+ http-form_data (2.3.0)
21
+ http_parser.rb (0.6.0)
22
+ idn-ruby (0.1.0)
23
+ launchy (2.4.3)
24
+ addressable (~> 2.3)
25
+ memoizable (0.4.2)
26
+ thread_safe (~> 0.3, >= 0.3.1)
27
+ multipart-post (2.1.1)
28
+ naught (1.1.0)
29
+ oauth (0.5.4)
30
+ public_suffix (4.0.5)
31
+ simple_oauth (0.3.1)
32
+ terminal-notifier (2.0.0)
33
+ thread_safe (0.3.6)
34
+ toml-rb (0.3.15)
35
+ citrus (~> 3.0, > 3.0)
36
+ twitter (6.2.0)
37
+ addressable (~> 2.3)
38
+ buftok (~> 0.2.0)
39
+ equalizer (~> 0.0.11)
40
+ http (~> 3.0)
41
+ http-form_data (~> 2.0)
42
+ http_parser.rb (~> 0.6.0)
43
+ memoizable (~> 0.4.0)
44
+ multipart-post (~> 2.0)
45
+ naught (~> 1.0)
46
+ simple_oauth (~> 0.3.0)
47
+ twitter-text (2.1.0)
48
+ idn-ruby
49
+ unf (~> 0.1.0)
50
+ twterm (2.8.0)
51
+ concurrent-ruby (~> 1.0.5)
52
+ curses (~> 1.3.2)
53
+ launchy (~> 2.4.3)
54
+ oauth (~> 0.5.1)
55
+ terminal-notifier (~> 2.0.0)
56
+ toml-rb (~> 0.3.14)
57
+ twitter (~> 6.2.0)
58
+ twitter-text (~> 2.1.0)
59
+ unf (0.1.4)
60
+ unf_ext
61
+ unf_ext (0.0.7.7)
62
+
63
+ PLATFORMS
64
+ ruby
65
+
66
+ DEPENDENCIES
67
+ twterm
68
+
69
+ BUNDLED WITH
70
+ 2.1.4
data/nix/gemset.nix ADDED
@@ -0,0 +1,283 @@
1
+ {
2
+ addressable = {
3
+ dependencies = ["public_suffix"];
4
+ groups = ["default"];
5
+ platforms = [];
6
+ source = {
7
+ remotes = ["https://rubygems.org"];
8
+ sha256 = "1fvchp2rhp2rmigx7qglf69xvjqvzq7x0g49naliw29r2bz656sy";
9
+ type = "gem";
10
+ };
11
+ version = "2.7.0";
12
+ };
13
+ buftok = {
14
+ groups = ["default"];
15
+ platforms = [];
16
+ source = {
17
+ remotes = ["https://rubygems.org"];
18
+ sha256 = "1rzsy1vy50v55x9z0nivf23y0r9jkmq6i130xa75pq9i8qrn1mxs";
19
+ type = "gem";
20
+ };
21
+ version = "0.2.0";
22
+ };
23
+ citrus = {
24
+ groups = ["default"];
25
+ platforms = [];
26
+ source = {
27
+ remotes = ["https://rubygems.org"];
28
+ sha256 = "0l7nhk3gkm1hdchkzzhg2f70m47pc0afxfpl6mkiibc9qcpl3hjf";
29
+ type = "gem";
30
+ };
31
+ version = "3.0.2";
32
+ };
33
+ concurrent-ruby = {
34
+ groups = ["default"];
35
+ platforms = [];
36
+ source = {
37
+ remotes = ["https://rubygems.org"];
38
+ sha256 = "183lszf5gx84kcpb779v6a2y0mx9sssy8dgppng1z9a505nj1qcf";
39
+ type = "gem";
40
+ };
41
+ version = "1.0.5";
42
+ };
43
+ curses = {
44
+ groups = ["default"];
45
+ platforms = [];
46
+ source = {
47
+ remotes = ["https://rubygems.org"];
48
+ sha256 = "0hic9kq09dhh8jqjx3k1991rnqhlj3glz82w0g7ndcri52m1hgqg";
49
+ type = "gem";
50
+ };
51
+ version = "1.3.2";
52
+ };
53
+ domain_name = {
54
+ dependencies = ["unf"];
55
+ groups = ["default"];
56
+ platforms = [];
57
+ source = {
58
+ remotes = ["https://rubygems.org"];
59
+ sha256 = "0lcqjsmixjp52bnlgzh4lg9ppsk52x9hpwdjd53k8jnbah2602h0";
60
+ type = "gem";
61
+ };
62
+ version = "0.5.20190701";
63
+ };
64
+ equalizer = {
65
+ groups = ["default"];
66
+ platforms = [];
67
+ source = {
68
+ remotes = ["https://rubygems.org"];
69
+ sha256 = "1kjmx3fygx8njxfrwcmn7clfhjhb6bvv3scy2lyyi0wqyi3brra4";
70
+ type = "gem";
71
+ };
72
+ version = "0.0.11";
73
+ };
74
+ http = {
75
+ dependencies = ["addressable" "http-cookie" "http-form_data" "http_parser.rb"];
76
+ groups = ["default"];
77
+ platforms = [];
78
+ source = {
79
+ remotes = ["https://rubygems.org"];
80
+ sha256 = "1jlm5prw437wqpfxcigh88lfap3m7g8mnmj5as7qw6dzqnvrxwmc";
81
+ type = "gem";
82
+ };
83
+ version = "3.3.0";
84
+ };
85
+ http-cookie = {
86
+ dependencies = ["domain_name"];
87
+ groups = ["default"];
88
+ platforms = [];
89
+ source = {
90
+ remotes = ["https://rubygems.org"];
91
+ sha256 = "004cgs4xg5n6byjs7qld0xhsjq3n6ydfh897myr2mibvh6fjc49g";
92
+ type = "gem";
93
+ };
94
+ version = "1.0.3";
95
+ };
96
+ http-form_data = {
97
+ groups = ["default"];
98
+ platforms = [];
99
+ source = {
100
+ remotes = ["https://rubygems.org"];
101
+ sha256 = "1wx591jdhy84901pklh1n9sgh74gnvq1qyqxwchni1yrc49ynknc";
102
+ type = "gem";
103
+ };
104
+ version = "2.3.0";
105
+ };
106
+ "http_parser.rb" = {
107
+ groups = ["default"];
108
+ platforms = [];
109
+ source = {
110
+ remotes = ["https://rubygems.org"];
111
+ sha256 = "15nidriy0v5yqfjsgsra51wmknxci2n2grliz78sf9pga3n0l7gi";
112
+ type = "gem";
113
+ };
114
+ version = "0.6.0";
115
+ };
116
+ idn-ruby = {
117
+ groups = ["default"];
118
+ platforms = [];
119
+ source = {
120
+ remotes = ["https://rubygems.org"];
121
+ sha256 = "07vblcyk3g72sbq12xz7xj28snpxnh3sbcnxy8bglqbfqqhvmawr";
122
+ type = "gem";
123
+ };
124
+ version = "0.1.0";
125
+ };
126
+ launchy = {
127
+ dependencies = ["addressable"];
128
+ groups = ["default"];
129
+ platforms = [];
130
+ source = {
131
+ remotes = ["https://rubygems.org"];
132
+ sha256 = "190lfbiy1vwxhbgn4nl4dcbzxvm049jwc158r2x7kq3g5khjrxa2";
133
+ type = "gem";
134
+ };
135
+ version = "2.4.3";
136
+ };
137
+ memoizable = {
138
+ dependencies = ["thread_safe"];
139
+ groups = ["default"];
140
+ platforms = [];
141
+ source = {
142
+ remotes = ["https://rubygems.org"];
143
+ sha256 = "0v42bvghsvfpzybfazl14qhkrjvx0xlmxz0wwqc960ga1wld5x5c";
144
+ type = "gem";
145
+ };
146
+ version = "0.4.2";
147
+ };
148
+ multipart-post = {
149
+ groups = ["default"];
150
+ platforms = [];
151
+ source = {
152
+ remotes = ["https://rubygems.org"];
153
+ sha256 = "1zgw9zlwh2a6i1yvhhc4a84ry1hv824d6g2iw2chs3k5aylpmpfj";
154
+ type = "gem";
155
+ };
156
+ version = "2.1.1";
157
+ };
158
+ naught = {
159
+ groups = ["default"];
160
+ platforms = [];
161
+ source = {
162
+ remotes = ["https://rubygems.org"];
163
+ sha256 = "1wwjx35zgbc0nplp8a866iafk4zsrbhwwz4pav5gydr2wm26nksg";
164
+ type = "gem";
165
+ };
166
+ version = "1.1.0";
167
+ };
168
+ oauth = {
169
+ groups = ["default"];
170
+ platforms = [];
171
+ source = {
172
+ remotes = ["https://rubygems.org"];
173
+ sha256 = "1zszdg8q1b135z7l7crjj234k4j0m347hywp5kj6zsq7q78pw09y";
174
+ type = "gem";
175
+ };
176
+ version = "0.5.4";
177
+ };
178
+ public_suffix = {
179
+ groups = ["default"];
180
+ platforms = [];
181
+ source = {
182
+ remotes = ["https://rubygems.org"];
183
+ sha256 = "0vywld400fzi17cszwrchrzcqys4qm6sshbv73wy5mwcixmrgg7g";
184
+ type = "gem";
185
+ };
186
+ version = "4.0.5";
187
+ };
188
+ simple_oauth = {
189
+ groups = ["default"];
190
+ platforms = [];
191
+ source = {
192
+ remotes = ["https://rubygems.org"];
193
+ sha256 = "0dw9ii6m7wckml100xhjc6vxpjcry174lbi9jz5v7ibjr3i94y8l";
194
+ type = "gem";
195
+ };
196
+ version = "0.3.1";
197
+ };
198
+ terminal-notifier = {
199
+ groups = ["default"];
200
+ platforms = [];
201
+ source = {
202
+ remotes = ["https://rubygems.org"];
203
+ sha256 = "1slc0y8pjpw30hy21v8ypafi8r7z9jlj4bjbgz03b65b28i2n3bs";
204
+ type = "gem";
205
+ };
206
+ version = "2.0.0";
207
+ };
208
+ thread_safe = {
209
+ groups = ["default"];
210
+ platforms = [];
211
+ source = {
212
+ remotes = ["https://rubygems.org"];
213
+ sha256 = "0nmhcgq6cgz44srylra07bmaw99f5271l0dpsvl5f75m44l0gmwy";
214
+ type = "gem";
215
+ };
216
+ version = "0.3.6";
217
+ };
218
+ toml-rb = {
219
+ dependencies = ["citrus"];
220
+ groups = ["default"];
221
+ platforms = [];
222
+ source = {
223
+ remotes = ["https://rubygems.org"];
224
+ sha256 = "03sr3k193i1r5bh9g4zc7iq9jklapmwj0rndcvhr9q7v5xm7x4rf";
225
+ type = "gem";
226
+ };
227
+ version = "0.3.15";
228
+ };
229
+ twitter = {
230
+ dependencies = ["addressable" "buftok" "equalizer" "http" "http-form_data" "http_parser.rb" "memoizable" "multipart-post" "naught" "simple_oauth"];
231
+ groups = ["default"];
232
+ platforms = [];
233
+ source = {
234
+ remotes = ["https://rubygems.org"];
235
+ sha256 = "0fjyz3viabz3xs5d9aad18zgdbhfwm51jsnzigc8kxk77p1x58n5";
236
+ type = "gem";
237
+ };
238
+ version = "6.2.0";
239
+ };
240
+ twitter-text = {
241
+ dependencies = ["idn-ruby" "unf"];
242
+ groups = ["default"];
243
+ platforms = [];
244
+ source = {
245
+ remotes = ["https://rubygems.org"];
246
+ sha256 = "1igv713wn6wqhq4nlr81r93v7wmgjqny24jwp3ai5i4ipk2f2k6a";
247
+ type = "gem";
248
+ };
249
+ version = "2.1.0";
250
+ };
251
+ twterm = {
252
+ dependencies = ["concurrent-ruby" "curses" "launchy" "oauth" "terminal-notifier" "toml-rb" "twitter" "twitter-text"];
253
+ groups = ["default"];
254
+ platforms = [];
255
+ source = {
256
+ remotes = ["https://rubygems.org"];
257
+ sha256 = "075rq11axsz41hcrmm6ixjyy0kz3axf0mhkvq3cgryqib2isjbk9";
258
+ type = "gem";
259
+ };
260
+ version = "2.8.0";
261
+ };
262
+ unf = {
263
+ dependencies = ["unf_ext"];
264
+ groups = ["default"];
265
+ platforms = [];
266
+ source = {
267
+ remotes = ["https://rubygems.org"];
268
+ sha256 = "0bh2cf73i2ffh4fcpdn9ir4mhq8zi50ik0zqa1braahzadx536a9";
269
+ type = "gem";
270
+ };
271
+ version = "0.1.4";
272
+ };
273
+ unf_ext = {
274
+ groups = ["default"];
275
+ platforms = [];
276
+ source = {
277
+ remotes = ["https://rubygems.org"];
278
+ sha256 = "0wc47r23h063l8ysws8sy24gzh74mks81cak3lkzlrw4qkqb3sg4";
279
+ type = "gem";
280
+ };
281
+ version = "0.0.7.7";
282
+ };
283
+ }