Class: Ruflet::Page

Inherits:
Object
  • Object
show all
Defined in:
lib/ruflet_ui/ruflet/page.rb

Defined Under Namespace

Classes: FlashlightService, ScreenBrightnessService, SharedPreferencesService, WakelockService

Constant Summary collapse

PAGE_PROP_KEYS =
%w[dark_theme fonts route rtl show_semantics_debugger theme theme_mode title vertical_alignment horizontal_alignment scroll].freeze
DIALOG_PROP_KEYS =
%w[dialog snack_bar bottom_sheet].freeze
WIDGET_HELPER_METHODS =
(
  Ruflet::UI::MaterialControlMethods.instance_methods(false) +
  Ruflet::UI::CupertinoControlMethods.instance_methods(false) +
  %i[control widget]
).map(&:to_s).to_set.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(session_id:, client_details:, sender:) ⇒ Page

Returns a new instance of Page.



152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
# File 'lib/ruflet_ui/ruflet/page.rb', line 152

def initialize(session_id:, client_details:, sender:)
  @session_id = session_id
  @client_details = client_details
  @sender = sender
  @control_index = {}
  @wire_index = {}
  @next_wire_id = 100
  @view_id = 20
  @root_controls = []
  @views = []
  @dialogs = []
  @services_container_mounted = false
  @visual_service_controls = {}
  @page_event_handlers = {}
  @view_props = {}
  @page_props = { "route" => (client_details["route"] || "/") }
  @overlay_container = Ruflet::Control.new(
    type: "overlay",
    id: "_overlay",
    controls: []
  )
  @services_container = Ruflet::Control.new(
    type: "service_registry",
    id: "_services",
    "_services": [],
    "_internals": { "uid" => Ruflet::Control.generate_id }
  )
  @dialogs_container = Ruflet::Control.new(
    type: "dialogs",
    id: "_dialogs",
    controls: []
  )
  @invoke_waiters = {}
  @invoke_callbacks = {}
  @invoke_waiters_mutex = Mutex.new
  @shared_preferences_proxy = SharedPreferencesService.new(self)
  @wakelock_proxy = WakelockService.new(self)
  @flashlight_proxy = FlashlightService.new(self)
  @screen_brightness_proxy = ScreenBrightnessService.new(self)
  refresh_overlay_container!
  refresh_services_container!
  refresh_dialogs_container!
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name, *args, &block) ⇒ Object



1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
# File 'lib/ruflet_ui/ruflet/page.rb', line 1237

def method_missing(name, *args, &block)
  method_name = name.to_s
  prop_name = method_name.delete_suffix("=")

  if method_name.end_with?("=")
    if widget_helper_method?(prop_name)
      raise NoMethodError, "Use `#{prop_name}(...)` as a free widget helper, then attach with `page.add(...)`."
    end
    assign_split_prop(prop_name, normalize_value(prop_name, args.first))
    return args.first
  end

  if args.empty? && !block
    return @page_props[method_name] if @page_props.key?(method_name)
    return @view_props[method_name] if @view_props.key?(method_name)
    return instance_variable_get("@#{method_name}") if DIALOG_PROP_KEYS.include?(method_name)
  end

  if widget_helper_method?(name)
    raise NoMethodError, "Use `#{name}(...)` as a free widget helper, then attach with `page.add(...)`."
  end

  super
end

Instance Attribute Details

#client_detailsObject (readonly)

Returns the value of attribute client_details.



150
151
152
# File 'lib/ruflet_ui/ruflet/page.rb', line 150

def client_details
  @client_details
end

#session_idObject (readonly)

Returns the value of attribute session_id.



150
151
152
# File 'lib/ruflet_ui/ruflet/page.rb', line 150

def session_id
  @session_id
end

#viewsObject

Returns the value of attribute views.



150
151
152
# File 'lib/ruflet_ui/ruflet/page.rb', line 150

def views
  @views
end

Instance Method Details

#accelerometer(**props) ⇒ Object



920
921
922
# File 'lib/ruflet_ui/ruflet/page.rb', line 920

def accelerometer(**props)
  service(:accelerometer, **props)
end

#add(*controls, appbar: nil, bottom_appbar: nil, floating_action_button: nil, navigation_bar: nil, dialog: nil, snack_bar: nil, bottom_sheet: nil) ⇒ Object



245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
# File 'lib/ruflet_ui/ruflet/page.rb', line 245

def add(*controls, appbar: nil, bottom_appbar: nil, floating_action_button: nil, navigation_bar: nil, dialog: nil, snack_bar: nil, bottom_sheet: nil)
  controls = controls.flatten
  visited = Set.new
  controls.each { |c| register_control_tree(c, visited) }
  @root_controls = controls

  @view_props["appbar"] = appbar if appbar
  @view_props["bottom_appbar"] = bottom_appbar if bottom_appbar
  @view_props["floating_action_button"] = floating_action_button if floating_action_button
  @view_props["navigation_bar"] = navigation_bar if navigation_bar
  @dialog = dialog if dialog
  @snack_bar = snack_bar if snack_bar
  @bottom_sheet = bottom_sheet if bottom_sheet

  refresh_dialogs_container!
  @view_props.each_value { |value| register_embedded_value(value, visited) }

  send_view_patch

  self
end

#add_service(*value) ⇒ Object



327
328
329
330
331
332
# File 'lib/ruflet_ui/ruflet/page.rb', line 327

def add_service(*value)
  @services_container.props["_services"] = services + value.flatten.compact
  refresh_services_container!
  push_services_update!
  self
end

#appbar=(value) ⇒ Object



424
425
426
# File 'lib/ruflet_ui/ruflet/page.rb', line 424

def appbar=(value)
  @view_props["appbar"] = value
end

#apply_client_update(control_or_id, props) ⇒ Object



1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
# File 'lib/ruflet_ui/ruflet/page.rb', line 1203

def apply_client_update(control_or_id, props)
  control = resolve_control(control_or_id)
  return self unless control

  patch = normalize_props(props || {})
  patch.each { |k, v| control.props[k] = v }

  remove_dialog_tracking(control) if patch.key?("open") && patch["open"] == false

  self
end

#audio(**props) ⇒ Object



307
308
309
# File 'lib/ruflet_ui/ruflet/page.rb', line 307

def audio(**props)
  service(:audio, **props)
end

#audio_recorder(**props) ⇒ Object



311
312
313
# File 'lib/ruflet_ui/ruflet/page.rb', line 311

def audio_recorder(**props)
  service(:audio_recorder, **props)
end

#barometer(**props) ⇒ Object



936
937
938
# File 'lib/ruflet_ui/ruflet/page.rb', line 936

def barometer(**props)
  service(:barometer, **props)
end

#battery(**props) ⇒ Object



952
953
954
# File 'lib/ruflet_ui/ruflet/page.rb', line 952

def battery(**props)
  service(:battery, **props)
end

#battery_save_mode?(timeout: nil, on_result: nil) ⇒ Boolean

Returns:

  • (Boolean)


916
917
918
# File 'lib/ruflet_ui/ruflet/page.rb', line 916

def battery_save_mode?(timeout: nil, on_result: nil)
  is_in_battery_save_mode(timeout: timeout, on_result: on_result)
end

#bgcolorObject



237
238
239
# File 'lib/ruflet_ui/ruflet/page.rb', line 237

def bgcolor
  @view_props["bgcolor"]
end

#bgcolor=(value) ⇒ Object



241
242
243
# File 'lib/ruflet_ui/ruflet/page.rb', line 241

def bgcolor=(value)
  @view_props["bgcolor"] = normalize_value("bgcolor", value)
end

#bottom_appbar=(value) ⇒ Object



428
429
430
# File 'lib/ruflet_ui/ruflet/page.rb', line 428

def bottom_appbar=(value)
  @view_props["bottom_appbar"] = value
end

#bottom_sheet=(value) ⇒ Object



496
497
498
499
# File 'lib/ruflet_ui/ruflet/page.rb', line 496

def bottom_sheet=(value)
  @bottom_sheet = value
  refresh_dialogs_container!
end

#bottomappbar=(value) ⇒ Object



432
433
434
# File 'lib/ruflet_ui/ruflet/page.rb', line 432

def bottomappbar=(value)
  self.bottom_appbar = value
end

#bottomsheet=(value) ⇒ Object



501
502
503
# File 'lib/ruflet_ui/ruflet/page.rb', line 501

def bottomsheet=(value)
  self.bottom_sheet = value
end

#browser_context_menu(**props) ⇒ Object



315
316
317
# File 'lib/ruflet_ui/ruflet/page.rb', line 315

def browser_context_menu(**props)
  service(:browser_context_menu, **props)
end

#camera(**props) ⇒ Object



980
981
982
# File 'lib/ruflet_ui/ruflet/page.rb', line 980

def camera(**props)
  service(:camera, **props)
end

#can_launch_url(url, timeout: 10) ⇒ Object



575
576
577
578
# File 'lib/ruflet_ui/ruflet/page.rb', line 575

def can_launch_url(url, timeout: 10)
  url_launcher = ensure_url_launcher_service
  invoke(url_launcher, "can_launch_url", args: { "url" => url }, timeout: timeout)
end

#center_window(timeout: 10, on_result: nil) ⇒ Object



696
697
698
# File 'lib/ruflet_ui/ruflet/page.rb', line 696

def center_window(timeout: 10, on_result: nil)
  invoke_window("center", timeout: timeout, on_result: on_result)
end

#clipboard(**props) ⇒ Object



960
961
962
# File 'lib/ruflet_ui/ruflet/page.rb', line 960

def clipboard(**props)
  service(:clipboard, **props)
end

#close_drawer(timeout: 10, on_result: nil) ⇒ Object



463
464
465
466
# File 'lib/ruflet_ui/ruflet/page.rb', line 463

def close_drawer(timeout: 10, on_result: nil)
  invoke_current_view("close_drawer", timeout: timeout, on_result: on_result)
  self
end

#close_end_drawer(timeout: 10, on_result: nil) ⇒ Object



475
476
477
478
# File 'lib/ruflet_ui/ruflet/page.rb', line 475

def close_end_drawer(timeout: 10, on_result: nil)
  invoke_current_view("close_end_drawer", timeout: timeout, on_result: on_result)
  self
end

#close_in_app_web_view(timeout: 10, on_result: nil) ⇒ Object



580
581
582
583
# File 'lib/ruflet_ui/ruflet/page.rb', line 580

def close_in_app_web_view(timeout: 10, on_result: nil)
  url_launcher = ensure_url_launcher_service
  invoke(url_launcher, "close_in_app_web_view", timeout: timeout, on_result: on_result)
end

#close_window(timeout: 10, on_result: nil) ⇒ Object



700
701
702
# File 'lib/ruflet_ui/ruflet/page.rb', line 700

def close_window(timeout: 10, on_result: nil)
  invoke_window("close", timeout: timeout, on_result: on_result)
end

#connectivity(**props) ⇒ Object



956
957
958
# File 'lib/ruflet_ui/ruflet/page.rb', line 956

def connectivity(**props)
  service(:connectivity, **props)
end

#destroy_window(timeout: 10, on_result: nil) ⇒ Object



704
705
706
# File 'lib/ruflet_ui/ruflet/page.rb', line 704

def destroy_window(timeout: 10, on_result: nil)
  invoke_window("destroy", timeout: timeout, on_result: on_result)
end

#dialogObject



480
# File 'lib/ruflet_ui/ruflet/page.rb', line 480

def dialog = @dialog

#dialog=(value) ⇒ Object



482
483
484
485
# File 'lib/ruflet_ui/ruflet/page.rb', line 482

def dialog=(value)
  @dialog = value
  refresh_dialogs_container!
end

#disable_browser_context_menu(timeout: 10, on_result: nil) ⇒ Object



680
681
682
# File 'lib/ruflet_ui/ruflet/page.rb', line 680

def disable_browser_context_menu(timeout: 10, on_result: nil)
  invoke_browser_context_menu("disable_menu", timeout: timeout, on_result: on_result)
end

#dispatch_event(target:, name:, data:) ⇒ Object



1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
# File 'lib/ruflet_ui/ruflet/page.rb', line 1215

def dispatch_event(target:, name:, data:)
  if page_control_target?(target)
    if name.to_s == "route_change"
      route_from_event = extract_route(data)
      @page_props["route"] = route_from_event if route_from_event
    end
    dispatch_page_event(name: name, data: data)
    return
  end

  control = @wire_index[target.to_i] || @control_index[target.to_s]
  return unless control

  event = Event.new(name: name, target: target, raw_data: data, page: self, control: control)
  apply_event_value_to_control(control, event) if %w[change select select_change].include?(name.to_s)
  control.emit(name, event)

  if name.to_s == "dismiss" && remove_dialog_tracking(control)
    push_dialogs_update!
  end
end

#drag(finder_id, offset, finder_index: nil, timeout: 10, on_result: nil) ⇒ Object



791
792
793
794
795
796
797
798
799
800
801
802
# File 'lib/ruflet_ui/ruflet/page.rb', line 791

def drag(finder_id, offset, finder_index: nil, timeout: 10, on_result: nil)
  invoke_tester(
    "drag",
    args: compact_service_args(
      "finder_id" => finder_id,
      "finder_index" => finder_index,
      "offset" => offset
    ),
    timeout: timeout,
    on_result: on_result
  )
end

#drag_from(start, offset, timeout: 10, on_result: nil) ⇒ Object



804
805
806
807
808
809
810
811
# File 'lib/ruflet_ui/ruflet/page.rb', line 804

def drag_from(start, offset, timeout: 10, on_result: nil)
  invoke_tester(
    "drag_from",
    args: compact_service_args("start" => start, "offset" => offset),
    timeout: timeout,
    on_result: on_result
  )
end

#drawerObject



440
441
442
# File 'lib/ruflet_ui/ruflet/page.rb', line 440

def drawer
  @view_props["drawer"]
end

#drawer=(value) ⇒ Object



444
445
446
# File 'lib/ruflet_ui/ruflet/page.rb', line 444

def drawer=(value)
  @view_props["drawer"] = value
end

#enable_browser_context_menu(timeout: 10, on_result: nil) ⇒ Object



684
685
686
# File 'lib/ruflet_ui/ruflet/page.rb', line 684

def enable_browser_context_menu(timeout: 10, on_result: nil)
  invoke_browser_context_menu("enable_menu", timeout: timeout, on_result: on_result)
end

#end_drawerObject



448
449
450
# File 'lib/ruflet_ui/ruflet/page.rb', line 448

def end_drawer
  @view_props["end_drawer"]
end

#end_drawer=(value) ⇒ Object



452
453
454
# File 'lib/ruflet_ui/ruflet/page.rb', line 452

def end_drawer=(value)
  @view_props["end_drawer"] = value
end

#enter_text(finder_id, text, options = nil, finder_index: nil, timeout: 10, on_result: nil) ⇒ Object



818
819
820
821
822
823
824
825
826
827
828
829
830
# File 'lib/ruflet_ui/ruflet/page.rb', line 818

def enter_text(finder_id, text, options = nil, finder_index: nil, timeout: 10, on_result: nil)
  finder_index = options[:finder_index] || options["finder_index"] if options.is_a?(Hash) && finder_index.nil?
  invoke_tester(
    "enter_text",
    args: compact_service_args(
      "finder_id" => finder_id,
      "finder_index" => finder_index,
      "text" => text
    ),
    timeout: timeout,
    on_result: on_result
  )
end

#file_picker(**props) ⇒ Object



964
965
966
# File 'lib/ruflet_ui/ruflet/page.rb', line 964

def file_picker(**props)
  service(:file_picker, **props)
end

#find_by_icon(icon, timeout: 10, on_result: nil) ⇒ Object



747
748
749
# File 'lib/ruflet_ui/ruflet/page.rb', line 747

def find_by_icon(icon, timeout: 10, on_result: nil)
  invoke_tester("find_by_icon", args: { "icon" => normalize_service_value(icon) }, timeout: timeout, on_result: on_result)
end

#find_by_key(key, timeout: 10, on_result: nil) ⇒ Object



739
740
741
# File 'lib/ruflet_ui/ruflet/page.rb', line 739

def find_by_key(key, timeout: 10, on_result: nil)
  invoke_tester("find_by_key", args: { "key" => key }, timeout: timeout, on_result: on_result)
end

#find_by_text(text, timeout: 10, on_result: nil) ⇒ Object



731
732
733
# File 'lib/ruflet_ui/ruflet/page.rb', line 731

def find_by_text(text, timeout: 10, on_result: nil)
  invoke_tester("find_by_text", args: { "text" => text }, timeout: timeout, on_result: on_result)
end

#find_by_text_containing(pattern, timeout: 10, on_result: nil) ⇒ Object



735
736
737
# File 'lib/ruflet_ui/ruflet/page.rb', line 735

def find_by_text_containing(pattern, timeout: 10, on_result: nil)
  invoke_tester("find_by_text_containing", args: { "pattern" => pattern }, timeout: timeout, on_result: on_result)
end

#find_by_tooltip(value, timeout: 10, on_result: nil) ⇒ Object



743
744
745
# File 'lib/ruflet_ui/ruflet/page.rb', line 743

def find_by_tooltip(value, timeout: 10, on_result: nil)
  invoke_tester("find_by_tooltip", args: { "value" => value }, timeout: timeout, on_result: on_result)
end

#flashlight(**props) ⇒ Object



295
296
297
298
299
# File 'lib/ruflet_ui/ruflet/page.rb', line 295

def flashlight(**props)
  return service(:flashlight, **props) unless props.empty?

  @flashlight_proxy
end

#floating_action_button=(value) ⇒ Object



436
437
438
# File 'lib/ruflet_ui/ruflet/page.rb', line 436

def floating_action_button=(value)
  @view_props["floating_action_button"] = value
end

#geolocator(**props) ⇒ Object



988
989
990
# File 'lib/ruflet_ui/ruflet/page.rb', line 988

def geolocator(**props)
  service(:geolocator, **props)
end

#get_application_cache_directory(timeout: nil, on_result: nil) ⇒ Object



1000
1001
1002
# File 'lib/ruflet_ui/ruflet/page.rb', line 1000

def get_application_cache_directory(timeout: nil, on_result: nil)
  invoke_storage_paths("get_application_cache_directory", timeout: timeout, on_result: on_result)
end

#get_application_documents_directory(timeout: nil, on_result: nil) ⇒ Object



1004
1005
1006
# File 'lib/ruflet_ui/ruflet/page.rb', line 1004

def get_application_documents_directory(timeout: nil, on_result: nil)
  invoke_storage_paths("get_application_documents_directory", timeout: timeout, on_result: on_result)
end

#get_application_support_directory(timeout: nil, on_result: nil) ⇒ Object



1008
1009
1010
# File 'lib/ruflet_ui/ruflet/page.rb', line 1008

def get_application_support_directory(timeout: nil, on_result: nil)
  invoke_storage_paths("get_application_support_directory", timeout: timeout, on_result: on_result)
end

#get_battery_level(timeout: nil, on_result: nil) ⇒ Object



904
905
906
# File 'lib/ruflet_ui/ruflet/page.rb', line 904

def get_battery_level(timeout: nil, on_result: nil)
  invoke_battery_method("get_battery_level", timeout: timeout, on_result: on_result)
end

#get_battery_state(timeout: nil, on_result: nil) ⇒ Object



908
909
910
# File 'lib/ruflet_ui/ruflet/page.rb', line 908

def get_battery_state(timeout: nil, on_result: nil)
  invoke_battery_method("get_battery_state", timeout: timeout, on_result: on_result)
end

#get_clipboard(timeout: nil, on_result: nil) ⇒ Object



870
871
872
# File 'lib/ruflet_ui/ruflet/page.rb', line 870

def get_clipboard(timeout: nil, on_result: nil)
  invoke_clipboard_method("get", timeout: timeout, on_result: on_result)
end

#get_clipboard_files(timeout: nil, on_result: nil) ⇒ Object



883
884
885
# File 'lib/ruflet_ui/ruflet/page.rb', line 883

def get_clipboard_files(timeout: nil, on_result: nil)
  invoke_clipboard_method("get_files", timeout: timeout, on_result: on_result)
end

#get_clipboard_image(timeout: nil, on_result: nil) ⇒ Object



896
897
898
# File 'lib/ruflet_ui/ruflet/page.rb', line 896

def get_clipboard_image(timeout: nil, on_result: nil)
  invoke_clipboard_method("get_image", timeout: timeout, on_result: on_result)
end

#get_connectivity(timeout: nil, on_result: nil) ⇒ Object



900
901
902
# File 'lib/ruflet_ui/ruflet/page.rb', line 900

def get_connectivity(timeout: nil, on_result: nil)
  invoke_connectivity_method("get_connectivity", timeout: timeout, on_result: on_result)
end

#get_console_log_filename(timeout: nil, on_result: nil) ⇒ Object



1036
1037
1038
# File 'lib/ruflet_ui/ruflet/page.rb', line 1036

def get_console_log_filename(timeout: nil, on_result: nil)
  invoke_storage_paths("get_console_log_filename", timeout: timeout, on_result: on_result)
end

#get_directory_path(dialog_title: nil, initial_directory: nil, timeout: nil, on_result: nil) ⇒ Object



655
656
657
658
659
660
661
662
663
664
665
# File 'lib/ruflet_ui/ruflet/page.rb', line 655

def get_directory_path(dialog_title: nil, initial_directory: nil, timeout: nil, on_result: nil)
  invoke_file_picker(
    "get_directory_path",
    compact_service_args(
      "dialog_title" => dialog_title,
      "initial_directory" => initial_directory
    ),
    timeout: timeout,
    on_result: on_result
  )
end

#get_downloads_directory(timeout: nil, on_result: nil) ⇒ Object



1012
1013
1014
# File 'lib/ruflet_ui/ruflet/page.rb', line 1012

def get_downloads_directory(timeout: nil, on_result: nil)
  invoke_storage_paths("get_downloads_directory", timeout: timeout, on_result: on_result)
end

#get_external_cache_directories(timeout: nil, on_result: nil) ⇒ Object



1016
1017
1018
# File 'lib/ruflet_ui/ruflet/page.rb', line 1016

def get_external_cache_directories(timeout: nil, on_result: nil)
  invoke_storage_paths("get_external_cache_directories", timeout: timeout, on_result: on_result)
end

#get_external_storage_directories(timeout: nil, on_result: nil) ⇒ Object



1020
1021
1022
# File 'lib/ruflet_ui/ruflet/page.rb', line 1020

def get_external_storage_directories(timeout: nil, on_result: nil)
  invoke_storage_paths("get_external_storage_directories", timeout: timeout, on_result: on_result)
end

#get_external_storage_directory(timeout: nil, on_result: nil) ⇒ Object



1028
1029
1030
# File 'lib/ruflet_ui/ruflet/page.rb', line 1028

def get_external_storage_directory(timeout: nil, on_result: nil)
  invoke_storage_paths("get_external_storage_directory", timeout: timeout, on_result: on_result)
end

#get_library_directory(timeout: nil, on_result: nil) ⇒ Object



1024
1025
1026
# File 'lib/ruflet_ui/ruflet/page.rb', line 1024

def get_library_directory(timeout: nil, on_result: nil)
  invoke_storage_paths("get_library_directory", timeout: timeout, on_result: on_result)
end

#get_temporary_directory(timeout: nil, on_result: nil) ⇒ Object



1032
1033
1034
# File 'lib/ruflet_ui/ruflet/page.rb', line 1032

def get_temporary_directory(timeout: nil, on_result: nil)
  invoke_storage_paths("get_temporary_directory", timeout: timeout, on_result: on_result)
end

#go(route, **query_params) ⇒ Object



386
387
388
389
390
391
# File 'lib/ruflet_ui/ruflet/page.rb', line 386

def go(route, **query_params)
  @page_props["route"] = build_route(route, query_params)
  dispatch_page_event(name: "route_change", data: @page_props["route"])
  send_view_patch
  self
end

#gyroscope(**props) ⇒ Object



924
925
926
# File 'lib/ruflet_ui/ruflet/page.rb', line 924

def gyroscope(**props)
  service(:gyroscope, **props)
end

#handle_invoke_method_result(payload) ⇒ Object



1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
# File 'lib/ruflet_ui/ruflet/page.rb', line 1125

def handle_invoke_method_result(payload)
  call_id = payload["call_id"].to_s
  waiter = @invoke_waiters_mutex.synchronize { @invoke_waiters[call_id] }
  if waiter
    waiter << payload
    return true
  end

  callback = @invoke_waiters_mutex.synchronize { @invoke_callbacks.delete(call_id) }
  return false unless callback

  callback.call(payload["result"], payload["error"])
  true
rescue StandardError => e
  Kernel.warn("invoke callback error: #{e.class}: #{e.message}")
  false
end

#haptic_feedback(**props) ⇒ Object



984
985
986
# File 'lib/ruflet_ui/ruflet/page.rb', line 984

def haptic_feedback(**props)
  service(:haptic_feedback, **props)
end

#heavy_impact(timeout: 10, on_result: nil) ⇒ Object



841
842
843
# File 'lib/ruflet_ui/ruflet/page.rb', line 841

def heavy_impact(timeout: 10, on_result: nil)
  invoke_haptic_feedback("heavy_impact", timeout: timeout, on_result: on_result)
end

#horizontal_alignmentObject



227
228
229
# File 'lib/ruflet_ui/ruflet/page.rb', line 227

def horizontal_alignment
  @page_props["horizontal_alignment"] || @view_props["horizontal_alignment"]
end

#horizontal_alignment=(value) ⇒ Object



231
232
233
234
235
# File 'lib/ruflet_ui/ruflet/page.rb', line 231

def horizontal_alignment=(value)
  v = normalize_value("horizontal_alignment", value)
  @page_props["horizontal_alignment"] = v
  @view_props["horizontal_alignment"] = v
end

#invoke(control_or_id, method_name, args: nil, timeout: 10, on_result: nil) ⇒ Object



518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
# File 'lib/ruflet_ui/ruflet/page.rb', line 518

def invoke(control_or_id, method_name, args: nil, timeout: 10, on_result: nil)
  control_id =
    if page_control_target?(control_or_id)
      1
    else
      control = resolve_control(control_or_id)
      return nil unless control
      control.wire_id
    end

  call_id = "call_#{Ruflet::Control.generate_id}"
  if on_result.respond_to?(:call)
    @invoke_waiters_mutex.synchronize { @invoke_callbacks[call_id] = on_result }
    unless timeout.nil?
      Thread.new(call_id, timeout.to_f) do |pending_call_id, invoke_timeout|
        sleep([invoke_timeout, 0.0].max + 0.1)
        callback = @invoke_waiters_mutex.synchronize { @invoke_callbacks.delete(pending_call_id) }
        callback&.call(nil, "execution expired")
      rescue StandardError => e
        Kernel.warn("invoke timeout callback error: #{e.class}: #{e.message}")
      end
    end
  end
  payload = {
    "control_id" => control_id,
    "call_id" => call_id,
    "name" => method_name.to_s,
    "args" => args
  }
  payload["timeout"] = timeout unless timeout.nil?
  send_message(Protocol::ACTIONS[:invoke_control_method], payload)

  call_id
end

#invoke_sync(control_or_id, method_name, args: nil, timeout: 10) ⇒ Object

Synchronous invoke for controls/services that must return a value before continuing (e.g. picker selection, camera discovery/init).



555
556
557
# File 'lib/ruflet_ui/ruflet/page.rb', line 555

def invoke_sync(control_or_id, method_name, args: nil, timeout: 10)
  invoke_and_wait(control_or_id, method_name, args: args, timeout: timeout)
end

#is_in_battery_save_mode(timeout: nil, on_result: nil) ⇒ Object



912
913
914
# File 'lib/ruflet_ui/ruflet/page.rb', line 912

def is_in_battery_save_mode(timeout: nil, on_result: nil)
  invoke_battery_method("is_in_battery_save_mode", timeout: timeout, on_result: on_result)
end

#launch_url(url, mode: nil, web_view_configuration: nil, browser_configuration: nil, web_only_window_name: nil, timeout: 10, on_result: nil) ⇒ Object



559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
# File 'lib/ruflet_ui/ruflet/page.rb', line 559

def launch_url(url, mode: nil, web_view_configuration: nil, browser_configuration: nil, web_only_window_name: nil, timeout: 10, on_result: nil)
  url_launcher = ensure_url_launcher_service
  args = { "url" => url }
  args["mode"] = mode unless mode.nil?
  args["web_view_configuration"] = web_view_configuration unless web_view_configuration.nil?
  args["browser_configuration"] = browser_configuration unless browser_configuration.nil?
  args["web_only_window_name"] = web_only_window_name unless web_only_window_name.nil?
  invoke(
    url_launcher,
    "launch_url",
    args: args,
    timeout: timeout,
    on_result: on_result
  )
end

#light_impact(timeout: 10, on_result: nil) ⇒ Object



849
850
851
# File 'lib/ruflet_ui/ruflet/page.rb', line 849

def light_impact(timeout: 10, on_result: nil)
  invoke_haptic_feedback("light_impact", timeout: timeout, on_result: on_result)
end

#long_press(finder_id = nil, options = nil, finder_index: nil, timeout: 10, on_result: nil) ⇒ Object



813
814
815
816
# File 'lib/ruflet_ui/ruflet/page.rb', line 813

def long_press(finder_id = nil, options = nil, finder_index: nil, timeout: 10, on_result: nil)
  finder_index = options[:finder_index] || options["finder_index"] if options.is_a?(Hash) && finder_index.nil?
  invoke_tester_finder("long_press", finder_id, finder_index: finder_index, timeout: timeout, on_result: on_result)
end

#magnetometer(**props) ⇒ Object



932
933
934
# File 'lib/ruflet_ui/ruflet/page.rb', line 932

def magnetometer(**props)
  service(:magnetometer, **props)
end

#medium_impact(timeout: 10, on_result: nil) ⇒ Object



845
846
847
# File 'lib/ruflet_ui/ruflet/page.rb', line 845

def medium_impact(timeout: 10, on_result: nil)
  invoke_haptic_feedback("medium_impact", timeout: timeout, on_result: on_result)
end

#mount(&block) ⇒ Object



418
419
420
421
422
# File 'lib/ruflet_ui/ruflet/page.rb', line 418

def mount(&block)
  builder = WidgetBuilder.new
  builder.instance_eval(&block)
  add(*builder.children)
end

#mouse_click(finder_id = nil, options = nil, finder_index: nil, timeout: 10, on_result: nil) ⇒ Object



760
761
762
763
# File 'lib/ruflet_ui/ruflet/page.rb', line 760

def mouse_click(finder_id = nil, options = nil, finder_index: nil, timeout: 10, on_result: nil)
  finder_index = options[:finder_index] || options["finder_index"] if options.is_a?(Hash) && finder_index.nil?
  invoke_tester_finder("mouse_click", finder_id, finder_index: finder_index, timeout: timeout, on_result: on_result)
end

#mouse_click_at(offset = nil, timeout: 10, on_result: nil) ⇒ Object



779
780
781
# File 'lib/ruflet_ui/ruflet/page.rb', line 779

def mouse_click_at(offset = nil, timeout: 10, on_result: nil)
  invoke_tester_at("mouse_click_at", offset, timeout: timeout, on_result: on_result)
end

#mouse_double_click(finder_id = nil, options = nil, finder_index: nil, timeout: 10, on_result: nil) ⇒ Object



765
766
767
768
# File 'lib/ruflet_ui/ruflet/page.rb', line 765

def mouse_double_click(finder_id = nil, options = nil, finder_index: nil, timeout: 10, on_result: nil)
  finder_index = options[:finder_index] || options["finder_index"] if options.is_a?(Hash) && finder_index.nil?
  invoke_tester_finder("mouse_double_click", finder_id, finder_index: finder_index, timeout: timeout, on_result: on_result)
end

#mouse_double_click_at(offset = nil, timeout: 10, on_result: nil) ⇒ Object



783
784
785
# File 'lib/ruflet_ui/ruflet/page.rb', line 783

def mouse_double_click_at(offset = nil, timeout: 10, on_result: nil)
  invoke_tester_at("mouse_double_click_at", offset, timeout: timeout, on_result: on_result)
end

#mouse_hover(finder_id = nil, options = nil, finder_index: nil, timeout: 10, on_result: nil) ⇒ Object



832
833
834
835
# File 'lib/ruflet_ui/ruflet/page.rb', line 832

def mouse_hover(finder_id = nil, options = nil, finder_index: nil, timeout: 10, on_result: nil)
  finder_index = options[:finder_index] || options["finder_index"] if options.is_a?(Hash) && finder_index.nil?
  invoke_tester_finder("mouse_hover", finder_id, finder_index: finder_index, timeout: timeout, on_result: on_result)
end


393
394
395
# File 'lib/ruflet_ui/ruflet/page.rb', line 393

def navigate(route, **query_params)
  go(route, **query_params)
end

#on(event_name, &block) ⇒ Object



413
414
415
416
# File 'lib/ruflet_ui/ruflet/page.rb', line 413

def on(event_name, &block)
  @page_event_handlers[event_name.to_s.sub(/\Aon_/, "")] = block
  self
end

#on_route_change=(handler) ⇒ Object



405
406
407
# File 'lib/ruflet_ui/ruflet/page.rb', line 405

def on_route_change=(handler)
  @page_event_handlers["route_change"] = handler
end

#on_view_pop=(handler) ⇒ Object



409
410
411
# File 'lib/ruflet_ui/ruflet/page.rb', line 409

def on_view_pop=(handler)
  @page_event_handlers["view_pop"] = handler
end

#open_window(url, title: nil, width: nil, height: nil, timeout: 10, on_result: nil) ⇒ Object



585
586
587
588
589
590
591
592
# File 'lib/ruflet_ui/ruflet/page.rb', line 585

def open_window(url, title: nil, width: nil, height: nil, timeout: 10, on_result: nil)
  url_launcher = ensure_url_launcher_service
  args = { "url" => url }
  args["title"] = title unless title.nil?
  args["width"] = width unless width.nil?
  args["height"] = height unless height.nil?
  invoke(url_launcher, "open_window", args: args, timeout: timeout, on_result: on_result)
end

#patch_page(control_id, **props) ⇒ Object



1199
1200
1201
# File 'lib/ruflet_ui/ruflet/page.rb', line 1199

def patch_page(control_id, **props)
  update(control_id, **props)
end

#permission_handler(**props) ⇒ Object



992
993
994
# File 'lib/ruflet_ui/ruflet/page.rb', line 992

def permission_handler(**props)
  service(:permission_handler, **props)
end

#pick_files(dialog_title: nil, initial_directory: nil, file_type: "any", allowed_extensions: nil, allow_multiple: false, with_data: false, timeout: nil, on_result: nil) ⇒ Object

File picker helpers: create an ephemeral service, invoke method, and dispose it.



605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
# File 'lib/ruflet_ui/ruflet/page.rb', line 605

def pick_files(
  dialog_title: nil,
  initial_directory: nil,
  file_type: "any",
  allowed_extensions: nil,
  allow_multiple: false,
  with_data: false,
  timeout: nil,
  on_result: nil
)
  invoke_file_picker(
    "pick_files",
    compact_service_args(
      "dialog_title" => dialog_title,
      "initial_directory" => initial_directory,
      "file_type" => file_type,
      "allowed_extensions" => allowed_extensions,
      "allow_multiple" => allow_multiple,
      "with_data" => with_data
    ),
    timeout: timeout,
    on_result: on_result
  )
end

#pop_dialogObject



1143
1144
1145
1146
1147
1148
1149
1150
1151
# File 'lib/ruflet_ui/ruflet/page.rb', line 1143

def pop_dialog
  dialog_control = latest_open_dialog
  return nil unless dialog_control

  dialog_control.props["open"] = false
  refresh_dialogs_container!
  push_dialogs_update!
  dialog_control
end

#push_route(route, **query_params) ⇒ Object



397
398
399
# File 'lib/ruflet_ui/ruflet/page.rb', line 397

def push_route(route, **query_params)
  go(route, **query_params)
end

#queryObject



401
402
403
# File 'lib/ruflet_ui/ruflet/page.rb', line 401

def query
  parse_query(route)
end

#remove_service(*value) ⇒ Object



334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
# File 'lib/ruflet_ui/ruflet/page.rb', line 334

def remove_service(*value)
  targets = value.flatten.compact
  return self if targets.empty?

  @services_container.props["_services"] = services.reject do |service|
    targets.any? do |target|
      case target
      when Control
        service.equal?(target) || (!target.id.nil? && service.id.to_s == target.id.to_s)
      else
        needle = target.to_s
        service.id.to_s == needle || service.type.to_s.downcase == needle.downcase
      end
    end
  end

  refresh_services_container!
  push_services_update!
  self
end

#respond_to_missing?(name, include_private = false) ⇒ Boolean

Returns:

  • (Boolean)


1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
# File 'lib/ruflet_ui/ruflet/page.rb', line 1262

def respond_to_missing?(name, include_private = false)
  method_name = name.to_s
  prop_name = method_name.delete_suffix("=")
  widget_helper_method?(name) ||
    widget_helper_method?(prop_name) ||
    method_name.end_with?("=") ||
    @page_props.key?(method_name) ||
    @view_props.key?(method_name) ||
    DIALOG_PROP_KEYS.include?(method_name) ||
    super
end

#right_mouse_click(finder_id = nil, options = nil, finder_index: nil, timeout: 10, on_result: nil) ⇒ Object



770
771
772
773
# File 'lib/ruflet_ui/ruflet/page.rb', line 770

def right_mouse_click(finder_id = nil, options = nil, finder_index: nil, timeout: 10, on_result: nil)
  finder_index = options[:finder_index] || options["finder_index"] if options.is_a?(Hash) && finder_index.nil?
  invoke_tester_finder("right_mouse_click", finder_id, finder_index: finder_index, timeout: timeout, on_result: on_result)
end

#right_mouse_click_at(offset = nil, timeout: 10, on_result: nil) ⇒ Object



787
788
789
# File 'lib/ruflet_ui/ruflet/page.rb', line 787

def right_mouse_click_at(offset = nil, timeout: 10, on_result: nil)
  invoke_tester_at("right_mouse_click_at", offset, timeout: timeout, on_result: on_result)
end

#routeObject



209
210
211
# File 'lib/ruflet_ui/ruflet/page.rb', line 209

def route
  @page_props["route"]
end

#route=(value) ⇒ Object



213
214
215
# File 'lib/ruflet_ui/ruflet/page.rb', line 213

def route=(value)
  @page_props["route"] = value
end

#save_file(dialog_title: nil, file_name: nil, initial_directory: nil, file_type: "any", allowed_extensions: nil, src_bytes: nil, timeout: nil, on_result: nil) ⇒ Object



630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
# File 'lib/ruflet_ui/ruflet/page.rb', line 630

def save_file(
  dialog_title: nil,
  file_name: nil,
  initial_directory: nil,
  file_type: "any",
  allowed_extensions: nil,
  src_bytes: nil,
  timeout: nil,
  on_result: nil
)
  invoke_file_picker(
    "save_file",
    compact_service_args(
      "dialog_title" => dialog_title,
      "file_name" => file_name,
      "initial_directory" => initial_directory,
      "file_type" => file_type,
      "allowed_extensions" => allowed_extensions,
      "src_bytes" => src_bytes
    ),
    timeout: timeout,
    on_result: on_result
  )
end

#screen_brightness(**props) ⇒ Object



301
302
303
304
305
# File 'lib/ruflet_ui/ruflet/page.rb', line 301

def screen_brightness(**props)
  return service(:screen_brightness, **props) unless props.empty?

  @screen_brightness_proxy
end

#screenshot(**props) ⇒ Object



948
949
950
# File 'lib/ruflet_ui/ruflet/page.rb', line 948

def screenshot(**props)
  service(:screenshot, **props)
end

#secure_storage(**props) ⇒ Object



996
997
998
# File 'lib/ruflet_ui/ruflet/page.rb', line 996

def secure_storage(**props)
  service(:secure_storage, **props)
end

#selection_click(timeout: 10, on_result: nil) ⇒ Object



853
854
855
# File 'lib/ruflet_ui/ruflet/page.rb', line 853

def selection_click(timeout: 10, on_result: nil)
  invoke_haptic_feedback("selection_click", timeout: timeout, on_result: on_result)
end

#semantics_service(**props) ⇒ Object



944
945
946
# File 'lib/ruflet_ui/ruflet/page.rb', line 944

def semantics_service(**props)
  service(:semantics_service, **props)
end

#service(type, **props) ⇒ Object



355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
# File 'lib/ruflet_ui/ruflet/page.rb', line 355

def service(type, **props)
  mapped_props = normalize_props(props || {})
  id = mapped_props.delete("id")
  normalized_type = type.to_s.downcase
  compact_type = normalized_type.delete("_")

  if visual_service_type?(normalized_type)
    key = id ? "id:#{id}" : normalized_type
    existing = @visual_service_controls[key]
    return existing if existing

    svc = Ruflet::UI::ControlFactory.build(type.to_s, id: id&.to_s, **mapped_props)
    @visual_service_controls[key] = svc
    return svc
  end

  existing =
    if id
      services.find { |s| s.is_a?(Control) && s.id.to_s == id.to_s }
    else
      services.find do |s|
        s.is_a?(Control) && s.type.to_s.downcase.delete("_") == compact_type
      end
    end
  return existing if existing

  svc = Ruflet::UI::ControlFactory.build(type.to_s, id: id&.to_s, **mapped_props)
  add_service(svc) unless services.include?(svc)
  svc
end

#servicesObject



272
273
274
# File 'lib/ruflet_ui/ruflet/page.rb', line 272

def services
  @services_container.props["_services"] ||= []
end

#services=(value) ⇒ Object



276
277
278
279
280
281
# File 'lib/ruflet_ui/ruflet/page.rb', line 276

def services=(value)
  @services_container.props["_services"] = Array(value).compact
  refresh_services_container!
  push_services_update!
  self
end

#set_clipboard(value, timeout: nil, on_result: nil) ⇒ Object



861
862
863
864
865
866
867
868
# File 'lib/ruflet_ui/ruflet/page.rb', line 861

def set_clipboard(value, timeout: nil, on_result: nil)
  invoke_clipboard_method(
    "set",
    args: { "data" => value.to_s },
    timeout: timeout,
    on_result: on_result
  )
end

#set_clipboard_files(files, timeout: nil, on_result: nil) ⇒ Object



874
875
876
877
878
879
880
881
# File 'lib/ruflet_ui/ruflet/page.rb', line 874

def set_clipboard_files(files, timeout: nil, on_result: nil)
  invoke_clipboard_method(
    "set_files",
    args: { "files" => Array(files).map(&:to_s) },
    timeout: timeout,
    on_result: on_result
  )
end

#set_clipboard_image(value, timeout: nil, on_result: nil) ⇒ Object



887
888
889
890
891
892
893
894
# File 'lib/ruflet_ui/ruflet/page.rb', line 887

def set_clipboard_image(value, timeout: nil, on_result: nil)
  invoke_clipboard_method(
    "set_image",
    args: { "data" => value },
    timeout: timeout,
    on_result: on_result
  )
end

#set_view_props(props) ⇒ Object



196
197
198
199
# File 'lib/ruflet_ui/ruflet/page.rb', line 196

def set_view_props(props)
  split_props(normalize_props(props || {}))
  self
end

#shake_detector(**props) ⇒ Object



940
941
942
# File 'lib/ruflet_ui/ruflet/page.rb', line 940

def shake_detector(**props)
  service(:shake_detector, **props)
end

#share(**props) ⇒ Object



976
977
978
# File 'lib/ruflet_ui/ruflet/page.rb', line 976

def share(**props)
  service(:share, **props)
end

#share_files(files = nil, text: nil, title: nil, subject: nil, preview_thumbnail: nil, share_position_origin: nil, download_fallback_enabled: true, mail_to_fallback_enabled: true, excluded_cupertino_activities: nil, timeout: nil, on_result: nil) ⇒ Object



1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
# File 'lib/ruflet_ui/ruflet/page.rb', line 1092

def share_files(
  files = nil,
  text: nil,
  title: nil,
  subject: nil,
  preview_thumbnail: nil,
  share_position_origin: nil,
  download_fallback_enabled: true,
  mail_to_fallback_enabled: true,
  excluded_cupertino_activities: nil,
  timeout: nil,
  on_result: nil
)
  share = ensure_share_service
  invoke(
    share,
    "share_files",
    args: compact_service_args(
      "files" => normalize_share_files(files),
      "text" => text,
      "title" => title,
      "subject" => subject,
      "preview_thumbnail" => normalize_share_file(preview_thumbnail),
      "share_position_origin" => share_position_origin,
      "download_fallback_enabled" => download_fallback_enabled,
      "mail_to_fallback_enabled" => mail_to_fallback_enabled,
      "excluded_cupertino_activities" => excluded_cupertino_activities
    ),
    timeout: timeout,
    on_result: on_result
  )
end

#share_text(text = nil, title: nil, subject: nil, preview_thumbnail: nil, share_position_origin: nil, download_fallback_enabled: true, mail_to_fallback_enabled: true, excluded_cupertino_activities: nil, timeout: nil, on_result: nil) ⇒ Object



1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
# File 'lib/ruflet_ui/ruflet/page.rb', line 1040

def share_text(
  text = nil,
  title: nil,
  subject: nil,
  preview_thumbnail: nil,
  share_position_origin: nil,
  download_fallback_enabled: true,
  mail_to_fallback_enabled: true,
  excluded_cupertino_activities: nil,
  timeout: nil,
  on_result: nil
)
  share = ensure_share_service
  invoke(
    share,
    "share_text",
    args: compact_service_args(
      "text" => text,
      "title" => title,
      "subject" => subject,
      "preview_thumbnail" => preview_thumbnail,
      "share_position_origin" => share_position_origin,
      "download_fallback_enabled" => download_fallback_enabled,
      "mail_to_fallback_enabled" => mail_to_fallback_enabled,
      "excluded_cupertino_activities" => excluded_cupertino_activities
    ),
    timeout: timeout,
    on_result: on_result
  )
end

#share_uri(uri = nil, share_position_origin: nil, excluded_cupertino_activities: nil, timeout: nil, on_result: nil) ⇒ Object



1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
# File 'lib/ruflet_ui/ruflet/page.rb', line 1071

def share_uri(
  uri = nil,
  share_position_origin: nil,
  excluded_cupertino_activities: nil,
  timeout: nil,
  on_result: nil
)
  share = ensure_share_service
  invoke(
    share,
    "share_uri",
    args: compact_service_args(
      "uri" => uri,
      "share_position_origin" => share_position_origin,
      "excluded_cupertino_activities" => excluded_cupertino_activities
    ),
    timeout: timeout,
    on_result: on_result
  )
end

#shared_preferences(**props) ⇒ Object



283
284
285
286
287
# File 'lib/ruflet_ui/ruflet/page.rb', line 283

def shared_preferences(**props)
  return service(:shared_preferences, **props) unless props.empty?

  @shared_preferences_proxy
end

#show_dialog(dialog_control) ⇒ Object



505
506
507
508
509
510
511
512
513
514
515
516
# File 'lib/ruflet_ui/ruflet/page.rb', line 505

def show_dialog(dialog_control)
  return self unless dialog_control

  return self if dialog_open?(dialog_control)

  dialog_control.props["open"] = true
  @dialogs << dialog_control unless @dialogs.include?(dialog_control)
  refresh_dialogs_container!
  send_view_patch unless @dialogs_container.wire_id
  push_dialogs_update!
  self
end

#show_drawer(timeout: 10, on_result: nil) ⇒ Object

Raises:

  • (ArgumentError)


456
457
458
459
460
461
# File 'lib/ruflet_ui/ruflet/page.rb', line 456

def show_drawer(timeout: 10, on_result: nil)
  raise ArgumentError, "show_drawer requires drawer" unless drawer

  invoke_current_view("show_drawer", timeout: timeout, on_result: on_result)
  self
end

#show_end_drawer(timeout: 10, on_result: nil) ⇒ Object

Raises:

  • (ArgumentError)


468
469
470
471
472
473
# File 'lib/ruflet_ui/ruflet/page.rb', line 468

def show_end_drawer(timeout: 10, on_result: nil)
  raise ArgumentError, "show_end_drawer requires end_drawer" unless end_drawer

  invoke_current_view("show_end_drawer", timeout: timeout, on_result: on_result)
  self
end

#snack_bar=(value) ⇒ Object



487
488
489
490
# File 'lib/ruflet_ui/ruflet/page.rb', line 487

def snack_bar=(value)
  @snack_bar = value
  refresh_dialogs_container!
end

#snackbar=(value) ⇒ Object



492
493
494
# File 'lib/ruflet_ui/ruflet/page.rb', line 492

def snackbar=(value)
  self.snack_bar = value
end

#start_window_dragging(timeout: 10, on_result: nil) ⇒ Object



708
709
710
# File 'lib/ruflet_ui/ruflet/page.rb', line 708

def start_window_dragging(timeout: 10, on_result: nil)
  invoke_window("start_dragging", timeout: timeout, on_result: on_result)
end

#start_window_resizing(edge, timeout: 10, on_result: nil) ⇒ Object



712
713
714
715
716
717
718
719
# File 'lib/ruflet_ui/ruflet/page.rb', line 712

def start_window_resizing(edge, timeout: 10, on_result: nil)
  invoke_window(
    "start_resizing",
    args: { "edge" => normalize_service_value(edge) },
    timeout: timeout,
    on_result: on_result
  )
end

#storage_paths(**props) ⇒ Object



972
973
974
# File 'lib/ruflet_ui/ruflet/page.rb', line 972

def storage_paths(**props)
  service(:storage_paths, **props)
end

#supports_close_for_launch_mode(mode, timeout: 10, on_result: nil) ⇒ Object



599
600
601
602
# File 'lib/ruflet_ui/ruflet/page.rb', line 599

def supports_close_for_launch_mode(mode, timeout: 10, on_result: nil)
  url_launcher = ensure_url_launcher_service
  invoke(url_launcher, "supports_close_for_launch_mode", args: { "mode" => mode }, timeout: timeout, on_result: on_result)
end

#supports_launch_mode(mode, timeout: 10, on_result: nil) ⇒ Object



594
595
596
597
# File 'lib/ruflet_ui/ruflet/page.rb', line 594

def supports_launch_mode(mode, timeout: 10, on_result: nil)
  url_launcher = ensure_url_launcher_service
  invoke(url_launcher, "supports_launch_mode", args: { "mode" => mode }, timeout: timeout, on_result: on_result)
end

#take_screenshot(name, timeout: 10, on_result: nil) ⇒ Object



751
752
753
# File 'lib/ruflet_ui/ruflet/page.rb', line 751

def take_screenshot(name, timeout: 10, on_result: nil)
  invoke_tester("take_screenshot", args: { "name" => name }, timeout: timeout, on_result: on_result)
end

#tap(finder_id = nil, options = nil, finder_index: nil, timeout: 10, on_result: nil) ⇒ Object



755
756
757
758
# File 'lib/ruflet_ui/ruflet/page.rb', line 755

def tap(finder_id = nil, options = nil, finder_index: nil, timeout: 10, on_result: nil)
  finder_index = options[:finder_index] || options["finder_index"] if options.is_a?(Hash) && finder_index.nil?
  invoke_tester_finder("tap", finder_id, finder_index: finder_index, timeout: timeout, on_result: on_result)
end

#tap_at(offset = nil, timeout: 10, on_result: nil) ⇒ Object



775
776
777
# File 'lib/ruflet_ui/ruflet/page.rb', line 775

def tap_at(offset = nil, timeout: 10, on_result: nil)
  invoke_tester_at("tap_at", offset, timeout: timeout, on_result: on_result)
end

#tester(**props) ⇒ Object



323
324
325
# File 'lib/ruflet_ui/ruflet/page.rb', line 323

def tester(**props)
  service(:tester, **props)
end

#tester_pump(options = nil, duration: nil, timeout: 10, on_result: nil) ⇒ Object



721
722
723
724
# File 'lib/ruflet_ui/ruflet/page.rb', line 721

def tester_pump(options = nil, duration: nil, timeout: 10, on_result: nil)
  duration = options[:duration] || options["duration"] if options.is_a?(Hash) && duration.nil?
  invoke_tester("pump", args: compact_service_args("duration" => duration), timeout: timeout, on_result: on_result)
end

#tester_pump_and_settle(options = nil, duration: nil, timeout: 10, on_result: nil) ⇒ Object



726
727
728
729
# File 'lib/ruflet_ui/ruflet/page.rb', line 726

def tester_pump_and_settle(options = nil, duration: nil, timeout: 10, on_result: nil)
  duration = options[:duration] || options["duration"] if options.is_a?(Hash) && duration.nil?
  invoke_tester("pump_and_settle", args: compact_service_args("duration" => duration), timeout: timeout, on_result: on_result)
end

#tester_teardown(timeout: 10, on_result: nil) ⇒ Object



837
838
839
# File 'lib/ruflet_ui/ruflet/page.rb', line 837

def tester_teardown(timeout: 10, on_result: nil)
  invoke_tester("teardown", timeout: timeout, on_result: on_result)
end

#titleObject



201
202
203
# File 'lib/ruflet_ui/ruflet/page.rb', line 201

def title
  @page_props["title"]
end

#title=(value) ⇒ Object



205
206
207
# File 'lib/ruflet_ui/ruflet/page.rb', line 205

def title=(value)
  @page_props["title"] = value
end

#update(control_or_id = nil, **props) ⇒ Object



1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
# File 'lib/ruflet_ui/ruflet/page.rb', line 1153

def update(control_or_id = nil, **props)
  if control_or_id.nil? && props.empty?
    send_view_patch
    return self
  end

  if page_control_target?(control_or_id)
    split_props(normalize_props(props))
    send_view_patch
    return self
  end

  control = resolve_control(control_or_id)
  return self unless control
  wire_id = control.wire_id
  if wire_id.nil?
    # Events can race with navigation/disposal; never emit patch_control with nil id.
    refresh_control_indexes!
    wire_id = control.wire_id
  end
  return self if wire_id.nil?

  patch = normalize_props(props)
  if text_maps_to_content?(control, patch)
    patch["content"] = patch.delete("text")
  end

  # Keep runtime control tree aligned with incremental patches.
  if patch.key?("controls")
    control.children.clear
    Array(patch["controls"]).each { |child| control.children << child if child.is_a?(Control) }
  end

  visited = Set.new
  patch.each_value { |value| register_embedded_value(value, visited) }

  patch_ops = patch.map { |k, v| [0, 0, k, serialize_patch_value(v)] }

  send_message(Protocol::ACTIONS[:patch_control], {
    "id" => wire_id,
    "patch" => [[0], *patch_ops]
  })

  self
end

#upload(files, timeout: nil, on_result: nil) ⇒ Object



667
668
669
670
671
672
673
674
# File 'lib/ruflet_ui/ruflet/page.rb', line 667

def upload(files, timeout: nil, on_result: nil)
  invoke_file_picker(
    "upload",
    { "files" => Array(files).map { |file| normalize_service_value(file) } },
    timeout: timeout,
    on_result: on_result
  )
end

#upload_files(files, timeout: nil, on_result: nil) ⇒ Object



676
677
678
# File 'lib/ruflet_ui/ruflet/page.rb', line 676

def upload_files(files, timeout: nil, on_result: nil)
  upload(files, timeout: timeout, on_result: on_result)
end

#url_launcher(**props) ⇒ Object



968
969
970
# File 'lib/ruflet_ui/ruflet/page.rb', line 968

def url_launcher(**props)
  service(:url_launcher, **props)
end

#user_accelerometer(**props) ⇒ Object



928
929
930
# File 'lib/ruflet_ui/ruflet/page.rb', line 928

def user_accelerometer(**props)
  service(:user_accelerometer, **props)
end

#vertical_alignmentObject



217
218
219
# File 'lib/ruflet_ui/ruflet/page.rb', line 217

def vertical_alignment
  @page_props["vertical_alignment"] || @view_props["vertical_alignment"]
end

#vertical_alignment=(value) ⇒ Object



221
222
223
224
225
# File 'lib/ruflet_ui/ruflet/page.rb', line 221

def vertical_alignment=(value)
  v = normalize_value("vertical_alignment", value)
  @page_props["vertical_alignment"] = v
  @view_props["vertical_alignment"] = v
end

#vibrate(timeout: 10, on_result: nil) ⇒ Object



857
858
859
# File 'lib/ruflet_ui/ruflet/page.rb', line 857

def vibrate(timeout: 10, on_result: nil)
  invoke_haptic_feedback("vibrate", timeout: timeout, on_result: on_result)
end

#wait_until_ready_to_show(timeout: 10, on_result: nil) ⇒ Object



688
689
690
# File 'lib/ruflet_ui/ruflet/page.rb', line 688

def wait_until_ready_to_show(timeout: 10, on_result: nil)
  invoke_window("wait_until_ready_to_show", timeout: timeout, on_result: on_result)
end

#wakelock(**props) ⇒ Object



289
290
291
292
293
# File 'lib/ruflet_ui/ruflet/page.rb', line 289

def wakelock(**props)
  return service(:wakelock, **props) unless props.empty?

  @wakelock_proxy
end

#window(**props) ⇒ Object



319
320
321
# File 'lib/ruflet_ui/ruflet/page.rb', line 319

def window(**props)
  service(:window, **props)
end

#window_to_front(timeout: 10, on_result: nil) ⇒ Object



692
693
694
# File 'lib/ruflet_ui/ruflet/page.rb', line 692

def window_to_front(timeout: 10, on_result: nil)
  invoke_window("to_front", timeout: timeout, on_result: on_result)
end