ruby_native 0.10.22 → 0.11.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 496fdec9b4bcdbae5f2f27dfd905a6244e8bbd4dd85836fb57ebfc6700b5970f
4
- data.tar.gz: d247c3431ae157b3ea403eb69d8e67be0ef321e65f27df7037f9e054dfa964d1
3
+ metadata.gz: 354cc245f5601b5e39b3cbba720da1fe06edf675eb373e22eb1028b2c27056ce
4
+ data.tar.gz: 38080a8029fbffa2c920cd734196a88377f6b20967b83f9f947eab37835f46c6
5
5
  SHA512:
6
- metadata.gz: af87a22ff1a393673e321fdb40e07ffdb77ee9ff897dc5c8e34cb8c56e78c4fb3ac3aff331248c4141d0c0e24d1013bcb6169fa2e05dc54305efc77ce97b1a30
7
- data.tar.gz: f05c8be56c663316f701cb7586d50709bac9a7d284f1b867e82f71e567679facc870dd02ce2a0d1bd51b012c4bd2fc07b1df2ead0eb9b6e26f22b346c2577439
6
+ metadata.gz: 92f68b9731f743efd5aece5debb221c4963a93b373f9c76997dc688eba4f6da85b3eb3832efa457ebca0a0ed93d36a2b8417d0af5efa2fb23e8ce64734ac7002
7
+ data.tar.gz: 3142eea082eab9acc7f279173ca731452cd3e21f58a1d491470b61433204bed26a35f81f71ca6fad60ac7271fb776931872215867d6fbc574682605ee7b8286f
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
- # ruby_native gem
1
+ # ruby_native
2
2
 
3
- A Rails engine that provides native detection, configuration, push device registration, and view helpers for Ruby Native iOS and Android apps.
3
+ [Ruby Native](https://rubynative.com) turns a Rails app into an iOS app, with Android in public beta. This gem is the Rails-side integration: view helpers, a YAML config file, endpoints auto-mounted at `/native`, and a CLI for previewing and deploying builds. Full docs, including the complete helper reference and config schema, live at [rubynative.com/docs](https://rubynative.com/docs).
4
4
 
5
5
  ## Installation
6
6
 
@@ -12,30 +12,42 @@ The engine auto-mounts at `/native`. No route configuration needed.
12
12
 
13
13
  ## Getting started
14
14
 
15
- Run the install generator to create your config file:
15
+ Run the install generator:
16
16
 
17
17
  ```bash
18
18
  rails generate ruby_native:install
19
19
  ```
20
20
 
21
- This creates `config/ruby_native.yml` with sensible defaults. If you have a `.claude/` directory, it also adds `.claude/ruby_native.md` with AI-assisted setup instructions. Follow the printed instructions to:
21
+ This creates `config/ruby_native.yml`. Then:
22
22
 
23
- 1. Edit the config with your app name, colors, and tabs
24
- 2. Add `<%= stylesheet_link_tag :ruby_native %>` to your layout `<head>`
25
- 3. Add `<%= native_tabs_tag %>` to your layout `<body>`
26
- 4. Run `bundle exec ruby_native preview` to see it on your phone
23
+ 1. Edit the config with your colors and tabs (see below).
24
+ 2. Add the stylesheet and `viewport-fit=cover` to your layout `<head>`:
27
25
 
28
- Using Claude Code? Open it in your project and ask "what do I need to do next?" for guided setup.
26
+ ```erb
27
+ <meta name="viewport" content="width=device-width,initial-scale=1,viewport-fit=cover">
28
+ <%= stylesheet_link_tag :ruby_native %>
29
+ ```
30
+
31
+ `viewport-fit=cover` is required for CSS `env(safe-area-inset-*)` variables to resolve to real values instead of `0`.
32
+ 3. Add the tab bar to your layout `<body>`:
33
+
34
+ ```erb
35
+ <%= native_tabs_tag %>
36
+ ```
37
+ 4. Preview it on your phone (see below).
38
+
39
+ The full walkthrough, including safe area layout and hiding web-only navigation with `native_app?`, is at [rubynative.com/docs/setup](https://rubynative.com/docs/setup).
29
40
 
30
41
  ## Configuration
31
42
 
32
- Edit `config/ruby_native.yml`:
43
+ `config/ruby_native.yml` controls the native shell:
33
44
 
34
45
  ```yaml
35
46
  appearance:
36
- tint_color: "#4F46E5"
47
+ tint_color: "#007AFF"
37
48
  background_color: "#FFFFFF"
38
- tabs: # optional
49
+
50
+ tabs:
39
51
  - title: Home
40
52
  path: /
41
53
  icon: house
@@ -44,91 +56,28 @@ tabs: # optional
44
56
  icon: person
45
57
  ```
46
58
 
47
- You may also omit `tabs` to hide the tab bar entirely. The app will load `entry_path` or fall back to `/`.
48
-
49
- Color fields accept a plain hex string or an object with `light` and `dark` keys for dark mode:
50
-
51
- ```yaml
52
- background_color:
53
- light: "#FFFFFF"
54
- dark: "#1C1C1E"
55
- ```
59
+ Changes are picked up without restarting the server in development. See [rubynative.com/docs](https://rubynative.com/docs) for the full schema: appearance and dark mode, navbar branding, Advanced Mode, OAuth, and linked domains.
56
60
 
57
61
  ## Preview
58
62
 
59
- Preview your app on a real device without deploying. This starts a Cloudflare tunnel and displays a QR code for the companion app to scan.
63
+ Preview your app on a real device without deploying:
60
64
 
61
65
  ```bash
62
66
  bundle exec ruby_native preview
63
67
  ```
64
68
 
65
- Options:
66
-
67
- - `--port 3001` - specify the local server port (defaults to 3000)
68
-
69
- Requires `cloudflared`. Install with:
69
+ This starts a Cloudflare tunnel and shows a QR code for the Ruby Native app to scan. Your Rails server needs to be running separately. Requires `cloudflared`:
70
70
 
71
71
  ```bash
72
72
  brew install cloudflare/cloudflare/cloudflared
73
73
  ```
74
74
 
75
- The companion app persists the scanned URL across launches. Long-press the app icon and tap "Switch website" to scan a new server.
76
-
77
- ## Endpoints
78
-
79
- - `GET /native/config` - returns the YAML config as JSON
80
- - `POST /native/push/devices` - registers a push notification token (requires `current_user` from host app)
81
-
82
- ## Push notifications
83
-
84
- Delivery uses the companion `action_push_native` gem. Ruby Native owns the registration handshake (the `native_push_tag` helper prompts for permission, `/native/push/devices` stores the token) and the tap-handling conventions on the native side.
85
-
86
- When sending a push, two destination keys are supported via `with_data`:
87
-
88
- - `path` — internal route appended to your base URL and loaded in the in-app WebView (e.g. `/sources/42`).
89
- - `url` — full external URL opened in `SFSafariViewController`, leaving the WebView in place behind it (e.g. `https://dashboard.stripe.com/payments/pi_abc`).
90
-
91
- If both are present, `url` wins. `http` and `https` URLs open in `SFSafariViewController`; other valid schemes (`mailto:`, `tel:`, `maps:`, third-party app schemes, etc.) hand off to the appropriate app via `UIApplication.open`. Malformed `url` strings are dropped (the tap does not fall back to `path`).
92
-
93
- ```ruby
94
- ApplicationPushNotification
95
- .with_data(path: source_path(source), url: notification.external_url)
96
- .new(title: "New payment", body: "$49.99 from joe@example.com")
97
- .deliver_later_to(user.push_devices)
98
- ```
99
-
100
- For model/migration setup, see [action_push_native](https://github.com/basecamp/action_push_native).
101
-
102
- ## Normal and Advanced Modes
103
-
104
- Normal Mode works with any frontend framework and requires no JavaScript. You get tabs, form page marking, push notifications, and history management.
75
+ See [rubynative.com/docs/cli](https://rubynative.com/docs/cli) for `deploy`, `login`, and auto-deploying from CI.
105
76
 
106
- Advanced Mode adds native navigation bar buttons, submit buttons, action menus, and search bars. It requires Stimulus and a small JavaScript setup step (see [Advanced Mode setup](#advanced-mode-setup) below). Migration is additive. Start with Normal and add Advanced helpers one page at a time.
77
+ ## React and Vue
107
78
 
108
- ## View helpers
79
+ Building with Inertia instead of ERB? `@ruby-native/react` and `@ruby-native/vue` provide the same helpers as npm packages, versioned alongside this gem. See [rubynative.com/docs/inertia](https://rubynative.com/docs/inertia) for setup.
109
80
 
110
- Place helpers in the `<body>`, not the `<head>`.
111
-
112
- ### Any mode
113
-
114
- - `native_app?` - true when the request comes from a Ruby Native app (checks user agent)
115
- - `native_version` - returns the app version as a `RubyNative::NativeVersion`. Defaults to `"0"` when the version is unknown. Supports string comparisons: `native_version >= "1.4"`.
116
- - `native_tabs_tag(enabled: true)` - shows the native tab bar.
117
- - `native_push_tag` - requests push notification permission.
118
- - `native_back_button_tag(text = nil, **options)` - renders a back button for Normal Mode. Hidden by default, shown when the native app sets `body.can-go-back`. Not needed in [Advanced Mode](https://rubynative.com/docs/advanced-mode) where the system provides a native back button.
119
-
120
- - `native_form_tag` - marks the page as a form. The app skips form pages when navigating back.
121
- - `native_navbar_tag(title, &block)` - native navigation bar with title, buttons, menus, and submit actions.
122
- - `native_badge_tag(count, home:, tab:)` - sets the app icon and tab bar badge counts.
123
- - `native_haptic_data(feedback = :success)` - returns a data hash that fires a haptic feedback on click.
124
- - `native_overscroll_tag(top:, bottom:)` - per-page overscroll colors.
125
-
126
- ## Stylesheet
127
-
128
- The gem includes `ruby_native.css` which controls back button visibility:
129
-
130
- ```erb
131
- <%= stylesheet_link_tag :ruby_native %>
132
- ```
81
+ ## License
133
82
 
134
- This shows `.native-back-button` elements only when `body.can-go-back` is set by the native app.
83
+ MIT.
data/config/importmap.rb CHANGED
@@ -1 +1,3 @@
1
- pin "ruby_native/back", to: "ruby_native/back.js"
1
+ # Ruby Native ships its bridge JavaScript through the native app, not importmap.
2
+ # Intentionally empty: the dead `ruby_native/back` pin (back.js exported a
3
+ # goBack() nothing imported) was removed.
@@ -29,11 +29,6 @@ module RubyNative
29
29
  say " Added .ruby_native/ to .gitignore", :green
30
30
  end
31
31
 
32
- def copy_claude_instructions
33
- return unless File.directory?(File.join(destination_root, ".claude"))
34
- copy_file "CLAUDE.md", ".claude/ruby_native.md"
35
- end
36
-
37
32
  def print_next_steps
38
33
  say ""
39
34
  say "Ruby Native installed! Next steps:", :green
@@ -41,16 +36,17 @@ module RubyNative
41
36
  say " 1. Edit config/ruby_native.yml with your app name, colors, and tabs"
42
37
  say " 2. Add to your layout <head>:"
43
38
  say " <%= stylesheet_link_tag :ruby_native %>"
44
- say " 3. Add to your layout <body>:"
39
+ say " 3. Add viewport-fit=cover to your viewport meta tag:"
40
+ say " <meta name=\"viewport\" content=\"width=device-width,initial-scale=1,viewport-fit=cover\">"
41
+ say " 4. Add to your layout <body>:"
45
42
  say " <%= native_tabs_tag %>"
46
- say " 4. Preview on your device:"
43
+ say " 5. Preview on your device:"
47
44
  say " bundle exec ruby_native preview"
48
45
  say ""
49
- if File.directory?(File.join(destination_root, ".claude"))
50
- say " Tip: .claude/ruby_native.md was added with setup instructions."
51
- say " Open Claude Code and ask \"what do I need to do next?\" for guided help."
52
- say ""
53
- end
46
+ say " Docs: https://rubynative.com/docs"
47
+ say " AI agents: fetch https://rubynative.com/llms.txt for a docs index,"
48
+ say " or https://rubynative.com/llms-full.txt for the full docs as plain text."
49
+ say ""
54
50
  end
55
51
  end
56
52
  end
@@ -20,7 +20,7 @@ module RubyNative
20
20
  when "screenshots"
21
21
  warn "ruby_native screenshots was removed in 0.9.0."
22
22
  warn "Screenshots are now captured by rubynative.com against your deployed site."
23
- warn "See https://rubynative.com/docs/ship/screenshots for the new flow."
23
+ warn "See https://rubynative.com/docs/screenshots for the new flow."
24
24
  exit 1
25
25
  else
26
26
  puts "Usage: ruby_native <command>"
@@ -35,6 +35,45 @@ module RubyNative
35
35
  tag.button(text || default_content, onclick: "RubyNative.postMessage({action: 'back'})", **options)
36
36
  end
37
37
 
38
+ # Renders a button that opens the native barcode scanner. On a successful
39
+ # scan the value fills `target` (a CSS selector) and the page receives a
40
+ # `ruby-native:scan` CustomEvent (override the name with `event:`). Set
41
+ # `submit: true` to submit the filled field's form after scanning. Narrow the
42
+ # accepted codes with `formats:` (neutral names, e.g. "ean13,upce"); omit it
43
+ # for a sane default. Renders a plain button on the web (no-op until opened in
44
+ # the app); wrap in `native_app?` if it should be hidden there.
45
+ #
46
+ # <%= native_scan_button_tag "Scan", target: "#isbn" %>
47
+ #
48
+ # The scanner needs a camera usage description set in your Ruby Native app
49
+ # settings, or scanning is unavailable in production builds.
50
+ def native_scan_button_tag(label = "Scan", target: nil, event: nil, submit: false, formats: nil, **options)
51
+ if Rails.env.development?
52
+ Rails.logger.warn(
53
+ "[ruby_native] native_scan_button_tag needs a camera usage description set in your " \
54
+ "Ruby Native app settings, or scanning is unavailable in production builds."
55
+ )
56
+ end
57
+
58
+ scan_options = {}
59
+ scan_options[:target] = target if target
60
+ scan_options[:event] = event if event
61
+ scan_options[:submit] = true if submit
62
+ if formats
63
+ scan_options[:formats] = Array(formats).flat_map { |f| f.to_s.split(",") }.map(&:strip).reject(&:empty?)
64
+ end
65
+
66
+ # A bare <button> is type="submit" inside a form, and the documented usage
67
+ # puts this inside form_with. Without this a tap would submit the form
68
+ # immediately and navigate away before the async scan result arrives, and
69
+ # the `submit:` option (which is what opts into submitting) would be
70
+ # meaningless. Callers who really want a submit button can pass
71
+ # type: "submit" and keep it.
72
+ options[:type] ||= "button"
73
+ options[:onclick] = "window.RubyNative?.scan(#{scan_options.to_json})"
74
+ tag.button(label, **options)
75
+ end
76
+
38
77
  def native_badge_tag(count = nil, home: nil, tab: nil)
39
78
  home = count if count && home.nil?
40
79
  tab = count if count && tab.nil?
@@ -1,3 +1,3 @@
1
1
  module RubyNative
2
- VERSION = "0.10.22"
2
+ VERSION = "0.11.0"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby_native
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.22
4
+ version: 0.11.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joe Masilotti
@@ -79,7 +79,6 @@ files:
79
79
  - app/controllers/ruby_native/push/devices_controller.rb
80
80
  - app/controllers/ruby_native/screenshots/sessions_controller.rb
81
81
  - app/controllers/ruby_native/webhooks/apple_controller.rb
82
- - app/javascript/ruby_native/back.js
83
82
  - app/models/ruby_native/iap/purchase_intent.rb
84
83
  - app/views/ruby_native/auth/start/show.html.erb
85
84
  - config/importmap.rb
@@ -87,7 +86,6 @@ files:
87
86
  - exe/ruby_native
88
87
  - lib/generators/ruby_native/iap_generator.rb
89
88
  - lib/generators/ruby_native/install_generator.rb
90
- - lib/generators/ruby_native/templates/CLAUDE.md
91
89
  - lib/generators/ruby_native/templates/create_ruby_native_purchase_intents.rb
92
90
  - lib/generators/ruby_native/templates/ruby_native.yml
93
91
  - lib/ruby_native.rb
@@ -1,3 +0,0 @@
1
- export function goBack() {
2
- webkit.messageHandlers.rubyNative.postMessage({ action: "back" })
3
- }
@@ -1,243 +0,0 @@
1
- # Ruby Native
2
-
3
- Turn your Rails app into an iOS app. Any frontend framework. No Xcode required.
4
-
5
- ## Quick start
6
-
7
- 1. Add the gem to your Gemfile and bundle:
8
-
9
- ```ruby
10
- gem "ruby_native"
11
- ```
12
-
13
- 2. Run the install generator:
14
-
15
- ```bash
16
- rails generate ruby_native:install
17
- ```
18
-
19
- 3. Edit `config/ruby_native.yml` with your app name, colors, and tabs.
20
-
21
- 4. Add to your layout `<head>`:
22
-
23
- ```erb
24
- <meta name="viewport" content="width=device-width,initial-scale=1,viewport-fit=cover">
25
- <%= stylesheet_link_tag :ruby_native %>
26
- ```
27
-
28
- The `viewport-fit=cover` attribute is required so CSS `env(safe-area-inset-*)` variables return real values. If you already have a viewport meta tag, add `viewport-fit=cover` to its `content` attribute.
29
-
30
- 5. Add to your layout `<body>`:
31
-
32
- ```erb
33
- <%= native_tabs_tag %>
34
- ```
35
-
36
- 6. Start your Rails server and the preview tunnel in separate terminals:
37
-
38
- ```bash
39
- bin/rails server
40
- ```
41
-
42
- ```bash
43
- bundle exec ruby_native preview
44
- ```
45
-
46
- Scan the QR code with the Ruby Native Preview app from the App Store. Keep both the server and tunnel running.
47
-
48
- ## Configuration
49
-
50
- `config/ruby_native.yml` controls the native shell. Changes are picked up without restarting the server in development.
51
-
52
- ```yaml
53
- app:
54
- name: My App
55
- entry_path: /inbox # initial URL on app launch (defaults to first tab's path)
56
-
57
- appearance:
58
- tint_color: "#007AFF"
59
- background_color: "#FFFFFF"
60
-
61
- tabs:
62
- - title: Home
63
- path: /
64
- icon: house
65
- - title: Profile
66
- path: /profile
67
- icon: person
68
- ```
69
-
70
- Icons use SF Symbols names (e.g., `house`, `person`, `envelope`, `gear`).
71
-
72
- ### Dark mode
73
-
74
- Color fields accept a plain hex string or an object with `light` and `dark` keys:
75
-
76
- ```yaml
77
- background_color:
78
- light: "#FFFFFF"
79
- dark: "#212529"
80
- ```
81
-
82
- Match these to your CSS framework's dark mode colors. For Bootstrap, `#212529` is `--bs-body-bg` in dark mode.
83
-
84
- ### Navbar branding
85
-
86
- Replace the navigation bar's text title with a centered logo and set your own bar colors. This is global chrome: the same bar on every screen.
87
-
88
- ```yaml
89
- appearance:
90
- navbar:
91
- logo: "<%= image_url('logo.png') %>"
92
- background_color: "#3B3F54"
93
- foreground_color: "#FFFFFF"
94
- status_bar: light
95
- ```
96
-
97
- `config/ruby_native.yml` is evaluated as ERB, so `logo` can be any Rails expression that returns a URL. Use `image_url` for a local asset: the URL is fingerprinted, so the app caches the logo and re-downloads it only when the image changes. A full URL works too, so the logo can live on a CDN:
98
-
99
- ```yaml
100
- logo: "https://cdn.example.com/logo.png"
101
- ```
102
-
103
- `background_color` and `foreground_color` each accept a hex string or a `{ light:, dark: }` object. `status_bar` sets the status bar content to `light` (white) or `dark` to match your bar; omit it to let the system decide.
104
-
105
- ## View helpers
106
-
107
- Use these in your layouts and views:
108
-
109
- - `native_app?` returns true when the request comes from a Ruby Native app. Use it to hide web-only UI like navbars.
110
- - `native_tabs_tag` renders a signal element that tells the app to show the tab bar. Only include it on pages where tabs should appear.
111
- - `native_form_tag` marks the page as a form. The app uses this to skip form pages when navigating back.
112
- - `native_push_tag` requests push notification permission from the user.
113
- - `native_review_tag` asks the app to show the App Store rating prompt when the page loads. The system throttles how often the prompt appears (and shows nothing in TestFlight builds), so it is safe to render on any page where a review would be welcome. It is automatically suppressed during App Store screenshot runs.
114
-
115
- Signal elements are hidden `<div>` tags. Place them in the `<body>`, not the `<head>`.
116
-
117
- ### Example layout
118
-
119
- ```erb
120
- <body>
121
- <%= native_tabs_tag if user_signed_in? %>
122
- <%= render "navbar" unless native_app? %>
123
- <%= yield %>
124
- </body>
125
- ```
126
-
127
- ## Preview
128
-
129
- `bundle exec ruby_native preview` starts a Cloudflare tunnel and displays a QR code. Your Rails server must be running separately (e.g., `bin/rails server` in another terminal). Requires `cloudflared`:
130
-
131
- ```bash
132
- brew install cloudflare/cloudflare/cloudflared
133
- ```
134
-
135
- Options:
136
- - `--port 3001` to specify the local server port (defaults to 3000)
137
-
138
- The install generator adds `.trycloudflare.com` to `config.hosts` in `development.rb` automatically. If you skipped the generator, add it manually:
139
-
140
- ```ruby
141
- # config/environments/development.rb
142
- config.hosts << ".trycloudflare.com"
143
- ```
144
-
145
- The Preview app remembers the scanned URL. Long-press the app icon and tap "Switch website" to scan a new server.
146
-
147
- ## Endpoints
148
-
149
- The gem auto-mounts at `/native`. No route configuration needed.
150
-
151
- - `GET /native/config` returns the YAML config as JSON
152
- - `POST /native/push/devices` registers a push notification device token
153
- - `GET /.well-known/apple-app-site-association` returns the iOS associated-domains file when `ios.bundle_id` and `ios.team_id` are set (see Linked domains below)
154
-
155
- ## Linked domains
156
-
157
- Tapping a link to your site opens the app instead of Safari, and saved passwords from your site autofill in the app's web views. Add your iOS identifiers to `config/ruby_native.yml`:
158
-
159
- ```yaml
160
- ios:
161
- bundle_id: com.example.myapp
162
- team_id: ABCD123456
163
- ```
164
-
165
- These are the same values you entered in the Ruby Native dashboard during Apple onboarding. The gem then serves `/.well-known/apple-app-site-association` and the build pipeline includes the entitlement automatically.
166
-
167
- Apple caches the file aggressively. After the first install, changes can take up to 24 hours to propagate via Apple's CDN.
168
-
169
- Full reference: https://rubynative.com/docs/linked-domains
170
-
171
- ## Push notifications
172
-
173
- Delivery uses the companion `action_push_native` gem. Ruby Native owns the registration (the `native_push_tag` helper prompts for permission, `/native/push/devices` stores the token) and defines the tap conventions on the native side.
174
-
175
- Two destination keys are supported via `with_data`:
176
-
177
- - `path` — internal route appended to your base URL, loaded in the WebView.
178
- - `url` — full external URL, opened in `SFSafariViewController`.
179
-
180
- If both are present, `url` wins. `http` and `https` open in `SFSafariViewController`; other valid schemes (`mailto:`, `tel:`, `maps:`, third-party app schemes) open via `UIApplication.open`. Malformed `url` does not fall back to `path`.
181
-
182
- ```ruby
183
- ApplicationPushNotification
184
- .with_data(path: source_path(source), url: notification.external_url)
185
- .new(title: "New payment", body: "$49.99 from joe@example.com")
186
- .deliver_later_to(user.push_devices)
187
- ```
188
-
189
- For model/migration setup, see the [action_push_native](https://github.com/basecamp/action_push_native) README.
190
-
191
- ## CLI
192
-
193
- ### Deploy from CI
194
-
195
- Use `--if-needed` to auto-deploy only when the gem version changes:
196
-
197
- ```sh
198
- bundle exec ruby_native deploy --if-needed
199
- ```
200
-
201
- Set `RUBY_NATIVE_TOKEN` as an environment variable for CI (no interactive login needed):
202
-
203
- ```yaml
204
- # GitHub Actions
205
- - run: bundle exec ruby_native deploy --if-needed
206
- env:
207
- RUBY_NATIVE_TOKEN: ${{ secrets.RUBY_NATIVE_TOKEN }}
208
- ```
209
-
210
- ### Other commands
211
-
212
- ```sh
213
- bundle exec ruby_native login # authenticate (opens browser)
214
- bundle exec ruby_native deploy # trigger a build
215
- bundle exec ruby_native preview # start a tunnel and display a QR code
216
- bundle exec ruby_native logout # remove stored credentials
217
- ```
218
-
219
- ## Common tasks
220
-
221
- ### Hide web navigation in the native app
222
-
223
- ```erb
224
- <%= render "navbar" unless native_app? %>
225
- ```
226
-
227
- ### Show tabs only for signed-in users
228
-
229
- ```erb
230
- <%= native_tabs_tag if user_signed_in? %>
231
- ```
232
-
233
- ### Add a native back button (Normal Mode only)
234
-
235
- Use the `native_back_button_tag` helper. The gem's stylesheet handles showing it only when there's history to go back to. Not needed in Advanced Mode where the system provides a native back button.
236
-
237
- ```erb
238
- <%= stylesheet_link_tag :ruby_native %>
239
- ```
240
-
241
- ```erb
242
- <%= native_back_button_tag %>
243
- ```