ruby_native 0.6.0 → 0.8.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 +4 -4
- data/README.md +4 -64
- data/app/assets/stylesheets/ruby_native.css +0 -11
- data/config/importmap.rb +0 -2
- data/lib/generators/ruby_native/install_generator.rb +0 -5
- data/lib/generators/ruby_native/templates/CLAUDE.md +32 -0
- data/lib/ruby_native/cli/credentials.rb +4 -0
- data/lib/ruby_native/cli/deploy.rb +44 -0
- data/lib/ruby_native/helper.rb +18 -84
- data/lib/ruby_native/version.rb +1 -1
- metadata +1 -10
- data/app/javascript/ruby_native/bridge/badge_controller.js +0 -21
- data/app/javascript/ruby_native/bridge/button_controller.js +0 -30
- data/app/javascript/ruby_native/bridge/form_controller.js +0 -27
- data/app/javascript/ruby_native/bridge/haptic_controller.js +0 -11
- data/app/javascript/ruby_native/bridge/index.js +0 -18
- data/app/javascript/ruby_native/bridge/menu_controller.js +0 -22
- data/app/javascript/ruby_native/bridge/push_controller.js +0 -10
- data/app/javascript/ruby_native/bridge/search_controller.js +0 -16
- data/app/javascript/ruby_native/bridge/tabs_controller.js +0 -11
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 59fd793a678f35fc19666a9e5a182a3d33fceab98957ec486f4fb02983c8050c
|
|
4
|
+
data.tar.gz: 045fd16fede9352d7a2c86502b633b5f06f432a16a9cf2bcce8dae520601b522
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d4eae6af16060395f8a75d58fcd883b4cd69dc2ff69465d7da8be31cf1074d5c558733072ef68db069f721291a5734ad1f0c448c9b10f5576fd1c07223236680
|
|
7
|
+
data.tar.gz: be5da276be7b009b947090396f96dfd7db7e53b9d182ab3c94e1c837d8fbe46774196de0510266f0c4ee85c778d1bd77f833f204e2f94bd9609fff64b77e2331
|
data/README.md
CHANGED
|
@@ -97,71 +97,11 @@ Place helpers in the `<body>`, not the `<head>`.
|
|
|
97
97
|
- `native_push_tag` - requests push notification permission.
|
|
98
98
|
- `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.
|
|
99
99
|
|
|
100
|
-
### Normal Mode
|
|
101
|
-
|
|
102
100
|
- `native_form_tag` - marks the page as a form. The app skips form pages when navigating back.
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
- `native_form_data` - returns the data hash for the native form submit button. Pass to `form_with`'s `data:` option.
|
|
109
|
-
- `native_submit_data` - returns the data hash for the native submit target. Pass to `form.submit`'s `data:` option.
|
|
110
|
-
- `native_button_tag(title, url, ios_image:, side: :right, **options)` - adds a native navigation bar button.
|
|
111
|
-
- `native_menu_tag(title:, side: :right, &block)` - displays a native action sheet menu.
|
|
112
|
-
- `native_search_tag` - adds a native search bar.
|
|
113
|
-
|
|
114
|
-
## Advanced Mode setup
|
|
115
|
-
|
|
116
|
-
1. Install the JavaScript dependency:
|
|
117
|
-
|
|
118
|
-
```bash
|
|
119
|
-
yarn add @hotwired/hotwire-native-bridge
|
|
120
|
-
# or
|
|
121
|
-
bin/importmap pin @hotwired/hotwire-native-bridge
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
2. Import the controllers in your JavaScript entrypoint:
|
|
125
|
-
|
|
126
|
-
```js
|
|
127
|
-
import "ruby_native/bridge"
|
|
128
|
-
```
|
|
129
|
-
|
|
130
|
-
### `native_form_data` / `native_submit_data`
|
|
131
|
-
|
|
132
|
-
```erb
|
|
133
|
-
<%= form_with model: @link, data: native_form_data do |f| %>
|
|
134
|
-
<%= f.text_field :url %>
|
|
135
|
-
<%= f.submit "Save", data: native_submit_data %>
|
|
136
|
-
<% end %>
|
|
137
|
-
```
|
|
138
|
-
|
|
139
|
-
### `native_button_tag`
|
|
140
|
-
|
|
141
|
-
```erb
|
|
142
|
-
<%= native_button_tag "Add a link", new_link_path, ios_image: "plus", class: "btn btn-primary" %>
|
|
143
|
-
```
|
|
144
|
-
|
|
145
|
-
Options:
|
|
146
|
-
- `ios_image:` - SF Symbol icon name (falls back to the title text)
|
|
147
|
-
- `side:` - `:left` or `:right` (default). Left supplements the back button.
|
|
148
|
-
|
|
149
|
-
### `native_menu_tag`
|
|
150
|
-
|
|
151
|
-
```erb
|
|
152
|
-
<%= native_menu_tag(title: "Actions") do |menu| %>
|
|
153
|
-
<%= menu.item "Edit", edit_link_path(@link) %>
|
|
154
|
-
<%= menu.item "Delete", link_path(@link), method: :delete, destructive: true %>
|
|
155
|
-
<% end %>
|
|
156
|
-
```
|
|
157
|
-
|
|
158
|
-
Options on `native_menu_tag`:
|
|
159
|
-
- `title:` - action sheet title
|
|
160
|
-
- `side:` - `:left` or `:right` (default)
|
|
161
|
-
|
|
162
|
-
Options on `menu.item`:
|
|
163
|
-
- `method:` - Turbo method (e.g., `:delete`)
|
|
164
|
-
- `destructive: true` - red styling
|
|
101
|
+
- `native_navbar_tag(title, &block)` - native navigation bar with title, buttons, menus, and submit actions.
|
|
102
|
+
- `native_badge_tag(count, home:, tab:)` - sets the app icon and tab bar badge counts.
|
|
103
|
+
- `native_haptic_data(feedback = :success)` - returns a data hash that fires a haptic feedback on click.
|
|
104
|
+
- `native_overscroll_tag(top:, bottom:)` - per-page overscroll colors.
|
|
165
105
|
|
|
166
106
|
## Stylesheet
|
|
167
107
|
|
|
@@ -23,14 +23,3 @@
|
|
|
23
23
|
body.can-go-back .native-back-button {
|
|
24
24
|
display: inline;
|
|
25
25
|
}
|
|
26
|
-
|
|
27
|
-
[data-bridge-components~="form"]
|
|
28
|
-
[data-controller~="bridge--form"]
|
|
29
|
-
[type="submit"] {
|
|
30
|
-
display: none;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
[data-bridge-components~="button"]
|
|
34
|
-
[data-controller~="bridge--button"] {
|
|
35
|
-
display: none;
|
|
36
|
-
}
|
data/config/importmap.rb
CHANGED
|
@@ -46,11 +46,6 @@ module RubyNative
|
|
|
46
46
|
say " 4. Preview on your device:"
|
|
47
47
|
say " bundle exec ruby_native preview"
|
|
48
48
|
say ""
|
|
49
|
-
say " For Advanced Mode (native buttons, menus, search):"
|
|
50
|
-
say " bin/importmap pin @hotwired/hotwire-native-bridge"
|
|
51
|
-
say " Then add to your JavaScript entrypoint:"
|
|
52
|
-
say " import \"ruby_native/bridge\""
|
|
53
|
-
say ""
|
|
54
49
|
if File.directory?(File.join(destination_root, ".claude"))
|
|
55
50
|
say " Tip: .claude/ruby_native.md was added with setup instructions."
|
|
56
51
|
say " Open Claude Code and ask \"what do I need to do next?\" for guided help."
|
|
@@ -21,9 +21,12 @@ rails generate ruby_native:install
|
|
|
21
21
|
4. Add to your layout `<head>`:
|
|
22
22
|
|
|
23
23
|
```erb
|
|
24
|
+
<meta name="viewport" content="width=device-width,initial-scale=1,viewport-fit=cover">
|
|
24
25
|
<%= stylesheet_link_tag :ruby_native %>
|
|
25
26
|
```
|
|
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
|
+
|
|
27
30
|
5. Add to your layout `<body>`:
|
|
28
31
|
|
|
29
32
|
```erb
|
|
@@ -126,6 +129,35 @@ The gem auto-mounts at `/native`. No route configuration needed.
|
|
|
126
129
|
- `GET /native/config` returns the YAML config as JSON
|
|
127
130
|
- `POST /native/push/devices` registers a push notification device token
|
|
128
131
|
|
|
132
|
+
## CLI
|
|
133
|
+
|
|
134
|
+
### Deploy from CI
|
|
135
|
+
|
|
136
|
+
Use `--if-needed` to auto-deploy only when the gem version changes:
|
|
137
|
+
|
|
138
|
+
```sh
|
|
139
|
+
bundle exec ruby_native deploy --if-needed
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
Set `RUBY_NATIVE_TOKEN` as an environment variable for CI (no interactive login needed):
|
|
143
|
+
|
|
144
|
+
```yaml
|
|
145
|
+
# GitHub Actions
|
|
146
|
+
- run: bundle exec ruby_native deploy --if-needed
|
|
147
|
+
env:
|
|
148
|
+
RUBY_NATIVE_TOKEN: ${{ secrets.RUBY_NATIVE_TOKEN }}
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### Other commands
|
|
152
|
+
|
|
153
|
+
```sh
|
|
154
|
+
bundle exec ruby_native login # authenticate (opens browser)
|
|
155
|
+
bundle exec ruby_native deploy # trigger a build
|
|
156
|
+
bundle exec ruby_native preview # start a tunnel and display a QR code
|
|
157
|
+
bundle exec ruby_native screenshots # capture App Store screenshots
|
|
158
|
+
bundle exec ruby_native logout # remove stored credentials
|
|
159
|
+
```
|
|
160
|
+
|
|
129
161
|
## Common tasks
|
|
130
162
|
|
|
131
163
|
### Hide web navigation in the native app
|
|
@@ -7,6 +7,10 @@ module RubyNative
|
|
|
7
7
|
PATH = File.join(Dir.home, ".ruby_native", "credentials")
|
|
8
8
|
|
|
9
9
|
def self.token
|
|
10
|
+
ENV["RUBY_NATIVE_TOKEN"] || file_token
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def self.file_token
|
|
10
14
|
return unless File.exist?(PATH)
|
|
11
15
|
JSON.parse(File.read(PATH))["token"]
|
|
12
16
|
rescue JSON::ParserError
|
|
@@ -2,6 +2,7 @@ require "json"
|
|
|
2
2
|
require "net/http"
|
|
3
3
|
require "uri"
|
|
4
4
|
require "ruby_native/cli/credentials"
|
|
5
|
+
require "ruby_native/version"
|
|
5
6
|
|
|
6
7
|
module RubyNative
|
|
7
8
|
class CLI
|
|
@@ -14,13 +15,22 @@ module RubyNative
|
|
|
14
15
|
TokenExpiredError = Class.new(StandardError)
|
|
15
16
|
|
|
16
17
|
def initialize(argv)
|
|
18
|
+
@if_needed = argv.include?("--if-needed")
|
|
17
19
|
end
|
|
18
20
|
|
|
19
21
|
def run
|
|
20
22
|
load_config!
|
|
21
23
|
ensure_authenticated!
|
|
22
24
|
app_id = resolve_app_id!
|
|
25
|
+
|
|
26
|
+
if @if_needed && skip_build?(app_id)
|
|
27
|
+
puts "Ruby Native v#{RubyNative::VERSION} already built. Skipping deploy."
|
|
28
|
+
return
|
|
29
|
+
end
|
|
30
|
+
|
|
23
31
|
build = trigger_build(app_id)
|
|
32
|
+
return if @if_needed
|
|
33
|
+
|
|
24
34
|
poll_build_status(app_id, build)
|
|
25
35
|
end
|
|
26
36
|
|
|
@@ -53,6 +63,39 @@ module RubyNative
|
|
|
53
63
|
app_id
|
|
54
64
|
end
|
|
55
65
|
|
|
66
|
+
# --- Version check ---
|
|
67
|
+
|
|
68
|
+
def skip_build?(app_id)
|
|
69
|
+
latest = fetch_latest_build(app_id)
|
|
70
|
+
return false unless latest
|
|
71
|
+
|
|
72
|
+
latest_gem_version = latest["gem_version"]
|
|
73
|
+
return false unless latest_gem_version
|
|
74
|
+
|
|
75
|
+
Gem::Version.new(latest_gem_version) >= Gem::Version.new(RubyNative::VERSION)
|
|
76
|
+
rescue ArgumentError
|
|
77
|
+
false
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def fetch_latest_build(app_id)
|
|
81
|
+
uri = URI("#{HOST}/api/v1/apps/#{app_id}/builds/latest")
|
|
82
|
+
req = Net::HTTP::Get.new(uri)
|
|
83
|
+
req["Authorization"] = "Token #{Credentials.token}"
|
|
84
|
+
|
|
85
|
+
response = make_request(uri, req)
|
|
86
|
+
|
|
87
|
+
case response
|
|
88
|
+
when Net::HTTPSuccess
|
|
89
|
+
JSON.parse(response.body)
|
|
90
|
+
when Net::HTTPNoContent
|
|
91
|
+
nil
|
|
92
|
+
when Net::HTTPUnauthorized
|
|
93
|
+
raise TokenExpiredError
|
|
94
|
+
else
|
|
95
|
+
nil
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
56
99
|
# --- Build ---
|
|
57
100
|
|
|
58
101
|
def trigger_build(app_id)
|
|
@@ -62,6 +105,7 @@ module RubyNative
|
|
|
62
105
|
req = Net::HTTP::Post.new(uri)
|
|
63
106
|
req["Authorization"] = "Token #{Credentials.token}"
|
|
64
107
|
req["Content-Type"] = "application/json"
|
|
108
|
+
req.body = JSON.generate(gem_version: RubyNative::VERSION)
|
|
65
109
|
|
|
66
110
|
response = make_request(uri, req)
|
|
67
111
|
|
data/lib/ruby_native/helper.rb
CHANGED
|
@@ -1,29 +1,16 @@
|
|
|
1
1
|
module RubyNative
|
|
2
2
|
module Helper
|
|
3
3
|
def native_tabs_tag(enabled: true)
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
tag.div(data: { controller: "bridge--tabs", bridge__tabs_enabled_value: enabled })
|
|
7
|
-
].compact)
|
|
4
|
+
return "".html_safe unless enabled
|
|
5
|
+
tag.div(data: { native_tabs: true }, hidden: true)
|
|
8
6
|
end
|
|
9
7
|
|
|
10
8
|
def native_form_tag
|
|
11
9
|
tag.div(data: { native_form: true }, hidden: true)
|
|
12
10
|
end
|
|
13
11
|
|
|
14
|
-
def native_form_data(**data)
|
|
15
|
-
merge_controller(data, "bridge--form")
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
def native_submit_data
|
|
19
|
-
{ bridge__form_target: "submit" }
|
|
20
|
-
end
|
|
21
|
-
|
|
22
12
|
def native_push_tag
|
|
23
|
-
|
|
24
|
-
tag.div(data: { native_push: true }, hidden: true),
|
|
25
|
-
tag.div(data: { controller: "bridge--push" })
|
|
26
|
-
])
|
|
13
|
+
tag.div(data: { native_push: true }, hidden: true)
|
|
27
14
|
end
|
|
28
15
|
|
|
29
16
|
def native_back_button_tag(text = nil, **options)
|
|
@@ -35,53 +22,29 @@ module RubyNative
|
|
|
35
22
|
tag.button(text || default_content, onclick: "RubyNative.postMessage({action: 'back'})", **options)
|
|
36
23
|
end
|
|
37
24
|
|
|
38
|
-
def native_search_tag
|
|
39
|
-
tag.div(data: { controller: "bridge--search" })
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
def native_button_tag(title, url, ios_image: nil, side: :right, **options)
|
|
43
|
-
data = options.delete(:data) || {}
|
|
44
|
-
data[:controller] = "bridge--button"
|
|
45
|
-
data[:bridge_side] = side.to_s
|
|
46
|
-
data[:bridge_ios_image] = ios_image if ios_image
|
|
47
|
-
|
|
48
|
-
link_to title, url, **options, data: data
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
def native_menu_tag(title:, side: :right, &block)
|
|
52
|
-
builder = MenuBuilder.new(self)
|
|
53
|
-
capture(builder, &block)
|
|
54
|
-
|
|
55
|
-
tag.div(style: "display:none", data: {
|
|
56
|
-
controller: "bridge--menu",
|
|
57
|
-
bridge__menu_title_value: title,
|
|
58
|
-
bridge__menu_side_value: side.to_s
|
|
59
|
-
}) { builder.to_html }
|
|
60
|
-
end
|
|
61
|
-
|
|
62
25
|
def native_badge_tag(count = nil, home: nil, tab: nil)
|
|
63
26
|
home = count if count && home.nil?
|
|
64
27
|
tab = count if count && tab.nil?
|
|
65
28
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
bridge_data = { controller: "bridge--badge" }
|
|
71
|
-
bridge_data[:bridge__badge_home_value] = home unless home.nil?
|
|
72
|
-
bridge_data[:bridge__badge_tab_value] = tab unless tab.nil?
|
|
29
|
+
data = { native_badge: "" }
|
|
30
|
+
data[:native_badge_home] = home unless home.nil?
|
|
31
|
+
data[:native_badge_tab] = tab unless tab.nil?
|
|
73
32
|
|
|
74
|
-
|
|
75
|
-
tag.div(data: signal_data, hidden: true),
|
|
76
|
-
tag.div(data: bridge_data)
|
|
77
|
-
])
|
|
33
|
+
tag.div(data: data, hidden: true)
|
|
78
34
|
end
|
|
79
35
|
|
|
80
|
-
def native_navbar_tag(title, &block)
|
|
36
|
+
def native_navbar_tag(title = nil, &block)
|
|
81
37
|
builder = NavbarBuilder.new(self)
|
|
82
38
|
capture(builder, &block) if block
|
|
83
39
|
|
|
84
|
-
tag.div(data: { native_navbar: title }, hidden: true) { builder.to_html }
|
|
40
|
+
tag.div(data: { native_navbar: title.to_s }, hidden: true) { builder.to_html }
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def native_fab_tag(icon:, href: nil, click: nil)
|
|
44
|
+
data = { native_fab: true, native_icon: icon }
|
|
45
|
+
data[:native_href] = href if href
|
|
46
|
+
data[:native_click] = click if click
|
|
47
|
+
tag.div(data: data, hidden: true)
|
|
85
48
|
end
|
|
86
49
|
|
|
87
50
|
def native_overscroll_tag(top:, bottom: nil)
|
|
@@ -91,49 +54,20 @@ module RubyNative
|
|
|
91
54
|
def native_haptic_data(feedback = :success, **data)
|
|
92
55
|
feedback = feedback.to_s
|
|
93
56
|
feedback = "success" if feedback.empty?
|
|
94
|
-
|
|
95
57
|
data[:native_haptic] = feedback
|
|
96
|
-
data[:bridge__haptic_feedback_value] = feedback
|
|
97
|
-
merge_controller(data, "bridge--haptic")
|
|
98
|
-
end
|
|
99
|
-
|
|
100
|
-
private
|
|
101
|
-
|
|
102
|
-
def merge_controller(data, controller)
|
|
103
|
-
data[:controller] = [data[:controller], controller].compact.join(" ")
|
|
104
58
|
data
|
|
105
59
|
end
|
|
106
60
|
|
|
107
|
-
class MenuBuilder
|
|
108
|
-
def initialize(context)
|
|
109
|
-
@context = context
|
|
110
|
-
@items = []
|
|
111
|
-
end
|
|
112
|
-
|
|
113
|
-
def item(title, url, method: nil, destructive: false, **options)
|
|
114
|
-
data = options.delete(:data) || {}
|
|
115
|
-
data[:bridge__menu_target] = "item"
|
|
116
|
-
data[:turbo_method] = method if method
|
|
117
|
-
data[:destructive] = "" if destructive
|
|
118
|
-
|
|
119
|
-
@items << @context.link_to(title, url, **options, data: data, hidden: true)
|
|
120
|
-
end
|
|
121
|
-
|
|
122
|
-
def to_html
|
|
123
|
-
@context.safe_join(@items)
|
|
124
|
-
end
|
|
125
|
-
end
|
|
126
|
-
|
|
127
61
|
class NavbarBuilder
|
|
128
62
|
def initialize(context)
|
|
129
63
|
@context = context
|
|
130
64
|
@items = []
|
|
131
65
|
end
|
|
132
66
|
|
|
133
|
-
def button(
|
|
67
|
+
def button(title = nil, icon: nil, href: nil, click: nil, position: :trailing, selected: false, &block)
|
|
134
68
|
data = { native_button: "" }
|
|
135
|
-
data[:native_icon] = icon if icon
|
|
136
69
|
data[:native_title] = title if title
|
|
70
|
+
data[:native_icon] = icon if icon
|
|
137
71
|
data[:native_href] = href if href
|
|
138
72
|
data[:native_click] = click if click
|
|
139
73
|
data[:native_position] = position.to_s
|
data/lib/ruby_native/version.rb
CHANGED
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.
|
|
4
|
+
version: 0.8.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Joe Masilotti
|
|
@@ -72,15 +72,6 @@ files:
|
|
|
72
72
|
- app/controllers/ruby_native/push/devices_controller.rb
|
|
73
73
|
- app/controllers/ruby_native/webhooks/apple_controller.rb
|
|
74
74
|
- app/javascript/ruby_native/back.js
|
|
75
|
-
- app/javascript/ruby_native/bridge/badge_controller.js
|
|
76
|
-
- app/javascript/ruby_native/bridge/button_controller.js
|
|
77
|
-
- app/javascript/ruby_native/bridge/form_controller.js
|
|
78
|
-
- app/javascript/ruby_native/bridge/haptic_controller.js
|
|
79
|
-
- app/javascript/ruby_native/bridge/index.js
|
|
80
|
-
- app/javascript/ruby_native/bridge/menu_controller.js
|
|
81
|
-
- app/javascript/ruby_native/bridge/push_controller.js
|
|
82
|
-
- app/javascript/ruby_native/bridge/search_controller.js
|
|
83
|
-
- app/javascript/ruby_native/bridge/tabs_controller.js
|
|
84
75
|
- app/models/ruby_native/iap/purchase_intent.rb
|
|
85
76
|
- app/views/ruby_native/auth/start/show.html.erb
|
|
86
77
|
- config/importmap.rb
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { BridgeComponent } from "@hotwired/hotwire-native-bridge"
|
|
2
|
-
|
|
3
|
-
export default class extends BridgeComponent {
|
|
4
|
-
static component = "badge"
|
|
5
|
-
static values = { home: Number, tab: Number }
|
|
6
|
-
|
|
7
|
-
connect() {
|
|
8
|
-
super.connect()
|
|
9
|
-
this.#update()
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
homeValueChanged() { this.#update() }
|
|
13
|
-
tabValueChanged() { this.#update() }
|
|
14
|
-
|
|
15
|
-
#update() {
|
|
16
|
-
const data = {}
|
|
17
|
-
if (this.hasHomeValue) data.home = this.homeValue
|
|
18
|
-
if (this.hasTabValue) data.tab = this.tabValue
|
|
19
|
-
this.send("connect", data)
|
|
20
|
-
}
|
|
21
|
-
}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import { BridgeComponent } from "@hotwired/hotwire-native-bridge"
|
|
2
|
-
|
|
3
|
-
export default class extends BridgeComponent {
|
|
4
|
-
static component = "button"
|
|
5
|
-
|
|
6
|
-
connect() {
|
|
7
|
-
super.connect()
|
|
8
|
-
this.#addButton()
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
disconnect() {
|
|
12
|
-
super.disconnect()
|
|
13
|
-
this.#removeButton()
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
#addButton() {
|
|
17
|
-
const element = this.bridgeElement
|
|
18
|
-
const side = element.bridgeAttribute("side") || "right"
|
|
19
|
-
const image = element.bridgeAttribute("ios-image")
|
|
20
|
-
const data = { title: element.title, image }
|
|
21
|
-
|
|
22
|
-
this.send(side, data, () => {
|
|
23
|
-
this.element.click()
|
|
24
|
-
})
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
#removeButton() {
|
|
28
|
-
this.send("disconnect")
|
|
29
|
-
}
|
|
30
|
-
}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { BridgeComponent, BridgeElement } from "@hotwired/hotwire-native-bridge"
|
|
2
|
-
|
|
3
|
-
export default class extends BridgeComponent {
|
|
4
|
-
static component = "form"
|
|
5
|
-
static targets = ["submit"]
|
|
6
|
-
|
|
7
|
-
connect() {
|
|
8
|
-
super.connect()
|
|
9
|
-
|
|
10
|
-
const title = new BridgeElement(this.submitTarget).title
|
|
11
|
-
this.send("connect", { submitTitle: title.trim() }, () => {
|
|
12
|
-
this.submitTarget.click()
|
|
13
|
-
})
|
|
14
|
-
|
|
15
|
-
this.element.addEventListener("turbo:submit-start", this.submitStarted)
|
|
16
|
-
this.element.addEventListener("turbo:submit-end", this.submitEnded)
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
disconnect() {
|
|
20
|
-
super.disconnect()
|
|
21
|
-
this.element.removeEventListener("turbo:submit-start", this.submitStarted)
|
|
22
|
-
this.element.removeEventListener("turbo:submit-end", this.submitEnded)
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
submitStarted = () => this.send("submitDisabled")
|
|
26
|
-
submitEnded = () => this.send("submitEnabled")
|
|
27
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { BridgeComponent } from "@hotwired/hotwire-native-bridge"
|
|
2
|
-
|
|
3
|
-
export default class extends BridgeComponent {
|
|
4
|
-
static component = "haptic"
|
|
5
|
-
static values = { feedback: { type: String, default: "success" } }
|
|
6
|
-
|
|
7
|
-
vibrate() {
|
|
8
|
-
const feedback = this.feedbackValue || "success"
|
|
9
|
-
this.send("vibrate", { feedback })
|
|
10
|
-
}
|
|
11
|
-
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { application } from "controllers/application"
|
|
2
|
-
import TabsController from "ruby_native/bridge/tabs_controller"
|
|
3
|
-
import FormController from "ruby_native/bridge/form_controller"
|
|
4
|
-
import PushController from "ruby_native/bridge/push_controller"
|
|
5
|
-
import MenuController from "ruby_native/bridge/menu_controller"
|
|
6
|
-
import SearchController from "ruby_native/bridge/search_controller"
|
|
7
|
-
import ButtonController from "ruby_native/bridge/button_controller"
|
|
8
|
-
import HapticController from "ruby_native/bridge/haptic_controller"
|
|
9
|
-
import BadgeController from "ruby_native/bridge/badge_controller"
|
|
10
|
-
|
|
11
|
-
application.register("bridge--tabs", TabsController)
|
|
12
|
-
application.register("bridge--form", FormController)
|
|
13
|
-
application.register("bridge--push", PushController)
|
|
14
|
-
application.register("bridge--menu", MenuController)
|
|
15
|
-
application.register("bridge--search", SearchController)
|
|
16
|
-
application.register("bridge--button", ButtonController)
|
|
17
|
-
application.register("bridge--haptic", HapticController)
|
|
18
|
-
application.register("bridge--badge", BadgeController)
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { BridgeComponent, BridgeElement } from "@hotwired/hotwire-native-bridge"
|
|
2
|
-
|
|
3
|
-
export default class extends BridgeComponent {
|
|
4
|
-
static component = "menu"
|
|
5
|
-
static targets = ["item"]
|
|
6
|
-
static values = { title: String, side: { type: String, default: "right" } }
|
|
7
|
-
|
|
8
|
-
connect() {
|
|
9
|
-
super.connect()
|
|
10
|
-
|
|
11
|
-
const items = this.itemTargets.map((el, index) => ({
|
|
12
|
-
title: new BridgeElement(el).title,
|
|
13
|
-
index,
|
|
14
|
-
destructive: el.hasAttribute("data-destructive")
|
|
15
|
-
}))
|
|
16
|
-
|
|
17
|
-
this.send("connect", { title: this.titleValue, items, side: this.sideValue }, (message) => {
|
|
18
|
-
const { selectedIndex } = message.data
|
|
19
|
-
this.itemTargets[selectedIndex]?.click()
|
|
20
|
-
})
|
|
21
|
-
}
|
|
22
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { BridgeComponent } from "@hotwired/hotwire-native-bridge"
|
|
2
|
-
|
|
3
|
-
export default class extends BridgeComponent {
|
|
4
|
-
static component = "search"
|
|
5
|
-
|
|
6
|
-
connect() {
|
|
7
|
-
super.connect()
|
|
8
|
-
|
|
9
|
-
this.send("connect", {}, (message) => {
|
|
10
|
-
const query = message.data.query
|
|
11
|
-
const detail = {query}
|
|
12
|
-
|
|
13
|
-
this.dispatch("queried", {detail})
|
|
14
|
-
})
|
|
15
|
-
}
|
|
16
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { BridgeComponent } from "@hotwired/hotwire-native-bridge"
|
|
2
|
-
|
|
3
|
-
export default class extends BridgeComponent {
|
|
4
|
-
static component = "tabs"
|
|
5
|
-
static values = { enabled: Boolean }
|
|
6
|
-
|
|
7
|
-
connect() {
|
|
8
|
-
super.connect()
|
|
9
|
-
this.send("connect", { enabled: this.enabledValue })
|
|
10
|
-
}
|
|
11
|
-
}
|