class BBS::Windows::Stream
A live stream window: scrollable history + single-line input + poll.
BBS::Windows::Stream.open(app, title: ' Live Chat ', initial_lines: services[:chat].history.map { |l| fmt(l) }, placeholder: 'Type a message and press Enter…', on_submit: ->(text, app) { services[:chat].broadcast(username, text.strip) }, on_poll: ->(app) { services[:chat].drain(app.session_id).map { |l| fmt(l) } } )
on_submit(text, app) is called when the user presses Enter on a non-empty input. The input is cleared automatically afterwards unless the handler returns :keep.
on_poll(app) is invoked from the application’s idle tick (~1s). It should return an Array of new lines to append (or nil/[]).
Constants
- OPTIONS
-
The options of
::newand their defaults.
Attributes
The BBS::Widgets::ScrollView of past lines and the BBS::Widgets::TextInput under it.
The BBS::Widgets::ScrollView of past lines and the BBS::Widgets::TextInput under it.
Public Class Methods
# File lib/bbs/windows/stream.rb, line 66 def initialize(app:, title:, **options) unknown = options.keys - OPTIONS.keys raise ArgumentError, "unknown stream options: #{unknown.inspect}" unless unknown.empty? @options = OPTIONS.merge(options) super(title: title, modal: false, maximizable: @options[:maximizable]) self.theme = app.theme @app = app build end
Creates the window and its widgets, centred on app‘s screen. It is not opened; see attach.
- app
-
the
BBS::Application - title
-
the window title
The options (OPTIONS):
- initial_lines
-
the lines the history starts with
- placeholder
-
the text the empty input shows
- on_submit
-
called with
(text, app)on Enter - on_poll
-
called with
appon each tick; returns new lines - buffer_size
-
the most lines the history keeps (default 500)
- width
-
the window width; by default the screen less 8
- height
-
the window height; by default the screen less 6
- close_button
-
adds a Close button (default true)
- close_label
-
the Close button’s label
- maximizable
-
gives the window the zoom gadget
Raises ArgumentError for an unknown option.
BBS::Window::new
Source
# File lib/bbs/windows/stream.rb, line 34 def self.open(app, **kw) new(app: app, **kw).tap(&:attach) end
Creates a stream window with the keywords of Stream.new and opens it on app.
Returns the Stream window.
Public Instance Methods
Source
# File lib/bbs/windows/stream.rb, line 80 def attach @app.open_window(self) reset_focus focus_manager.focus(@input) self end
Opens the window on the application and focuses the input.
Returns self.
Source
# File lib/bbs/windows/stream.rb, line 104 def normal_rect w = @options[:width] || (@app.cols - 8) h = @options[:height] || (@app.rows - 6) [((@app.cols - w) / 2) + 1, ((@app.rows - h) / 2) + 1, w, h] end
Returns the un-maximized bounds as [x, y, width, height]: the requested size, or the screen less 8 columns and 6 rows, centred.
Source
# File lib/bbs/windows/stream.rb, line 112 def place(x, y, width, height) layout(x, y, width, height) @history.layout(x + 2, y + 1, width - 4, [height - 4, 1].max) scroll_to_end @input.layout(x + 2, y + height - 3, width - 4, 1) @input.send(:adjust_scroll) ButtonBar.place(self, @bar[:widgets], @bar_descriptors) if @bar end
History on top, the input line under it, the button row at the bottom; the history stays scrolled to its end.
Source
# File lib/bbs/windows/stream.rb, line 99 def resizable? = true
A stream window can be resized; place lays it out again.
Source
# File lib/bbs/windows/stream.rb, line 90 def tick(_app) new_lines = @options[:on_poll]&.call(@app) return if new_lines.nil? || new_lines.empty? @history.lines = (@history.lines + Array(new_lines)).last(@options[:buffer_size]) scroll_to_end end
Called on the application’s idle tick: appends the lines on_poll returns to the history, drops the oldest beyond buffer_size, and scrolls to the end. Does nothing without on_poll or new lines.