mars_base_10 0.4.0 → 0.5.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fd093ec957e418592f791bb2dfc1e1e7efa56973fd553534278a6dcb818f3482
4
- data.tar.gz: 478b185df1d0c2280788691e4bd61bfac817c200348e63bb29a7a36e05f1eb84
3
+ metadata.gz: 9ea353d6a59cf0d1ad388a521fa07a121cd94942eb4556c23ee4a11603622141
4
+ data.tar.gz: 6fd28ad9bd47d54172c4a3c6a0f64e5e4da244af6065ad8514f779cc388dc0c6
5
5
  SHA512:
6
- metadata.gz: e9044477c9eb149f2212f5dd5e7e44eb8d0fa247e0db7a382aa5256708ba53027e8c48c18f992b4c2c7dde36281cd5f725f86662283d71f713f50ed6a08662a2
7
- data.tar.gz: ac4c86d4ab841a92e262138bdf6a290af01d93e65d1afe514d6076681bb217dc59bde4ec2e90ccd3e10d4936ae298387ae0d662565e3030e88658a1f0a78deb6
6
+ metadata.gz: 248ae50be666debca25a7c253822e941af1c3ba19ac484b6e21423526497c9777419b4b2417756a565bc890afb9dc817d0eb3060eb0b7db34bab0ae5c396ac58
7
+ data.tar.gz: 20e525d483036e6a815f0e46a3529cdf6d1bee8e4a96bc8c32cc0d27b774331e13d1ae3c76177904da39b845224ed12cfa6b4dc3cb667e943704c75799cb7360
@@ -11,7 +11,7 @@ module MarsBase10
11
11
  end
12
12
 
13
13
  def self.Default
14
- ActionBar.new actions: {'j': 'Move Down', 'k': 'Move Up', 'J': 'Page Down', 'K': 'Page Up', 'q': 'Quit'}
14
+ ActionBar.new actions: {'j': 'Move Down', 'k': 'Move Up', 'J': 'Page Down', 'K': 'Page Up', 'X': 'Switch App', 'q': 'Quit'}
15
15
  end
16
16
 
17
17
  def actions_first_col
@@ -2,6 +2,7 @@
2
2
  require 'urbit'
3
3
 
4
4
  require_relative 'graph_rover'
5
+ require_relative 'group_room'
5
6
  require_relative 'viewport'
6
7
 
7
8
  module MarsBase10
@@ -10,22 +11,38 @@ module MarsBase10
10
11
  class CommCentral
11
12
  def initialize(config_filename:)
12
13
  @viewport = Viewport.new
13
- @rover = GraphRover.new ship_connection: Urbit.connect(config_file: config_filename),
14
- viewport: @viewport
14
+ @ship = Urbit.connect(config_file: config_filename)
15
+ @ship.login
16
+ sleep 2 # This is temporary for now, we need a way to know that the subscription callbacks have finished.
17
+ @controller = GroupRoom.new manager: self, ship_connection: @ship, viewport: @viewport
15
18
  end
16
19
 
17
20
  def activate
18
- self.rover.start
21
+ self.controller.start
22
+ end
23
+
24
+ def swap_controller
25
+ self.controller.stop
26
+ if GroupRoom == self.controller.class
27
+ @controller = GraphRover.new manager: self, ship_connection: self.ship, viewport: @viewport
28
+ else
29
+ @controller = GroupRoom.new manager: self, ship_connection: self.ship, viewport: @viewport
30
+ end
31
+ self.controller.start
19
32
  end
20
33
 
21
34
  def shutdown
22
- self.rover.stop
35
+ self.controller.stop
23
36
  end
24
37
 
25
38
  private
26
39
 
27
- def rover
28
- @rover
40
+ def controller
41
+ @controller
42
+ end
43
+
44
+ def ship
45
+ @ship
29
46
  end
30
47
  end
31
48
  end
@@ -6,9 +6,10 @@ require_relative 'subject'
6
6
 
7
7
  module MarsBase10
8
8
  class GraphRover
9
- attr_reader :panes, :ship, :viewport
9
+ attr_reader :manager, :panes, :ship, :viewport
10
10
 
11
- def initialize(ship_connection:, viewport:)
11
+ def initialize(manager:, ship_connection:, viewport:)
12
+ @manager = manager
12
13
  @ship = Ship.new connection: ship_connection
13
14
  @stack = Stack.new
14
15
  @viewport = viewport
@@ -75,6 +76,8 @@ module MarsBase10
75
76
  self.viewport.action_bar.remove_action(:p)
76
77
  end
77
78
  end
79
+ when 'X'
80
+ self.manager.swap_controller
78
81
  end
79
82
  self.resync if resync_needed
80
83
  end
@@ -0,0 +1,128 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'ship'
4
+ require_relative 'stack'
5
+ require_relative 'subject'
6
+
7
+ module MarsBase10
8
+ class GroupRoom
9
+ attr_reader :manager, :panes, :ship, :viewport
10
+
11
+ def initialize(manager:, ship_connection:, viewport:)
12
+ @manager = manager
13
+ @ship = Ship.new connection: ship_connection
14
+ @stack = Stack.new
15
+ @viewport = viewport
16
+ @viewport.controller = self
17
+
18
+ self.wire_up_panes
19
+ self.viewport.action_bar = ActionBar.Default.add_action({'i': 'Inspect'})
20
+ self.viewport.activate pane: @pane_1
21
+ self.resync
22
+ end
23
+
24
+ def active_node
25
+ self.ship.fetch_node(resource: self.active_resource, index: self.active_node_index)
26
+ end
27
+
28
+ def active_resource
29
+ @pane_1.current_subject_index
30
+ end
31
+
32
+ def active_subject(pane:)
33
+ pane.current_subject_index
34
+ end
35
+
36
+ def load_history
37
+ return 0 unless @pane_3 == self.viewport.active_pane
38
+ new_content = self.ship.fetch_older_nodes(resource: self.active_resource, node: self.active_node)
39
+ @pane_3.subject.prepend_content(ary: new_content)
40
+ new_content.length
41
+ end
42
+
43
+ #
44
+ # Called by a pane in this controller for bubbling a key press up
45
+ #
46
+ def send(key:)
47
+ resync_needed = true
48
+ case key
49
+ when 'g' # (G)raph View
50
+ unless @pane_1.active?
51
+ self.viewport.activate pane: @pane_1
52
+ end
53
+ when 'i' # (I)nspect
54
+ begin
55
+ self.viewport.activate pane: @pane_3
56
+ self.viewport.action_bar = ActionBar.Default.add_action({'g': 'Group List'})
57
+ resync_needed = false
58
+ end
59
+ when 'X'
60
+ self.manager.swap_controller
61
+ end
62
+ self.resync if resync_needed
63
+ end
64
+
65
+ def start
66
+ self.viewport.open
67
+ end
68
+
69
+ def stop
70
+ self.viewport.close
71
+ end
72
+
73
+ private
74
+
75
+ def resync
76
+ self.resync_node_list
77
+ self.resync_node_view
78
+ end
79
+
80
+ def resync_node_list
81
+ if @pane_1 == self.viewport.active_pane
82
+ group_title = self.active_subject(pane: @pane_1)
83
+ @pane_2.clear
84
+ @pane_2.subject.title = "#{group_title}"
85
+ @pane_2.subject.contents = self.ship.fetch_group(group_title: group_title)
86
+
87
+ @pane_3.clear
88
+ @pane_3.subject.title = "Channels of #{self.active_subject(pane: @pane_1)}"
89
+ @pane_3.subject.contents = self.ship.fetch_group_channels(group_title: self.active_subject(pane: @pane_1))
90
+ end
91
+ nil
92
+ end
93
+
94
+ def resync_node_view
95
+ channel_title = self.active_subject(pane: @pane_3)
96
+ @pane_4.subject.title = "#{channel_title}"
97
+ @pane_4.clear
98
+ @pane_4.subject.contents = self.ship.fetch_channel(group_title: self.active_subject(pane: @pane_1), channel_title: channel_title)
99
+ nil
100
+ end
101
+
102
+ def wire_up_panes
103
+ @panes = []
104
+
105
+ # Pane #1 is the Group list, It is a fixed height and width in the upper left corner.
106
+ @pane_1 = @viewport.add_pane height_pct: 0.5, width_pct: 0.5
107
+ # if @ship.group_names.empty?
108
+ # @pane_1.view(subject: @ship.graph_names)
109
+ # else
110
+ @pane_1.view(subject: @ship.group_names)
111
+ # end
112
+
113
+ # Pane 2 displays the properties of the selected Group. It is variable height in the bottom left corner.
114
+ @pane_2 = @viewport.add_variable_height_pane at_row: @pane_1.last_row, width_pct: 0.5
115
+ @pane_2.view(subject: @ship.empty_node)
116
+ @pane_2.highlight = false
117
+
118
+ # The node list is a variable width, fixed height pane in the upper right.
119
+ @pane_3 = @viewport.add_variable_width_pane at_col: @pane_1.last_col, height_pct: 0.5
120
+ @pane_3.view(subject: @ship.empty_node_list)
121
+
122
+ # The single node viewer is a variable width, variable height pane in the lower right.
123
+ @pane_4 = @viewport.add_variable_both_pane at_row: @pane_3.last_row, at_col: @pane_1.last_col
124
+ @pane_4.view(subject: @ship.empty_node)
125
+ @pane_4.highlight = false
126
+ end
127
+ end
128
+ end
@@ -3,13 +3,14 @@ require 'curses'
3
3
 
4
4
  module MarsBase10
5
5
  class Pane
6
- attr_accessor :draw_row, :draw_col, :index, :latch, :subject
6
+ attr_accessor :draw_row, :draw_col, :highlight, :index, :latch, :subject
7
7
  attr_reader :height_pct, :left_edge_col, :top_row, :viewport, :width_pct
8
8
 
9
9
  def initialize(viewport:, at_row:, at_col:, height_pct: 1, width_pct: 1)
10
10
  @top_row = at_row
11
11
  @left_edge_col = at_col
12
12
  @height_pct = height_pct
13
+ @highlight = true
13
14
  @index = 1
14
15
  @latch = ''
15
16
  @latch_depth = 0
@@ -48,10 +49,10 @@ module MarsBase10
48
49
  (first_draw_row..last_draw_row).each do |index|
49
50
  self.draw_line
50
51
  item_index = index + @visible_content_shift
51
- self.window.attron(Curses::A_REVERSE) if item_index == self.index
52
+ self.window.attron(Curses::A_REVERSE) if (item_index == self.index) && self.highlight
52
53
 
53
54
  if self.subject.line_length_at(index: item_index) > self.last_col
54
- chunks = self.subject.line_at(index: item_index).chars.each_slice(self.last_col).map(&:join)
55
+ chunks = self.subject.line_at(index: item_index).chars.each_slice(self.last_col - 2).map(&:join)
55
56
  chunks.each do |c|
56
57
  self.window.addstr(c)
57
58
  self.draw_row += 1
@@ -63,7 +64,7 @@ module MarsBase10
63
64
  self.window.addstr("#{self.subject.line_at(index: item_index)}")
64
65
  end
65
66
 
66
- self.window.attroff(Curses::A_REVERSE) if item_index == self.index
67
+ self.window.attroff(Curses::A_REVERSE) if (item_index == self.index) && self.highlight
67
68
  self.window.clrtoeol
68
69
  self.draw_row += 1
69
70
  end
@@ -244,6 +245,16 @@ module MarsBase10
244
245
  end
245
246
  end
246
247
 
248
+ class VariableHeightPane < Pane
249
+ def last_col
250
+ (self.viewport.max_cols * self.width_pct).floor
251
+ end
252
+
253
+ def last_row
254
+ self.viewport.max_rows - self.top_row
255
+ end
256
+ end
257
+
247
258
  class VariableWidthPane < Pane
248
259
  def last_col
249
260
  self.viewport.max_cols - self.left_edge_col
@@ -20,6 +20,44 @@ module MarsBase10
20
20
  Subject.new title: 'Graphs', contents: @ship.graph_names
21
21
  end
22
22
 
23
+ def group_names
24
+ Subject.new title: 'Groups', contents: (@ship.groups.map {|g| g.to_list})
25
+ end
26
+
27
+ def fetch_channel(group_title:, channel_title:)
28
+ if (group = @ship.groups[title: group_title])
29
+ if (channel = group.graphs.select {|c| channel_title == c.title unless c.nil?}.first)
30
+ # What we are calling a channel here is really a graph in the urbit-ruby bridge.
31
+ # This is the equivalent of node.to_pretty_array
32
+ props = {
33
+ title: channel.title,
34
+ description: channel.description,
35
+ creator: channel.creator,
36
+ host_ship: channel.host_ship,
37
+ resource: channel.resource,
38
+ type: channel.type
39
+ }
40
+ return props.each.map {|k, v| "#{k}#{(' ' * [(18 - k.length), 0].max)}#{v}"}
41
+ end
42
+ end
43
+ ["Group not found."]
44
+ end
45
+
46
+ def fetch_group(group_title:)
47
+ if (group = @ship.groups[title: group_title])
48
+ # This is the equivalent of node.to_pretty_array
49
+ return group.to_h.each.map {|k, v| "#{k}#{(' ' * [(18 - k.length), 0].max)}#{v}"}
50
+ end
51
+ ["Group not found."]
52
+ end
53
+
54
+ def fetch_group_channels(group_title:)
55
+ if (group = @ship.groups[title: group_title])
56
+ return group.graphs.map {|g| g.nil? ? "Unnamed" : g.title}
57
+ end
58
+ ["No Channels Available."]
59
+ end
60
+
23
61
  def fetch_node(resource:, index:)
24
62
  @ship.graph(resource: resource).node(index: index)
25
63
  end
@@ -27,6 +27,10 @@ module MarsBase10
27
27
  @contents = a_contents_array
28
28
  end
29
29
 
30
+ def empty?
31
+ self.contents.empty?
32
+ end
33
+
30
34
  def index_width
31
35
  [self.item_count.to_s.length, 2].max
32
36
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module MarsBase10
4
- VERSION = "0.4.0"
4
+ VERSION = "0.5.0"
5
5
  end
@@ -70,15 +70,6 @@ module MarsBase10
70
70
  @active_pane = p
71
71
  end
72
72
 
73
- def add_variable_width_pane(at_row: self.min_row, at_col: self.min_col, height_pct:)
74
- p = VariableWidthPane.new viewport: self,
75
- at_row: at_row,
76
- at_col: at_col,
77
- height_pct: height_pct
78
- @panes << p
79
- p
80
- end
81
-
82
73
  #
83
74
  # Adds a new variable width drawable area (VariableBothPane) to the
84
75
  # right-hand side of the viewport.
@@ -95,6 +86,24 @@ module MarsBase10
95
86
  p
96
87
  end
97
88
 
89
+ def add_variable_height_pane(at_row:, width_pct:)
90
+ p = VariableHeightPane.new viewport: self,
91
+ at_row: at_row,
92
+ at_col: self.min_col,
93
+ width_pct: width_pct
94
+ @panes << p
95
+ p
96
+ end
97
+
98
+ def add_variable_width_pane(at_row: self.min_row, at_col: self.min_col, height_pct:)
99
+ p = VariableWidthPane.new viewport: self,
100
+ at_row: at_row,
101
+ at_col: at_col,
102
+ height_pct: height_pct
103
+ @panes << p
104
+ p
105
+ end
106
+
98
107
  def close
99
108
  Curses.close_screen
100
109
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mars_base_10
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daryl Richter
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-05-10 00:00:00.000000000 Z
11
+ date: 2022-06-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: curses
@@ -152,6 +152,7 @@ files:
152
152
  - lib/mars_base_10/cli.rb
153
153
  - lib/mars_base_10/comm_central.rb
154
154
  - lib/mars_base_10/graph_rover.rb
155
+ - lib/mars_base_10/group_room.rb
155
156
  - lib/mars_base_10/pane.rb
156
157
  - lib/mars_base_10/ship.rb
157
158
  - lib/mars_base_10/stack.rb