Module: RubyNative::Helper
- Defined in:
- lib/ruby_native/helper.rb
Defined Under Namespace
Classes: NavbarBuilder, NavbarMenuBuilder
Class Method Summary
collapse
Instance Method Summary
collapse
-
#native_back_button_tag(text = nil, **options) ⇒ Object
-
#native_badge_tag(count = nil, home: nil, tab: nil) ⇒ Object
-
#native_fab_tag(icon: nil, icons: nil, href: nil, click: nil) ⇒ Object
-
#native_form_tag ⇒ Object
-
#native_haptic_data(feedback = :success, **data) ⇒ Object
-
#native_navbar_tag(title = nil, pull_to_refresh: true, &block) ⇒ Object
-
#native_overscroll_tag(top:, bottom: nil) ⇒ Object
-
#native_push_tag ⇒ Object
-
#native_review_tag ⇒ Object
Renders a signal element that asks the app to request an App Store rating from the user.
-
#native_scan_button_tag(label = "Scan", target: nil, event: nil, submit: false, formats: nil, **options) ⇒ Object
Renders a button that opens the native barcode scanner.
-
#native_tabs_tag(enabled: true) ⇒ Object
-
#ruby_native_screenshot_session? ⇒ Boolean
True when the current request is part of a Ruby Native screenshot run.
Class Method Details
.resolve_icon(icon: nil, icons: nil, platform: nil) ⇒ Object
Picks the right icon name for the current native platform. Accepts the
single icon: form (applied to every platform) and/or the icons: hash
form ({ ios: "...", android: "..." }). When both are given, a matching
icons[platform] wins; otherwise falls back to icon. Returns nil when
nothing resolves.
A non-Hash icons: raises rather than falling through. icons: [ios: "...", android: "..."] is an easy slip in ERB and yields an Array holding
one Hash, which used to skip the lookup and fall back to icon — usually
nil, so the button rendered with no icon on either platform and nothing
said why. That reads as "per-platform icons are broken" rather than "wrong
bracket," and it is invisible on whichever platform you aren't testing.
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
|
# File 'lib/ruby_native/helper.rb', line 141
def self.resolve_icon(icon: nil, icons: nil, platform: nil)
if !icons.nil? && !icons.is_a?(Hash)
raise ArgumentError,
"icons: must be a Hash like { ios: \"square.and.arrow.up\", android: \"share\" }, " \
"got #{icons.class}. Check for square brackets instead of curly braces."
end
if icons.is_a?(Hash) && platform
key = platform.to_sym
per_platform = icons[key] || icons[key.to_s]
return per_platform if per_platform
end
icon || fallback_icon(icons)
end
|
Instance Method Details
29
30
31
32
33
34
35
36
|
# File 'lib/ruby_native/helper.rb', line 29
def native_back_button_tag(text = nil, **options)
options[:class] = [options[:class], "native-back-button"].compact.join(" ")
default_content = tag.svg(
tag.path(d: "M15.75 19.5L8.25 12l7.5-7.5", stroke_linecap: "round", stroke_linejoin: "round"),
width: 24, height: 24, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", stroke_width: 2.5
)
tag.button(text || default_content, onclick: "RubyNative.postMessage({action: 'back'})", **options)
end
|
#native_badge_tag(count = nil, home: nil, tab: nil) ⇒ Object
77
78
79
80
81
82
83
84
85
86
|
# File 'lib/ruby_native/helper.rb', line 77
def native_badge_tag(count = nil, home: nil, tab: nil)
home = count if count && home.nil?
tab = count if count && tab.nil?
data = { native_badge: "" }
data[:native_badge_home] = home unless home.nil?
data[:native_badge_tab] = tab unless tab.nil?
tag.div(data: data, hidden: true)
end
|
#native_fab_tag(icon: nil, icons: nil, href: nil, click: nil) ⇒ Object
97
98
99
100
101
102
103
104
|
# File 'lib/ruby_native/helper.rb', line 97
def native_fab_tag(icon: nil, icons: nil, href: nil, click: nil)
resolved = RubyNative::Helper.resolve_icon(icon: icon, icons: icons, platform: try(:native_platform))
raise ArgumentError, "native_fab_tag requires an icon" if resolved.nil?
data = { native_fab: true, native_icon: resolved }
data[:native_href] = href if href
data[:native_click] = click if click
tag.div(data: data, hidden: true)
end
|
21
22
23
|
# File 'lib/ruby_native/helper.rb', line 21
def native_form_tag
tag.div(data: { native_form: true }, hidden: true)
end
|
#native_haptic_data(feedback = :success, **data) ⇒ Object
110
111
112
113
114
115
|
# File 'lib/ruby_native/helper.rb', line 110
def native_haptic_data(feedback = :success, **data)
feedback = feedback.to_s
feedback = "success" if feedback.empty?
data[:native_haptic] = feedback
data
end
|
#native_navbar_tag(title = nil, pull_to_refresh: true, &block) ⇒ Object
88
89
90
91
92
93
94
95
|
# File 'lib/ruby_native/helper.rb', line 88
def native_navbar_tag(title = nil, pull_to_refresh: true, &block)
builder = NavbarBuilder.new(self)
capture(builder, &block) if block
data = { native_navbar: title.to_s }
data[:native_pull_to_refresh] = "false" unless pull_to_refresh
tag.div(data: data, hidden: true) { builder.to_html }
end
|
106
107
108
|
# File 'lib/ruby_native/helper.rb', line 106
def native_overscroll_tag(top:, bottom: nil)
tag.div(data: { native_overscroll_top: top, native_overscroll_bottom: bottom || top }, hidden: true)
end
|
#native_push_tag ⇒ Object
25
26
27
|
# File 'lib/ruby_native/helper.rb', line 25
def native_push_tag
tag.div(data: { native_push: true }, hidden: true)
end
|
#native_review_tag ⇒ Object
Renders a signal element that asks the app to request an App Store
rating from the user. The system decides whether to actually show the
prompt (Apple throttles it to a few times per year), so it is safe to
render this on any page where a review would be welcome, like a
confirmation screen after the user finishes something worthwhile.
See Apple's docs on requesting App Store reviews:
https://developer.apple.com/documentation/storekit/requesting-app-store-reviews
125
126
127
|
# File 'lib/ruby_native/helper.rb', line 125
def native_review_tag
tag.div(data: { native_review: true }, hidden: true)
end
|
Renders a button that opens the native barcode scanner. On a successful
scan the value fills target (a CSS selector) and the page receives a
ruby-native:scan CustomEvent (override the name with event:). Set
submit: true to submit the filled field's form after scanning. Narrow the
accepted codes with formats: (neutral names, e.g. "ean13,upce"); omit it
for a sane default. Renders a plain button on the web (no-op until opened in
the app); wrap in native_app? if it should be hidden there.
<%= native_scan_button_tag "Scan", target: "#isbn" %>
The scanner needs a camera usage description set in your Ruby Native app
settings, or scanning is unavailable in production builds.
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
|
# File 'lib/ruby_native/helper.rb', line 50
def native_scan_button_tag(label = "Scan", target: nil, event: nil, submit: false, formats: nil, **options)
if Rails.env.development?
Rails.logger.warn(
"[ruby_native] native_scan_button_tag needs a camera usage description set in your " \
"Ruby Native app settings, or scanning is unavailable in production builds."
)
end
scan_options = {}
scan_options[:target] = target if target
scan_options[:event] = event if event
scan_options[:submit] = true if submit
if formats
scan_options[:formats] = Array(formats).flat_map { |f| f.to_s.split(",") }.map(&:strip).reject(&:empty?)
end
options[:type] ||= "button"
options[:onclick] = "window.RubyNative?.scan(#{scan_options.to_json})"
tag.button(label, **options)
end
|
#native_tabs_tag(enabled: true) ⇒ Object
16
17
18
19
|
# File 'lib/ruby_native/helper.rb', line 16
def native_tabs_tag(enabled: true)
return "".html_safe unless enabled
tag.div(data: { native_tabs: true }, hidden: true)
end
|
#ruby_native_screenshot_session? ⇒ Boolean
True when the current request is part of a Ruby Native screenshot run.
Use this to render deterministically: freeze relative timestamps, hide
push banners, suppress ads, disable A/B variants, skip notifications.
<% if ruby_native_screenshot_session? %>
Stamped 2 days ago
<% else %>
<%= time_ago_in_words(stamp.created_at) %>
<% end %>
12
13
14
|
# File 'lib/ruby_native/helper.rb', line 12
def ruby_native_screenshot_session?
cookies[:_ruby_native_screenshot_session] == "1"
end
|