ruby_native 0.9.3 → 0.10.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: bea37c1e721c525bee3535c67771d53969d46eca1458cbdf3948c5b6cb7c1bcc
4
- data.tar.gz: 63963d9b8707c01862cc9a603e0a26baf8ae91eb4f84a84404c955b1a1e0742b
3
+ metadata.gz: 78d36e84e6d0ebfefb6461526fcf8cdfa8fd30952bb013b4a632f4f1ab91eb74
4
+ data.tar.gz: a81d356f6aed9aeca458531d832e0a81813eeecde701328b727019661dc43f49
5
5
  SHA512:
6
- metadata.gz: 0e97a991d0bc54079de18af9be52f4bc7e3df3e57229047a1c424e7ea89329db48a1d8f3715cd3cdd37ef026afbc01185985192fc6d7dabf7d3d7d8ea869237b
7
- data.tar.gz: 31c81f18e641df0c60f6b1f97e3c5f8086dd7f9962353655b71a3fb935050e3be8853491c1a4b0fae0af55371ba10fab566fb5d66ef23f1e6dd98af6ae21e919
6
+ metadata.gz: 5ed6f7fb6bf0847342695cf57e7037654de5bf4c461d6bea04a477904f8ecc6bc4d7c3b90f20cac6bf1718d0d2e3fcbf04623fe31b5c617afd22907c6bb620d1
7
+ data.tar.gz: 770a073e3f8805ed04d4a0cf7e9e47d477dfcfb5da96be34a08eca14767c3c6fc1b4c7a1cb05715d9fb1c1145c92c3ab4303349d7e8765c6c0bb7db4157bc352
@@ -2,18 +2,22 @@
2
2
  display: none !important;
3
3
  }
4
4
 
5
+ /* Android's WebView doesn't populate env(safe-area-inset-*) from system bars
6
+ (only display cutouts), so the native shell pushes the real top/bottom
7
+ system bar heights into these CSS variables. iOS leaves the variables
8
+ undefined and falls back to env(), which works there. */
5
9
  .native-inset-top::before,
6
10
  .native-inset::before {
7
11
  content: "";
8
12
  display: block;
9
- height: env(safe-area-inset-top);
13
+ height: var(--ruby-native-safe-area-inset-top, env(safe-area-inset-top));
10
14
  }
11
15
 
12
16
  .native-inset-bottom::after,
13
17
  .native-inset::after {
14
18
  content: "";
15
19
  display: block;
16
- height: env(safe-area-inset-bottom);
20
+ height: var(--ruby-native-safe-area-inset-bottom, env(safe-area-inset-bottom));
17
21
  }
18
22
 
19
23
  .native-back-button {
@@ -0,0 +1,24 @@
1
+ module RubyNative
2
+ class AasaController < ::ActionController::Base
3
+ def show
4
+ RubyNative.load_config if Rails.env.development?
5
+
6
+ bundle_id = RubyNative.config&.dig(:ios, :bundle_id)
7
+ team_id = RubyNative.config&.dig(:ios, :team_id)
8
+ return head :not_found unless bundle_id.present? && team_id.present?
9
+
10
+ app_id = "#{team_id}.#{bundle_id}"
11
+ response.set_header("Cache-Control", "no-cache")
12
+ render json: {
13
+ applinks: {
14
+ details: [
15
+ { appIDs: [ app_id ], components: [ { "/": "*" } ] }
16
+ ]
17
+ },
18
+ webcredentials: {
19
+ apps: [ app_id ]
20
+ }
21
+ }
22
+ end
23
+ end
24
+ end
@@ -129,6 +129,23 @@ The gem auto-mounts at `/native`. No route configuration needed.
129
129
 
130
130
  - `GET /native/config` returns the YAML config as JSON
131
131
  - `POST /native/push/devices` registers a push notification device token
132
+ - `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)
133
+
134
+ ## Linked domains
135
+
136
+ 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`:
137
+
138
+ ```yaml
139
+ ios:
140
+ bundle_id: com.example.myapp
141
+ team_id: ABCD123456
142
+ ```
143
+
144
+ 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.
145
+
146
+ Apple caches the file aggressively. After the first install, changes can take up to 24 hours to propagate via Apple's CDN.
147
+
148
+ Full reference: https://rubynative.com/docs/linked-domains
132
149
 
133
150
  ## Push notifications
134
151
 
@@ -1,26 +1,82 @@
1
+ # Ruby Native reads this file on launch to configure the native app.
2
+ # Edit and relaunch the native app to see changes.
3
+
4
+ # Configure how the app launches and navigates between pages.
5
+ # https://rubynative.com/docs/advanced-mode
1
6
  app:
2
- mode: normal # normal or advanced
3
- # entry_path: /inbox # Initial URL on app launch (defaults to first tab's path)
7
+ # Navigation mode. Options:
8
+ # normal - no screen transitions (default)
9
+ # advanced - Hotwire Native navigator with native transitions
10
+ mode: normal
11
+
12
+ # First URL shown when the app launches.
13
+ # Default: the first tab's path.
14
+ # entry_path: /inbox
4
15
 
16
+ # Configure the app's colors, theme, and orientation.
17
+ # https://rubynative.com/docs/appearance
5
18
  appearance:
19
+ # Color of interactive elements (links, buttons, tab selection).
20
+ # Accepts a hex string, or { light:, dark: } for dark mode support.
6
21
  tint_color: "#007AFF"
22
+
23
+ # Color shown briefly during launch and as the safe-area fill.
24
+ # Accepts a hex string, or { light:, dark: } for dark mode support.
7
25
  background_color: "#FFFFFF"
8
- # theme: auto # auto (default), light, or dark
9
- # landscape: true # Allow landscape orientation on iPhone (defaults to portrait only)
10
- # Dark mode example (replace the plain string above):
11
- # background_color:
12
- # light: "#FFFFFF"
13
- # dark: "#1C1C1E"
14
26
 
27
+ # Light/dark theme. Options:
28
+ # auto - follows system setting (default)
29
+ # light - force light mode
30
+ # dark - force dark mode
31
+ # theme: auto
32
+
33
+ # Enable device rotation.
34
+ # Default: false (portrait-only).
35
+ # landscape: true
36
+
37
+ # Configure the native tab bar on the bottom of the screen.
38
+ # https://rubynative.com/docs/tabs
15
39
  tabs:
40
+ # Icons are SF Symbols on iOS and Material Icons on Android.
41
+ # https://rubynative.com/docs/icons
16
42
  - title: Home
17
43
  path: /
18
44
  icon: house
19
- # auto_route: false # Disable automatic tab switching for this tab (e.g., "/" matches everything)
20
- # auto_route: # Or provide explicit route prefixes (replaces default prefix match):
21
- # - /
22
- # - /pages/
23
45
  - title: Profile
24
46
  path: /profile
25
47
  icon: person
26
- # eager: true # Load this tab on app launch instead of when first tapped
48
+
49
+ # Per-tab options (add to any tab above):
50
+ #
51
+ # # Load this tab on launch instead of lazily.
52
+ # # Default: false.
53
+ # eager: true
54
+ #
55
+ # # Show a search field in the navigation bar.
56
+ # # Default: false.
57
+ # search: true
58
+ #
59
+ # # Allow this tab to show a notification badge.
60
+ # # Default: false.
61
+ # badge: true
62
+ #
63
+ # # Routes that switch to this tab. Options:
64
+ # # false - never auto-switch
65
+ # # [/orders/, /a/] - switch when visiting these path prefixes
66
+ # # Default: routes matching the tab's path prefix.
67
+ # auto_route: [/orders/]
68
+
69
+ # Link your domain to the app to share passwords from your site. Also,
70
+ # tapping a link to your site opens in the app instead of the browser.
71
+ # https://rubynative.com/docs/linked-domains
72
+ # ios:
73
+ # bundle_id: com.example.myapp
74
+ # team_id: ABCD123456
75
+
76
+ # Enable OAuth. Each path triggers a native ASWebAuthenticationSession
77
+ # on iOS instead of an in-app web view.
78
+ # https://rubynative.com/docs/oauth
79
+ # auth:
80
+ # oauth_paths:
81
+ # - /auth/google
82
+ # - /auth/github
@@ -13,36 +13,44 @@ module RubyNative
13
13
  PUBLIC_NAMESERVERS = ["1.1.1.1", "8.8.8.8"].freeze
14
14
 
15
15
  def initialize(argv)
16
+ @url = parse_option(argv, "--url")
16
17
  @port = parse_port(argv)
18
+ @upstream = @url || "http://localhost:#{@port}"
17
19
  end
18
20
 
19
21
  def run
20
22
  check_cloudflared!
21
- check_local_server!
23
+ check_upstream!
22
24
  start_tunnel
23
25
  end
24
26
 
25
27
  private
26
28
 
27
- def check_local_server!
28
- uri = URI("http://localhost:#{@port}#{CONFIG_PATH}")
29
+ def check_upstream!
30
+ uri = URI("#{@upstream}#{CONFIG_PATH}")
29
31
  response = fetch_config_response(uri)
30
32
 
31
33
  return if response.is_a?(Net::HTTPSuccess)
32
34
 
33
- puts "Rails server is running on port #{@port}, but #{CONFIG_PATH} returned #{response.code}."
35
+ puts "Rails server is reachable at #{@upstream}, but #{CONFIG_PATH} returned #{response.code}."
34
36
  puts ""
35
37
  puts "Make sure the ruby_native gem is installed and mounted:"
36
38
  puts " https://rubynative.com/docs/install"
37
39
  exit 1
38
40
  rescue Errno::ECONNREFUSED
39
- puts "Nothing is running on port #{@port}."
40
- puts ""
41
- puts "Start your Rails server in another terminal:"
42
- puts " bin/rails server -p #{@port}"
41
+ if @url
42
+ puts "Could not connect to #{@url}."
43
+ puts ""
44
+ puts "Make sure your Rails server is reachable at that URL."
45
+ else
46
+ puts "Nothing is running on port #{@port}."
47
+ puts ""
48
+ puts "Start your Rails server in another terminal:"
49
+ puts " bin/rails server -p #{@port}"
50
+ end
43
51
  exit 1
44
52
  rescue => e
45
- puts "Could not reach http://localhost:#{@port}#{CONFIG_PATH}: #{e.message}"
53
+ puts "Could not reach #{@upstream}#{CONFIG_PATH}: #{e.message}"
46
54
  exit 1
47
55
  end
48
56
 
@@ -100,12 +108,13 @@ module RubyNative
100
108
  end
101
109
 
102
110
  def parse_port(argv)
103
- index = argv.index("--port")
104
- if index
105
- argv[index + 1]&.to_i || 3000
106
- else
107
- 3000
108
- end
111
+ value = parse_option(argv, "--port")
112
+ value ? value.to_i : 3000
113
+ end
114
+
115
+ def parse_option(argv, flag)
116
+ index = argv.index(flag)
117
+ index ? argv[index + 1] : nil
109
118
  end
110
119
 
111
120
  def check_cloudflared!
@@ -121,12 +130,16 @@ module RubyNative
121
130
  end
122
131
 
123
132
  def start_tunnel
124
- puts "Starting tunnel to http://localhost:#{@port}..."
125
- puts "Make sure your Rails server is running on port #{@port} in another terminal."
133
+ puts "Starting tunnel to #{@upstream}..."
134
+ if @url
135
+ puts "Make sure your Rails server is reachable at #{@url}."
136
+ else
137
+ puts "Make sure your Rails server is running on port #{@port} in another terminal."
138
+ end
126
139
  puts ""
127
140
 
128
141
  stdin, stdout_err, wait_thread = Open3.popen2e(
129
- "cloudflared", "tunnel", "--url", "http://localhost:#{@port}"
142
+ "cloudflared", "tunnel", "--url", @upstream
130
143
  )
131
144
  stdin.close
132
145
 
@@ -175,7 +188,11 @@ module RubyNative
175
188
  puts url
176
189
  puts ""
177
190
  puts "Scan the QR code or paste the URL into the Ruby Native Preview app."
178
- puts "Keep this running and your Rails server on port #{@port} in another terminal."
191
+ if @url
192
+ puts "Keep this running and your Rails server reachable at #{@url}."
193
+ else
194
+ puts "Keep this running and your Rails server on port #{@port} in another terminal."
195
+ end
179
196
  puts "Press Ctrl+C to stop."
180
197
  end
181
198
 
@@ -50,6 +50,7 @@ module RubyNative
50
50
 
51
51
  initializer "ruby_native.routes" do |app|
52
52
  app.routes.prepend do
53
+ get "/.well-known/apple-app-site-association", to: "ruby_native/aasa#show"
53
54
  mount RubyNative::Engine, at: "/native"
54
55
  end
55
56
  end
@@ -46,11 +46,13 @@ module RubyNative
46
46
  tag.div(data: data, hidden: true)
47
47
  end
48
48
 
49
- def native_navbar_tag(title = nil, &block)
49
+ def native_navbar_tag(title = nil, pull_to_refresh: true, &block)
50
50
  builder = NavbarBuilder.new(self)
51
51
  capture(builder, &block) if block
52
52
 
53
- tag.div(data: { native_navbar: title.to_s }, hidden: true) { builder.to_html }
53
+ data = { native_navbar: title.to_s }
54
+ data[:native_pull_to_refresh] = "false" unless pull_to_refresh
55
+ tag.div(data: data, hidden: true) { builder.to_html }
54
56
  end
55
57
 
56
58
  def native_fab_tag(icon: nil, icons: nil, href: nil, click: nil)
@@ -1,3 +1,3 @@
1
1
  module RubyNative
2
- VERSION = "0.9.3"
2
+ VERSION = "0.10.0"
3
3
  end
data/lib/ruby_native.rb CHANGED
@@ -39,7 +39,6 @@ module RubyNative
39
39
 
40
40
  self.config = YAML.load_file(path).deep_symbolize_keys
41
41
  self.config[:app] ||= {}
42
- self.config[:app][:name] ||= "Ruby Native"
43
42
  self.config[:app][:entry_path] ||= self.config.dig(:tabs, 0, :path) || "/"
44
43
  self.config[:auth] ||= {}
45
44
  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.9.3
4
+ version: 0.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joe Masilotti
@@ -63,6 +63,7 @@ files:
63
63
  - LICENSE
64
64
  - README.md
65
65
  - app/assets/stylesheets/ruby_native.css
66
+ - app/controllers/ruby_native/aasa_controller.rb
66
67
  - app/controllers/ruby_native/auth/sessions_controller.rb
67
68
  - app/controllers/ruby_native/auth/start_controller.rb
68
69
  - app/controllers/ruby_native/config_controller.rb