ruflet_core 0.0.12 → 0.0.13
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/lib/ruflet/version.rb +1 -1
- data/lib/ruflet_protocol/ruflet/protocol.rb +50 -4
- data/lib/ruflet_ui/ruflet/control.rb +11 -4
- data/lib/ruflet_ui/ruflet/dsl.rb +229 -37
- data/lib/ruflet_ui/ruflet/events/gesture_events.rb +113 -9
- data/lib/ruflet_ui/ruflet/page.rb +820 -145
- data/lib/ruflet_ui/ruflet/types/animation.rb +110 -0
- data/lib/ruflet_ui/ruflet/ui/control_registry.rb +1 -0
- data/lib/ruflet_ui/ruflet/ui/controls/cupertinos/cupertinoactionsheet_control.rb +13 -0
- data/lib/ruflet_ui/ruflet/ui/controls/cupertinos/cupertinoactionsheetaction_control.rb +4 -0
- data/lib/ruflet_ui/ruflet/ui/controls/cupertinos/cupertinoactivityindicator_control.rb +4 -0
- data/lib/ruflet_ui/ruflet/ui/controls/cupertinos/cupertinoalertdialog_control.rb +17 -0
- data/lib/ruflet_ui/ruflet/ui/controls/cupertinos/cupertinoappbar_control.rb +3 -0
- data/lib/ruflet_ui/ruflet/ui/controls/cupertinos/cupertinobottomsheet_control.rb +4 -0
- data/lib/ruflet_ui/ruflet/ui/controls/cupertinos/cupertinobutton_control.rb +9 -0
- data/lib/ruflet_ui/ruflet/ui/controls/cupertinos/cupertinocheckbox_control.rb +6 -0
- data/lib/ruflet_ui/ruflet/ui/controls/cupertinos/cupertinocontextmenu_control.rb +11 -0
- data/lib/ruflet_ui/ruflet/ui/controls/cupertinos/cupertinocontextmenuaction_control.rb +4 -0
- data/lib/ruflet_ui/ruflet/ui/controls/cupertinos/cupertinodatepicker_control.rb +14 -0
- data/lib/ruflet_ui/ruflet/ui/controls/cupertinos/cupertinodialogaction_control.rb +4 -0
- data/lib/ruflet_ui/ruflet/ui/controls/cupertinos/cupertinofilledbutton_control.rb +9 -0
- data/lib/ruflet_ui/ruflet/ui/controls/cupertinos/cupertinolisttile_control.rb +12 -0
- data/lib/ruflet_ui/ruflet/ui/controls/cupertinos/cupertinonavigationbar_control.rb +11 -0
- data/lib/ruflet_ui/ruflet/ui/controls/cupertinos/cupertinopicker_control.rb +18 -0
- data/lib/ruflet_ui/ruflet/ui/controls/cupertinos/cupertinoradio_control.rb +6 -0
- data/lib/ruflet_ui/ruflet/ui/controls/cupertinos/cupertinosegmentedbutton_control.rb +2 -0
- data/lib/ruflet_ui/ruflet/ui/controls/cupertinos/cupertinoslider_control.rb +7 -0
- data/lib/ruflet_ui/ruflet/ui/controls/cupertinos/cupertinoslidingsegmentedbutton_control.rb +3 -0
- data/lib/ruflet_ui/ruflet/ui/controls/cupertinos/cupertinoswitch_control.rb +7 -1
- data/lib/ruflet_ui/ruflet/ui/controls/cupertinos/cupertinotextfield_control.rb +7 -0
- data/lib/ruflet_ui/ruflet/ui/controls/cupertinos/cupertinotimerpicker_control.rb +18 -0
- data/lib/ruflet_ui/ruflet/ui/controls/cupertinos/cupertinotintedbutton_control.rb +9 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/alertdialog_control.rb +4 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/appbar_control.rb +4 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/audio_control.rb +35 -1
- data/lib/ruflet_ui/ruflet/ui/controls/materials/autocomplete_control.rb +4 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/autocompletesuggestion_control.rb +26 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/badge_control.rb +7 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/banner_control.rb +11 -1
- data/lib/ruflet_ui/ruflet/ui/controls/materials/bottomappbar_control.rb +2 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/bottomsheet_control.rb +5 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/button_control.rb +2 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/card_control.rb +4 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/chip_control.rb +11 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/circleavatar_control.rb +12 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/contextmenu_control.rb +19 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/datacell_control.rb +4 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/datacolumn_control.rb +4 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/datatable_control.rb +34 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/datepicker_control.rb +18 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/daterangepicker_control.rb +20 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/divider_control.rb +9 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/dropdown_control.rb +11 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/dropdownoption_control.rb +5 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/expansionpanel_control.rb +8 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/expansionpanellist_control.rb +6 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/expansiontile_control.rb +6 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/filledbutton_control.rb +5 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/fillediconbutton_control.rb +8 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/filledtonalbutton_control.rb +5 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/filledtonaliconbutton_control.rb +8 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/floatingactionbutton_control.rb +20 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/iconbutton_control.rb +4 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/listtile_control.rb +4 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/map_controls.rb +240 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/menubar_control.rb +2 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/menuitembutton_control.rb +6 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/navigationbar_control.rb +11 -1
- data/lib/ruflet_ui/ruflet/ui/controls/materials/navigationbardestination_control.rb +2 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/navigationdrawer_control.rb +12 -1
- data/lib/ruflet_ui/ruflet/ui/controls/materials/navigationdrawerdestination_control.rb +2 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/navigationrail_control.rb +21 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/navigationraildestination_control.rb +2 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/outlinedbutton_control.rb +5 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/outlinediconbutton_control.rb +8 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/popupmenubutton_control.rb +4 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/popupmenuitem_control.rb +6 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/progressbar_control.rb +9 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/progressring_control.rb +8 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/rangeslider_control.rb +13 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/ruflet_controls.rb +24 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/searchbar_control.rb +28 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/segment_control.rb +5 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/segmentedbutton_control.rb +19 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/selectionarea_control.rb +4 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/snackbar_control.rb +5 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/submenubutton_control.rb +8 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/tab_control.rb +7 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/tabbar_control.rb +4 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/tabbarview_control.rb +7 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/tabs_control.rb +6 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/textbutton_control.rb +5 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/verticaldivider_control.rb +9 -0
- data/lib/ruflet_ui/ruflet/ui/controls/materials/video_control.rb +86 -1
- data/lib/ruflet_ui/ruflet/ui/controls/ruflet_controls.rb +24 -0
- data/lib/ruflet_ui/ruflet/ui/controls/shared/animatedswitcher_control.rb +10 -0
- data/lib/ruflet_ui/ruflet/ui/controls/shared/browsercontextmenu_control.rb +12 -1
- data/lib/ruflet_ui/ruflet/ui/controls/shared/canvas_control.rb +14 -0
- data/lib/ruflet_ui/ruflet/ui/controls/shared/dismissible_control.rb +19 -0
- data/lib/ruflet_ui/ruflet/ui/controls/shared/draggable_control.rb +9 -0
- data/lib/ruflet_ui/ruflet/ui/controls/shared/dragtarget_control.rb +6 -0
- data/lib/ruflet_ui/ruflet/ui/controls/shared/gridview_control.rb +20 -0
- data/lib/ruflet_ui/ruflet/ui/controls/shared/image_control.rb +19 -1
- data/lib/ruflet_ui/ruflet/ui/controls/shared/interactiveviewer_control.rb +37 -0
- data/lib/ruflet_ui/ruflet/ui/controls/shared/listview_control.rb +17 -0
- data/lib/ruflet_ui/ruflet/ui/controls/shared/pageview_control.rb +13 -0
- data/lib/ruflet_ui/ruflet/ui/controls/shared/placeholder_control.rb +12 -0
- data/lib/ruflet_ui/ruflet/ui/controls/shared/reorderabledraghandle_control.rb +4 -0
- data/lib/ruflet_ui/ruflet/ui/controls/shared/responsiverow_control.rb +22 -0
- data/lib/ruflet_ui/ruflet/ui/controls/shared/safearea_control.rb +11 -0
- data/lib/ruflet_ui/ruflet/ui/controls/shared/semantics_control.rb +2 -0
- data/lib/ruflet_ui/ruflet/ui/controls/shared/stack_control.rb +3 -0
- data/lib/ruflet_ui/ruflet/ui/controls/shared/text_control.rb +20 -1
- data/lib/ruflet_ui/ruflet/ui/controls/shared/view_control.rb +8 -0
- data/lib/ruflet_ui/ruflet/ui/controls/shared/window_control.rb +16 -0
- data/lib/ruflet_ui/ruflet/ui/controls/shared/windowdragarea_control.rb +6 -0
- data/lib/ruflet_ui/ruflet/ui/cupertino_control_methods.rb +83 -6
- data/lib/ruflet_ui/ruflet/ui/material_control_methods.rb +513 -33
- data/lib/ruflet_ui/ruflet/ui/material_control_registry.rb +2 -0
- data/lib/ruflet_ui/ruflet/ui/services/ruflet/audio_recorder_control.rb +87 -0
- data/lib/ruflet_ui/ruflet/ui/services/ruflet/geolocator_control.rb +85 -0
- data/lib/ruflet_ui/ruflet/ui/services/ruflet/permissionhandler_control.rb +53 -0
- data/lib/ruflet_ui/ruflet/ui/services/ruflet/securestorage_control.rb +89 -0
- data/lib/ruflet_ui/ruflet/ui/services/ruflet/semanticsservice_control.rb +28 -0
- data/lib/ruflet_ui/ruflet/ui/services/ruflet/tester_control.rb +126 -0
- data/lib/ruflet_ui/ruflet/ui/services/ruflet_services.rb +16 -0
- data/lib/ruflet_ui/ruflet/ui/shared_control_forwarders.rb +230 -38
- data/lib/ruflet_ui.rb +4 -0
- metadata +9 -1
|
@@ -14,7 +14,132 @@ require "timeout"
|
|
|
14
14
|
|
|
15
15
|
module Ruflet
|
|
16
16
|
class Page
|
|
17
|
-
|
|
17
|
+
class SharedPreferencesService
|
|
18
|
+
def initialize(page)
|
|
19
|
+
@page = page
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def set(key, value, timeout: 10, on_result: nil)
|
|
23
|
+
invoke("set", { "key" => key, "value" => value }, timeout: timeout, on_result: on_result)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def get(key, timeout: 10, on_result: nil)
|
|
27
|
+
invoke("get", { "key" => key }, timeout: timeout, on_result: on_result)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def contains_key(key, timeout: 10, on_result: nil)
|
|
31
|
+
invoke("contains_key", { "key" => key }, timeout: timeout, on_result: on_result)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def get_keys(key_prefix, timeout: 10, on_result: nil)
|
|
35
|
+
invoke("get_keys", { "key_prefix" => key_prefix }, timeout: timeout, on_result: on_result)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def remove(key, timeout: 10, on_result: nil)
|
|
39
|
+
invoke("remove", { "key" => key }, timeout: timeout, on_result: on_result)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def clear(timeout: 10, on_result: nil)
|
|
43
|
+
invoke("clear", nil, timeout: timeout, on_result: on_result)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
private
|
|
47
|
+
|
|
48
|
+
def invoke(method_name, args, timeout:, on_result:)
|
|
49
|
+
@page.__send__(:invoke_shared_preferences, method_name, args: args, timeout: timeout, on_result: on_result)
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
class WakelockService
|
|
54
|
+
def initialize(page)
|
|
55
|
+
@page = page
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def enable(timeout: 10, on_result: nil)
|
|
59
|
+
invoke("enable", timeout: timeout, on_result: on_result)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def disable(timeout: 10, on_result: nil)
|
|
63
|
+
invoke("disable", timeout: timeout, on_result: on_result)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def is_enabled(timeout: 10, on_result: nil)
|
|
67
|
+
invoke("is_enabled", timeout: timeout, on_result: on_result)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
private
|
|
71
|
+
|
|
72
|
+
def invoke(method_name, timeout:, on_result:)
|
|
73
|
+
@page.__send__(:invoke_wakelock, method_name, timeout: timeout, on_result: on_result)
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
class FlashlightService
|
|
78
|
+
def initialize(page)
|
|
79
|
+
@page = page
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def on(timeout: 10, on_result: nil)
|
|
83
|
+
invoke("on", timeout: timeout, on_result: on_result)
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def off(timeout: 10, on_result: nil)
|
|
87
|
+
invoke("off", timeout: timeout, on_result: on_result)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def is_available(timeout: 10, on_result: nil)
|
|
91
|
+
invoke("is_available", timeout: timeout, on_result: on_result)
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
private
|
|
95
|
+
|
|
96
|
+
def invoke(method_name, timeout:, on_result:)
|
|
97
|
+
@page.__send__(:invoke_flashlight, method_name, timeout: timeout, on_result: on_result)
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
class ScreenBrightnessService
|
|
102
|
+
def initialize(page)
|
|
103
|
+
@page = page
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
%w[
|
|
107
|
+
can_change_system_screen_brightness
|
|
108
|
+
get_application_screen_brightness
|
|
109
|
+
get_system_screen_brightness
|
|
110
|
+
is_animate
|
|
111
|
+
is_auto_reset
|
|
112
|
+
reset_application_screen_brightness
|
|
113
|
+
].each do |method_name|
|
|
114
|
+
define_method(method_name) do |timeout: 10, on_result: nil|
|
|
115
|
+
invoke(method_name, nil, timeout: timeout, on_result: on_result)
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def set_animate(animate, timeout: 10, on_result: nil)
|
|
120
|
+
invoke("set_animate", { "value" => animate }, timeout: timeout, on_result: on_result)
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def set_auto_reset(auto_reset, timeout: 10, on_result: nil)
|
|
124
|
+
invoke("set_auto_reset", { "value" => auto_reset }, timeout: timeout, on_result: on_result)
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def set_application_screen_brightness(brightness, timeout: 10, on_result: nil)
|
|
128
|
+
invoke("set_application_screen_brightness", { "value" => brightness }, timeout: timeout, on_result: on_result)
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def set_system_screen_brightness(brightness, timeout: 10, on_result: nil)
|
|
132
|
+
invoke("set_system_screen_brightness", { "value" => brightness }, timeout: timeout, on_result: on_result)
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
private
|
|
136
|
+
|
|
137
|
+
def invoke(method_name, args, timeout:, on_result:)
|
|
138
|
+
@page.__send__(:invoke_screen_brightness, method_name, args: args, timeout: timeout, on_result: on_result)
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
PAGE_PROP_KEYS = %w[dark_theme fonts route rtl show_semantics_debugger theme theme_mode title vertical_alignment horizontal_alignment scroll].freeze
|
|
18
143
|
DIALOG_PROP_KEYS = %w[dialog snack_bar bottom_sheet].freeze
|
|
19
144
|
WIDGET_HELPER_METHODS = (
|
|
20
145
|
Ruflet::UI::MaterialControlMethods.instance_methods(false) +
|
|
@@ -35,6 +160,8 @@ module Ruflet
|
|
|
35
160
|
@root_controls = []
|
|
36
161
|
@views = []
|
|
37
162
|
@dialogs = []
|
|
163
|
+
@services_container_mounted = false
|
|
164
|
+
@visual_service_controls = {}
|
|
38
165
|
@page_event_handlers = {}
|
|
39
166
|
@view_props = {}
|
|
40
167
|
@page_props = { "route" => (client_details["route"] || "/") }
|
|
@@ -57,6 +184,10 @@ module Ruflet
|
|
|
57
184
|
@invoke_waiters = {}
|
|
58
185
|
@invoke_callbacks = {}
|
|
59
186
|
@invoke_waiters_mutex = Mutex.new
|
|
187
|
+
@shared_preferences_proxy = SharedPreferencesService.new(self)
|
|
188
|
+
@wakelock_proxy = WakelockService.new(self)
|
|
189
|
+
@flashlight_proxy = FlashlightService.new(self)
|
|
190
|
+
@screen_brightness_proxy = ScreenBrightnessService.new(self)
|
|
60
191
|
refresh_overlay_container!
|
|
61
192
|
refresh_services_container!
|
|
62
193
|
refresh_dialogs_container!
|
|
@@ -111,13 +242,14 @@ module Ruflet
|
|
|
111
242
|
@view_props["bgcolor"] = normalize_value("bgcolor", value)
|
|
112
243
|
end
|
|
113
244
|
|
|
114
|
-
def add(*controls, appbar: nil, floating_action_button: nil, navigation_bar: nil, dialog: nil, snack_bar: nil, bottom_sheet: nil)
|
|
245
|
+
def add(*controls, appbar: nil, bottom_appbar: nil, floating_action_button: nil, navigation_bar: nil, dialog: nil, snack_bar: nil, bottom_sheet: nil)
|
|
115
246
|
controls = controls.flatten
|
|
116
247
|
visited = Set.new
|
|
117
248
|
controls.each { |c| register_control_tree(c, visited) }
|
|
118
249
|
@root_controls = controls
|
|
119
250
|
|
|
120
251
|
@view_props["appbar"] = appbar if appbar
|
|
252
|
+
@view_props["bottom_appbar"] = bottom_appbar if bottom_appbar
|
|
121
253
|
@view_props["floating_action_button"] = floating_action_button if floating_action_button
|
|
122
254
|
@view_props["navigation_bar"] = navigation_bar if navigation_bar
|
|
123
255
|
@dialog = dialog if dialog
|
|
@@ -148,6 +280,50 @@ module Ruflet
|
|
|
148
280
|
self
|
|
149
281
|
end
|
|
150
282
|
|
|
283
|
+
def shared_preferences(**props)
|
|
284
|
+
return service(:shared_preferences, **props) unless props.empty?
|
|
285
|
+
|
|
286
|
+
@shared_preferences_proxy
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
def wakelock(**props)
|
|
290
|
+
return service(:wakelock, **props) unless props.empty?
|
|
291
|
+
|
|
292
|
+
@wakelock_proxy
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
def flashlight(**props)
|
|
296
|
+
return service(:flashlight, **props) unless props.empty?
|
|
297
|
+
|
|
298
|
+
@flashlight_proxy
|
|
299
|
+
end
|
|
300
|
+
|
|
301
|
+
def screen_brightness(**props)
|
|
302
|
+
return service(:screen_brightness, **props) unless props.empty?
|
|
303
|
+
|
|
304
|
+
@screen_brightness_proxy
|
|
305
|
+
end
|
|
306
|
+
|
|
307
|
+
def audio(**props)
|
|
308
|
+
service(:audio, **props)
|
|
309
|
+
end
|
|
310
|
+
|
|
311
|
+
def audio_recorder(**props)
|
|
312
|
+
service(:audio_recorder, **props)
|
|
313
|
+
end
|
|
314
|
+
|
|
315
|
+
def browser_context_menu(**props)
|
|
316
|
+
service(:browser_context_menu, **props)
|
|
317
|
+
end
|
|
318
|
+
|
|
319
|
+
def window(**props)
|
|
320
|
+
service(:window, **props)
|
|
321
|
+
end
|
|
322
|
+
|
|
323
|
+
def tester(**props)
|
|
324
|
+
service(:tester, **props)
|
|
325
|
+
end
|
|
326
|
+
|
|
151
327
|
def add_service(*value)
|
|
152
328
|
@services_container.props["_services"] = services + value.flatten.compact
|
|
153
329
|
refresh_services_container!
|
|
@@ -180,12 +356,25 @@ module Ruflet
|
|
|
180
356
|
mapped_props = normalize_props(props || {})
|
|
181
357
|
id = mapped_props.delete("id")
|
|
182
358
|
normalized_type = type.to_s.downcase
|
|
359
|
+
compact_type = normalized_type.delete("_")
|
|
360
|
+
|
|
361
|
+
if visual_service_type?(normalized_type)
|
|
362
|
+
key = id ? "id:#{id}" : normalized_type
|
|
363
|
+
existing = @visual_service_controls[key]
|
|
364
|
+
return existing if existing
|
|
365
|
+
|
|
366
|
+
svc = Ruflet::UI::ControlFactory.build(type.to_s, id: id&.to_s, **mapped_props)
|
|
367
|
+
@visual_service_controls[key] = svc
|
|
368
|
+
return svc
|
|
369
|
+
end
|
|
183
370
|
|
|
184
371
|
existing =
|
|
185
372
|
if id
|
|
186
373
|
services.find { |s| s.is_a?(Control) && s.id.to_s == id.to_s }
|
|
187
374
|
else
|
|
188
|
-
services.find
|
|
375
|
+
services.find do |s|
|
|
376
|
+
s.is_a?(Control) && s.type.to_s.downcase.delete("_") == compact_type
|
|
377
|
+
end
|
|
189
378
|
end
|
|
190
379
|
return existing if existing
|
|
191
380
|
|
|
@@ -201,6 +390,18 @@ module Ruflet
|
|
|
201
390
|
self
|
|
202
391
|
end
|
|
203
392
|
|
|
393
|
+
def navigate(route, **query_params)
|
|
394
|
+
go(route, **query_params)
|
|
395
|
+
end
|
|
396
|
+
|
|
397
|
+
def push_route(route, **query_params)
|
|
398
|
+
go(route, **query_params)
|
|
399
|
+
end
|
|
400
|
+
|
|
401
|
+
def query
|
|
402
|
+
parse_query(route)
|
|
403
|
+
end
|
|
404
|
+
|
|
204
405
|
def on_route_change=(handler)
|
|
205
406
|
@page_event_handlers["route_change"] = handler
|
|
206
407
|
end
|
|
@@ -224,10 +425,58 @@ module Ruflet
|
|
|
224
425
|
@view_props["appbar"] = value
|
|
225
426
|
end
|
|
226
427
|
|
|
428
|
+
def bottom_appbar=(value)
|
|
429
|
+
@view_props["bottom_appbar"] = value
|
|
430
|
+
end
|
|
431
|
+
|
|
432
|
+
def bottomappbar=(value)
|
|
433
|
+
self.bottom_appbar = value
|
|
434
|
+
end
|
|
435
|
+
|
|
227
436
|
def floating_action_button=(value)
|
|
228
437
|
@view_props["floating_action_button"] = value
|
|
229
438
|
end
|
|
230
439
|
|
|
440
|
+
def drawer
|
|
441
|
+
@view_props["drawer"]
|
|
442
|
+
end
|
|
443
|
+
|
|
444
|
+
def drawer=(value)
|
|
445
|
+
@view_props["drawer"] = value
|
|
446
|
+
end
|
|
447
|
+
|
|
448
|
+
def end_drawer
|
|
449
|
+
@view_props["end_drawer"]
|
|
450
|
+
end
|
|
451
|
+
|
|
452
|
+
def end_drawer=(value)
|
|
453
|
+
@view_props["end_drawer"] = value
|
|
454
|
+
end
|
|
455
|
+
|
|
456
|
+
def show_drawer(timeout: 10, on_result: nil)
|
|
457
|
+
raise ArgumentError, "show_drawer requires drawer" unless drawer
|
|
458
|
+
|
|
459
|
+
invoke_current_view("show_drawer", timeout: timeout, on_result: on_result)
|
|
460
|
+
self
|
|
461
|
+
end
|
|
462
|
+
|
|
463
|
+
def close_drawer(timeout: 10, on_result: nil)
|
|
464
|
+
invoke_current_view("close_drawer", timeout: timeout, on_result: on_result)
|
|
465
|
+
self
|
|
466
|
+
end
|
|
467
|
+
|
|
468
|
+
def show_end_drawer(timeout: 10, on_result: nil)
|
|
469
|
+
raise ArgumentError, "show_end_drawer requires end_drawer" unless end_drawer
|
|
470
|
+
|
|
471
|
+
invoke_current_view("show_end_drawer", timeout: timeout, on_result: on_result)
|
|
472
|
+
self
|
|
473
|
+
end
|
|
474
|
+
|
|
475
|
+
def close_end_drawer(timeout: 10, on_result: nil)
|
|
476
|
+
invoke_current_view("close_end_drawer", timeout: timeout, on_result: on_result)
|
|
477
|
+
self
|
|
478
|
+
end
|
|
479
|
+
|
|
231
480
|
def dialog = @dialog
|
|
232
481
|
|
|
233
482
|
def dialog=(value)
|
|
@@ -328,6 +577,30 @@ module Ruflet
|
|
|
328
577
|
invoke(url_launcher, "can_launch_url", args: { "url" => url }, timeout: timeout)
|
|
329
578
|
end
|
|
330
579
|
|
|
580
|
+
def close_in_app_web_view(timeout: 10, on_result: nil)
|
|
581
|
+
url_launcher = ensure_url_launcher_service
|
|
582
|
+
invoke(url_launcher, "close_in_app_web_view", timeout: timeout, on_result: on_result)
|
|
583
|
+
end
|
|
584
|
+
|
|
585
|
+
def open_window(url, title: nil, width: nil, height: nil, timeout: 10, on_result: nil)
|
|
586
|
+
url_launcher = ensure_url_launcher_service
|
|
587
|
+
args = { "url" => url }
|
|
588
|
+
args["title"] = title unless title.nil?
|
|
589
|
+
args["width"] = width unless width.nil?
|
|
590
|
+
args["height"] = height unless height.nil?
|
|
591
|
+
invoke(url_launcher, "open_window", args: args, timeout: timeout, on_result: on_result)
|
|
592
|
+
end
|
|
593
|
+
|
|
594
|
+
def supports_launch_mode(mode, timeout: 10, on_result: nil)
|
|
595
|
+
url_launcher = ensure_url_launcher_service
|
|
596
|
+
invoke(url_launcher, "supports_launch_mode", args: { "mode" => mode }, timeout: timeout, on_result: on_result)
|
|
597
|
+
end
|
|
598
|
+
|
|
599
|
+
def supports_close_for_launch_mode(mode, timeout: 10, on_result: nil)
|
|
600
|
+
url_launcher = ensure_url_launcher_service
|
|
601
|
+
invoke(url_launcher, "supports_close_for_launch_mode", args: { "mode" => mode }, timeout: timeout, on_result: on_result)
|
|
602
|
+
end
|
|
603
|
+
|
|
331
604
|
# File picker helpers: create an ephemeral service, invoke method, and dispose it.
|
|
332
605
|
def pick_files(
|
|
333
606
|
dialog_title: nil,
|
|
@@ -341,14 +614,14 @@ module Ruflet
|
|
|
341
614
|
)
|
|
342
615
|
invoke_file_picker(
|
|
343
616
|
"pick_files",
|
|
344
|
-
|
|
617
|
+
compact_service_args(
|
|
345
618
|
"dialog_title" => dialog_title,
|
|
346
619
|
"initial_directory" => initial_directory,
|
|
347
620
|
"file_type" => file_type,
|
|
348
621
|
"allowed_extensions" => allowed_extensions,
|
|
349
622
|
"allow_multiple" => allow_multiple,
|
|
350
623
|
"with_data" => with_data
|
|
351
|
-
|
|
624
|
+
),
|
|
352
625
|
timeout: timeout,
|
|
353
626
|
on_result: on_result
|
|
354
627
|
)
|
|
@@ -366,14 +639,14 @@ module Ruflet
|
|
|
366
639
|
)
|
|
367
640
|
invoke_file_picker(
|
|
368
641
|
"save_file",
|
|
369
|
-
|
|
642
|
+
compact_service_args(
|
|
370
643
|
"dialog_title" => dialog_title,
|
|
371
644
|
"file_name" => file_name,
|
|
372
645
|
"initial_directory" => initial_directory,
|
|
373
646
|
"file_type" => file_type,
|
|
374
647
|
"allowed_extensions" => allowed_extensions,
|
|
375
648
|
"src_bytes" => src_bytes
|
|
376
|
-
|
|
649
|
+
),
|
|
377
650
|
timeout: timeout,
|
|
378
651
|
on_result: on_result
|
|
379
652
|
)
|
|
@@ -382,18 +655,212 @@ module Ruflet
|
|
|
382
655
|
def get_directory_path(dialog_title: nil, initial_directory: nil, timeout: nil, on_result: nil)
|
|
383
656
|
invoke_file_picker(
|
|
384
657
|
"get_directory_path",
|
|
385
|
-
|
|
658
|
+
compact_service_args(
|
|
386
659
|
"dialog_title" => dialog_title,
|
|
387
660
|
"initial_directory" => initial_directory
|
|
388
|
-
|
|
661
|
+
),
|
|
662
|
+
timeout: timeout,
|
|
663
|
+
on_result: on_result
|
|
664
|
+
)
|
|
665
|
+
end
|
|
666
|
+
|
|
667
|
+
def upload(files, timeout: nil, on_result: nil)
|
|
668
|
+
invoke_file_picker(
|
|
669
|
+
"upload",
|
|
670
|
+
{ "files" => Array(files).map { |file| normalize_service_value(file) } },
|
|
671
|
+
timeout: timeout,
|
|
672
|
+
on_result: on_result
|
|
673
|
+
)
|
|
674
|
+
end
|
|
675
|
+
|
|
676
|
+
def upload_files(files, timeout: nil, on_result: nil)
|
|
677
|
+
upload(files, timeout: timeout, on_result: on_result)
|
|
678
|
+
end
|
|
679
|
+
|
|
680
|
+
def disable_browser_context_menu(timeout: 10, on_result: nil)
|
|
681
|
+
invoke_browser_context_menu("disable_menu", timeout: timeout, on_result: on_result)
|
|
682
|
+
end
|
|
683
|
+
|
|
684
|
+
def enable_browser_context_menu(timeout: 10, on_result: nil)
|
|
685
|
+
invoke_browser_context_menu("enable_menu", timeout: timeout, on_result: on_result)
|
|
686
|
+
end
|
|
687
|
+
|
|
688
|
+
def wait_until_ready_to_show(timeout: 10, on_result: nil)
|
|
689
|
+
invoke_window("wait_until_ready_to_show", timeout: timeout, on_result: on_result)
|
|
690
|
+
end
|
|
691
|
+
|
|
692
|
+
def window_to_front(timeout: 10, on_result: nil)
|
|
693
|
+
invoke_window("to_front", timeout: timeout, on_result: on_result)
|
|
694
|
+
end
|
|
695
|
+
|
|
696
|
+
def center_window(timeout: 10, on_result: nil)
|
|
697
|
+
invoke_window("center", timeout: timeout, on_result: on_result)
|
|
698
|
+
end
|
|
699
|
+
|
|
700
|
+
def close_window(timeout: 10, on_result: nil)
|
|
701
|
+
invoke_window("close", timeout: timeout, on_result: on_result)
|
|
702
|
+
end
|
|
703
|
+
|
|
704
|
+
def destroy_window(timeout: 10, on_result: nil)
|
|
705
|
+
invoke_window("destroy", timeout: timeout, on_result: on_result)
|
|
706
|
+
end
|
|
707
|
+
|
|
708
|
+
def start_window_dragging(timeout: 10, on_result: nil)
|
|
709
|
+
invoke_window("start_dragging", timeout: timeout, on_result: on_result)
|
|
710
|
+
end
|
|
711
|
+
|
|
712
|
+
def start_window_resizing(edge, timeout: 10, on_result: nil)
|
|
713
|
+
invoke_window(
|
|
714
|
+
"start_resizing",
|
|
715
|
+
args: { "edge" => normalize_service_value(edge) },
|
|
716
|
+
timeout: timeout,
|
|
717
|
+
on_result: on_result
|
|
718
|
+
)
|
|
719
|
+
end
|
|
720
|
+
|
|
721
|
+
def tester_pump(options = nil, duration: nil, timeout: 10, on_result: nil)
|
|
722
|
+
duration = options[:duration] || options["duration"] if options.is_a?(Hash) && duration.nil?
|
|
723
|
+
invoke_tester("pump", args: compact_service_args("duration" => duration), timeout: timeout, on_result: on_result)
|
|
724
|
+
end
|
|
725
|
+
|
|
726
|
+
def tester_pump_and_settle(options = nil, duration: nil, timeout: 10, on_result: nil)
|
|
727
|
+
duration = options[:duration] || options["duration"] if options.is_a?(Hash) && duration.nil?
|
|
728
|
+
invoke_tester("pump_and_settle", args: compact_service_args("duration" => duration), timeout: timeout, on_result: on_result)
|
|
729
|
+
end
|
|
730
|
+
|
|
731
|
+
def find_by_text(text, timeout: 10, on_result: nil)
|
|
732
|
+
invoke_tester("find_by_text", args: { "text" => text }, timeout: timeout, on_result: on_result)
|
|
733
|
+
end
|
|
734
|
+
|
|
735
|
+
def find_by_text_containing(pattern, timeout: 10, on_result: nil)
|
|
736
|
+
invoke_tester("find_by_text_containing", args: { "pattern" => pattern }, timeout: timeout, on_result: on_result)
|
|
737
|
+
end
|
|
738
|
+
|
|
739
|
+
def find_by_key(key, timeout: 10, on_result: nil)
|
|
740
|
+
invoke_tester("find_by_key", args: { "key" => key }, timeout: timeout, on_result: on_result)
|
|
741
|
+
end
|
|
742
|
+
|
|
743
|
+
def find_by_tooltip(value, timeout: 10, on_result: nil)
|
|
744
|
+
invoke_tester("find_by_tooltip", args: { "value" => value }, timeout: timeout, on_result: on_result)
|
|
745
|
+
end
|
|
746
|
+
|
|
747
|
+
def find_by_icon(icon, timeout: 10, on_result: nil)
|
|
748
|
+
invoke_tester("find_by_icon", args: { "icon" => normalize_service_value(icon) }, timeout: timeout, on_result: on_result)
|
|
749
|
+
end
|
|
750
|
+
|
|
751
|
+
def take_screenshot(name, timeout: 10, on_result: nil)
|
|
752
|
+
invoke_tester("take_screenshot", args: { "name" => name }, timeout: timeout, on_result: on_result)
|
|
753
|
+
end
|
|
754
|
+
|
|
755
|
+
def tap(finder_id = nil, options = nil, finder_index: nil, timeout: 10, on_result: nil)
|
|
756
|
+
finder_index = options[:finder_index] || options["finder_index"] if options.is_a?(Hash) && finder_index.nil?
|
|
757
|
+
invoke_tester_finder("tap", finder_id, finder_index: finder_index, timeout: timeout, on_result: on_result)
|
|
758
|
+
end
|
|
759
|
+
|
|
760
|
+
def mouse_click(finder_id = nil, options = nil, finder_index: nil, timeout: 10, on_result: nil)
|
|
761
|
+
finder_index = options[:finder_index] || options["finder_index"] if options.is_a?(Hash) && finder_index.nil?
|
|
762
|
+
invoke_tester_finder("mouse_click", finder_id, finder_index: finder_index, timeout: timeout, on_result: on_result)
|
|
763
|
+
end
|
|
764
|
+
|
|
765
|
+
def mouse_double_click(finder_id = nil, options = nil, finder_index: nil, timeout: 10, on_result: nil)
|
|
766
|
+
finder_index = options[:finder_index] || options["finder_index"] if options.is_a?(Hash) && finder_index.nil?
|
|
767
|
+
invoke_tester_finder("mouse_double_click", finder_id, finder_index: finder_index, timeout: timeout, on_result: on_result)
|
|
768
|
+
end
|
|
769
|
+
|
|
770
|
+
def right_mouse_click(finder_id = nil, options = nil, finder_index: nil, timeout: 10, on_result: nil)
|
|
771
|
+
finder_index = options[:finder_index] || options["finder_index"] if options.is_a?(Hash) && finder_index.nil?
|
|
772
|
+
invoke_tester_finder("right_mouse_click", finder_id, finder_index: finder_index, timeout: timeout, on_result: on_result)
|
|
773
|
+
end
|
|
774
|
+
|
|
775
|
+
def tap_at(offset = nil, timeout: 10, on_result: nil)
|
|
776
|
+
invoke_tester_at("tap_at", offset, timeout: timeout, on_result: on_result)
|
|
777
|
+
end
|
|
778
|
+
|
|
779
|
+
def mouse_click_at(offset = nil, timeout: 10, on_result: nil)
|
|
780
|
+
invoke_tester_at("mouse_click_at", offset, timeout: timeout, on_result: on_result)
|
|
781
|
+
end
|
|
782
|
+
|
|
783
|
+
def mouse_double_click_at(offset = nil, timeout: 10, on_result: nil)
|
|
784
|
+
invoke_tester_at("mouse_double_click_at", offset, timeout: timeout, on_result: on_result)
|
|
785
|
+
end
|
|
786
|
+
|
|
787
|
+
def right_mouse_click_at(offset = nil, timeout: 10, on_result: nil)
|
|
788
|
+
invoke_tester_at("right_mouse_click_at", offset, timeout: timeout, on_result: on_result)
|
|
789
|
+
end
|
|
790
|
+
|
|
791
|
+
def drag(finder_id, offset, finder_index: nil, timeout: 10, on_result: nil)
|
|
792
|
+
invoke_tester(
|
|
793
|
+
"drag",
|
|
794
|
+
args: compact_service_args(
|
|
795
|
+
"finder_id" => finder_id,
|
|
796
|
+
"finder_index" => finder_index,
|
|
797
|
+
"offset" => offset
|
|
798
|
+
),
|
|
389
799
|
timeout: timeout,
|
|
390
800
|
on_result: on_result
|
|
391
801
|
)
|
|
392
802
|
end
|
|
393
803
|
|
|
804
|
+
def drag_from(start, offset, timeout: 10, on_result: nil)
|
|
805
|
+
invoke_tester(
|
|
806
|
+
"drag_from",
|
|
807
|
+
args: compact_service_args("start" => start, "offset" => offset),
|
|
808
|
+
timeout: timeout,
|
|
809
|
+
on_result: on_result
|
|
810
|
+
)
|
|
811
|
+
end
|
|
812
|
+
|
|
813
|
+
def long_press(finder_id = nil, options = nil, finder_index: nil, timeout: 10, on_result: nil)
|
|
814
|
+
finder_index = options[:finder_index] || options["finder_index"] if options.is_a?(Hash) && finder_index.nil?
|
|
815
|
+
invoke_tester_finder("long_press", finder_id, finder_index: finder_index, timeout: timeout, on_result: on_result)
|
|
816
|
+
end
|
|
817
|
+
|
|
818
|
+
def enter_text(finder_id, text, options = nil, finder_index: nil, timeout: 10, on_result: nil)
|
|
819
|
+
finder_index = options[:finder_index] || options["finder_index"] if options.is_a?(Hash) && finder_index.nil?
|
|
820
|
+
invoke_tester(
|
|
821
|
+
"enter_text",
|
|
822
|
+
args: compact_service_args(
|
|
823
|
+
"finder_id" => finder_id,
|
|
824
|
+
"finder_index" => finder_index,
|
|
825
|
+
"text" => text
|
|
826
|
+
),
|
|
827
|
+
timeout: timeout,
|
|
828
|
+
on_result: on_result
|
|
829
|
+
)
|
|
830
|
+
end
|
|
831
|
+
|
|
832
|
+
def mouse_hover(finder_id = nil, options = nil, finder_index: nil, timeout: 10, on_result: nil)
|
|
833
|
+
finder_index = options[:finder_index] || options["finder_index"] if options.is_a?(Hash) && finder_index.nil?
|
|
834
|
+
invoke_tester_finder("mouse_hover", finder_id, finder_index: finder_index, timeout: timeout, on_result: on_result)
|
|
835
|
+
end
|
|
836
|
+
|
|
837
|
+
def tester_teardown(timeout: 10, on_result: nil)
|
|
838
|
+
invoke_tester("teardown", timeout: timeout, on_result: on_result)
|
|
839
|
+
end
|
|
840
|
+
|
|
841
|
+
def heavy_impact(timeout: 10, on_result: nil)
|
|
842
|
+
invoke_haptic_feedback("heavy_impact", timeout: timeout, on_result: on_result)
|
|
843
|
+
end
|
|
844
|
+
|
|
845
|
+
def medium_impact(timeout: 10, on_result: nil)
|
|
846
|
+
invoke_haptic_feedback("medium_impact", timeout: timeout, on_result: on_result)
|
|
847
|
+
end
|
|
848
|
+
|
|
849
|
+
def light_impact(timeout: 10, on_result: nil)
|
|
850
|
+
invoke_haptic_feedback("light_impact", timeout: timeout, on_result: on_result)
|
|
851
|
+
end
|
|
852
|
+
|
|
853
|
+
def selection_click(timeout: 10, on_result: nil)
|
|
854
|
+
invoke_haptic_feedback("selection_click", timeout: timeout, on_result: on_result)
|
|
855
|
+
end
|
|
856
|
+
|
|
857
|
+
def vibrate(timeout: 10, on_result: nil)
|
|
858
|
+
invoke_haptic_feedback("vibrate", timeout: timeout, on_result: on_result)
|
|
859
|
+
end
|
|
860
|
+
|
|
394
861
|
def set_clipboard(value, timeout: nil, on_result: nil)
|
|
395
862
|
invoke_clipboard_method(
|
|
396
|
-
"
|
|
863
|
+
"set",
|
|
397
864
|
args: { "data" => value.to_s },
|
|
398
865
|
timeout: timeout,
|
|
399
866
|
on_result: on_result
|
|
@@ -401,7 +868,7 @@ module Ruflet
|
|
|
401
868
|
end
|
|
402
869
|
|
|
403
870
|
def get_clipboard(timeout: nil, on_result: nil)
|
|
404
|
-
invoke_clipboard_method("
|
|
871
|
+
invoke_clipboard_method("get", timeout: timeout, on_result: on_result)
|
|
405
872
|
end
|
|
406
873
|
|
|
407
874
|
def set_clipboard_files(files, timeout: nil, on_result: nil)
|
|
@@ -442,10 +909,94 @@ module Ruflet
|
|
|
442
909
|
invoke_battery_method("get_battery_state", timeout: timeout, on_result: on_result)
|
|
443
910
|
end
|
|
444
911
|
|
|
445
|
-
def
|
|
912
|
+
def is_in_battery_save_mode(timeout: nil, on_result: nil)
|
|
446
913
|
invoke_battery_method("is_in_battery_save_mode", timeout: timeout, on_result: on_result)
|
|
447
914
|
end
|
|
448
915
|
|
|
916
|
+
def battery_save_mode?(timeout: nil, on_result: nil)
|
|
917
|
+
is_in_battery_save_mode(timeout: timeout, on_result: on_result)
|
|
918
|
+
end
|
|
919
|
+
|
|
920
|
+
def accelerometer(**props)
|
|
921
|
+
service(:accelerometer, **props)
|
|
922
|
+
end
|
|
923
|
+
|
|
924
|
+
def gyroscope(**props)
|
|
925
|
+
service(:gyroscope, **props)
|
|
926
|
+
end
|
|
927
|
+
|
|
928
|
+
def user_accelerometer(**props)
|
|
929
|
+
service(:user_accelerometer, **props)
|
|
930
|
+
end
|
|
931
|
+
|
|
932
|
+
def magnetometer(**props)
|
|
933
|
+
service(:magnetometer, **props)
|
|
934
|
+
end
|
|
935
|
+
|
|
936
|
+
def barometer(**props)
|
|
937
|
+
service(:barometer, **props)
|
|
938
|
+
end
|
|
939
|
+
|
|
940
|
+
def shake_detector(**props)
|
|
941
|
+
service(:shake_detector, **props)
|
|
942
|
+
end
|
|
943
|
+
|
|
944
|
+
def semantics_service(**props)
|
|
945
|
+
service(:semantics_service, **props)
|
|
946
|
+
end
|
|
947
|
+
|
|
948
|
+
def screenshot(**props)
|
|
949
|
+
service(:screenshot, **props)
|
|
950
|
+
end
|
|
951
|
+
|
|
952
|
+
def battery(**props)
|
|
953
|
+
service(:battery, **props)
|
|
954
|
+
end
|
|
955
|
+
|
|
956
|
+
def connectivity(**props)
|
|
957
|
+
service(:connectivity, **props)
|
|
958
|
+
end
|
|
959
|
+
|
|
960
|
+
def clipboard(**props)
|
|
961
|
+
service(:clipboard, **props)
|
|
962
|
+
end
|
|
963
|
+
|
|
964
|
+
def file_picker(**props)
|
|
965
|
+
service(:file_picker, **props)
|
|
966
|
+
end
|
|
967
|
+
|
|
968
|
+
def url_launcher(**props)
|
|
969
|
+
service(:url_launcher, **props)
|
|
970
|
+
end
|
|
971
|
+
|
|
972
|
+
def storage_paths(**props)
|
|
973
|
+
service(:storage_paths, **props)
|
|
974
|
+
end
|
|
975
|
+
|
|
976
|
+
def share(**props)
|
|
977
|
+
service(:share, **props)
|
|
978
|
+
end
|
|
979
|
+
|
|
980
|
+
def camera(**props)
|
|
981
|
+
service(:camera, **props)
|
|
982
|
+
end
|
|
983
|
+
|
|
984
|
+
def haptic_feedback(**props)
|
|
985
|
+
service(:haptic_feedback, **props)
|
|
986
|
+
end
|
|
987
|
+
|
|
988
|
+
def geolocator(**props)
|
|
989
|
+
service(:geolocator, **props)
|
|
990
|
+
end
|
|
991
|
+
|
|
992
|
+
def permission_handler(**props)
|
|
993
|
+
service(:permission_handler, **props)
|
|
994
|
+
end
|
|
995
|
+
|
|
996
|
+
def secure_storage(**props)
|
|
997
|
+
service(:secure_storage, **props)
|
|
998
|
+
end
|
|
999
|
+
|
|
449
1000
|
def get_application_cache_directory(timeout: nil, on_result: nil)
|
|
450
1001
|
invoke_storage_paths("get_application_cache_directory", timeout: timeout, on_result: on_result)
|
|
451
1002
|
end
|
|
@@ -487,7 +1038,7 @@ module Ruflet
|
|
|
487
1038
|
end
|
|
488
1039
|
|
|
489
1040
|
def share_text(
|
|
490
|
-
text
|
|
1041
|
+
text = nil,
|
|
491
1042
|
title: nil,
|
|
492
1043
|
subject: nil,
|
|
493
1044
|
preview_thumbnail: nil,
|
|
@@ -502,7 +1053,7 @@ module Ruflet
|
|
|
502
1053
|
invoke(
|
|
503
1054
|
share,
|
|
504
1055
|
"share_text",
|
|
505
|
-
args:
|
|
1056
|
+
args: compact_service_args(
|
|
506
1057
|
"text" => text,
|
|
507
1058
|
"title" => title,
|
|
508
1059
|
"subject" => subject,
|
|
@@ -511,14 +1062,14 @@ module Ruflet
|
|
|
511
1062
|
"download_fallback_enabled" => download_fallback_enabled,
|
|
512
1063
|
"mail_to_fallback_enabled" => mail_to_fallback_enabled,
|
|
513
1064
|
"excluded_cupertino_activities" => excluded_cupertino_activities
|
|
514
|
-
|
|
1065
|
+
),
|
|
515
1066
|
timeout: timeout,
|
|
516
1067
|
on_result: on_result
|
|
517
1068
|
)
|
|
518
1069
|
end
|
|
519
1070
|
|
|
520
1071
|
def share_uri(
|
|
521
|
-
uri
|
|
1072
|
+
uri = nil,
|
|
522
1073
|
share_position_origin: nil,
|
|
523
1074
|
excluded_cupertino_activities: nil,
|
|
524
1075
|
timeout: nil,
|
|
@@ -528,18 +1079,18 @@ module Ruflet
|
|
|
528
1079
|
invoke(
|
|
529
1080
|
share,
|
|
530
1081
|
"share_uri",
|
|
531
|
-
args:
|
|
1082
|
+
args: compact_service_args(
|
|
532
1083
|
"uri" => uri,
|
|
533
1084
|
"share_position_origin" => share_position_origin,
|
|
534
1085
|
"excluded_cupertino_activities" => excluded_cupertino_activities
|
|
535
|
-
|
|
1086
|
+
),
|
|
536
1087
|
timeout: timeout,
|
|
537
1088
|
on_result: on_result
|
|
538
1089
|
)
|
|
539
1090
|
end
|
|
540
1091
|
|
|
541
1092
|
def share_files(
|
|
542
|
-
files
|
|
1093
|
+
files = nil,
|
|
543
1094
|
text: nil,
|
|
544
1095
|
title: nil,
|
|
545
1096
|
subject: nil,
|
|
@@ -555,17 +1106,17 @@ module Ruflet
|
|
|
555
1106
|
invoke(
|
|
556
1107
|
share,
|
|
557
1108
|
"share_files",
|
|
558
|
-
args:
|
|
559
|
-
"files" => files,
|
|
1109
|
+
args: compact_service_args(
|
|
1110
|
+
"files" => normalize_share_files(files),
|
|
560
1111
|
"text" => text,
|
|
561
1112
|
"title" => title,
|
|
562
1113
|
"subject" => subject,
|
|
563
|
-
"preview_thumbnail" => preview_thumbnail,
|
|
1114
|
+
"preview_thumbnail" => normalize_share_file(preview_thumbnail),
|
|
564
1115
|
"share_position_origin" => share_position_origin,
|
|
565
1116
|
"download_fallback_enabled" => download_fallback_enabled,
|
|
566
1117
|
"mail_to_fallback_enabled" => mail_to_fallback_enabled,
|
|
567
1118
|
"excluded_cupertino_activities" => excluded_cupertino_activities
|
|
568
|
-
|
|
1119
|
+
),
|
|
569
1120
|
timeout: timeout,
|
|
570
1121
|
on_result: on_result
|
|
571
1122
|
)
|
|
@@ -675,6 +1226,7 @@ module Ruflet
|
|
|
675
1226
|
return unless control
|
|
676
1227
|
|
|
677
1228
|
event = Event.new(name: name, target: target, raw_data: data, page: self, control: control)
|
|
1229
|
+
apply_event_value_to_control(control, event) if %w[change select select_change].include?(name.to_s)
|
|
678
1230
|
control.emit(name, event)
|
|
679
1231
|
|
|
680
1232
|
if name.to_s == "dismiss" && remove_dialog_tracking(control)
|
|
@@ -754,10 +1306,56 @@ module Ruflet
|
|
|
754
1306
|
|
|
755
1307
|
def build_widget(type, **props, &block) = WidgetBuilder.new.control(type, **props, &block)
|
|
756
1308
|
|
|
1309
|
+
def compact_service_args(hash)
|
|
1310
|
+
hash.each_with_object({}) do |(key, value), result|
|
|
1311
|
+
result[key] = normalize_service_value(value) unless value.nil?
|
|
1312
|
+
end
|
|
1313
|
+
end
|
|
1314
|
+
|
|
1315
|
+
def normalize_service_value(value)
|
|
1316
|
+
case value
|
|
1317
|
+
when Array
|
|
1318
|
+
value.map { |item| normalize_service_value(item) }
|
|
1319
|
+
when Hash
|
|
1320
|
+
value.transform_keys(&:to_s).each_with_object({}) do |(key, item), result|
|
|
1321
|
+
next if item.nil?
|
|
1322
|
+
|
|
1323
|
+
result[key] = key == "data" && byte_array?(item) ? item.pack("C*").b : normalize_service_value(item)
|
|
1324
|
+
end
|
|
1325
|
+
else
|
|
1326
|
+
value
|
|
1327
|
+
end
|
|
1328
|
+
end
|
|
1329
|
+
|
|
1330
|
+
def normalize_share_files(files)
|
|
1331
|
+
return nil if files.nil?
|
|
1332
|
+
|
|
1333
|
+
Array(files).map { |file| normalize_share_file(file) }
|
|
1334
|
+
end
|
|
1335
|
+
|
|
1336
|
+
def normalize_share_file(file)
|
|
1337
|
+
case file
|
|
1338
|
+
when nil
|
|
1339
|
+
nil
|
|
1340
|
+
when String
|
|
1341
|
+
{ "path" => file }
|
|
1342
|
+
else
|
|
1343
|
+
normalize_service_value(file)
|
|
1344
|
+
end
|
|
1345
|
+
end
|
|
1346
|
+
|
|
1347
|
+
def byte_array?(value)
|
|
1348
|
+
value.is_a?(Array) && value.all? { |item| item.is_a?(Integer) && item.between?(0, 255) }
|
|
1349
|
+
end
|
|
1350
|
+
|
|
757
1351
|
def widget_helper_method?(name)
|
|
758
1352
|
WIDGET_HELPER_METHODS.include?(name.to_s)
|
|
759
1353
|
end
|
|
760
1354
|
|
|
1355
|
+
def visual_service_type?(type)
|
|
1356
|
+
type.to_s.delete("_") == "camera"
|
|
1357
|
+
end
|
|
1358
|
+
|
|
761
1359
|
def text_maps_to_content?(control, patch)
|
|
762
1360
|
patch.key?("text") && control.type.end_with?("button")
|
|
763
1361
|
end
|
|
@@ -785,6 +1383,7 @@ module Ruflet
|
|
|
785
1383
|
*page_patch_ops
|
|
786
1384
|
]
|
|
787
1385
|
})
|
|
1386
|
+
@services_container_mounted = true if @services_container.wire_id
|
|
788
1387
|
end
|
|
789
1388
|
|
|
790
1389
|
def register_control_tree(control, visited = Set.new)
|
|
@@ -895,6 +1494,15 @@ module Ruflet
|
|
|
895
1494
|
"#{base}#{separator}#{query}"
|
|
896
1495
|
end
|
|
897
1496
|
|
|
1497
|
+
def parse_query(route_value)
|
|
1498
|
+
query_string = route_value.to_s.split("?", 2)[1].to_s
|
|
1499
|
+
return {} if query_string.empty?
|
|
1500
|
+
|
|
1501
|
+
CGI.parse(query_string).each_with_object({}) do |(key, values), result|
|
|
1502
|
+
result[key] = values.size == 1 ? values.first : values
|
|
1503
|
+
end
|
|
1504
|
+
end
|
|
1505
|
+
|
|
898
1506
|
def extract_route(data)
|
|
899
1507
|
case data
|
|
900
1508
|
when String
|
|
@@ -910,10 +1518,46 @@ module Ruflet
|
|
|
910
1518
|
handler = @page_event_handlers[name.to_s.sub(/\Aon_/, "")]
|
|
911
1519
|
return unless handler.respond_to?(:call)
|
|
912
1520
|
|
|
913
|
-
event = Event.new(name: name.to_s, target: 1, raw_data: data, page: self, control: nil)
|
|
1521
|
+
event = Ruflet::Event.new(name: name.to_s, target: 1, raw_data: data, page: self, control: nil)
|
|
914
1522
|
handler.call(event)
|
|
915
1523
|
end
|
|
916
1524
|
|
|
1525
|
+
def apply_event_value_to_control(control, event)
|
|
1526
|
+
return unless event.typed_data && event.typed_data.respond_to?(:value)
|
|
1527
|
+
|
|
1528
|
+
value = event.typed_data.value
|
|
1529
|
+
if control.props.key?("start_value") && control.props.key?("end_value")
|
|
1530
|
+
raw = event.typed_data.respond_to?(:raw) ? event.typed_data.raw : event.data
|
|
1531
|
+
range_value = value.is_a?(Hash) ? value : raw
|
|
1532
|
+
if range_value.is_a?(Hash)
|
|
1533
|
+
start_value = range_value["start_value"] || range_value[:start_value]
|
|
1534
|
+
end_value = range_value["end_value"] || range_value[:end_value]
|
|
1535
|
+
control.props["start_value"] = start_value unless start_value.nil?
|
|
1536
|
+
control.props["end_value"] = end_value unless end_value.nil?
|
|
1537
|
+
return
|
|
1538
|
+
end
|
|
1539
|
+
end
|
|
1540
|
+
|
|
1541
|
+
return if value.nil?
|
|
1542
|
+
return if control.type == "selectionarea"
|
|
1543
|
+
|
|
1544
|
+
prop_name =
|
|
1545
|
+
if event.name == "select"
|
|
1546
|
+
control.props.key?("value") ? "value" : "selected"
|
|
1547
|
+
elsif event.name == "select_change" && control.props.key?("selected")
|
|
1548
|
+
"selected"
|
|
1549
|
+
elsif control.props.key?("expanded")
|
|
1550
|
+
"expanded"
|
|
1551
|
+
elsif control.props.key?("selected")
|
|
1552
|
+
"selected"
|
|
1553
|
+
elsif control.props.key?("selected_index")
|
|
1554
|
+
"selected_index"
|
|
1555
|
+
else
|
|
1556
|
+
"value"
|
|
1557
|
+
end
|
|
1558
|
+
control.props[prop_name] = value
|
|
1559
|
+
end
|
|
1560
|
+
|
|
917
1561
|
def page_control_target?(control_or_id)
|
|
918
1562
|
control_or_id == 1 || control_or_id.to_s == "1" || control_or_id.to_s == "page"
|
|
919
1563
|
end
|
|
@@ -927,7 +1571,7 @@ module Ruflet
|
|
|
927
1571
|
when Array
|
|
928
1572
|
value.map { |v| serialize_patch_value(v) }
|
|
929
1573
|
when Hash
|
|
930
|
-
value.
|
|
1574
|
+
value.each_with_object({}) { |(k, v), result| result[k.to_s] = serialize_patch_value(v) }
|
|
931
1575
|
else
|
|
932
1576
|
value
|
|
933
1577
|
end
|
|
@@ -1026,200 +1670,231 @@ module Ruflet
|
|
|
1026
1670
|
# same IDs and detach service invoke listeners on the Flutter side.
|
|
1027
1671
|
next nil if k == "_overlay" && @overlay_container.wire_id
|
|
1028
1672
|
next nil if k == "_dialogs" && @dialogs_container.wire_id
|
|
1673
|
+
next nil if k == "_services" && @services_container_mounted
|
|
1029
1674
|
|
|
1030
1675
|
[0, 0, k, serialize_patch_value(v)]
|
|
1031
1676
|
end
|
|
1032
1677
|
end
|
|
1033
1678
|
|
|
1034
|
-
def
|
|
1035
|
-
|
|
1036
|
-
|
|
1679
|
+
def service_by_type(type)
|
|
1680
|
+
compact_type = type.to_s.downcase.delete("_")
|
|
1681
|
+
services.find do |service|
|
|
1682
|
+
service.is_a?(Control) && service.type.to_s.downcase.delete("_") == compact_type
|
|
1683
|
+
end
|
|
1684
|
+
end
|
|
1685
|
+
|
|
1686
|
+
def service_with_created(type)
|
|
1687
|
+
existing = service_by_type(type)
|
|
1688
|
+
return [existing, false] if existing
|
|
1689
|
+
|
|
1690
|
+
[service(type), true]
|
|
1691
|
+
end
|
|
1037
1692
|
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
[clipboard, true]
|
|
1693
|
+
def ensure_clipboard_service
|
|
1694
|
+
service_with_created(:clipboard)
|
|
1041
1695
|
end
|
|
1042
1696
|
|
|
1043
1697
|
def invoke_clipboard_method(method_name, args: nil, timeout:, on_result:)
|
|
1044
|
-
clipboard,
|
|
1045
|
-
send_view_patch if created
|
|
1046
|
-
sleep(0.05) if created
|
|
1698
|
+
clipboard, = ensure_clipboard_service
|
|
1047
1699
|
invoke(
|
|
1048
1700
|
clipboard,
|
|
1049
1701
|
method_name,
|
|
1050
1702
|
args: args,
|
|
1051
1703
|
timeout: timeout,
|
|
1052
|
-
on_result:
|
|
1053
|
-
message = error.to_s
|
|
1054
|
-
if message.include?("inexistent control")
|
|
1055
|
-
remove_service(clipboard)
|
|
1056
|
-
fresh_clipboard, = ensure_clipboard_service
|
|
1057
|
-
sleep(0.08)
|
|
1058
|
-
invoke(
|
|
1059
|
-
fresh_clipboard,
|
|
1060
|
-
method_name,
|
|
1061
|
-
args: args,
|
|
1062
|
-
timeout: timeout,
|
|
1063
|
-
on_result: on_result
|
|
1064
|
-
)
|
|
1065
|
-
else
|
|
1066
|
-
on_result&.call(result, error)
|
|
1067
|
-
end
|
|
1068
|
-
}
|
|
1704
|
+
on_result: on_result
|
|
1069
1705
|
)
|
|
1070
1706
|
rescue StandardError => e
|
|
1071
1707
|
on_result&.call(nil, e.message)
|
|
1072
1708
|
end
|
|
1073
1709
|
|
|
1074
1710
|
def ensure_url_launcher_service
|
|
1075
|
-
|
|
1076
|
-
|
|
1711
|
+
service(:url_launcher)
|
|
1712
|
+
end
|
|
1077
1713
|
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
url_launcher
|
|
1714
|
+
def ensure_browser_context_menu_service
|
|
1715
|
+
service(:browser_context_menu)
|
|
1081
1716
|
end
|
|
1082
1717
|
|
|
1083
|
-
def
|
|
1084
|
-
|
|
1085
|
-
|
|
1718
|
+
def invoke_browser_context_menu(method_name, timeout:, on_result:)
|
|
1719
|
+
browser_context_menu = ensure_browser_context_menu_service
|
|
1720
|
+
invoke(browser_context_menu, method_name, timeout: timeout, on_result: on_result)
|
|
1721
|
+
end
|
|
1722
|
+
|
|
1723
|
+
def ensure_window_service
|
|
1724
|
+
service(:window)
|
|
1725
|
+
end
|
|
1726
|
+
|
|
1727
|
+
def invoke_window(method_name, args: nil, timeout:, on_result:)
|
|
1728
|
+
window = ensure_window_service
|
|
1729
|
+
invoke(window, method_name, args: args, timeout: timeout, on_result: on_result)
|
|
1730
|
+
end
|
|
1731
|
+
|
|
1732
|
+
def ensure_tester_service
|
|
1733
|
+
service(:tester)
|
|
1734
|
+
end
|
|
1735
|
+
|
|
1736
|
+
def invoke_tester(method_name, args: nil, timeout:, on_result:)
|
|
1737
|
+
tester = ensure_tester_service
|
|
1738
|
+
invoke(tester, method_name, args: args, timeout: timeout, on_result: on_result)
|
|
1739
|
+
end
|
|
1740
|
+
|
|
1741
|
+
def invoke_tester_finder(method_name, finder_id, finder_index:, timeout:, on_result:)
|
|
1742
|
+
invoke_tester(
|
|
1743
|
+
method_name,
|
|
1744
|
+
args: compact_service_args("finder_id" => finder_id, "finder_index" => finder_index),
|
|
1745
|
+
timeout: timeout,
|
|
1746
|
+
on_result: on_result
|
|
1747
|
+
)
|
|
1748
|
+
end
|
|
1749
|
+
|
|
1750
|
+
def invoke_tester_at(method_name, offset, timeout:, on_result:)
|
|
1751
|
+
invoke_tester(
|
|
1752
|
+
method_name,
|
|
1753
|
+
args: compact_service_args("offset" => offset),
|
|
1754
|
+
timeout: timeout,
|
|
1755
|
+
on_result: on_result
|
|
1756
|
+
)
|
|
1757
|
+
end
|
|
1086
1758
|
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1759
|
+
def ensure_haptic_feedback_service
|
|
1760
|
+
service(:haptic_feedback)
|
|
1761
|
+
end
|
|
1762
|
+
|
|
1763
|
+
def invoke_haptic_feedback(method_name, timeout:, on_result:)
|
|
1764
|
+
haptic_feedback = ensure_haptic_feedback_service
|
|
1765
|
+
invoke(haptic_feedback, method_name, timeout: timeout, on_result: on_result)
|
|
1766
|
+
end
|
|
1767
|
+
|
|
1768
|
+
def invoke_current_view(method_name, timeout:, on_result:)
|
|
1769
|
+
target_id = @views.last&.wire_id || @view_id
|
|
1770
|
+
invoke_control_id(target_id, method_name, timeout: timeout, on_result: on_result)
|
|
1771
|
+
end
|
|
1772
|
+
|
|
1773
|
+
def invoke_control_id(control_id, method_name, args: nil, timeout: 10, on_result: nil)
|
|
1774
|
+
call_id = "call_#{Ruflet::Control.generate_id}"
|
|
1775
|
+
if on_result.respond_to?(:call)
|
|
1776
|
+
@invoke_waiters_mutex.synchronize { @invoke_callbacks[call_id] = on_result }
|
|
1777
|
+
unless timeout.nil?
|
|
1778
|
+
Thread.new(call_id, timeout.to_f) do |pending_call_id, invoke_timeout|
|
|
1779
|
+
sleep([invoke_timeout, 0.0].max + 0.1)
|
|
1780
|
+
callback = @invoke_waiters_mutex.synchronize { @invoke_callbacks.delete(pending_call_id) }
|
|
1781
|
+
callback&.call(nil, "execution expired")
|
|
1782
|
+
rescue StandardError => e
|
|
1783
|
+
Kernel.warn("invoke timeout callback error: #{e.class}: #{e.message}")
|
|
1784
|
+
end
|
|
1785
|
+
end
|
|
1786
|
+
end
|
|
1787
|
+
|
|
1788
|
+
payload = {
|
|
1789
|
+
"control_id" => control_id,
|
|
1790
|
+
"call_id" => call_id,
|
|
1791
|
+
"name" => method_name.to_s,
|
|
1792
|
+
"args" => args
|
|
1793
|
+
}
|
|
1794
|
+
payload["timeout"] = timeout unless timeout.nil?
|
|
1795
|
+
send_message(Protocol::ACTIONS[:invoke_control_method], payload)
|
|
1796
|
+
|
|
1797
|
+
call_id
|
|
1798
|
+
end
|
|
1799
|
+
|
|
1800
|
+
def ensure_connectivity_service
|
|
1801
|
+
service_with_created(:connectivity)
|
|
1090
1802
|
end
|
|
1091
1803
|
|
|
1092
1804
|
def invoke_connectivity_method(method_name, timeout:, on_result:)
|
|
1093
|
-
connectivity,
|
|
1094
|
-
send_view_patch if created
|
|
1095
|
-
sleep(0.05) if created
|
|
1805
|
+
connectivity, = ensure_connectivity_service
|
|
1096
1806
|
invoke(
|
|
1097
1807
|
connectivity,
|
|
1098
1808
|
method_name,
|
|
1099
1809
|
timeout: timeout,
|
|
1100
|
-
on_result:
|
|
1101
|
-
message = error.to_s
|
|
1102
|
-
if message.include?("inexistent control")
|
|
1103
|
-
remove_service(connectivity)
|
|
1104
|
-
fresh_connectivity, = ensure_connectivity_service
|
|
1105
|
-
sleep(0.08)
|
|
1106
|
-
invoke(
|
|
1107
|
-
fresh_connectivity,
|
|
1108
|
-
method_name,
|
|
1109
|
-
timeout: timeout,
|
|
1110
|
-
on_result: on_result
|
|
1111
|
-
)
|
|
1112
|
-
else
|
|
1113
|
-
on_result&.call(result, error)
|
|
1114
|
-
end
|
|
1115
|
-
}
|
|
1810
|
+
on_result: on_result
|
|
1116
1811
|
)
|
|
1117
1812
|
rescue StandardError => e
|
|
1118
1813
|
on_result&.call(nil, e.message)
|
|
1119
1814
|
end
|
|
1120
1815
|
|
|
1121
1816
|
def ensure_battery_service
|
|
1122
|
-
battery
|
|
1123
|
-
return [battery, false] if battery
|
|
1124
|
-
|
|
1125
|
-
battery = build_widget(:battery)
|
|
1126
|
-
add_service(battery)
|
|
1127
|
-
[battery, true]
|
|
1817
|
+
service_with_created(:battery)
|
|
1128
1818
|
end
|
|
1129
1819
|
|
|
1130
1820
|
def ensure_share_service
|
|
1131
|
-
|
|
1132
|
-
|
|
1821
|
+
service(:share)
|
|
1822
|
+
end
|
|
1823
|
+
|
|
1824
|
+
def ensure_shared_preferences_service
|
|
1825
|
+
service(:shared_preferences)
|
|
1826
|
+
end
|
|
1827
|
+
|
|
1828
|
+
def invoke_shared_preferences(method_name, args: nil, timeout:, on_result:)
|
|
1829
|
+
shared_preferences = ensure_shared_preferences_service
|
|
1830
|
+
invoke(shared_preferences, method_name, args: args, timeout: timeout, on_result: on_result)
|
|
1831
|
+
end
|
|
1832
|
+
|
|
1833
|
+
def ensure_wakelock_service
|
|
1834
|
+
service(:wakelock)
|
|
1835
|
+
end
|
|
1836
|
+
|
|
1837
|
+
def invoke_wakelock(method_name, timeout:, on_result:)
|
|
1838
|
+
wakelock = ensure_wakelock_service
|
|
1839
|
+
invoke(wakelock, method_name, timeout: timeout, on_result: on_result)
|
|
1840
|
+
end
|
|
1841
|
+
|
|
1842
|
+
def ensure_flashlight_service
|
|
1843
|
+
service(:flashlight)
|
|
1844
|
+
end
|
|
1845
|
+
|
|
1846
|
+
def invoke_flashlight(method_name, timeout:, on_result:)
|
|
1847
|
+
flashlight = ensure_flashlight_service
|
|
1848
|
+
invoke(flashlight, method_name, timeout: timeout, on_result: on_result)
|
|
1849
|
+
end
|
|
1850
|
+
|
|
1851
|
+
def ensure_screen_brightness_service
|
|
1852
|
+
service(:screen_brightness)
|
|
1853
|
+
end
|
|
1133
1854
|
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1855
|
+
def invoke_screen_brightness(method_name, args: nil, timeout:, on_result:)
|
|
1856
|
+
screen_brightness = ensure_screen_brightness_service
|
|
1857
|
+
invoke(screen_brightness, method_name, args: args, timeout: timeout, on_result: on_result)
|
|
1137
1858
|
end
|
|
1138
1859
|
|
|
1139
1860
|
def invoke_battery_method(method_name, timeout:, on_result:)
|
|
1140
|
-
battery,
|
|
1141
|
-
send_view_patch if created
|
|
1142
|
-
sleep(0.05) if created
|
|
1861
|
+
battery, = ensure_battery_service
|
|
1143
1862
|
invoke(
|
|
1144
1863
|
battery,
|
|
1145
1864
|
method_name,
|
|
1146
1865
|
timeout: timeout,
|
|
1147
|
-
on_result:
|
|
1148
|
-
message = error.to_s
|
|
1149
|
-
if message.include?("inexistent control")
|
|
1150
|
-
remove_service(battery)
|
|
1151
|
-
fresh_battery, = ensure_battery_service
|
|
1152
|
-
sleep(0.08)
|
|
1153
|
-
invoke(
|
|
1154
|
-
fresh_battery,
|
|
1155
|
-
method_name,
|
|
1156
|
-
timeout: timeout,
|
|
1157
|
-
on_result: on_result
|
|
1158
|
-
)
|
|
1159
|
-
else
|
|
1160
|
-
on_result&.call(result, error)
|
|
1161
|
-
end
|
|
1162
|
-
}
|
|
1866
|
+
on_result: on_result
|
|
1163
1867
|
)
|
|
1164
1868
|
rescue StandardError => e
|
|
1165
1869
|
on_result&.call(nil, e.message)
|
|
1166
1870
|
end
|
|
1167
1871
|
|
|
1168
1872
|
def ensure_storage_paths_service
|
|
1169
|
-
storage_paths
|
|
1170
|
-
service.is_a?(Control) && %w[storage_paths storagepaths].include?(service.type.to_s)
|
|
1171
|
-
end
|
|
1172
|
-
return [storage_paths, false] if storage_paths
|
|
1173
|
-
|
|
1174
|
-
storage_paths = build_widget(:storage_paths)
|
|
1175
|
-
add_service(storage_paths)
|
|
1176
|
-
[storage_paths, true]
|
|
1873
|
+
service_with_created(:storage_paths)
|
|
1177
1874
|
end
|
|
1178
1875
|
|
|
1179
1876
|
def invoke_storage_paths(method_name, timeout:, on_result:)
|
|
1180
|
-
storage_paths,
|
|
1181
|
-
send_view_patch if created
|
|
1182
|
-
sleep(0.05) if created
|
|
1877
|
+
storage_paths, = ensure_storage_paths_service
|
|
1183
1878
|
invoke(
|
|
1184
1879
|
storage_paths,
|
|
1185
1880
|
method_name,
|
|
1186
1881
|
timeout: timeout,
|
|
1187
|
-
on_result:
|
|
1188
|
-
message = error.to_s
|
|
1189
|
-
if message.include?("inexistent control")
|
|
1190
|
-
remove_service(storage_paths)
|
|
1191
|
-
fresh_storage_paths, = ensure_storage_paths_service
|
|
1192
|
-
sleep(0.08)
|
|
1193
|
-
invoke(
|
|
1194
|
-
fresh_storage_paths,
|
|
1195
|
-
method_name,
|
|
1196
|
-
timeout: timeout,
|
|
1197
|
-
on_result: on_result
|
|
1198
|
-
)
|
|
1199
|
-
else
|
|
1200
|
-
on_result&.call(result, error)
|
|
1201
|
-
end
|
|
1202
|
-
}
|
|
1882
|
+
on_result: on_result
|
|
1203
1883
|
)
|
|
1204
1884
|
rescue StandardError => e
|
|
1205
1885
|
on_result&.call(nil, e.message)
|
|
1206
1886
|
end
|
|
1207
1887
|
|
|
1208
1888
|
def invoke_file_picker(method_name, args, timeout:, on_result:)
|
|
1209
|
-
picker =
|
|
1210
|
-
add_service(picker)
|
|
1889
|
+
picker = service(:file_picker)
|
|
1211
1890
|
invoke(
|
|
1212
1891
|
picker,
|
|
1213
1892
|
method_name,
|
|
1214
1893
|
args: args,
|
|
1215
1894
|
timeout: timeout,
|
|
1216
|
-
on_result:
|
|
1217
|
-
remove_service(picker)
|
|
1218
|
-
on_result&.call(result, error)
|
|
1219
|
-
}
|
|
1895
|
+
on_result: on_result
|
|
1220
1896
|
)
|
|
1221
1897
|
rescue StandardError => e
|
|
1222
|
-
remove_service(picker) if picker
|
|
1223
1898
|
on_result&.call(nil, e.message)
|
|
1224
1899
|
end
|
|
1225
1900
|
end
|