ruflet_rails 0.0.10 → 0.0.12
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 +42 -48
- data/lib/generators/ruflet/install/install_generator.rb +45 -18
- data/lib/generators/ruflet/scaffold/scaffold_generator.rb +10 -16
- data/lib/ruflet/rails/assets.rb +87 -0
- data/lib/ruflet/rails/configuration.rb +111 -0
- data/lib/ruflet/rails/install_support.rb +84 -154
- data/lib/ruflet/rails/native_app.rb +253 -0
- data/lib/ruflet/rails/protocol/endpoint.rb +3 -11
- data/lib/ruflet/rails/protocol/local_server.rb +27 -194
- data/lib/ruflet/rails/protocol/runner.rb +0 -2
- data/lib/ruflet/rails/protocol/web_app.rb +243 -0
- data/lib/ruflet/rails/protocol/websocket_detection.rb +19 -0
- data/lib/ruflet/rails/protocol.rb +2 -3
- data/lib/ruflet/rails/railtie.rb +63 -40
- data/lib/ruflet/rails/resource_component.rb +188 -8
- data/lib/ruflet/rails/route_stack.rb +90 -0
- data/lib/ruflet/rails/view_helpers.rb +58 -0
- data/lib/ruflet/rails/web_installer.rb +137 -0
- data/lib/ruflet/rails/webview_app.rb +54 -0
- data/lib/ruflet/rails.rb +90 -147
- data/lib/ruflet/version.rb +1 -1
- data/lib/ruflet_rails.rb +7 -2
- metadata +16 -12
- data/lib/ruflet/rails/protocol/middleware.rb +0 -17
- data/lib/ruflet/rails/protocol/web_socket_connection.rb +0 -11
- data/lib/ruflet/rails/protocol/wire_codec.rb +0 -11
- data/lib/ruflet/rails/resource_view.rb +0 -124
- data/lib/ruflet/rails/view.rb +0 -57
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: d142d63121dae012354a763ef756504d64534adbc4b2c11eaf0dc51b514c6b32
|
|
4
|
+
data.tar.gz: d3d1e6cbf9af94c81d5514b71325484e547b40ba34afe3d8601a111f08e4af6a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: daf5bf66b258ece12da18cbb4c455d2f9f5dd141faa3638c2ef0ec9a64d85be9b25d94add15ae0374a96c6694f6e393ee015290df62368bd1d9cd6920a3185f3
|
|
7
|
+
data.tar.gz: 075def7cfb22688619559ba1ca55ede0d4c152c403c95a2273c1fa322a2862b20aafe7bda0507bf73bb4a8e8f40e03eb6c87b9505900fb31aa3ac08098dbf88b
|
data/README.md
CHANGED
|
@@ -24,7 +24,8 @@ bin/rails generate ruflet:install --web --desktop
|
|
|
24
24
|
This generator will:
|
|
25
25
|
- create `app/views/ruflet/main.rb`
|
|
26
26
|
- create `ruflet.yaml`
|
|
27
|
-
- add the Ruflet
|
|
27
|
+
- add the Ruflet WebSocket route to `config/routes.rb`
|
|
28
|
+
- add a `/ruflet` web mount when `--web` is used
|
|
28
29
|
- download prebuilt clients from GitHub releases when `--web`, `--desktop`, or
|
|
29
30
|
`--client=web|desktop|all` is used
|
|
30
31
|
|
|
@@ -44,12 +45,30 @@ assets:
|
|
|
44
45
|
|
|
45
46
|
For Rails apps, those asset paths are resolved from `app/assets/` during build.
|
|
46
47
|
|
|
47
|
-
##
|
|
48
|
+
## Web client
|
|
48
49
|
|
|
49
|
-
|
|
50
|
+
Rails installs the prebuilt web client into `frontend/`; it does not need
|
|
51
|
+
Flutter source or a Flutter web build:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
bundle exec rake ruflet:web
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Mount the installed client and a developer-owned Ruflet entrypoint:
|
|
58
|
+
|
|
59
|
+
```ruby
|
|
60
|
+
mount Ruflet::Rails.web_app(app_file: Rails.root.join("app/views/ruflet/main.rb")), at: "/app"
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
The install generator adds the same mount at `/ruflet` when `--web` is used.
|
|
64
|
+
The mount serves the static client and its WebSocket endpoint together. The
|
|
65
|
+
same `main.rb` also drives native clients through the generated `/ws` route.
|
|
66
|
+
|
|
67
|
+
## Build native clients from Rails
|
|
68
|
+
|
|
69
|
+
Uses the same native build pipeline as `ruflet build`:
|
|
50
70
|
|
|
51
71
|
```bash
|
|
52
|
-
bundle exec rake ruflet:build[web]
|
|
53
72
|
bundle exec rake ruflet:build[macos]
|
|
54
73
|
bundle exec rake ruflet:build[windows]
|
|
55
74
|
bundle exec rake ruflet:build[linux]
|
|
@@ -59,8 +78,6 @@ bundle exec rake ruflet:build[ios]
|
|
|
59
78
|
bundle exec rake ruflet:build[aab]
|
|
60
79
|
```
|
|
61
80
|
|
|
62
|
-
Rails web builds are published to `public/ruflet` and served by Rails at `/ruflet/`.
|
|
63
|
-
|
|
64
81
|
`desktop` is also accepted as a host-platform alias:
|
|
65
82
|
|
|
66
83
|
```bash
|
|
@@ -82,16 +99,14 @@ bin/rails s --desktop
|
|
|
82
99
|
|
|
83
100
|
## Update prebuilt clients
|
|
84
101
|
|
|
85
|
-
|
|
102
|
+
Reinstall web or update native desktop clients:
|
|
86
103
|
|
|
87
104
|
```bash
|
|
88
|
-
bundle exec rake ruflet:
|
|
105
|
+
bundle exec rake ruflet:web
|
|
89
106
|
bundle exec rake ruflet:update[desktop]
|
|
90
|
-
bundle exec rake ruflet:update[all]
|
|
91
107
|
```
|
|
92
108
|
|
|
93
|
-
|
|
94
|
-
by Rails at `/ruflet/`. The Rails app does not vendor Flutter source code.
|
|
109
|
+
The Rails app does not vendor Flutter source code.
|
|
95
110
|
|
|
96
111
|
## Install mobile build
|
|
97
112
|
|
|
@@ -104,7 +119,7 @@ bundle exec rake ruflet:install[DEVICE_ID]
|
|
|
104
119
|
|
|
105
120
|
## Ruflet resource scaffolds
|
|
106
121
|
|
|
107
|
-
Generate a Ruflet CRUD
|
|
122
|
+
Generate a mountable Ruflet CRUD component for an existing Rails model:
|
|
108
123
|
|
|
109
124
|
```bash
|
|
110
125
|
bin/rails generate ruflet:scaffold Post
|
|
@@ -113,30 +128,6 @@ bin/rails generate ruflet:scaffold Post
|
|
|
113
128
|
The scaffold creates generated app code the Rails developer can own and edit:
|
|
114
129
|
|
|
115
130
|
```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
131
|
# app/views/ruflet/components/posts/post_component.rb
|
|
141
132
|
class PostComponent < Ruflet::Rails::ResourceComponent
|
|
142
133
|
def render
|
|
@@ -145,11 +136,16 @@ class PostComponent < Ruflet::Rails::ResourceComponent
|
|
|
145
136
|
end
|
|
146
137
|
```
|
|
147
138
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
139
|
+
Mount it explicitly in `config/routes.rb`:
|
|
140
|
+
|
|
141
|
+
```ruby
|
|
142
|
+
mount Ruflet::Rails.web_app(view: "PostComponent"), at: "/posts"
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
The generated component contains the developer-owned UI and persistence calls.
|
|
146
|
+
`ruflet_rails` provides the reusable model, navigation, dialog, and formatting
|
|
147
|
+
helpers. Component files under `app/views/ruflet/components` are loaded by the
|
|
148
|
+
Railtie so both web mounts and `main.rb` can reference them.
|
|
153
149
|
|
|
154
150
|
## Ruflet model forms
|
|
155
151
|
|
|
@@ -175,8 +171,8 @@ when that base component does not already exist.
|
|
|
175
171
|
|
|
176
172
|
## Shared Ruflet components
|
|
177
173
|
|
|
178
|
-
Put shared Ruflet UI components under `app/views/ruflet/components`.
|
|
179
|
-
|
|
174
|
+
Put shared Ruflet UI components under `app/views/ruflet/components`. Those files
|
|
175
|
+
are reloaded with Rails application code:
|
|
180
176
|
|
|
181
177
|
```ruby
|
|
182
178
|
# app/views/ruflet/components/page_title_component.rb
|
|
@@ -188,11 +184,9 @@ end
|
|
|
188
184
|
```
|
|
189
185
|
|
|
190
186
|
```ruby
|
|
191
|
-
# app/views/ruflet/
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
page.add(PageTitleComponent.render(page, "Posts"))
|
|
195
|
-
end
|
|
187
|
+
# app/views/ruflet/main.rb
|
|
188
|
+
Ruflet.run do |page|
|
|
189
|
+
page.add(PageTitleComponent.render(page, "Posts"))
|
|
196
190
|
end
|
|
197
191
|
```
|
|
198
192
|
|
|
@@ -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: "
|
|
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,15 +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
|
-
|
|
29
|
-
|
|
30
|
-
|
|
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(")
|
|
31
35
|
|
|
32
|
-
route
|
|
33
|
-
|
|
34
|
-
|
|
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(")
|
|
35
45
|
|
|
36
|
-
|
|
46
|
+
route Ruflet::Rails::InstallSupport.web_route_snippet(entrypoint: entrypoint_path)
|
|
37
47
|
end
|
|
38
48
|
|
|
39
49
|
def add_desktop_flag_to_binstubs
|
|
@@ -47,14 +57,8 @@ module Ruflet
|
|
|
47
57
|
client = requested_client
|
|
48
58
|
return if client == "none"
|
|
49
59
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
Ruflet::CLI.command_update([client])
|
|
53
|
-
end
|
|
54
|
-
unless exit_code.to_i.zero?
|
|
55
|
-
@client_download_failed = true
|
|
56
|
-
say_status(:warn, "Ruflet client download failed; install files were generated and build/update steps are printed below", :yellow)
|
|
57
|
-
end
|
|
60
|
+
install_web_client if %w[web all].include?(client)
|
|
61
|
+
install_desktop_client if %w[desktop all].include?(client)
|
|
58
62
|
rescue StandardError => e
|
|
59
63
|
@client_download_failed = true
|
|
60
64
|
say_status(:warn, "Ruflet client download failed: #{e.class}: #{e.message}", :yellow)
|
|
@@ -81,24 +85,47 @@ module Ruflet
|
|
|
81
85
|
def requested_client
|
|
82
86
|
explicit = options[:client].to_s.strip.downcase
|
|
83
87
|
unless explicit.empty?
|
|
84
|
-
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)
|
|
85
89
|
|
|
86
90
|
return explicit
|
|
87
91
|
end
|
|
88
92
|
|
|
93
|
+
return "all" if options[:web] && options[:desktop]
|
|
94
|
+
return "web" if options[:web]
|
|
89
95
|
return "desktop" if options[:desktop]
|
|
90
96
|
|
|
91
97
|
"none"
|
|
92
98
|
end
|
|
93
99
|
|
|
94
100
|
def desktop_requested?
|
|
95
|
-
requested_client
|
|
101
|
+
%w[desktop all].include?(requested_client)
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def web_requested?
|
|
105
|
+
%w[web all].include?(requested_client)
|
|
96
106
|
end
|
|
97
107
|
|
|
98
108
|
def install_target
|
|
99
109
|
"ruflet"
|
|
100
110
|
end
|
|
101
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
|
+
|
|
102
129
|
def install_desktop_flag_bootstrap(relative_path)
|
|
103
130
|
target = File.join(destination_root, relative_path)
|
|
104
131
|
return unless File.file?(target)
|
|
@@ -10,17 +10,7 @@ module Ruflet
|
|
|
10
10
|
argument :model_name, type: :string
|
|
11
11
|
argument :attributes, type: :array, default: [], banner: "field:type field:type"
|
|
12
12
|
|
|
13
|
-
desc "Generate a Rails-first Ruflet resource
|
|
14
|
-
|
|
15
|
-
def create_ruflet_resource_view
|
|
16
|
-
create_file(
|
|
17
|
-
File.join(destination_root, scaffold_view_path),
|
|
18
|
-
Ruflet::Rails::InstallSupport.scaffold_view_template(
|
|
19
|
-
model_name: model_name,
|
|
20
|
-
attributes: scaffold_attributes
|
|
21
|
-
)
|
|
22
|
-
)
|
|
23
|
-
end
|
|
13
|
+
desc "Generate a Rails-first Ruflet resource component for an existing model."
|
|
24
14
|
|
|
25
15
|
def create_ruflet_resource_component
|
|
26
16
|
create_file(
|
|
@@ -33,15 +23,19 @@ module Ruflet
|
|
|
33
23
|
end
|
|
34
24
|
|
|
35
25
|
def print_scaffold_status
|
|
36
|
-
say "Ruflet
|
|
37
|
-
say "
|
|
38
|
-
say "
|
|
26
|
+
say "Ruflet resource component generated at #{scaffold_component_path}"
|
|
27
|
+
say "Mount it in config/routes.rb:"
|
|
28
|
+
say " mount Ruflet::Rails.web_app(view: #{scaffold_component_class.inspect}), at: \"/#{scaffold_route_segment}\""
|
|
39
29
|
end
|
|
40
30
|
|
|
41
31
|
private
|
|
42
32
|
|
|
43
|
-
def
|
|
44
|
-
|
|
33
|
+
def scaffold_component_class
|
|
34
|
+
"#{model_name.to_s.camelize}Component"
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def scaffold_route_segment
|
|
38
|
+
model_name.to_s.underscore.pluralize
|
|
45
39
|
end
|
|
46
40
|
|
|
47
41
|
def scaffold_component_path
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Ruflet
|
|
4
|
+
module Rails
|
|
5
|
+
# Resolve Rails assets to absolute URLs the Flutter client can load over
|
|
6
|
+
# HTTP, so server-driven UI can show app images:
|
|
7
|
+
#
|
|
8
|
+
# image(src: Ruflet::Rails.asset_url("logo.png"))
|
|
9
|
+
# image(src: Ruflet::Rails.image_url("brand/header.png"), fit: "cover")
|
|
10
|
+
#
|
|
11
|
+
# The *path* comes from the Rails asset pipeline — digested in production
|
|
12
|
+
# (/assets/logo-<digest>.png), plain otherwise — so it survives
|
|
13
|
+
# fingerprinting and CDNs. The *host* is resolved, in order, from:
|
|
14
|
+
#
|
|
15
|
+
# 1. an explicit `host:` argument
|
|
16
|
+
# 2. Ruflet::Rails.config.backend_url
|
|
17
|
+
# 3. the host the client connected on (the live WebSocket request)
|
|
18
|
+
#
|
|
19
|
+
# The client is a separate device (simulator, phone, browser), so a bare
|
|
20
|
+
# "/assets/..." path would not resolve — the URL must be absolute. If Rails
|
|
21
|
+
# already has an asset_host/CDN configured, the pipeline returns an absolute
|
|
22
|
+
# URL and it is used unchanged. A value that is already a full URL passes
|
|
23
|
+
# through untouched.
|
|
24
|
+
module_function
|
|
25
|
+
|
|
26
|
+
# The base URL the Flutter client uses to reach this Rails app — the single
|
|
27
|
+
# source of truth for asset URLs, the build-time RUFLET_URL define and the
|
|
28
|
+
# desktop launcher. A Rails Ruflet app always needs one, so this always
|
|
29
|
+
# resolves to a usable value:
|
|
30
|
+
#
|
|
31
|
+
# 1. an explicit host: argument
|
|
32
|
+
# 2. Ruflet::Rails.config.backend_url (set it in config/initializers/ruflet.rb)
|
|
33
|
+
# 3. the host the client connected on (the live WebSocket request)
|
|
34
|
+
#
|
|
35
|
+
# Returns "" only when none of those are available (e.g. a build with no
|
|
36
|
+
# configured backend_url) — set config.backend_url to cover that case.
|
|
37
|
+
def backend_url(host: nil)
|
|
38
|
+
candidate = host || config.backend_url
|
|
39
|
+
candidate = request_base_url if candidate.to_s.strip.empty?
|
|
40
|
+
candidate.to_s.strip.sub(%r{/+\z}, "")
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def asset_url(source, host: nil)
|
|
44
|
+
raw = source.to_s
|
|
45
|
+
return raw if absolute_url?(raw)
|
|
46
|
+
|
|
47
|
+
path = asset_pipeline_path(raw)
|
|
48
|
+
return path if absolute_url?(path)
|
|
49
|
+
|
|
50
|
+
base = backend_url(host: host)
|
|
51
|
+
base.empty? ? path : "#{base}#{path}"
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Readability alias for image sources — identical resolution.
|
|
55
|
+
def image_url(source, host: nil)
|
|
56
|
+
asset_url(source, host: host)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def asset_pipeline_path(source)
|
|
60
|
+
::ActionController::Base.helpers.asset_path(source)
|
|
61
|
+
rescue StandardError
|
|
62
|
+
source.start_with?("/") ? source : "/#{source}"
|
|
63
|
+
end
|
|
64
|
+
private_class_method :asset_pipeline_path
|
|
65
|
+
|
|
66
|
+
# Derive scheme://host from the live WebSocket request env so the URL points
|
|
67
|
+
# back at the exact host the client reached — the one address guaranteed to
|
|
68
|
+
# be reachable from that device.
|
|
69
|
+
def request_base_url
|
|
70
|
+
env = Protocol::Context.current_env
|
|
71
|
+
return nil unless env
|
|
72
|
+
|
|
73
|
+
host = env["HTTP_X_FORWARDED_HOST"] || env["HTTP_HOST"]
|
|
74
|
+
return nil if host.to_s.strip.empty?
|
|
75
|
+
|
|
76
|
+
scheme = (env["HTTP_X_FORWARDED_PROTO"] || env["rack.url_scheme"] || "http").to_s.split(",").first.to_s.strip
|
|
77
|
+
scheme = "http" if scheme.empty?
|
|
78
|
+
"#{scheme}://#{host}"
|
|
79
|
+
end
|
|
80
|
+
private_class_method :request_base_url
|
|
81
|
+
|
|
82
|
+
def absolute_url?(value)
|
|
83
|
+
!(value.to_s =~ %r{\A[a-z][a-z0-9+.-]*://}i).nil?
|
|
84
|
+
end
|
|
85
|
+
private_class_method :absolute_url?
|
|
86
|
+
end
|
|
87
|
+
end
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Ruflet
|
|
4
|
+
module Rails
|
|
5
|
+
# Central configuration for ruflet_rails.
|
|
6
|
+
#
|
|
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:
|
|
10
|
+
#
|
|
11
|
+
# Ruflet::Rails.configure do |config|
|
|
12
|
+
# # Runtime / server
|
|
13
|
+
# config.backend_url = Rails.env.production? ? "https://example.com" : "http://localhost:3000"
|
|
14
|
+
#
|
|
15
|
+
# # App metadata (ruflet.yaml → app:)
|
|
16
|
+
# config.app_name = "My App"
|
|
17
|
+
#
|
|
18
|
+
# # Services (ruflet.yaml → services:)
|
|
19
|
+
# config.services = []
|
|
20
|
+
#
|
|
21
|
+
# # Assets (ruflet.yaml → assets:)
|
|
22
|
+
# config.splash_screen = Rails.root.join("app/assets/images/splash.png")
|
|
23
|
+
# config.splash_dark = Rails.root.join("app/assets/images/splash_dark.png")
|
|
24
|
+
# config.icon_launcher = Rails.root.join("app/assets/images/icon.png")
|
|
25
|
+
# config.icon_android = Rails.root.join("app/assets/images/icon_android.png")
|
|
26
|
+
# config.icon_ios = Rails.root.join("app/assets/images/icon_ios.png")
|
|
27
|
+
# config.icon_web = Rails.root.join("app/assets/images/icon_web.png")
|
|
28
|
+
# config.icon_windows = Rails.root.join("app/assets/images/icon_windows.png")
|
|
29
|
+
# config.icon_macos = Rails.root.join("app/assets/images/icon_macos.png")
|
|
30
|
+
#
|
|
31
|
+
# # Build options (ruflet.yaml → build:)
|
|
32
|
+
# config.splash_color = "#FFFFFF"
|
|
33
|
+
# config.splash_dark_color = "#000000"
|
|
34
|
+
# config.icon_background = "#FFFFFF"
|
|
35
|
+
# config.theme_color = "#FFFFFF"
|
|
36
|
+
# end
|
|
37
|
+
class Configuration
|
|
38
|
+
# --- Runtime / server ---
|
|
39
|
+
|
|
40
|
+
# Backend base URL. Used as --dart-define=RUFLET_URL at build time
|
|
41
|
+
# and by the desktop launcher. Replaces ruflet.yaml → app.backend_url.
|
|
42
|
+
attr_accessor :backend_url
|
|
43
|
+
|
|
44
|
+
# --- App metadata (ruflet.yaml → app:) ---
|
|
45
|
+
|
|
46
|
+
attr_accessor :app_name
|
|
47
|
+
|
|
48
|
+
# --- Services (ruflet.yaml → services:) ---
|
|
49
|
+
|
|
50
|
+
attr_accessor :services
|
|
51
|
+
|
|
52
|
+
# --- Assets (ruflet.yaml → assets:) ---
|
|
53
|
+
|
|
54
|
+
attr_accessor :splash_screen
|
|
55
|
+
attr_accessor :splash_dark
|
|
56
|
+
attr_accessor :icon_launcher
|
|
57
|
+
attr_accessor :icon_android
|
|
58
|
+
attr_accessor :icon_ios
|
|
59
|
+
attr_accessor :icon_web
|
|
60
|
+
attr_accessor :icon_windows
|
|
61
|
+
attr_accessor :icon_macos
|
|
62
|
+
|
|
63
|
+
# --- Build options (ruflet.yaml → build:) ---
|
|
64
|
+
|
|
65
|
+
attr_accessor :splash_color
|
|
66
|
+
attr_accessor :splash_dark_color
|
|
67
|
+
attr_accessor :icon_background
|
|
68
|
+
attr_accessor :theme_color
|
|
69
|
+
|
|
70
|
+
def initialize
|
|
71
|
+
@backend_url = nil
|
|
72
|
+
@app_name = nil
|
|
73
|
+
@services = []
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# Serialises config to the ruflet.yaml hash structure so the CLI can
|
|
77
|
+
# consume it without a yaml file on disk (written to a temp file by
|
|
78
|
+
# the Railtie's build task).
|
|
79
|
+
def to_ruflet_yaml_hash
|
|
80
|
+
hash = {}
|
|
81
|
+
|
|
82
|
+
app = {}
|
|
83
|
+
app["name"] = @app_name if @app_name
|
|
84
|
+
app["backend_url"] = @backend_url if @backend_url
|
|
85
|
+
hash["app"] = app unless app.empty?
|
|
86
|
+
|
|
87
|
+
hash["services"] = Array(@services)
|
|
88
|
+
|
|
89
|
+
assets = {}
|
|
90
|
+
assets["splash_screen"] = @splash_screen.to_s if @splash_screen
|
|
91
|
+
assets["splash_dark"] = @splash_dark.to_s if @splash_dark
|
|
92
|
+
assets["icon_launcher"] = @icon_launcher.to_s if @icon_launcher
|
|
93
|
+
assets["icon_android"] = @icon_android.to_s if @icon_android
|
|
94
|
+
assets["icon_ios"] = @icon_ios.to_s if @icon_ios
|
|
95
|
+
assets["icon_web"] = @icon_web.to_s if @icon_web
|
|
96
|
+
assets["icon_windows"] = @icon_windows.to_s if @icon_windows
|
|
97
|
+
assets["icon_macos"] = @icon_macos.to_s if @icon_macos
|
|
98
|
+
hash["assets"] = assets unless assets.empty?
|
|
99
|
+
|
|
100
|
+
build = {}
|
|
101
|
+
build["splash_color"] = @splash_color if @splash_color
|
|
102
|
+
build["splash_dark_color"] = @splash_dark_color if @splash_dark_color
|
|
103
|
+
build["icon_background"] = @icon_background if @icon_background
|
|
104
|
+
build["theme_color"] = @theme_color if @theme_color
|
|
105
|
+
hash["build"] = build unless build.empty?
|
|
106
|
+
|
|
107
|
+
hash
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
end
|