//! YT Player — zero-native app entry. //! //! This file shows how the App is wired to the runtime and how the bridge //! handlers in `bridge.zig` are registered. When you scaffold with //! `zero-native init`, a `src/main.zig` + `src/runner.zig` + `build.zig` are //! generated for your installed version. Merge the `bridge()` registration and //! the `handlers`/`policies` below into that generated App — the handler //! implementations themselves live in `bridge.zig` and need no changes. const std = @import("std"); const zero_native = @import("zero_native"); const handlers_impl = @import("bridge.zig"); const Handler = zero_native.bridge.Handler; // Commands the UI is allowed to call, matched against window.zero.invoke names. const policies = [_]zero_native.bridge.CommandPolicy{ .{ .command = "yt.search" }, .{ .command = "yt.streams" }, .{ .command = "store.load" }, .{ .command = "store.save" }, }; pub const App = struct { handlers: [4]Handler = undefined, pub fn app(self: *App) zero_native.App { return .{ .context = self, .name = "YT Player", // Serve the packaged static UI from the zero://app origin. .source = zero_native.WebViewSource.packaged("frontend", "index.html"), .bridge = bridge(self), }; } fn bridge(self: *App) zero_native.BridgeDispatcher { self.handlers = .{ .{ .name = "yt.search", .context = self, .invoke_fn = handlers_impl.ytSearch }, .{ .name = "yt.streams", .context = self, .invoke_fn = handlers_impl.ytStreams }, .{ .name = "store.load", .context = self, .invoke_fn = handlers_impl.storeLoad }, .{ .name = "store.save", .context = self, .invoke_fn = handlers_impl.storeSave }, }; return .{ .policy = .{ .enabled = true, .commands = &policies }, .registry = .{ .handlers = &self.handlers }, }; } }; pub fn main() !void { var instance: App = .{}; var runtime = try zero_native.Runtime.init(std.heap.page_allocator); defer runtime.deinit(); try runtime.run(instance.app()); }