vapp.h Header

#include <vapp.h>

Types

struct ListEntry One row of an app-supplied list (see VApp::set_list). id keys the row in the render diff + action routing; fields are looked up by template nodes bound with Bind:"Field:<name>".
struct ListAction A generated row's action (a row button with Intent:"list:<action>"), routed to the app's list-action handler on click. One per registered action button.
struct HttpRequest An async HTTP request the app core hands to the platform-injected transport (see VApp::set_http_handler). The core stays transport-agnostic: it builds the request, the platform shell performs it off the UI thread (Qt QNetworkAccessManager, web fetch, Android OkHttp) and delivers the response.
struct HttpResponse The reply delivered back to the request's callback. status is the HTTP code (200, 401, ...); 0 means the request never completed (transport/network failure), with the reason in error.
struct UploadResult File pick + upload seam. Binary file bytes can't safely cross the core<->platform boundary on web (Embind string marshaling) or Android (jstring/modified-UTF-8), so rather than route an upload's bytes through http(), the platform owns the whole operation: it opens a native file picker (filtered by accept, an HTML- style MIME list like "image/png,image/jpeg"), then multipart-uploads the chosen file — under form field fieldName, with the HTTP verb method (e.g. "POST" for post attachments, "PUT" for a profile picture) — to url with headers (e.g. an Authorization bearer), and delivers the API's JSON reply back as a string. The binary never enters the core; only the response text does. Per-platform shells inject the transport at startup (desktop QFileDialog+QHttpMultiPart, web <input>+FormData/fetch, Android SAF+OkHttp). Backs attachment uploads (POST {profile}/api/uploads) and the profile picture (PUT {profile}/api/profile/ picture). [Attachments]
struct PickRequest Local path-pick seam: open the platform's native file dialog and hand the chosen filesystem PATH back to the app (no bytes cross the boundary — a desktop app that links its own engine reads the file itself). The upload seam above is the remote cousin (pick + POST the bytes); this one exists for desktop-class apps (Docuriser) whose engines take paths. Web/Android have no usable filesystem paths, so shells there simply don't install a handler and pick_path() degrades to an immediate cancel.
struct PurchaseResult In-app purchase seam: run the platform store's native purchase flow (Android Google Play; desktop/web install no handler — they bill via Stripe, so this is a safe no-op there). Async like the upload seam: the shell launches the store sheet for productId/planId (attaching accountId, an opaque per-account id the store hashes for fraud signals) and delivers a purchase token back. Only a string crosses the boundary — the server verifies the token, so no billing logic lives in the core.
class VApp

Type Aliases

using HttpCallback
using HttpHandler
using UploadCallback
using UploadHandler
using PickCallback The picked absolute path, or "" when the user canceled (or no handler).
using PickHandler
using TimerHandler One-shot timer seam: schedule cb to run on the UI thread after ms milliseconds. The platform shell injects a transport once at startup (desktop QTimer::singleShot, web setTimeout, Android Handler.postDelayed); app code schedules deferred work via VApp::after(). The networking analog for time — drives the search debounce. No cancellation in the seam: callers that need it guard the callback with a generation counter (a superseded fire is a no-op).
using PostHandler Post-to-UI-thread seam: marshal cb from ANY thread onto the UI thread (the timer seam's cross-thread cousin — after() defers, post() crosses). Exists for apps that run their own worker threads (Docuriser's engine builds): VApp is single-threaded by contract, so a worker must hand results (a streamed log line, a completion) to post() and let the UI thread touch the app. The installed transport must be safe to call off-thread and must QUEUE the callback (desktop QMetaObject::invokeMethod, Qt::QueuedConnection) — never run it inline on the calling thread.
using OpenUrlHandler External-URL seam: hand a URL to the platform to open in its system browser (the "leave the app" analog of the file-upload seam). The platform shell injects a handler once at startup (desktop QDesktopServices::openUrl, web window.open, Android ACTION_VIEW). App code calls VApp::open_url() to steer a user off-app — e.g. to the billing surface (web host / Play subscriptions page) for a subscription on the other platform's rail, which can't transact in-app.
using BackHandler System-back seam: the platform reports the OS back gesture/button (Android today; a web history pop could ride it later) and the APP owns what back means — it installs ONE handler holding its whole priority chain (close the top overlay, else pop the view, else swap to the home tab, ...). The handler is called two ways, split by commit: commit=true — a real back press: perform the navigation, return whether it was consumed (false = at the terminating point; the platform lets the system take it, i.e. leave the app). commit=false — a side-effect-free PEEK: "would a back press be consumed right now?". Android re-asks after every applied patch set and eagerly registers/unregisters its OS-level callback on the answer, which is what lets predictive back preview the back-to-home animation at the terminating point. The peek must not mutate anything: same chain, but each branch only reports that it WOULD act. No handler installed (desktop/web/headless) → false.
using CopyTextHandler Clipboard seam: put a text string on the system clipboard (desktop QClipboard, web navigator.clipboard — which requires a user gesture, so call this from a click handler — Android ClipboardManager). Fire-and-forget like open_url: no handler installed (headless) → silent no-op.
using SaveTextCallback Save-text seam: hand a small TEXT payload to the platform to persist as a user-visible file (the outbound cousin of pick_path — bytes still don't cross the boundary as binary, only a string). Desktop opens a save dialog and writes; web triggers a Blob download (no dialog, no cancel); Android opens ACTION_CREATE_DOCUMENT and writes on result. ok is false when the user canceled or no handler is installed; web's download path always reports true once triggered.
using SaveTextHandler
using ProcessLineCallback Subprocess seam: run a companion executable and stream its output back (e.g. Docuriser's GUI shelling out to docuriser-cli for site builds, so work that would fight over process-global state — Layers' controller — runs in its own process). argv[0] is the program: an absolute/relative path runs as given; a bare name resolves against the app executable's own directory first (companion tools ship beside the app), then the platform's normal lookup (PATH). The platform delivers each line of merged stdout+stderr via on_line and one on_exit with the exit code, both on the UI thread; -1 means the process failed to start or crashed. Desktop-only for now (QProcess) — sandboxed shells (web) install no handler.
using ProcessExitCallback
using RunProcessHandler
using PurchaseCallback
using PurchaseHandler
using QueryPurchasesCallback Purchase-recovery seam: list already-owned, server-unverified purchase tokens WITHOUT showing a sheet. A purchase can complete at the store yet never reach the server (app killed mid-flow); the store requires it be acknowledged within a few days or it auto-refunds, so on launch the app replays verification for any token here. Empty list = nothing pending. No handler → empty (desktop/web).
using QueryPurchasesHandler

Type Alias Documentation

using HttpCallback = std::function<void (const HttpResponse &)>

No description available.

using HttpHandler = std::function<void (const HttpRequest &, HttpCallback)>

No description available.

using UploadCallback = std::function<void (const UploadResult &)>

No description available.

using UploadHandler = std::function<void (const std::string &, const std::string &, const std::string &, const int &, const std::string &, UploadCallback)>

No description available.

using PickCallback = std::function<void (const std::string &)>

The picked absolute path, or "" when the user canceled (or no handler).

using PickHandler = std::function<void (const PickRequest &, PickCallback)>

No description available.

using TimerHandler = std::function<void (int, std::function<void ()>)>

One-shot timer seam: schedule cb to run on the UI thread after ms milliseconds. The platform shell injects a transport once at startup (desktop QTimer::singleShot, web setTimeout, Android Handler.postDelayed); app code schedules deferred work via VApp::after(). The networking analog for time — drives the search debounce. No cancellation in the seam: callers that need it guard the callback with a generation counter (a superseded fire is a no-op).

using PostHandler = std::function<void (std::function<void ()>)>

Post-to-UI-thread seam: marshal cb from ANY thread onto the UI thread (the timer seam's cross-thread cousin — after() defers, post() crosses). Exists for apps that run their own worker threads (Docuriser's engine builds): VApp is single-threaded by contract, so a worker must hand results (a streamed log line, a completion) to post() and let the UI thread touch the app. The installed transport must be safe to call off-thread and must QUEUE the callback (desktop QMetaObject::invokeMethod, Qt::QueuedConnection) — never run it inline on the calling thread.

using OpenUrlHandler = std::function<void (const std::string &)>

External-URL seam: hand a URL to the platform to open in its system browser (the "leave the app" analog of the file-upload seam). The platform shell injects a handler once at startup (desktop QDesktopServices::openUrl, web window.open, Android ACTION_VIEW). App code calls VApp::open_url() to steer a user off-app — e.g. to the billing surface (web host / Play subscriptions page) for a subscription on the other platform's rail, which can't transact in-app.

using BackHandler = std::function<bool (bool)>

System-back seam: the platform reports the OS back gesture/button (Android today; a web history pop could ride it later) and the APP owns what back means — it installs ONE handler holding its whole priority chain (close the top overlay, else pop the view, else swap to the home tab, ...). The handler is called two ways, split by commit: commit=true — a real back press: perform the navigation, return whether it was consumed (false = at the terminating point; the platform lets the system take it, i.e. leave the app). commit=false — a side-effect-free PEEK: "would a back press be consumed right now?". Android re-asks after every applied patch set and eagerly registers/unregisters its OS-level callback on the answer, which is what lets predictive back preview the back-to-home animation at the terminating point. The peek must not mutate anything: same chain, but each branch only reports that it WOULD act. No handler installed (desktop/web/headless) → false.

using CopyTextHandler = std::function<void (const std::string &)>

Clipboard seam: put a text string on the system clipboard (desktop QClipboard, web navigator.clipboard — which requires a user gesture, so call this from a click handler — Android ClipboardManager). Fire-and-forget like open_url: no handler installed (headless) → silent no-op.

using SaveTextCallback = std::function<void (bool)>

Save-text seam: hand a small TEXT payload to the platform to persist as a user-visible file (the outbound cousin of pick_path — bytes still don't cross the boundary as binary, only a string). Desktop opens a save dialog and writes; web triggers a Blob download (no dialog, no cancel); Android opens ACTION_CREATE_DOCUMENT and writes on result. ok is false when the user canceled or no handler is installed; web's download path always reports true once triggered.

using SaveTextHandler = std::function<void (const std::string &, const std::string &, const std::string &, SaveTextCallback)>

No description available.

using ProcessLineCallback = std::function<void (const std::string &)>

Subprocess seam: run a companion executable and stream its output back (e.g. Docuriser's GUI shelling out to docuriser-cli for site builds, so work that would fight over process-global state — Layers' controller — runs in its own process). argv[0] is the program: an absolute/relative path runs as given; a bare name resolves against the app executable's own directory first (companion tools ship beside the app), then the platform's normal lookup (PATH). The platform delivers each line of merged stdout+stderr via on_line and one on_exit with the exit code, both on the UI thread; -1 means the process failed to start or crashed. Desktop-only for now (QProcess) — sandboxed shells (web) install no handler.

using ProcessExitCallback = std::function<void (int)>

No description available.

using RunProcessHandler = std::function<void (const int &, ProcessLineCallback, ProcessExitCallback)>

No description available.

using PurchaseCallback = std::function<void (const PurchaseResult &)>

No description available.

using PurchaseHandler = std::function<void (const std::string &, const std::string &, const std::string &, PurchaseCallback)>

No description available.

using QueryPurchasesCallback = std::function<void (const int &, const std::string &)>

Purchase-recovery seam: list already-owned, server-unverified purchase tokens WITHOUT showing a sheet. A purchase can complete at the store yet never reach the server (app killed mid-flow); the store requires it be acknowledged within a few days or it auto-refunds, so on launch the app replays verification for any token here. Empty list = nothing pending. No handler → empty (desktop/web).

using QueryPurchasesHandler = std::function<void (QueryPurchasesCallback)>

No description available.

Appearance
Theme
—