Class: Ruflet::Rails::NativeApp
- Inherits:
-
Object
- Object
- Ruflet::Rails::NativeApp
- Defined in:
- lib/ruflet/rails/native_app.rb
Overview
Hotwire Native-style driver for ruflet_rails.
Your existing web app is the body, rendered in a WebView. Navigation works out of the box: a tiny JS bridge injected into each page intercepts link clicks and proposes them to native, so every visit becomes a NATIVE screen pushed onto the stack (with an automatic back button) — no per-link code. The native AppBar title tracks each page’s <title>, and you declare special paths as data.
Ruflet.run do |page|
Ruflet::Rails.native_app(
page,
start_url: "https://myapp.com",
title: "My App", # auto-updates from <title>
actions: -> { [icon_button("search", on_click: ->(_e) { ... })] },
navigation_bar: navigation_bar(destinations: [...]),
# web content shown in a bottom sheet (auth, quick forms):
modal: ["/sign_in", "/sign_up", %r{/new\z}],
# optional: override a path with a fully native screen:
native: { %r{\A/products/(\d+)\z} => ->(ctx) { product_screen(ctx.match[1]) } }
)
end
Normal links just push a native webview screen (back returns). Paths listed in ‘modal:` open as a bottom sheet. Paths in `native:` render your own UI.
The bridge talks to native over the webview’s console channel (on_console_message), which works on iOS/Android/macOS. On platforms without a native webview the body degrades to a plain frame.
Defined Under Namespace
Constant Summary collapse
- BRIDGE_JS =
Injected into every page: report the title, and turn same-origin link clicks into native visit proposals (so they don’t load in place).
<<~JS (function () { function report(kind, value) { console.log("ruflet:" + kind + ":" + value); } report("title", document.title || ""); if (window.__rufletBridgeBound) return; window.__rufletBridgeBound = true; document.addEventListener("click", function (e) { var a = e.target && e.target.closest ? e.target.closest("a[href]") : null; if (!a || a.target === "_blank") return; if (a.origin && a.origin !== location.origin) return; // external: leave it e.preventDefault(); report("visit", a.href); }, true); })(); JS
- VISIT_PREFIX =
"ruflet:visit:"- TITLE_PREFIX =
"ruflet:title:"
Class Method Summary collapse
Instance Method Summary collapse
-
#initialize(page, start_url:, title: nil, actions: nil, navigation_bar: nil, bottom_appbar: nil, modal: [], native: {}) ⇒ NativeApp
constructor
A new instance of NativeApp.
- #start ⇒ Object
Constructor Details
#initialize(page, start_url:, title: nil, actions: nil, navigation_bar: nil, bottom_appbar: nil, modal: [], native: {}) ⇒ NativeApp
Returns a new instance of NativeApp.
63 64 65 66 67 68 69 70 71 72 73 74 75 |
# File 'lib/ruflet/rails/native_app.rb', line 63 def initialize(page, start_url:, title: nil, actions: nil, navigation_bar: nil, bottom_appbar: nil, modal: [], native: {}) @page = page @start_url = start_url.to_s @title = title.to_s @actions = actions @navigation_bar = @bottom_appbar = @modal_patterns = Array(modal).map { |p| compile_pattern(p) } @native_rules = native.map { |pattern, builder| [compile_pattern(pattern), builder] } @screens = [] @modal_sheet = nil end |
Class Method Details
.bridge_js ⇒ Object
77 |
# File 'lib/ruflet/rails/native_app.rb', line 77 def self.bridge_js = BRIDGE_JS |
Instance Method Details
#start ⇒ Object
79 80 81 82 83 |
# File 'lib/ruflet/rails/native_app.rb', line 79 def start @page.on_view_pop = ->(_event) { pop } push_webview(@start_url, root: true) self end |