Class: Kward::PluginUI
- Inherits:
-
Object
- Object
- Kward::PluginUI
- Defined in:
- lib/kward/plugins/ui.rb
Overview
Frontend-neutral structured UI exposed to trusted plugin handlers.
Frontends provide a small backend that handles blocking requests and non-blocking events. Unsupported requests fail closed: selection, question, and input return nil, while confirmation returns false.
Defined Under Namespace
Classes: Backend
Constant Summary collapse
- FEATURES =
%i[question select confirm input progress notify].freeze
- NOTIFICATION_LEVELS =
%i[info success warning error].freeze
- MAX_TEXT_BYTES =
16_384- MAX_OPTIONS =
100- MAX_ID_BYTES =
128
Instance Method Summary collapse
- #capabilities ⇒ Object
- #confirm(title, message = nil, default: false) ⇒ Object
-
#initialize(backend: nil, say_callback: nil, cancellation: nil) ⇒ PluginUI
constructor
A new instance of PluginUI.
- #input(title, placeholder = nil, default: nil) ⇒ Object
- #notify(message, level = :info, **options) ⇒ Object
- #progress(id = nil, message = nil, percent: nil, done: false, **values) ⇒ Object
- #question(questions) ⇒ Object
- #select(title, options, message: nil) ⇒ Object
- #supported?(feature) ⇒ Boolean
- #with_cancellation(cancellation) ⇒ Object
Constructor Details
#initialize(backend: nil, say_callback: nil, cancellation: nil) ⇒ PluginUI
Returns a new instance of PluginUI.
53 54 55 56 57 |
# File 'lib/kward/plugins/ui.rb', line 53 def initialize(backend: nil, say_callback: nil, cancellation: nil) @backend = backend || Backend.new @say_callback = say_callback @cancellation = cancellation end |
Instance Method Details
#capabilities ⇒ Object
59 60 61 |
# File 'lib/kward/plugins/ui.rb', line 59 def capabilities @backend.capabilities.dup.freeze end |
#confirm(title, message = nil, default: false) ⇒ Object
88 89 90 91 92 93 94 95 96 97 98 99 100 |
# File 'lib/kward/plugins/ui.rb', line 88 def confirm(title, = nil, default: false) if .nil? = title title = "Confirm" end answer = request( :confirm, title: required_text(title, "confirm title"), message: required_text(, "confirm message"), default: default == true ) answer == true end |
#input(title, placeholder = nil, default: nil) ⇒ Object
102 103 104 105 106 107 108 109 110 111 112 113 |
# File 'lib/kward/plugins/ui.rb', line 102 def input(title, placeholder = nil, default: nil) answer = request( :input, title: required_text(title, "input title"), placeholder: optional_text(placeholder), default: optional_text(default) ) return nil if answer.nil? raise ArgumentError, "plugin UI input answer must be a string" unless answer.is_a?(String) bounded_text(answer, "input answer") end |
#notify(message, level = :info, **options) ⇒ Object
115 116 117 118 119 120 121 122 123 |
# File 'lib/kward/plugins/ui.rb', line 115 def notify(, level = :info, **) level = [:level] if .key?(:level) level = level.to_sym raise ArgumentError, "unsupported plugin notification level: #{level}" unless NOTIFICATION_LEVELS.include?(level) payload = { message: required_text(, "notification message"), level: level } @say_callback&.call(payload[:message]) unless @backend.emit(:notify, immutable(payload)) nil end |
#progress(id = nil, message = nil, percent: nil, done: false, **values) ⇒ Object
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
# File 'lib/kward/plugins/ui.rb', line 125 def progress(id = nil, = nil, percent: nil, done: false, **values) id ||= values[:id] ||= values[:message] payload = { id: required_text(id, "progress id", max_bytes: MAX_ID_BYTES), message: required_text(, "progress message"), percent: normalize_percent(percent), done: done == true }.compact unless @backend.emit(:progress, immutable(payload)) fallback = payload[:percent] ? "#{payload[:message]} (#{payload[:percent]}%)" : payload[:message] @say_callback&.call(fallback) end nil end |
#question(questions) ⇒ Object
67 68 69 70 |
# File 'lib/kward/plugins/ui.rb', line 67 def question(questions) normalized = QuestionContract.normalize_questions(questions) request(:question, questions: normalized) end |
#select(title, options, message: nil) ⇒ Object
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/kward/plugins/ui.rb', line 72 def select(title, , message: nil) normalized = () answer = request( :select, title: required_text(title, "select title"), message: optional_text(), options: normalized ) return nil if answer.nil? selected = normalized.find { |option| option[:value] == answer.to_s || option[:label] == answer.to_s } raise ArgumentError, "plugin UI returned an unknown selection" unless selected selected[:value] end |
#supported?(feature) ⇒ Boolean
63 64 65 |
# File 'lib/kward/plugins/ui.rb', line 63 def supported?(feature) @backend.supported?(feature) end |
#with_cancellation(cancellation) ⇒ Object
141 142 143 |
# File 'lib/kward/plugins/ui.rb', line 141 def with_cancellation(cancellation) self.class.new(backend: @backend, say_callback: @say_callback, cancellation: cancellation) end |