twterm 1.0.9 → 1.0.10
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/.rspec +2 -0
- data/{LICENSE.txt → LICENSE} +0 -0
- data/README.md +24 -2
- data/lib/twterm/app.rb +14 -4
- data/lib/twterm/auth.rb +5 -5
- data/lib/twterm/client.rb +185 -142
- data/lib/twterm/color_manager.rb +15 -11
- data/lib/twterm/config.rb +22 -17
- data/lib/twterm/list.rb +9 -9
- data/lib/twterm/notifier.rb +7 -22
- data/lib/twterm/scheduler.rb +5 -8
- data/lib/twterm/screen.rb +25 -20
- data/lib/twterm/status.rb +84 -79
- data/lib/twterm/tab/base.rb +26 -11
- data/lib/twterm/tab/conversation_tab.rb +16 -16
- data/lib/twterm/tab/key_assignments_cheatsheet.rb +113 -0
- data/lib/twterm/tab/list_tab.rb +1 -1
- data/lib/twterm/tab/mentions_tab.rb +13 -13
- data/lib/twterm/tab/new/list.rb +51 -40
- data/lib/twterm/tab/new/search.rb +8 -5
- data/lib/twterm/tab/new/start.rb +26 -35
- data/lib/twterm/tab/new/user.rb +8 -5
- data/lib/twterm/tab/scroll_manager.rb +84 -0
- data/lib/twterm/tab/search_tab.rb +16 -16
- data/lib/twterm/tab/statuses_tab.rb +177 -128
- data/lib/twterm/tab/timeline_tab.rb +13 -15
- data/lib/twterm/tab/user_tab.rb +18 -18
- data/lib/twterm/tab_manager.rb +49 -44
- data/lib/twterm/tweetbox.rb +51 -25
- data/lib/twterm/user.rb +5 -8
- data/lib/twterm/version.rb +1 -1
- data/lib/twterm.rb +4 -2
- data/spec/resources/config +4 -0
- data/spec/spec_helper.rb +7 -0
- data/spec/twterm/config_spec.rb +34 -0
- data/twterm.gemspec +2 -0
- metadata +25 -6
- data/lib/twterm/tab/scrollable.rb +0 -130
data/lib/twterm/tab/new/list.rb
CHANGED
@@ -3,84 +3,95 @@ module Twterm
|
|
3
3
|
module New
|
4
4
|
class List
|
5
5
|
include Base
|
6
|
-
include Scrollable
|
7
6
|
|
8
7
|
@@lists = nil
|
9
8
|
|
9
|
+
def ==(other)
|
10
|
+
other.is_a?(self.class)
|
11
|
+
end
|
12
|
+
|
10
13
|
def initialize
|
11
14
|
super
|
12
15
|
|
13
16
|
@title = 'New tab'
|
17
|
+
refresh
|
14
18
|
end
|
15
19
|
|
16
20
|
def respond_to_key(key)
|
17
|
-
return true if super
|
18
|
-
|
19
21
|
case key
|
22
|
+
when ?g
|
23
|
+
scroll_manager.move_to_top
|
24
|
+
when ?G
|
25
|
+
scroll_manager.move_to_bottom
|
26
|
+
when ?j, 14, Curses::Key::DOWN
|
27
|
+
scroll_manager.move_down
|
20
28
|
when 10
|
21
29
|
return true if current_list.nil?
|
22
30
|
list_tab = Tab::ListTab.new(current_list.id)
|
23
31
|
TabManager.instance.switch(list_tab)
|
32
|
+
when ?k, 16, Curses::Key::UP
|
33
|
+
scroll_manager.move_up
|
24
34
|
else
|
25
35
|
return false
|
26
36
|
end
|
27
37
|
true
|
28
38
|
end
|
29
39
|
|
30
|
-
def ==(other)
|
31
|
-
other.is_a?(self.class)
|
32
|
-
end
|
33
|
-
|
34
40
|
private
|
35
41
|
|
42
|
+
def count
|
43
|
+
@@lists.nil? ? 0 : @@lists.count
|
44
|
+
end
|
45
|
+
|
36
46
|
def current_list
|
37
|
-
@@lists.nil? ? nil : @@lists[index]
|
47
|
+
@@lists.nil? ? nil : @@lists[scroll_manager.index]
|
38
48
|
end
|
39
49
|
|
40
|
-
def
|
41
|
-
|
50
|
+
def offset_from_bottom
|
51
|
+
0
|
52
|
+
end
|
42
53
|
|
43
|
-
|
44
|
-
|
45
|
-
|
54
|
+
def show_lists
|
55
|
+
return if @@lists.nil?
|
56
|
+
|
57
|
+
@@lists.each.with_index(0) do |list, i|
|
58
|
+
window.with_color(:black, :magenta) do
|
59
|
+
window.setpos(i * 3 + 5, 4)
|
60
|
+
window.addstr(' ')
|
61
|
+
window.setpos(i * 3 + 6, 4)
|
62
|
+
window.addstr(' ')
|
63
|
+
end if i == scroll_manager.index
|
64
|
+
|
65
|
+
window.setpos(i * 3 + 5, 6)
|
66
|
+
window.addstr("#{list.full_name} (#{list.member_count} members / #{list.subscriber_count} subscribers)")
|
67
|
+
window.setpos(i * 3 + 6, 8)
|
68
|
+
window.addstr(list.description)
|
46
69
|
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def scroll_manager
|
73
|
+
return @scroll_manager unless @scroll_manager.nil?
|
74
|
+
|
75
|
+
@scroll_manager = ScrollManager.new
|
76
|
+
@scroll_manager.delegate = self
|
77
|
+
@scroll_manager.after_move { refresh }
|
78
|
+
@scroll_manager
|
79
|
+
end
|
80
|
+
|
81
|
+
def update
|
82
|
+
window.setpos(2, 3)
|
83
|
+
window.bold { window.addstr('Open list tab') }
|
47
84
|
|
48
85
|
Thread.new do
|
49
86
|
Notifier.instance.show_message('Loading lists ...')
|
50
87
|
Client.current.lists do |lists|
|
51
88
|
@@lists = lists.sort_by(&:full_name)
|
52
89
|
show_lists
|
53
|
-
|
54
|
-
@window.refresh if TabManager.instance.current_tab == self
|
90
|
+
window.refresh if TabManager.instance.current_tab == self
|
55
91
|
end
|
56
92
|
end if @@lists.nil?
|
57
93
|
|
58
94
|
show_lists
|
59
|
-
draw_scroll_bar
|
60
|
-
|
61
|
-
@window.refresh
|
62
|
-
end
|
63
|
-
|
64
|
-
def show_lists
|
65
|
-
return if @@lists.nil?
|
66
|
-
|
67
|
-
@@lists.each.with_index(0) do |list, i|
|
68
|
-
@window.with_color(:black, :magenta) do
|
69
|
-
@window.setpos(i * 3 + 5, 4)
|
70
|
-
@window.addstr(' ')
|
71
|
-
@window.setpos(i * 3 + 6, 4)
|
72
|
-
@window.addstr(' ')
|
73
|
-
end if i == index
|
74
|
-
|
75
|
-
@window.setpos(i * 3 + 5, 6)
|
76
|
-
@window.addstr("#{list.full_name} (#{list.member_count} members / #{list.subscriber_count} subscribers)")
|
77
|
-
@window.setpos(i * 3 + 6, 8)
|
78
|
-
@window.addstr(list.description)
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
def count
|
83
|
-
@@lists.nil? ? 0 : @@lists.count
|
84
95
|
end
|
85
96
|
end
|
86
97
|
end
|
@@ -5,15 +5,14 @@ module Twterm
|
|
5
5
|
include Base
|
6
6
|
include Readline
|
7
7
|
|
8
|
+
def ==(other)
|
9
|
+
other.is_a?(self.class)
|
10
|
+
end
|
11
|
+
|
8
12
|
def initialize
|
9
13
|
super
|
10
14
|
|
11
15
|
@title = 'New tab'
|
12
|
-
@window.refresh
|
13
|
-
end
|
14
|
-
|
15
|
-
def respond_to_key(_)
|
16
|
-
false
|
17
16
|
end
|
18
17
|
|
19
18
|
def invoke_input
|
@@ -44,6 +43,10 @@ module Twterm
|
|
44
43
|
input_thread.join
|
45
44
|
end
|
46
45
|
|
46
|
+
def respond_to_key(_)
|
47
|
+
false
|
48
|
+
end
|
49
|
+
|
47
50
|
private
|
48
51
|
|
49
52
|
def update; end
|
data/lib/twterm/tab/new/start.rb
CHANGED
@@ -4,6 +4,10 @@ module Twterm
|
|
4
4
|
class Start
|
5
5
|
include Base
|
6
6
|
|
7
|
+
def ==(other)
|
8
|
+
other.is_a?(self.class)
|
9
|
+
end
|
10
|
+
|
7
11
|
def initialize
|
8
12
|
super
|
9
13
|
@title = 'New tab'
|
@@ -23,54 +27,41 @@ module Twterm
|
|
23
27
|
tab = Tab::New::User.new
|
24
28
|
TabManager.instance.switch(tab)
|
25
29
|
tab.invoke_input
|
30
|
+
when 'x'
|
31
|
+
tab = Tab::New::Track.new
|
32
|
+
TabManager.instance.switch(tab)
|
33
|
+
tab.invoke_input
|
26
34
|
else
|
27
35
|
return false
|
28
36
|
end
|
29
37
|
true
|
30
38
|
end
|
31
39
|
|
32
|
-
def ==(other)
|
33
|
-
other.is_a?(self.class)
|
34
|
-
end
|
35
|
-
|
36
40
|
private
|
37
41
|
|
38
42
|
def update
|
39
|
-
|
40
|
-
|
41
|
-
@window.bold do
|
42
|
-
@window.setpos(2, 3)
|
43
|
-
@window.addstr("You've opened a new tab")
|
44
|
-
end
|
43
|
+
window.setpos(2, 3)
|
44
|
+
window.bold { window.addstr("You've opened a new tab") }
|
45
45
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
@window.addstr('[L]')
|
51
|
-
end
|
46
|
+
window.setpos(4, 5)
|
47
|
+
window.addstr('- [L] Open list tab')
|
48
|
+
window.setpos(4, 7)
|
49
|
+
window.bold { window.addstr('[L]') }
|
52
50
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
@window.addstr('[S]')
|
58
|
-
end
|
51
|
+
window.setpos(6, 5)
|
52
|
+
window.addstr('- [S] Open search tab')
|
53
|
+
window.setpos(6, 7)
|
54
|
+
window.bold { window.addstr('[S]') }
|
59
55
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
@window.addstr('[U]')
|
65
|
-
end
|
56
|
+
window.setpos(8, 5)
|
57
|
+
window.addstr('- [U] Open user tab')
|
58
|
+
window.setpos(8, 7)
|
59
|
+
window.bold { window.addstr('[U]') }
|
66
60
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
@window.addstr('[w]')
|
72
|
-
end
|
73
|
-
@window.refresh
|
61
|
+
window.setpos(11, 3)
|
62
|
+
window.addstr('To cancel opening a new tab, just press [w] to close this tab.')
|
63
|
+
window.setpos(11, 43)
|
64
|
+
window.bold { window.addstr('[w]') }
|
74
65
|
end
|
75
66
|
end
|
76
67
|
end
|
data/lib/twterm/tab/new/user.rb
CHANGED
@@ -5,15 +5,14 @@ module Twterm
|
|
5
5
|
include Base
|
6
6
|
include Readline
|
7
7
|
|
8
|
+
def ==(other)
|
9
|
+
other.is_a?(self.class)
|
10
|
+
end
|
11
|
+
|
8
12
|
def initialize
|
9
13
|
super
|
10
14
|
|
11
15
|
@title = 'New tab'
|
12
|
-
@window.refresh
|
13
|
-
end
|
14
|
-
|
15
|
-
def respond_to_key(_)
|
16
|
-
false
|
17
16
|
end
|
18
17
|
|
19
18
|
def invoke_input
|
@@ -56,6 +55,10 @@ module Twterm
|
|
56
55
|
input_thread.join
|
57
56
|
end
|
58
57
|
|
58
|
+
def respond_to_key(_)
|
59
|
+
false
|
60
|
+
end
|
61
|
+
|
59
62
|
private
|
60
63
|
|
61
64
|
def update; end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
module Twterm
|
2
|
+
module Tab
|
3
|
+
class ScrollManager
|
4
|
+
extend Forwardable
|
5
|
+
|
6
|
+
attr_reader :index, :offset
|
7
|
+
attr_accessor :last
|
8
|
+
|
9
|
+
attr_accessor :delegate
|
10
|
+
def_delegators :delegate, :count, :offset_from_bottom
|
11
|
+
|
12
|
+
def after_move(&block)
|
13
|
+
add_hook(:after_move, &block)
|
14
|
+
end
|
15
|
+
|
16
|
+
def initialize
|
17
|
+
@index = 0
|
18
|
+
@offset = 0
|
19
|
+
@last = 0
|
20
|
+
end
|
21
|
+
|
22
|
+
def item_appended!
|
23
|
+
@index -= 1
|
24
|
+
@offset -= 1 if @offset > 0
|
25
|
+
end
|
26
|
+
|
27
|
+
def item_prepended!
|
28
|
+
@index += 1
|
29
|
+
@offset += 1
|
30
|
+
end
|
31
|
+
|
32
|
+
def move_down
|
33
|
+
return if count == 0 || index == count - 1
|
34
|
+
|
35
|
+
@index = [index + 1, count - 1].min
|
36
|
+
@offset = [
|
37
|
+
offset + 1,
|
38
|
+
count - 1,
|
39
|
+
count - offset_from_bottom
|
40
|
+
].min if index > last - 4
|
41
|
+
|
42
|
+
hook :after_move
|
43
|
+
end
|
44
|
+
|
45
|
+
def move_to_bottom
|
46
|
+
return if count == 0 || index == count - 1
|
47
|
+
|
48
|
+
@index = count - 1
|
49
|
+
@offset = count - 1 - offset_from_bottom
|
50
|
+
|
51
|
+
hook :after_move
|
52
|
+
end
|
53
|
+
|
54
|
+
def move_to_top
|
55
|
+
return if count == 0 || index == 0
|
56
|
+
|
57
|
+
@index = 0
|
58
|
+
@offset = 0
|
59
|
+
|
60
|
+
hook :after_move
|
61
|
+
end
|
62
|
+
|
63
|
+
def move_up
|
64
|
+
return if count == 0 || index == 0
|
65
|
+
|
66
|
+
@index = [index - 1, 0].max
|
67
|
+
@offset = [offset - 1, 0].max if index - 4 < offset
|
68
|
+
|
69
|
+
hook :after_move
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
def add_hook(name, &block)
|
75
|
+
@hooks ||= {}
|
76
|
+
@hooks[name] = block
|
77
|
+
end
|
78
|
+
|
79
|
+
def hook(name)
|
80
|
+
@hooks[name].call unless @hooks[name].nil?
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -6,34 +6,34 @@ module Twterm
|
|
6
6
|
|
7
7
|
attr_reader :query
|
8
8
|
|
9
|
-
def
|
10
|
-
|
9
|
+
def ==(other)
|
10
|
+
other.is_a?(self.class) && query == other.query
|
11
|
+
end
|
11
12
|
|
12
|
-
|
13
|
-
@
|
13
|
+
def close
|
14
|
+
@auto_reloader.kill if @auto_reloader
|
15
|
+
super
|
16
|
+
end
|
14
17
|
|
15
|
-
|
16
|
-
@
|
18
|
+
def dump
|
19
|
+
@query
|
17
20
|
end
|
18
21
|
|
19
22
|
def fetch
|
20
23
|
Client.current.search(@query) do |statuses|
|
21
|
-
statuses.reverse.each
|
24
|
+
statuses.reverse.each(&method(:prepend))
|
22
25
|
yield if block_given?
|
23
26
|
end
|
24
27
|
end
|
25
28
|
|
26
|
-
def
|
27
|
-
|
28
|
-
super
|
29
|
-
end
|
29
|
+
def initialize(query)
|
30
|
+
super()
|
30
31
|
|
31
|
-
|
32
|
-
|
33
|
-
end
|
32
|
+
@query = query
|
33
|
+
@title = "\"#{@query}\""
|
34
34
|
|
35
|
-
|
36
|
-
@
|
35
|
+
fetch { scroll_manager.move_to_top }
|
36
|
+
@auto_reloader = Scheduler.new(300) { fetch }
|
37
37
|
end
|
38
38
|
end
|
39
39
|
end
|