ruflet_rails 0.0.11 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ebf6ba0607ab65bf23420e9d03d39283aac94ad1ffd92bcd6e96c21fa7d79c9a
4
- data.tar.gz: 74bba5b6bbf7976457a49556f5ee3c81c42f7afe30ede8979e5cf6f3f4e77354
3
+ metadata.gz: dc30304299f6e6c539c8fcc838c7f843b54b2d106e6219c657ac8c856c69f9cf
4
+ data.tar.gz: 52ec66b70428d3d1d4ff2d3d7ac4cf6bae34b497addd74e6ba39f8f9c3cc5d3f
5
5
  SHA512:
6
- metadata.gz: d1027674f71e87d89e24e2ca90bb9906fe60a67b7f23d93b30e90e053e7a710439fe8d22774976f9c83cdbf83ca82b28aa6610eeec6178d413430fa105ced16c
7
- data.tar.gz: e55b5f9c8a3549fb37833f5cc88d9950cf35428a2bd688884205b6c83a1ff7d68c627a25469a5893d0b81dd445d5c697fe66b80dcac91c57ae129748da9f1e6b
6
+ metadata.gz: 976c713a63c7a6f3663fbd2541474008e010947a81c6d205cb43f318d6e6fbdaae59c71564f145f34311570518c1910ead0f0278173e270f9ce6bbda3bd4d659
7
+ data.tar.gz: 88d2668bd895b3e817bae881f65ab8fa395ec54377b850a9f7aef163bcf1caa96982656103fdeb8b6034a40271ae1c4dfe80ae43a7f987fd0cf816e56f28cb2d
data/README.md CHANGED
@@ -2,17 +2,18 @@
2
2
 
3
3
  `ruflet_rails` is the Rails-first integration package for Ruflet.
4
4
 
5
- Internal Rails transport/protocol code is bundled inside this gem as `Ruflet::Rails::Protocol`.
6
- No separate protocol gem is required.
5
+ It mounts Ruby-driven Ruflet interfaces in a Rails application, makes Rails
6
+ models available to Ruflet components, and connects web, mobile, and desktop
7
+ clients to the same application entrypoint.
7
8
 
8
- ## Usage
9
+ ## Add The Gem
9
10
 
10
11
  ```ruby
11
12
  # Gemfile
12
- gem "ruflet_rails", ">= 0.0.5"
13
+ gem "ruflet_rails"
13
14
  ```
14
15
 
15
- ## Install into Rails
16
+ ## Install Into Rails
16
17
 
17
18
  ```bash
18
19
  bin/rails generate ruflet:install
@@ -24,7 +25,8 @@ bin/rails generate ruflet:install --web --desktop
24
25
  This generator will:
25
26
  - create `app/views/ruflet/main.rb`
26
27
  - create `ruflet.yaml`
27
- - add the Ruflet mount route to `config/routes.rb`
28
+ - add the Ruflet WebSocket route to `config/routes.rb`
29
+ - add a `/ruflet` web mount when `--web` is used
28
30
  - download prebuilt clients from GitHub releases when `--web`, `--desktop`, or
29
31
  `--client=web|desktop|all` is used
30
32
 
@@ -44,12 +46,30 @@ assets:
44
46
 
45
47
  For Rails apps, those asset paths are resolved from `app/assets/` during build.
46
48
 
47
- ## Build client from Rails
49
+ ## Web client
48
50
 
49
- Uses the same build pipeline as `ruflet build`:
51
+ Rails installs the prebuilt web client into `frontend/`; it does not need
52
+ Flutter source or a Flutter web build:
53
+
54
+ ```bash
55
+ bundle exec rake ruflet:web
56
+ ```
57
+
58
+ Mount the installed client and a developer-owned Ruflet entrypoint:
59
+
60
+ ```ruby
61
+ mount Ruflet::Rails.web_app(app_file: Rails.root.join("app/views/ruflet/main.rb")), at: "/app"
62
+ ```
63
+
64
+ The install generator adds the same mount at `/ruflet` when `--web` is used.
65
+ The mount serves the static client and its WebSocket endpoint together. The
66
+ same `main.rb` also drives native clients through the generated `/ws` route.
67
+
68
+ ## Build native clients from Rails
69
+
70
+ Uses the same native build pipeline as `ruflet build`:
50
71
 
51
72
  ```bash
52
- bundle exec rake ruflet:build[web]
53
73
  bundle exec rake ruflet:build[macos]
54
74
  bundle exec rake ruflet:build[windows]
55
75
  bundle exec rake ruflet:build[linux]
@@ -59,8 +79,6 @@ bundle exec rake ruflet:build[ios]
59
79
  bundle exec rake ruflet:build[aab]
60
80
  ```
61
81
 
62
- Rails web builds are published to `public/ruflet` and served by Rails at `/ruflet/`.
63
-
64
82
  `desktop` is also accepted as a host-platform alias:
65
83
 
66
84
  ```bash
@@ -82,16 +100,14 @@ bin/rails s --desktop
82
100
 
83
101
  ## Update prebuilt clients
84
102
 
85
- Uses the same GitHub release assets as `ruflet update`:
103
+ Reinstall web or update native desktop clients:
86
104
 
87
105
  ```bash
88
- bundle exec rake ruflet:update[web]
106
+ bundle exec rake ruflet:web
89
107
  bundle exec rake ruflet:update[desktop]
90
- bundle exec rake ruflet:update[all]
91
108
  ```
92
109
 
93
- For web, the downloaded static client is published to `public/ruflet` and served
94
- by Rails at `/ruflet/`. The Rails app does not vendor Flutter source code.
110
+ The Rails app does not vendor Flutter source code.
95
111
 
96
112
  ## Install mobile build
97
113
 
@@ -104,39 +120,18 @@ bundle exec rake ruflet:install[DEVICE_ID]
104
120
 
105
121
  ## Ruflet resource scaffolds
106
122
 
107
- Generate a Ruflet CRUD view for an existing Rails model:
123
+ The standard Rails scaffold command also generates a mountable Ruflet CRUD
124
+ component:
108
125
 
109
126
  ```bash
110
- bin/rails generate ruflet:scaffold Post
127
+ bin/rails generate scaffold Post title:string body:text published:boolean
111
128
  ```
112
129
 
113
- The scaffold creates generated app code the Rails developer can own and edit:
130
+ The Rails model attributes are passed to the Ruflet component generator. The
131
+ scaffold creates generated application code the Rails developer can own and
132
+ edit:
114
133
 
115
134
  ```ruby
116
- # app/views/ruflet/posts_view.rb
117
- require_relative "components/posts/post_component"
118
-
119
- class PostView < RufletView
120
- include Ruflet::Rails::FormHelpers
121
-
122
- route "/posts"
123
-
124
- def render
125
- page.title = resource_title
126
- render_index
127
- end
128
-
129
- private
130
-
131
- def records
132
- # edit resource query logic here
133
- end
134
-
135
- def component
136
- @component ||= PostComponent.new(page, controller: self)
137
- end
138
- end
139
-
140
135
  # app/views/ruflet/components/posts/post_component.rb
141
136
  class PostComponent < Ruflet::Rails::ResourceComponent
142
137
  def render
@@ -145,11 +140,19 @@ class PostComponent < Ruflet::Rails::ResourceComponent
145
140
  end
146
141
  ```
147
142
 
148
- The generated view contains the resource logic: query, model helpers, field
149
- introspection, save/delete, dialog close, and display formatting. The generated
150
- component contains the UI: tables, lists, and dialogs. `ruflet_rails` only
151
- provides the base classes and generic helpers. The generator does not dump field
152
- declarations like `title:string` or literal metadata tables into the app.
143
+ Mount it explicitly in `config/routes.rb`:
144
+
145
+ ```ruby
146
+ mount Ruflet::Rails.web_app(view: "PostComponent"), at: "/posts"
147
+ ```
148
+
149
+ The generated component contains the developer-owned UI and persistence calls.
150
+ `ruflet_rails` provides the reusable model, navigation, dialog, and formatting
151
+ helpers. Component files under `app/views/ruflet/components` are loaded by the
152
+ Railtie so both web mounts and `main.rb` can reference them.
153
+
154
+ Use `--skip-ruflet` when a Rails scaffold should not generate a Ruflet
155
+ component.
153
156
 
154
157
  ## Ruflet model forms
155
158
 
@@ -175,8 +178,8 @@ when that base component does not already exist.
175
178
 
176
179
  ## Shared Ruflet components
177
180
 
178
- Put shared Ruflet UI components under `app/views/ruflet/components`. Component
179
- files are loaded before `*_view.rb` files, so views can call them directly:
181
+ Put shared Ruflet UI components under `app/views/ruflet/components`. Those files
182
+ are reloaded with Rails application code:
180
183
 
181
184
  ```ruby
182
185
  # app/views/ruflet/components/page_title_component.rb
@@ -188,11 +191,9 @@ end
188
191
  ```
189
192
 
190
193
  ```ruby
191
- # app/views/ruflet/posts/posts_view.rb
192
- class PostsView < RufletView
193
- def render
194
- page.add(PageTitleComponent.render(page, "Posts"))
195
- end
194
+ # app/views/ruflet/main.rb
195
+ Ruflet.run do |page|
196
+ page.add(PageTitleComponent.render(page, "Posts"))
196
197
  end
197
198
  ```
198
199
 
@@ -6,8 +6,9 @@ require "ruflet/rails/install_support"
6
6
  module Ruflet
7
7
  module Generators
8
8
  class InstallGenerator < ::Rails::Generators::Base
9
+ class_option :web, type: :boolean, default: false, desc: "Install the prebuilt Ruflet web client"
9
10
  class_option :desktop, type: :boolean, default: false, desc: "Download the server-driven desktop Ruflet client"
10
- class_option :client, type: :string, default: nil, desc: "Download prebuilt client from GitHub releases: desktop or none"
11
+ class_option :client, type: :string, default: nil, desc: "Install prebuilt clients: web, desktop, all, or none"
11
12
 
12
13
  desc "Install Ruflet into a Rails app."
13
14
 
@@ -25,11 +26,24 @@ module Ruflet
25
26
  create_file target, Ruflet::Rails::InstallSupport.default_ruflet_yaml(app_name: app_name)
26
27
  end
27
28
 
28
- def create_ruflet_initializer
29
- target = File.join(destination_root, Ruflet::Rails::InstallSupport.initializer_path)
30
- return if File.exist?(target)
29
+ # Mount the native WebSocket endpoint explicitly in config/routes.rb.
30
+ # Nothing is auto-mounted — the dev owns the route, like any other.
31
+ def mount_websocket
32
+ routes = File.join(destination_root, "config", "routes.rb")
33
+ return unless File.file?(routes)
34
+ return if File.read(routes).include?("Ruflet::Rails.app(")
35
+
36
+ route Ruflet::Rails::InstallSupport.route_snippet(entrypoint: entrypoint_path)
37
+ end
38
+
39
+ def mount_web_app
40
+ return unless web_requested?
41
+
42
+ routes = File.join(destination_root, "config", "routes.rb")
43
+ return unless File.file?(routes)
44
+ return if File.read(routes).include?("Ruflet::Rails.web_app(")
31
45
 
32
- create_file target, Ruflet::Rails::InstallSupport.initializer_template(entrypoint: entrypoint_path)
46
+ route Ruflet::Rails::InstallSupport.web_route_snippet(entrypoint: entrypoint_path)
33
47
  end
34
48
 
35
49
  def add_desktop_flag_to_binstubs
@@ -43,14 +57,8 @@ module Ruflet
43
57
  client = requested_client
44
58
  return if client == "none"
45
59
 
46
- require "ruflet/cli"
47
- exit_code = Dir.chdir(destination_root) do
48
- Ruflet::CLI.command_update([client])
49
- end
50
- unless exit_code.to_i.zero?
51
- @client_download_failed = true
52
- say_status(:warn, "Ruflet client download failed; install files were generated and build/update steps are printed below", :yellow)
53
- end
60
+ install_web_client if %w[web all].include?(client)
61
+ install_desktop_client if %w[desktop all].include?(client)
54
62
  rescue StandardError => e
55
63
  @client_download_failed = true
56
64
  say_status(:warn, "Ruflet client download failed: #{e.class}: #{e.message}", :yellow)
@@ -77,24 +85,47 @@ module Ruflet
77
85
  def requested_client
78
86
  explicit = options[:client].to_s.strip.downcase
79
87
  unless explicit.empty?
80
- raise Thor::Error, "--client must be desktop or none" unless %w[desktop none].include?(explicit)
88
+ raise Thor::Error, "--client must be web, desktop, all, or none" unless %w[web desktop all none].include?(explicit)
81
89
 
82
90
  return explicit
83
91
  end
84
92
 
93
+ return "all" if options[:web] && options[:desktop]
94
+ return "web" if options[:web]
85
95
  return "desktop" if options[:desktop]
86
96
 
87
97
  "none"
88
98
  end
89
99
 
90
100
  def desktop_requested?
91
- requested_client == "desktop"
101
+ %w[desktop all].include?(requested_client)
102
+ end
103
+
104
+ def web_requested?
105
+ %w[web all].include?(requested_client)
92
106
  end
93
107
 
94
108
  def install_target
95
109
  "ruflet"
96
110
  end
97
111
 
112
+ def install_web_client
113
+ return if Ruflet::Rails::WebInstaller.install!(root: destination_root)
114
+
115
+ client_download_failed("web")
116
+ end
117
+
118
+ def install_desktop_client
119
+ require "ruflet/cli"
120
+ exit_code = Dir.chdir(destination_root) { Ruflet::CLI.command_update(["desktop"]) }
121
+ client_download_failed("desktop") unless exit_code.to_i.zero?
122
+ end
123
+
124
+ def client_download_failed(client)
125
+ @client_download_failed = true
126
+ say_status(:warn, "Ruflet #{client} client download failed; install files were still generated", :yellow)
127
+ end
128
+
98
129
  def install_desktop_flag_bootstrap(relative_path)
99
130
  target = File.join(destination_root, relative_path)
100
131
  return unless File.file?(target)
@@ -4,20 +4,14 @@ module Ruflet
4
4
  module Rails
5
5
  # Central configuration for ruflet_rails.
6
6
  #
7
- # Mirrors the full ruflet.yaml schema so a Rails app needs only
8
- # config/initializers/ruflet.rb no ruflet.yaml on disk.
9
- #
10
- # Set in config/initializers/ruflet.rb:
7
+ # An install needs no config/initializers/ruflet.rb: routes mount
8
+ # app/views/ruflet/main.rb explicitly and build metadata is read from
9
+ # ruflet.yaml. Add an initializer only to override these settings:
11
10
  #
12
11
  # Ruflet::Rails.configure do |config|
13
12
  # # Runtime / server
14
- # config.app_file = Rails.root.join("app/views/ruflet/main.rb")
15
- # config.ws_path = "/ws"
16
13
  # config.backend_url = Rails.env.production? ? "https://example.com" : "http://localhost:3000"
17
14
  #
18
- # # Flutter web build output directory
19
- # config.web_build_dir = Rails.root.join("public/app")
20
- #
21
15
  # # App metadata (ruflet.yaml → app:)
22
16
  # config.app_name = "My App"
23
17
  #
@@ -43,19 +37,10 @@ module Ruflet
43
37
  class Configuration
44
38
  # --- Runtime / server ---
45
39
 
46
- # Absolute path to the Ruflet app entry-point.
47
- attr_accessor :app_file
48
-
49
- # URL path the WebSocket endpoint listens on. Defaults to "/ws".
50
- attr_accessor :ws_path
51
-
52
40
  # Backend base URL. Used as --dart-define=RUFLET_URL at build time
53
41
  # and by the desktop launcher. Replaces ruflet.yaml → app.backend_url.
54
42
  attr_accessor :backend_url
55
43
 
56
- # Absolute directory containing the Flutter web build (index.html + assets).
57
- attr_accessor :web_build_dir
58
-
59
44
  # --- App metadata (ruflet.yaml → app:) ---
60
45
 
61
46
  attr_accessor :app_name
@@ -83,12 +68,9 @@ module Ruflet
83
68
  attr_accessor :theme_color
84
69
 
85
70
  def initialize
86
- @ws_path = "/ws"
87
- @app_file = nil
88
- @backend_url = nil
89
- @web_build_dir = nil
90
- @app_name = nil
91
- @services = []
71
+ @backend_url = nil
72
+ @app_name = nil
73
+ @services = []
92
74
  end
93
75
 
94
76
  # Serialises config to the ruflet.yaml hash structure so the CLI can
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ruflet
4
+ module Rails
5
+ module GeneratorHooks
6
+ module_function
7
+
8
+ def install!
9
+ require "active_support/core_ext/string/filters"
10
+ require "rails/generators/rails/scaffold/scaffold_generator"
11
+ require "generators/ruflet/scaffold/scaffold_generator"
12
+
13
+ generator = ::Rails::Generators::ScaffoldGenerator
14
+ return if generator.class_options.key?(:ruflet)
15
+
16
+ generator.hook_for(
17
+ :ruflet,
18
+ type: :boolean,
19
+ default: true,
20
+ desc: "Generate a Ruflet resource component"
21
+ )
22
+ end
23
+ end
24
+ end
25
+ end
@@ -10,18 +10,33 @@ module Ruflet
10
10
  module_function
11
11
 
12
12
  def default_app_template(app_title:)
13
- template = <<~RUBY
14
- require "ruflet"
15
- require "ruflet_rails"
16
-
17
- Ruflet::Rails.load_views(__dir__)
13
+ <<~RUBY
14
+ # frozen_string_literal: true
18
15
 
16
+ # The home screen for this Ruflet app. You own this file — declare your
17
+ # screens here; nothing is auto-discovered. It is mounted explicitly in
18
+ # config/routes.rb (the install generator adds this line):
19
+ # match "/ws", to: Ruflet::Rails.app(Rails.root.join("app/views/ruflet/main.rb")), via: :all
19
20
  Ruflet.run do |page|
20
21
  page.title = #{app_title.inspect}
21
- Ruflet::Rails.render(page)
22
+ page.add(
23
+ safe_area(
24
+ container(
25
+ expand: true,
26
+ padding: 24,
27
+ content: column(
28
+ spacing: 12,
29
+ controls: [
30
+ text(#{app_title.inspect}, size: 24, weight: "bold"),
31
+ text("Edit app/views/ruflet/main.rb to build your app.")
32
+ ]
33
+ )
34
+ ),
35
+ expand: true
36
+ )
37
+ )
22
38
  end
23
39
  RUBY
24
- template.gsub(/^ /, " ")
25
40
  end
26
41
 
27
42
  def application_component_template
@@ -90,10 +105,6 @@ module Ruflet
90
105
  File.join("app", "views", "ruflet", "components", "application_component.rb")
91
106
  end
92
107
 
93
- def default_mobile_app_template(app_title:)
94
- default_app_template(app_title: app_title)
95
- end
96
-
97
108
  def model_names(model_name)
98
109
  raw = model_name.to_s.strip
99
110
  class_name = raw.camelize
@@ -673,22 +684,6 @@ module Ruflet
673
684
  YAML
674
685
  end
675
686
 
676
- def desktop_initializer_path
677
- File.join("config", "initializers", "ruflet_desktop.rb")
678
- end
679
-
680
- def desktop_initializer_template
681
- <<~RUBY
682
- # frozen_string_literal: true
683
-
684
- # Set this to true when you intentionally want the Rails server process to
685
- # launch the server-driven Ruflet desktop client.
686
- Rails.application.configure do
687
- config.x.ruflet_rails.desktop = false
688
- end
689
- RUBY
690
- end
691
-
692
687
  def ruby_desktop_flag_bootstrap
693
688
  <<~RUBY
694
689
  # ruflet_rails desktop flag
@@ -746,70 +741,41 @@ module Ruflet
746
741
  value
747
742
  end
748
743
 
744
+ # ruflet_rails builds only native clients. The web client is installed
745
+ # prebuilt (rake ruflet:web), never compiled, so "web" is not a build
746
+ # target here.
749
747
  def build_args_for_platform(platform, ruflet_url: nil)
750
748
  normalized = normalize_build_platform(platform)
751
749
  return [] if normalized.to_s.empty?
750
+ return [] if normalized == "web"
752
751
 
753
- args = [normalized]
754
- args += ["--dart-define", "RUFLET_URL=#{ruflet_url}"] if normalized == "web" && ruflet_url.to_s.strip != ""
755
- args
752
+ [normalized]
756
753
  end
757
754
 
758
755
  def default_entrypoint_path
759
756
  File.join("app", "views", "ruflet", "main.rb")
760
757
  end
761
758
 
762
- def initializer_template(entrypoint: default_entrypoint_path, ws_path: "/ws")
763
- <<~RUBY
764
- # frozen_string_literal: true
765
-
766
- Ruflet::Rails.configure do |config|
767
- # Ruflet app entry-point. Auto-mounts a WebSocket endpoint at ws_path —
768
- # no explicit route needed in config/routes.rb.
769
- config.app_file = Rails.root.join(#{entrypoint.inspect})
770
-
771
- # URL path the WebSocket endpoint listens on (default: "/ws").
772
- config.ws_path = #{ws_path.inspect}
773
-
774
- # Base URL the Flutter client uses to reach this Rails app. Always
775
- # required: it backs asset URLs (Ruflet::Rails.asset_url), the
776
- # build-time RUFLET_URL define, and the desktop launcher. At runtime
777
- # it can fall back to the connecting host, but a build has no request,
778
- # so set it here. Point it at a LAN IP (not localhost) to test on a
779
- # real device.
780
- config.backend_url = ENV.fetch("RUFLET_BACKEND_URL") do
781
- Rails.env.production? ? "https://example.com" : "http://localhost:3000"
782
- end
783
-
784
- # Directory the Flutter web build is served from. Defaults to
785
- # Rails.root/build/web (where `rake ruflet:build[web]` outputs).
786
- # Must stay OUTSIDE public/, or Rails would serve it statically and
787
- # expose the app at a path no route declares.
788
- # config.web_build_dir = Rails.root.join("build", "web")
789
- end
790
- RUBY
791
- end
792
-
793
- def initializer_path
794
- File.join("config", "initializers", "ruflet.rb")
795
- end
796
-
797
759
  # Kept for backward compatibility with apps that use manual mount.
798
760
  def route_snippet(entrypoint: default_entrypoint_path, mount_path: "/ws", helper: "app")
799
761
  %(match "#{mount_path}", to: Ruflet::Rails.#{helper}(Rails.root.join("#{entrypoint}")), via: :all)
800
762
  end
801
763
 
764
+ def web_route_snippet(entrypoint: default_entrypoint_path, mount_path: "/ruflet")
765
+ %(mount Ruflet::Rails.web_app(app_file: Rails.root.join("#{entrypoint}")), at: "#{mount_path}")
766
+ end
767
+
802
768
  def install_next_steps(target:, entrypoint:, client:, mount_path: "/ws")
803
769
  lines = [
804
770
  "Ruflet Rails installed.",
805
771
  "Generated entrypoint: #{entrypoint}",
806
- "Mounted websocket: #{mount_path}",
772
+ "Added WebSocket route #{mount_path} to config/routes.rb",
807
773
  "Next steps:",
808
774
  " 1. Start Rails: bin/rails server",
809
775
  " 2. Connect your Ruflet app to ws://localhost:3000#{mount_path}"
810
776
  ]
811
777
 
812
- if client.to_s == "desktop"
778
+ if %w[desktop all].include?(client.to_s)
813
779
  lines += [
814
780
  "Desktop clients are server-driven and connect to this Rails app.",
815
781
  "Plain bin/dev, bin/rails server, and bin/rails s do not launch desktop.",
@@ -819,6 +785,13 @@ module Ruflet
819
785
  ]
820
786
  end
821
787
 
788
+ if %w[web all].include?(client.to_s)
789
+ lines += [
790
+ "Web client installed into frontend/.",
791
+ "Open the mounted Ruflet web app at http://localhost:3000/ruflet"
792
+ ]
793
+ end
794
+
822
795
  lines
823
796
  end
824
797
  end
@@ -4,7 +4,7 @@ require "uri"
4
4
 
5
5
  module Ruflet
6
6
  module Rails
7
- # Hotwire Native-style driver for ruflet_rails.
7
+ # Managed webview navigation driver for ruflet_rails.
8
8
  #
9
9
  # Your existing web app is the body, rendered in a WebView. Navigation works
10
10
  # out of the box: a tiny JS bridge injected into each page intercepts link
@@ -122,6 +122,7 @@ module Ruflet
122
122
  Ruflet::UI::ControlFactory.build(
123
123
  :webview,
124
124
  url: screen.url,
125
+ method: "get",
125
126
  expand: true,
126
127
  on_page_ended: ->(_event) { inject_bridge(screen) },
127
128
  on_console_message: ->(event) { handle_message(screen, message_of(event)) }
@@ -190,7 +191,7 @@ module Ruflet
190
191
  # --- Modal (bottom sheet of web content) -------------------------------
191
192
 
192
193
  def present_modal(url)
193
- sheet_webview = Ruflet::UI::ControlFactory.build(:webview, url: url.to_s, expand: true)
194
+ sheet_webview = Ruflet::UI::ControlFactory.build(:webview, url: url.to_s, method: "get", expand: true)
194
195
  @modal_sheet = Ruflet::UI::ControlFactory.build(
195
196
  :bottomsheet,
196
197
  open: true,
@@ -245,7 +246,7 @@ module Ruflet
245
246
 
246
247
  module_function
247
248
 
248
- # Start a Hotwire Native-style app. See NativeApp.
249
+ # Start a managed webview app. See NativeApp.
249
250
  def native_app(page, **opts)
250
251
  NativeApp.new(page, **opts).start
251
252
  end
@@ -26,8 +26,6 @@ module Ruflet
26
26
  path: path
27
27
  )
28
28
  end
29
- alias build_mobile_endpoint build_app_endpoint
30
-
31
29
  private
32
30
 
33
31
  def build_server(entrypoint)