twterm 2.3.0 → 2.4.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.
Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -0
  3. data/lib/twterm.rb +4 -4
  4. data/lib/twterm/app.rb +4 -1
  5. data/lib/twterm/direct_message_composer.rb +2 -1
  6. data/lib/twterm/environment.rb +5 -0
  7. data/lib/twterm/event/{base.rb → abstract_event.rb} +1 -1
  8. data/lib/twterm/event/direct_message/fetched.rb +2 -2
  9. data/lib/twterm/event/message/abstract_message.rb +2 -2
  10. data/lib/twterm/event/notification/abstract_notification.rb +2 -2
  11. data/lib/twterm/event/open_photo.rb +13 -0
  12. data/lib/twterm/event/open_uri.rb +2 -2
  13. data/lib/twterm/event/screen/refresh.rb +13 -0
  14. data/lib/twterm/event/screen/resize.rb +2 -2
  15. data/lib/twterm/event/status/{base.rb → abstract_status_event.rb} +2 -2
  16. data/lib/twterm/event/status/delete.rb +2 -2
  17. data/lib/twterm/event/status/mention.rb +2 -2
  18. data/lib/twterm/event/status/timeline.rb +2 -2
  19. data/lib/twterm/event/status_garbage_collected.rb +2 -2
  20. data/lib/twterm/event/user_garbage_collected.rb +2 -2
  21. data/lib/twterm/event_dispatcher.rb +2 -2
  22. data/lib/twterm/photo_viewer.rb +36 -0
  23. data/lib/twterm/photo_viewer_backend/abstract_photo_viewer_backend.rb +46 -0
  24. data/lib/twterm/photo_viewer_backend/browser_backend.rb +16 -0
  25. data/lib/twterm/photo_viewer_backend/imgcat_backend.rb +33 -0
  26. data/lib/twterm/photo_viewer_backend/quick_look_backend.rb +13 -0
  27. data/lib/twterm/preferences.rb +10 -0
  28. data/lib/twterm/publisher.rb +2 -2
  29. data/lib/twterm/rest_client.rb +5 -5
  30. data/lib/twterm/screen.rb +8 -6
  31. data/lib/twterm/status.rb +7 -1
  32. data/lib/twterm/tab/{base.rb → abstract_tab.rb} +1 -1
  33. data/lib/twterm/tab/direct_message/conversation.rb +2 -2
  34. data/lib/twterm/tab/direct_message/conversation_list.rb +2 -2
  35. data/lib/twterm/tab/key_assignments_cheatsheet.rb +2 -2
  36. data/lib/twterm/tab/new/{start.rb → index.rb} +2 -2
  37. data/lib/twterm/tab/new/list.rb +2 -2
  38. data/lib/twterm/tab/new/search.rb +6 -3
  39. data/lib/twterm/tab/new/user.rb +8 -7
  40. data/lib/twterm/tab/preferences/index.rb +9 -3
  41. data/lib/twterm/tab/preferences/notification_backend.rb +2 -2
  42. data/lib/twterm/tab/preferences/photo_viewer_backend.rb +86 -0
  43. data/lib/twterm/tab/rate_limit_status.rb +1 -1
  44. data/lib/twterm/tab/status_tab.rb +4 -3
  45. data/lib/twterm/tab/statuses/{base.rb → abstract_statuses_tab.rb} +2 -2
  46. data/lib/twterm/tab/statuses/conversation.rb +2 -2
  47. data/lib/twterm/tab/statuses/favorites.rb +2 -2
  48. data/lib/twterm/tab/statuses/home.rb +2 -2
  49. data/lib/twterm/tab/statuses/list_timeline.rb +2 -2
  50. data/lib/twterm/tab/statuses/mentions.rb +2 -2
  51. data/lib/twterm/tab/statuses/search.rb +2 -2
  52. data/lib/twterm/tab/statuses/user_timeline.rb +2 -2
  53. data/lib/twterm/tab/user_list_management.rb +1 -1
  54. data/lib/twterm/tab/user_tab.rb +2 -2
  55. data/lib/twterm/tab/users/{base.rb → abstract_users_tab.rb} +2 -2
  56. data/lib/twterm/tab/users/followers.rb +2 -2
  57. data/lib/twterm/tab/users/friends.rb +2 -2
  58. data/lib/twterm/tab_manager.rb +2 -2
  59. data/lib/twterm/tweetbox.rb +20 -16
  60. data/lib/twterm/version.rb +1 -1
  61. data/spec/twterm/event_dispatcher_spec.rb +1 -1
  62. data/twterm.gemspec +1 -1
  63. metadata +20 -13
  64. data/lib/twterm/tab/favorites.rb +0 -7
@@ -0,0 +1,13 @@
1
+ require 'twterm/photo_viewer_backend/abstract_photo_viewer_backend'
2
+
3
+ module Twterm
4
+ module PhotoViewerBackend
5
+ class QuickLookBackend < AbstractPhotoViewerBackend
6
+ def view(photo)
7
+ with_downloaded_file(photo.media_url_https) do |file|
8
+ `qlmanage -p #{file.path} 2>/dev/null`
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -27,6 +27,11 @@ module Twterm
27
27
  # @return [Twterm::Preferences] an instance having the default value
28
28
  def self.default
29
29
  new({
30
+ photo_viewer_backend: {
31
+ browser: true,
32
+ imgcat: false,
33
+ quick_look: false,
34
+ },
30
35
  notification_backend: {
31
36
  inline: true,
32
37
  terminal_notifier: false,
@@ -45,6 +50,11 @@ module Twterm
45
50
  bool = -> x { x == true || x == false }
46
51
 
47
52
  {
53
+ photo_viewer_backend: {
54
+ browser: bool,
55
+ imgcat: bool,
56
+ quick_look: bool,
57
+ },
48
58
  notification_backend: {
49
59
  inline: bool,
50
60
  terminal_notifier: bool,
@@ -1,5 +1,5 @@
1
1
  require 'twterm/event_dispatcher'
2
- require 'twterm/event/base'
2
+ require 'twterm/event/abstract_event'
3
3
  require 'twterm/utils'
4
4
 
5
5
  module Twterm
@@ -7,7 +7,7 @@ module Twterm
7
7
  include Utils
8
8
 
9
9
  def publish(event)
10
- check_type Event::Base, event
10
+ check_type Event::AbstractEvent, event
11
11
 
12
12
  EventDispatcher.instance.dispatch(event)
13
13
  event
@@ -85,7 +85,7 @@ module Twterm
85
85
  user_id ||= self.user_id
86
86
 
87
87
  send_request do
88
- rest_client.favorites(user_id, count: 200)
88
+ rest_client.favorites(user_id, count: 200, tweet_mode: :extended)
89
89
  end.then do |tweets|
90
90
  tweets.map { |tweet| status_repository.create(tweet) }
91
91
  end
@@ -145,7 +145,7 @@ module Twterm
145
145
 
146
146
  def home_timeline
147
147
  send_request do
148
- rest_client.home_timeline(count: 200)
148
+ rest_client.home_timeline(count: 200, tweet_mode: :extended)
149
149
  end.then do |tweets|
150
150
  tweets
151
151
  .select(&@mute_filter)
@@ -163,7 +163,7 @@ module Twterm
163
163
 
164
164
  def list_timeline(list_id)
165
165
  send_request do
166
- rest_client.list_timeline(list_id, count: 200)
166
+ rest_client.list_timeline(list_id, count: 200, tweet_mode: :extended)
167
167
  end.then do |statuses|
168
168
  statuses
169
169
  .select(&@mute_filter)
@@ -219,7 +219,7 @@ module Twterm
219
219
 
220
220
  def mentions
221
221
  send_request do
222
- rest_client.mentions(count: 200)
222
+ rest_client.mentions(count: 200, tweet_mode: :extended)
223
223
  end.then do |statuses|
224
224
  statuses
225
225
  .select(&@mute_filter)
@@ -300,7 +300,7 @@ module Twterm
300
300
 
301
301
  def search(query)
302
302
  send_request do
303
- rest_client.search(query, count: 100).attrs[:statuses]
303
+ rest_client.search(query, count: 100, tweet_mode: :extended).attrs[:statuses]
304
304
  end.then do |statuses|
305
305
  statuses
306
306
  .map(&Twitter::Tweet.method(:new))
data/lib/twterm/screen.rb CHANGED
@@ -1,3 +1,4 @@
1
+ require 'twterm/event/screen/refresh'
1
2
  require 'twterm/event/screen/resize'
2
3
  require 'twterm/key_mapper'
3
4
  require 'twterm/subscriber'
@@ -18,15 +19,10 @@ module Twterm
18
19
  start_color
19
20
  use_default_colors
20
21
 
22
+ subscribe(Event::Screen::Refresh) { refresh }
21
23
  subscribe(Event::Screen::Resize, :resize)
22
24
  end
23
25
 
24
- def refresh
25
- app.tab_manager.refresh_window
26
- app.tab_manager.current_tab.render
27
- MessageWindow.instance.show
28
- end
29
-
30
26
  def respond_to_key(key)
31
27
  k = KeyMapper.instance
32
28
 
@@ -57,6 +53,12 @@ module Twterm
57
53
 
58
54
  attr_reader :app, :client
59
55
 
56
+ def refresh
57
+ app.tab_manager.refresh_window
58
+ app.tab_manager.current_tab.render
59
+ MessageWindow.instance.show
60
+ end
61
+
60
62
  def resize(event)
61
63
  return if closed?
62
64
 
data/lib/twterm/status.rb CHANGED
@@ -43,7 +43,13 @@ module Twterm
43
43
  end
44
44
 
45
45
  @id = tweet.id
46
- @text = CGI.unescapeHTML(tweet.full_text.dup)
46
+ text =
47
+ if tweet.truncated? && tweet.attrs[:extended_tweet]
48
+ tweet.attrs[:extended_tweet][:full_text]
49
+ else
50
+ tweet.attrs[:text] || tweet.attrs[:full_text]
51
+ end
52
+ @text = CGI.unescapeHTML(text)
47
53
  @created_at = tweet.created_at.dup.localtime
48
54
  @in_reply_to_status_id = tweet.in_reply_to_status_id
49
55
  @quoted_status_id = tweet.quoted_status_id
@@ -6,7 +6,7 @@ require 'twterm/subscriber'
6
6
 
7
7
  module Twterm
8
8
  module Tab
9
- class Base
9
+ class AbstractTab
10
10
  include Curses
11
11
  include Subscriber
12
12
 
@@ -2,14 +2,14 @@ require 'twterm/direct_message_composer'
2
2
  require 'twterm/event/direct_message/fetched'
3
3
  require 'twterm/image_builder/user_name_image_builder'
4
4
  require 'twterm/subscriber'
5
- require 'twterm/tab/base'
5
+ require 'twterm/tab/abstract_tab'
6
6
  require 'twterm/tab/loadable'
7
7
  require 'twterm/tab/searchable'
8
8
 
9
9
  module Twterm
10
10
  module Tab
11
11
  module DirectMessage
12
- class Conversation < Base
12
+ class Conversation < AbstractTab
13
13
  include Searchable
14
14
  include Subscriber
15
15
  include Loadable
@@ -2,14 +2,14 @@ require 'twterm/direct_message_composer'
2
2
  require 'twterm/event/direct_message/fetched'
3
3
  require 'twterm/image_builder/user_name_image_builder'
4
4
  require 'twterm/subscriber'
5
- require 'twterm/tab/base'
5
+ require 'twterm/tab/abstract_tab'
6
6
  require 'twterm/tab/loadable'
7
7
  require 'twterm/tab/direct_message/conversation'
8
8
 
9
9
  module Twterm
10
10
  module Tab
11
11
  module DirectMessage
12
- class ConversationList < Base
12
+ class ConversationList < AbstractTab
13
13
  include Loadable
14
14
  include Searchable
15
15
  include Subscriber
@@ -1,10 +1,10 @@
1
1
  require 'twterm/image'
2
- require 'twterm/tab/base'
2
+ require 'twterm/tab/abstract_tab'
3
3
  require 'twterm/tab/searchable'
4
4
 
5
5
  module Twterm
6
6
  module Tab
7
- class KeyAssignmentsCheatsheet < Base
7
+ class KeyAssignmentsCheatsheet < AbstractTab
8
8
  include Scrollable
9
9
 
10
10
  def ==(other)
@@ -1,4 +1,4 @@
1
- require 'twterm/tab/base'
1
+ require 'twterm/tab/abstract_tab'
2
2
  require 'twterm/tab/direct_message/conversation_list'
3
3
  require 'twterm/tab/rate_limit_status'
4
4
  require 'twterm/tab/preferences/index'
@@ -6,7 +6,7 @@ require 'twterm/tab/preferences/index'
6
6
  module Twterm
7
7
  module Tab
8
8
  module New
9
- class Start < Base
9
+ class Index < AbstractTab
10
10
  include Scrollable
11
11
 
12
12
  def ==(other)
@@ -1,11 +1,11 @@
1
1
  require 'twterm/event/message/info'
2
- require 'twterm/tab/base'
2
+ require 'twterm/tab/abstract_tab'
3
3
  require 'twterm/tab/loadable'
4
4
 
5
5
  module Twterm
6
6
  module Tab
7
7
  module New
8
- class List < Base
8
+ class List < AbstractTab
9
9
  include Loadable
10
10
  include Publisher
11
11
  include Searchable
@@ -1,13 +1,16 @@
1
1
  require 'concurrent'
2
2
 
3
- require 'twterm/tab/base'
3
+ require 'twterm/event/screen/refresh'
4
+ require 'twterm/publisher'
5
+ require 'twterm/tab/abstract_tab'
4
6
  require 'twterm/tab/loadable'
5
7
 
6
8
  module Twterm
7
9
  module Tab
8
10
  module New
9
- class Search < Base
11
+ class Search < AbstractTab
10
12
  include Loadable
13
+ include Publisher
11
14
  include Readline
12
15
  include Searchable
13
16
 
@@ -31,7 +34,7 @@ module Twterm
31
34
  resetter = proc do
32
35
  reset_prog_mode
33
36
  sleep 0.1
34
- app.screen.refresh
37
+ publish(Event::Screen::Refresh.new)
35
38
  end
36
39
 
37
40
  input_thread = Thread.new do
@@ -1,11 +1,12 @@
1
- require 'twterm/publisher'
2
- require 'twterm/tab/base'
3
1
  require 'twterm/event/message/error'
2
+ require 'twterm/event/screen/refresh'
3
+ require 'twterm/publisher'
4
+ require 'twterm/tab/abstract_tab'
4
5
 
5
6
  module Twterm
6
7
  module Tab
7
8
  module New
8
- class User < Base
9
+ class User < AbstractTab
9
10
  include Publisher
10
11
  include Readline
11
12
 
@@ -17,7 +18,7 @@ module Twterm
17
18
  resetter = proc do
18
19
  reset_prog_mode
19
20
  sleep 0.1
20
- app.screen.refresh
21
+ publish(Event::Screen::Refresh.new)
21
22
  end
22
23
 
23
24
  app.completion_manager.set_screen_name_mode!
@@ -29,12 +30,12 @@ module Twterm
29
30
  resetter.call
30
31
 
31
32
  if screen_name.nil? || screen_name.empty?
32
- app.tab_manager.switch(Tab::New::Start.new(app, client))
33
+ app.tab_manager.switch(Tab::New::Index.new(app, client))
33
34
  else
34
35
  client.show_user(screen_name).then do |user|
35
36
  if user.nil?
36
37
  publish(Event::Message::Error.new('User not found'))
37
- tab = Tab::New::Start.new(app, client)
38
+ tab = Tab::New::Index.new(app, client)
38
39
  else
39
40
  tab = Tab::UserTab.new(app, client, user.id)
40
41
  end
@@ -46,7 +47,7 @@ module Twterm
46
47
  app.register_interruption_handler do
47
48
  input_thread.kill
48
49
  resetter.call
49
- tab = Tab::New::Start.new(app, client)
50
+ tab = Tab::New::Index.new(app, client)
50
51
  app.tab_manager.switch(tab)
51
52
  end
52
53
 
@@ -1,14 +1,15 @@
1
1
  require 'twterm/image'
2
2
  require 'twterm/tab/preferences/notification_backend'
3
+ require 'twterm/tab/preferences/photo_viewer_backend'
3
4
  require 'twterm/preferences'
4
5
  require 'twterm/publisher'
5
- require 'twterm/tab/base'
6
+ require 'twterm/tab/abstract_tab'
6
7
  require 'twterm/tab/scrollable'
7
8
 
8
9
  module Twterm
9
10
  module Tab
10
11
  module Preferences
11
- class Index < Tab::Base
12
+ class Index < AbstractTab
12
13
  include Scrollable
13
14
 
14
15
  def initialize(app, client)
@@ -27,6 +28,8 @@ module Twterm
27
28
  case item
28
29
  when :notification_backend
29
30
  'Notification backend preferences'
31
+ when :photo_viewer_backend
32
+ 'Photo viewer backend preferences'
30
33
  end
31
34
 
32
35
  cursor - Image.whitespace - Image.string(desc).bold(curr)
@@ -37,7 +40,8 @@ module Twterm
37
40
 
38
41
  def items
39
42
  [
40
- :notification_backend
43
+ :notification_backend,
44
+ :photo_viewer_backend,
41
45
  ]
42
46
  end
43
47
 
@@ -65,6 +69,8 @@ module Twterm
65
69
  case scroller.current_item
66
70
  when :notification_backend
67
71
  Tab::Preferences::NotificationBackend.new(app, client)
72
+ when :photo_viewer_backend
73
+ Tab::Preferences::PhotoViewerBackend.new(app, client)
68
74
  end
69
75
 
70
76
  app.tab_manager.add_and_show(tab)
@@ -1,13 +1,13 @@
1
1
  require 'twterm/image'
2
2
  require 'twterm/preferences'
3
3
  require 'twterm/publisher'
4
- require 'twterm/tab/base'
4
+ require 'twterm/tab/abstract_tab'
5
5
  require 'twterm/tab/scrollable'
6
6
 
7
7
  module Twterm
8
8
  module Tab
9
9
  module Preferences
10
- class NotificationBackend < Tab::Base
10
+ class NotificationBackend < AbstractTab
11
11
  include Scrollable
12
12
  include Publisher
13
13
 
@@ -0,0 +1,86 @@
1
+ require 'twterm/image'
2
+ require 'twterm/preferences'
3
+ require 'twterm/publisher'
4
+ require 'twterm/tab/abstract_tab'
5
+ require 'twterm/tab/scrollable'
6
+
7
+ module Twterm
8
+ module Tab
9
+ module Preferences
10
+ class PhotoViewerBackend < AbstractTab
11
+ include Scrollable
12
+ include Publisher
13
+
14
+ def drawable_item_count
15
+ (window.maxy - 1) / 2
16
+ end
17
+
18
+ def image
19
+ drawable_items.map.with_index do |item, i|
20
+ curr = scroller.current_index?(i)
21
+ cursor = Image.cursor(1, curr)
22
+ checkbox = Image.checkbox(app.preferences[:photo_viewer_backend, item])
23
+ desc =
24
+ case item
25
+ when :browser
26
+ 'Web browser backend'
27
+ when :imgcat
28
+ 'imgcat backend'
29
+ when :quick_look
30
+ 'Quick Look backend'
31
+ end
32
+
33
+ cursor - Image.whitespace - checkbox - Image.whitespace - Image.string(desc).bold(curr)
34
+ end
35
+ .intersperse(Image.blank_line)
36
+ .reduce(Image.empty) { |acc, x| acc | x }
37
+ end
38
+
39
+ def items
40
+ env = app.environment
41
+
42
+ [
43
+ :browser,
44
+ (:imgcat if env.with_imgcat?),
45
+ (:quick_look if env.with_qlmanage?),
46
+ ].compact
47
+ end
48
+
49
+ def respond_to_key(key)
50
+ return true if scroller.respond_to_key(key)
51
+
52
+ case key
53
+ when 10
54
+ perform_selected_action
55
+ end
56
+
57
+ false
58
+ end
59
+
60
+ def title
61
+ 'Photo viewer backend preferences'
62
+ end
63
+
64
+ private
65
+
66
+ def perform_selected_action
67
+ item = scroller.current_item
68
+
69
+ case item
70
+ when :browser
71
+ app.preferences[:photo_viewer_backend, :browser] =
72
+ !app.preferences[:photo_viewer_backend, :browser]
73
+ when :imgcat
74
+ app.preferences[:photo_viewer_backend, :imgcat] =
75
+ !app.preferences[:photo_viewer_backend, :imgcat]
76
+ when :quick_look
77
+ app.preferences[:photo_viewer_backend, :quick_look] =
78
+ !app.preferences[:photo_viewer_backend, :quick_look]
79
+ end
80
+
81
+ render
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end