twterm 1.3.0 → 2.0.0.beta1

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 (121) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +14 -18
  3. data/bin/twterm +1 -1
  4. data/lib/twterm/app.rb +120 -30
  5. data/lib/twterm/client.rb +10 -13
  6. data/lib/twterm/completion_mamanger.rb +11 -6
  7. data/lib/twterm/direct_message.rb +6 -28
  8. data/lib/twterm/direct_message_composer.rb +10 -5
  9. data/lib/twterm/direct_message_manager.rb +5 -6
  10. data/lib/twterm/event/notification/abstract_notification.rb +27 -0
  11. data/lib/twterm/event/notification/error.rb +13 -0
  12. data/lib/twterm/event/notification/info.rb +13 -0
  13. data/lib/twterm/event/notification/success.rb +13 -0
  14. data/lib/twterm/event/notification/warning.rb +13 -0
  15. data/lib/twterm/event_dispatcher.rb +1 -1
  16. data/lib/twterm/extensions/array.rb +5 -0
  17. data/lib/twterm/extensions/enumerator/lazy.rb +3 -0
  18. data/lib/twterm/extensions/string.rb +0 -4
  19. data/lib/twterm/friendship.rb +1 -85
  20. data/lib/twterm/image/between.rb +31 -0
  21. data/lib/twterm/image/blank_line.rb +21 -0
  22. data/lib/twterm/image/bold.rb +31 -0
  23. data/lib/twterm/image/brackets.rb +21 -0
  24. data/lib/twterm/image/color.rb +45 -0
  25. data/lib/twterm/image/empty.rb +21 -0
  26. data/lib/twterm/image/horizontal_sequential_image.rb +48 -0
  27. data/lib/twterm/image/parens.rb +21 -0
  28. data/lib/twterm/image/string_image.rb +38 -0
  29. data/lib/twterm/image/vertical_sequential_image.rb +43 -0
  30. data/lib/twterm/image.rb +107 -0
  31. data/lib/twterm/key_mapper/abstract_key_mapper.rb +51 -0
  32. data/lib/twterm/key_mapper/app_key_mapper.rb +13 -0
  33. data/lib/twterm/key_mapper/cursor_key_mapper.rb +13 -0
  34. data/lib/twterm/key_mapper/general_key_mapper.rb +18 -0
  35. data/lib/twterm/key_mapper/no_such_command.rb +20 -0
  36. data/lib/twterm/key_mapper/no_such_key.rb +16 -0
  37. data/lib/twterm/key_mapper/status_key_mapper.rb +18 -0
  38. data/lib/twterm/key_mapper/tab_key_mapper.rb +31 -0
  39. data/lib/twterm/key_mapper.rb +127 -0
  40. data/lib/twterm/list.rb +0 -31
  41. data/lib/twterm/notifier.rb +7 -7
  42. data/lib/twterm/repository/abstract_entity_repository.rb +41 -0
  43. data/lib/twterm/repository/abstract_expirable_entity_repository.rb +35 -0
  44. data/lib/twterm/repository/abstract_repository.rb +64 -0
  45. data/lib/twterm/repository/direct_message_repository.rb +14 -0
  46. data/lib/twterm/repository/friendship_repository.rb +108 -0
  47. data/lib/twterm/repository/hashtag_repository.rb +39 -0
  48. data/lib/twterm/repository/list_repository.rb +14 -0
  49. data/lib/twterm/repository/status_repository.rb +36 -0
  50. data/lib/twterm/repository/user_repository.rb +22 -0
  51. data/lib/twterm/rest_client.rb +107 -63
  52. data/lib/twterm/screen.rb +21 -15
  53. data/lib/twterm/search_query_window.rb +139 -0
  54. data/lib/twterm/status.rb +14 -108
  55. data/lib/twterm/streaming_client.rb +13 -12
  56. data/lib/twterm/tab/base.rb +48 -8
  57. data/lib/twterm/tab/direct_message/conversation.rb +53 -52
  58. data/lib/twterm/tab/direct_message/conversation_list.rb +46 -45
  59. data/lib/twterm/tab/dumpable.rb +3 -3
  60. data/lib/twterm/tab/key_assignments_cheatsheet.rb +58 -57
  61. data/lib/twterm/tab/loadable.rb +20 -0
  62. data/lib/twterm/tab/new/list.rb +32 -43
  63. data/lib/twterm/tab/new/search.rb +31 -44
  64. data/lib/twterm/tab/new/start.rb +44 -55
  65. data/lib/twterm/tab/new/user.rb +15 -12
  66. data/lib/twterm/tab/rate_limit_status.rb +84 -0
  67. data/lib/twterm/tab/scrollable.rb +39 -19
  68. data/lib/twterm/tab/searchable.rb +133 -0
  69. data/lib/twterm/tab/statuses/base.rb +139 -129
  70. data/lib/twterm/tab/statuses/conversation.rb +26 -15
  71. data/lib/twterm/tab/statuses/favorites.rb +10 -8
  72. data/lib/twterm/tab/statuses/home.rb +10 -9
  73. data/lib/twterm/tab/statuses/list_timeline.rb +12 -8
  74. data/lib/twterm/tab/statuses/mentions.rb +17 -11
  75. data/lib/twterm/tab/statuses/search.rb +8 -5
  76. data/lib/twterm/tab/statuses/user_timeline.rb +11 -8
  77. data/lib/twterm/tab/user_list_management.rb +109 -0
  78. data/lib/twterm/tab/user_tab.rb +125 -126
  79. data/lib/twterm/tab/users/base.rb +39 -41
  80. data/lib/twterm/tab/users/followers.rb +9 -6
  81. data/lib/twterm/tab/users/friends.rb +9 -6
  82. data/lib/twterm/tab_manager.rb +64 -40
  83. data/lib/twterm/tweetbox.rb +18 -13
  84. data/lib/twterm/uri_opener.rb +2 -1
  85. data/lib/twterm/user.rb +2 -110
  86. data/lib/twterm/version.rb +1 -1
  87. data/lib/twterm/view.rb +30 -0
  88. data/lib/twterm.rb +3 -9
  89. data/spec/fixtures/status.json +107 -0
  90. data/spec/fixtures/user.json +102 -0
  91. data/spec/spec_helper.rb +7 -0
  92. data/spec/supports/shared_examples/abstract_key_mapper.rb +17 -0
  93. data/spec/twterm/extension/enumerator/lazy_spec.rb +11 -0
  94. data/spec/twterm/friendship_spec.rb +0 -102
  95. data/spec/twterm/image/blank_line_spec.rb +11 -0
  96. data/spec/twterm/image/brackets_spec.rb +12 -0
  97. data/spec/twterm/image/color_spec.rb +22 -0
  98. data/spec/twterm/image/empry_spec.rb +11 -0
  99. data/spec/twterm/image/horizontal_sequential_image_spec.rb +15 -0
  100. data/spec/twterm/image/parens_spec.rb +12 -0
  101. data/spec/twterm/image/string_image_spec.rb +12 -0
  102. data/spec/twterm/image/vertical_sequential_image_spec.rb +14 -0
  103. data/spec/twterm/image_spec.rb +65 -0
  104. data/spec/twterm/key_mapper/abstract_key_mapper_spec.rb +21 -0
  105. data/spec/twterm/key_mapper/app_key_mapper_spec.rb +7 -0
  106. data/spec/twterm/key_mapper/status_key_mapper_spec.rb +7 -0
  107. data/spec/twterm/key_mapper/tab_key_mapper_spec.rb +7 -0
  108. data/spec/twterm/repository/friendship_repository_spec.rb +108 -0
  109. data/spec/twterm/status_spec.rb +58 -0
  110. data/spec/twterm/user_spec.rb +94 -0
  111. data/twterm.gemspec +13 -10
  112. metadata +129 -35
  113. data/lib/twterm/event/notification.rb +0 -33
  114. data/lib/twterm/extensions/integer.rb +0 -5
  115. data/lib/twterm/filter_query_window.rb +0 -91
  116. data/lib/twterm/filterable_list.rb +0 -41
  117. data/lib/twterm/history/base.rb +0 -21
  118. data/lib/twterm/history/hashtag.rb +0 -13
  119. data/lib/twterm/history/savable.rb +0 -37
  120. data/lib/twterm/history/screen_name.rb +0 -11
  121. data/lib/twterm/promise.rb +0 -143
@@ -1,4 +1,6 @@
1
+ require 'twterm/image'
1
2
  require 'twterm/tab/base'
3
+ require 'twterm/tab/searchable'
2
4
 
3
5
  module Twterm
4
6
  module Tab
@@ -10,39 +12,44 @@ module Twterm
10
12
  end
11
13
 
12
14
  SHORTCUTS = {
13
- 'General' => {
14
- '[d] [C-d]' => 'Scroll down',
15
- '[g]' => 'Move to top',
16
- '[G]' => 'Move to bottom',
17
- '[j] [C-p] [DOWN]' => 'Move down',
18
- '[k] [C-n] [UP]' => 'Move up',
19
- '[u] [C-u]' => 'Scroll up',
20
- '[Q]' => 'Quit twterm'
15
+ ['General', :general] => {
16
+ page_down: 'Page down',
17
+ top: 'Move to top',
18
+ bottom: 'Move to bottom',
19
+ down: 'Move down',
20
+ up: 'Move up',
21
+ page_up: 'Page up',
22
+ left: 'Left',
23
+ right: 'Right',
21
24
  },
22
- 'Tabs' => {
23
- '[h] [C-b] [LEFT]' => 'Previous tab',
24
- '[l] [C-f] [RIGHT]' => 'Next tab',
25
- '[N]' => 'New tab',
26
- '[C-R]' => 'Reload',
27
- '[w]' => 'Close tab',
28
- '[q]' => 'Quit filter mode',
29
- '[/]' => 'Filter mode',
30
- '[1] - [9]' => 'Nth tab',
31
- '[0]' => 'Last tab'
25
+ ['Tabs', :tab] => {
26
+ new: 'New tab',
27
+ reload: 'Reload',
28
+ close: 'Close tab',
29
+ search_down: 'Search down',
30
+ search_up: 'Search up',
31
+ find_next: 'Find next',
32
+ find_previous: 'Find previous',
32
33
  },
33
- 'Tweets' => {
34
- '[c]' => 'Conversation',
35
- '[D]' => 'Delete',
36
- '[L]' => 'Like',
37
- '[n]' => 'New tweet',
38
- '[o]' => 'Open URLs',
39
- '[r]' => 'Reply',
40
- '[R]' => 'Retweet',
41
- '[U]' => 'User'
34
+ ['Tweets', :status] => {
35
+ compose: 'New tweet',
36
+ conversation: 'Conversation',
37
+ destroy: 'Delete',
38
+ like: 'Like',
39
+ open_link: 'Open URLs',
40
+ reply: 'Reply',
41
+ retweet: 'Retweet',
42
+ user: 'User',
42
43
  },
43
- 'Others' => {
44
- '[P]' => 'My profile',
45
- '[?]' => 'Key assignments cheatsheet'
44
+ ['Cursor', :cursor] => {
45
+ top_of_window: 'Top of window',
46
+ middle_of_window: 'Middle of window',
47
+ bottom_of_window: 'Bottom of window'
48
+ },
49
+ ['Others', :app] => {
50
+ me: 'My profile',
51
+ cheatsheet: 'Key assignments cheatsheet',
52
+ quit: 'Quit',
46
53
  }
47
54
  }
48
55
 
@@ -50,8 +57,27 @@ module Twterm
50
57
  window.maxy - 3
51
58
  end
52
59
 
53
- def initialize
54
- super
60
+ def image
61
+ k = KeyMapper.instance
62
+
63
+ SHORTCUTS
64
+ .flat_map { |(cat_str, cat_sym), shortcuts|
65
+ [
66
+ !Image.string(cat_str).color(:green),
67
+ Image.blank_line,
68
+ *shortcuts.map { |cmd, desc|
69
+ Image.string(' ') - !Image.string(k.as_string(cat_sym, cmd).center(3)).color(:cyan) - Image.whitespace - Image.string(desc)
70
+ },
71
+ Image.blank_line,
72
+ ]
73
+ }
74
+ .drop(scroller.offset)
75
+ .take(drawable_item_count)
76
+ .reduce(Image.empty, :|)
77
+ end
78
+
79
+ def initialize(app, client)
80
+ super(app, client)
55
81
  scroller.set_no_cursor_mode!
56
82
  end
57
83
 
@@ -68,31 +94,6 @@ module Twterm
68
94
  def total_item_count
69
95
  @count ||= SHORTCUTS.count * 4 + SHORTCUTS.values.map(&:count).reduce(0, :+) + 1
70
96
  end
71
-
72
- def update
73
- offset = scroller.offset
74
- line = 0
75
-
76
- window.setpos(line - offset + 2, 3)
77
- window.bold { window.addstr('Key assignments') } if scroller.nth_item_drawable?(line)
78
-
79
- SHORTCUTS.each do |category, shortcuts|
80
- line += 3
81
- window.setpos(line - offset + 2, 5)
82
- window.bold { window.addstr("<#{category}>") } if scroller.nth_item_drawable?(line)
83
- line += 1
84
-
85
- shortcuts.each do |key, description|
86
- line += 1
87
- next unless scroller.nth_item_drawable?(line)
88
-
89
- window.setpos(line - offset + 2, 7)
90
- window.bold { window.addstr(key.rjust(17)) }
91
- window.setpos(line - offset + 2, 25)
92
- window.addstr(": #{description}")
93
- end
94
- end
95
- end
96
97
  end
97
98
  end
98
99
  end
@@ -0,0 +1,20 @@
1
+ module Twterm
2
+ module Tab
3
+ module Loadable
4
+ def initialize(*)
5
+ super
6
+
7
+ @initially_loaded = false
8
+ end
9
+
10
+ def initially_loaded?
11
+ @initially_loaded
12
+ end
13
+
14
+ def initially_loaded!
15
+ @initially_loaded = true
16
+ render
17
+ end
18
+ end
19
+ end
20
+ end
@@ -1,12 +1,14 @@
1
- require 'twterm/event/notification'
1
+ require 'twterm/event/notification/info'
2
2
  require 'twterm/tab/base'
3
+ require 'twterm/tab/loadable'
3
4
 
4
5
  module Twterm
5
6
  module Tab
6
7
  module New
7
8
  class List < Base
8
- include FilterableList
9
- include Scrollable
9
+ include Loadable
10
+ include Publisher
11
+ include Searchable
10
12
 
11
13
  @@lists = nil
12
14
 
@@ -18,28 +20,36 @@ module Twterm
18
20
  (window.maxy - 6).div(3)
19
21
  end
20
22
 
21
- def initialize
22
- super
23
+ def initialize(app, client)
24
+ super(app, client)
23
25
 
24
- refresh
26
+ client.lists.then do |lists|
27
+ @@lists = lists.sort_by(&:full_name)
28
+ initially_loaded!
29
+ end
25
30
  end
26
31
 
27
32
  def items
28
- (@@lists || []).select { |l| l.matches?(filter_query) }
33
+ @@lists || []
34
+ end
35
+
36
+ def matches?(list, query)
37
+ [
38
+ other.description,
39
+ other.full_name,
40
+ ].any? { |x| x.downcase.include?(query.downcase) }
29
41
  end
30
42
 
31
43
  def respond_to_key(key)
32
44
  return true if scroller.respond_to_key(key)
33
45
 
46
+ k = KeyMapper.instance
47
+
34
48
  case key
35
49
  when 10
36
50
  return true if current_list.nil?
37
- list_tab = Tab::Statuses::ListTimeline.new(current_list.id)
38
- TabManager.instance.switch(list_tab)
39
- when ?q
40
- reset_filter
41
- when ?/
42
- filter
51
+ list_tab = Tab::Statuses::ListTimeline.new(app, client, current_list.id)
52
+ app.tab_manager.switch(list_tab)
43
53
  else
44
54
  return false
45
55
  end
@@ -61,40 +71,19 @@ module Twterm
61
71
  @@lists.nil? ? nil : items[scroller.index]
62
72
  end
63
73
 
64
- def show_lists
65
- return if @@lists.nil?
74
+ def image
75
+ return Image.string(initially_loaded? ? 'No results found' : 'Loading...') if items.empty?
66
76
 
67
- index, offset = scroller.index, scroller.offset
77
+ drawable_items.map.with_index(0) do |list, i|
78
+ cursor = Image.cursor(2, scroller.current_index?(i))
68
79
 
69
- drawable_items.each.with_index(0) do |list, i|
70
- window.with_color(:black, :magenta) do
71
- window.setpos(i * 3 + 5, 4)
72
- window.addstr(' ')
73
- window.setpos(i * 3 + 6, 4)
74
- window.addstr(' ')
75
- end if scroller.current_item?(i)
80
+ summary = Image.string("#{list.full_name} (#{list.member_count} members / #{list.subscriber_count} subscribers)")
81
+ desc = Image.string(' ') - Image.string(list.description)
76
82
 
77
- window.setpos(i * 3 + 5, 6)
78
- window.addstr("#{list.full_name} (#{list.member_count} members / #{list.subscriber_count} subscribers)")
79
- window.setpos(i * 3 + 6, 8)
80
- window.addstr(list.description)
83
+ cursor - Image.whitespace - (summary | desc)
81
84
  end
82
- end
83
-
84
- def update
85
- window.setpos(2, 3)
86
- window.bold { window.addstr('Open list tab') }
87
-
88
- Thread.new do
89
- publish(Event::Notification.new(:message, 'Loading lists ...'))
90
- Client.current.lists.then do |lists|
91
- @@lists = lists.sort_by(&:full_name)
92
- show_lists
93
- window.refresh if TabManager.instance.current_tab == self
94
- end
95
- end if @@lists.nil?
96
-
97
- show_lists
85
+ .intersperse(Image.blank_line)
86
+ .reduce(Image.empty, :|)
98
87
  end
99
88
  end
100
89
  end
@@ -1,14 +1,17 @@
1
+ require 'concurrent'
2
+
1
3
  require 'twterm/tab/base'
4
+ require 'twterm/tab/loadable'
2
5
 
3
6
  module Twterm
4
7
  module Tab
5
8
  module New
6
9
  class Search < Base
10
+ include Loadable
7
11
  include Readline
8
- include FilterableList
9
- include Scrollable
12
+ include Searchable
10
13
 
11
- @@queries = []
14
+ @@queries = Concurrent::Array.new
12
15
 
13
16
  def ==(other)
14
17
  other.is_a?(self.class)
@@ -18,8 +21,8 @@ module Twterm
18
21
  (window.maxy - 6).div(3)
19
22
  end
20
23
 
21
- def initialize
22
- super
24
+ def initialize(app, client)
25
+ super(app, client)
23
26
 
24
27
  update_saved_search
25
28
  end
@@ -28,36 +31,32 @@ module Twterm
28
31
  resetter = proc do
29
32
  reset_prog_mode
30
33
  sleep 0.1
31
- Screen.instance.refresh
34
+ app.screen.refresh
32
35
  end
33
36
 
34
37
  input_thread = Thread.new do
35
38
  close_screen
36
- CompletionManager.instance.set_default_mode!
39
+ app.completion_manager.set_default_mode!
37
40
  puts "\ninput search query"
38
41
  query = (readline('> ') || '').strip
39
42
  resetter.call
40
43
 
41
- tab = query.nil? || query.empty? ? Tab::New::Search.new : Tab::Statuses::Search.new(query)
42
- TabManager.instance.switch(tab)
44
+ tab = query.nil? || query.empty? ? Tab::New::Search.new(app, client) : Tab::Statuses::Search.new(app, client, query)
45
+ app.tab_manager.switch(tab)
43
46
  end
44
47
 
45
- App.instance.register_interruption_handler do
48
+ app.register_interruption_handler do
46
49
  input_thread.kill
47
50
  resetter.call
48
51
  tab = Tab::New::Search.new
49
- TabManager.instance.switch(tab)
52
+ app.tab_manager.switch(tab)
50
53
  end
51
54
 
52
55
  input_thread.join
53
56
  end
54
57
 
55
58
  def items
56
- if filter_query.empty?
57
- ['<Input search query>'] + @@queries
58
- else
59
- @@queries.select { |q| q.matches?(filter_query) }
60
- end
59
+ ['<Input search query>', *@@queries]
61
60
  end
62
61
 
63
62
  def respond_to_key(key)
@@ -66,10 +65,6 @@ module Twterm
66
65
  case key
67
66
  when 10
68
67
  open_search_tab_with_current_query
69
- when ?q
70
- reset_filter
71
- when ?/
72
- filter
73
68
  else
74
69
  return false
75
70
  end
@@ -92,42 +87,34 @@ module Twterm
92
87
  def open_search_tab_with_current_query
93
88
  index = scroller.index
94
89
 
95
- if filter_query.empty? && index.zero?
90
+ if search_query.empty? && index.zero?
96
91
  invoke_input
97
92
  else
98
93
  query = items[index]
99
- tab = Tab::Statuses::Search.new(query)
100
- TabManager.instance.switch(tab)
94
+ tab = Tab::Statuses::Search.new(app, client, query)
95
+ app.tab_manager.switch(tab)
101
96
  end
102
97
  end
103
98
 
104
- def update
105
- offset = scroller.offset
106
-
107
- window.setpos(2, 3)
108
- window.bold { window.addstr('Open search tab') }
109
-
110
- drawable_items.each.with_index(0) do |query, i|
111
- line = 3 * i + 5
112
-
113
- window.with_color(:black, :magenta) do
114
- window.setpos(line, 4)
115
- window.addstr(' ')
116
- window.setpos(line + 1, 4)
117
- window.addstr(' ')
118
- end if scroller.current_item?(i)
119
-
120
- window.setpos(line, 6)
121
- window.addstr(query)
122
- end
99
+ def image
100
+ [
101
+ *drawable_items
102
+ .map.with_index(0) { |query, i|
103
+ Image.cursor(1, scroller.current_index?(i)) - Image.whitespace - Image.string(query)
104
+ },
105
+ (Image.string(' Loading saved searches...') unless initially_loaded?),
106
+ ]
107
+ .reject(&:nil?)
108
+ .intersperse(Image.blank_line)
109
+ .reduce(Image.empty, :|)
123
110
  end
124
111
 
125
112
  def update_saved_search
126
113
  return unless @@queries.empty?
127
114
 
128
- Client.current.saved_search.then do |searches|
115
+ client.saved_search.then do |searches|
129
116
  @@queries = searches.map(&:query)
130
- refresh
117
+ initially_loaded!
131
118
  end
132
119
  end
133
120
  end
@@ -1,5 +1,6 @@
1
1
  require 'twterm/tab/base'
2
2
  require 'twterm/tab/direct_message/conversation_list'
3
+ require 'twterm/tab/rate_limit_status'
3
4
 
4
5
  module Twterm
5
6
  module Tab
@@ -22,28 +23,21 @@ module Twterm
22
23
  search_tab
23
24
  user_tab
24
25
  key_assignments_cheatsheet
26
+ rate_limit_status
25
27
  ).freeze
26
28
  end
27
29
 
28
- def initialize
29
- super
30
- refresh
30
+ def initialize(app, client)
31
+ super(app, client)
32
+ render
31
33
  end
32
34
 
33
35
  def respond_to_key(key)
34
36
  return true if scroller.respond_to_key(key)
35
37
 
36
38
  case key
37
- when 'D'
38
- open_direct_messages
39
39
  when 10
40
40
  perform_selected_action
41
- when 'L'
42
- open_list_tab
43
- when 'S'
44
- open_search_tab
45
- when 'U'
46
- open_user_tab
47
41
  else
48
42
  return false
49
43
  end
@@ -56,26 +50,57 @@ module Twterm
56
50
 
57
51
  private
58
52
 
53
+ def image
54
+ drawable_items
55
+ .map.with_index(0) { |item, i|
56
+ cursor = Image.cursor(1, scroller.current_index?(i))
57
+
58
+ desc =
59
+ case item
60
+ when :direct_messages
61
+ 'Direct messages'
62
+ when :list_tab
63
+ 'List tab'
64
+ when :search_tab
65
+ 'Search tab'
66
+ when :user_tab
67
+ 'User tab'
68
+ when :key_assignments_cheatsheet
69
+ 'Key assignments cheatsheet'
70
+ when :rate_limit_status
71
+ 'Rate limit status'
72
+ end
73
+
74
+ cursor - Image.whitespace - Image.string(desc)
75
+ }
76
+ .intersperse(Image.blank_line)
77
+ .reduce(Image.empty, :|)
78
+ end
79
+
59
80
  def open_direct_messages
60
- switch(Tab::DirectMessage::ConversationList.new)
81
+ switch(Tab::DirectMessage::ConversationList.new(app, client))
61
82
  end
62
83
 
63
84
  def open_list_tab
64
- switch(Tab::New::List.new)
85
+ switch(Tab::New::List.new(app, client))
65
86
  end
66
87
 
67
88
  def open_search_tab
68
- switch(Tab::New::Search.new)
89
+ switch(Tab::New::Search.new(app, client))
90
+ end
91
+
92
+ def open_rate_limit_status
93
+ switch(Tab::RateLimitStatus.new(app, client))
69
94
  end
70
95
 
71
96
  def open_user_tab
72
- tab = Tab::New::User.new
97
+ tab = Tab::New::User.new(app, client)
73
98
  switch(tab)
74
99
  tab.invoke_input
75
100
  end
76
101
 
77
102
  def open_key_assignments_cheatsheet
78
- switch(Tab::KeyAssignmentsCheatsheet.new)
103
+ switch(Tab::KeyAssignmentsCheatsheet.new(app, client))
79
104
  end
80
105
 
81
106
  def perform_selected_action
@@ -90,49 +115,13 @@ module Twterm
90
115
  open_user_tab
91
116
  when :key_assignments_cheatsheet
92
117
  open_key_assignments_cheatsheet
118
+ when :rate_limit_status
119
+ open_rate_limit_status
93
120
  end
94
121
  end
95
122
 
96
123
  def switch(tab)
97
- TabManager.instance.switch(tab)
98
- end
99
-
100
- def update
101
- window.setpos(2, 3)
102
- window.bold { window.addstr('Open new tab') }
103
-
104
- drawable_items.each.with_index(0) do |item, i|
105
- line = 4 + i * 2
106
- window.setpos(line, 5)
107
-
108
- case item
109
- when :direct_messages
110
- window.addstr('[D] Direct messages')
111
- window.setpos(line, 6)
112
- window.bold { window.addch(?D) }
113
- when :list_tab
114
- window.addstr('[L] List tab')
115
- window.setpos(line, 6)
116
- window.bold { window.addch(?L) }
117
- when :search_tab
118
- window.addstr('[S] Search tab')
119
- window.setpos(line, 6)
120
- window.bold { window.addch(?S) }
121
- when :user_tab
122
- window.addstr('[U] User tab')
123
- window.setpos(line, 6)
124
- window.bold { window.addch(?U) }
125
- when :key_assignments_cheatsheet
126
- window.addstr('[?] Key assignments cheatsheet')
127
- window.setpos(line, 6)
128
- window.bold { window.addch(??) }
129
- end
130
-
131
- window.with_color(:black, :magenta) do
132
- window.setpos(line, 3)
133
- window.addch(' ')
134
- end if scroller.current_item?(i)
135
- end
124
+ app.tab_manager.switch(tab)
136
125
  end
137
126
  end
138
127
  end
@@ -1,5 +1,6 @@
1
1
  require 'twterm/publisher'
2
2
  require 'twterm/tab/base'
3
+ require 'twterm/event/notification/error'
3
4
 
4
5
  module Twterm
5
6
  module Tab
@@ -16,10 +17,10 @@ module Twterm
16
17
  resetter = proc do
17
18
  reset_prog_mode
18
19
  sleep 0.1
19
- Screen.instance.refresh
20
+ app.screen.refresh
20
21
  end
21
22
 
22
- CompletionManager.instance.set_screen_name_mode!
23
+ app.completion_manager.set_screen_name_mode!
23
24
 
24
25
  input_thread = Thread.new do
25
26
  close_screen
@@ -28,25 +29,25 @@ module Twterm
28
29
  resetter.call
29
30
 
30
31
  if screen_name.nil? || screen_name.empty?
31
- TabManager.instance.switch(Tab::New::Start.new)
32
+ app.tab_manager.switch(Tab::New::Start.new(app, client))
32
33
  else
33
- Client.current.show_user(screen_name).then do |user|
34
+ client.show_user(screen_name).then do |user|
34
35
  if user.nil?
35
- publish(Event::Notification.new(:error, 'User not found'))
36
- tab = Tab::New::Start.new
36
+ publish(Event::Notification::Error.new('User not found'))
37
+ tab = Tab::New::Start.new(app, client)
37
38
  else
38
- tab = Tab::UserTab.new(user.id)
39
+ tab = Tab::UserTab.new(app, client, user.id)
39
40
  end
40
- TabManager.instance.switch(tab)
41
+ app.tab_manager.switch(tab)
41
42
  end
42
43
  end
43
44
  end
44
45
 
45
- App.instance.register_interruption_handler do
46
+ app.register_interruption_handler do
46
47
  input_thread.kill
47
48
  resetter.call
48
- tab = Tab::New::Start.new
49
- TabManager.instance.switch(tab)
49
+ tab = Tab::New::Start.new(app, client)
50
+ app.tab_manager.switch(tab)
50
51
  end
51
52
 
52
53
  input_thread.join
@@ -62,7 +63,9 @@ module Twterm
62
63
 
63
64
  private
64
65
 
65
- def update; end
66
+ def image
67
+ Image.empty
68
+ end
66
69
  end
67
70
  end
68
71
  end