@eazo/sdk 0.11.0 → 0.14.0

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.
Files changed (88) hide show
  1. package/PROTOCOL.md +7 -1
  2. package/README.md +78 -7
  3. package/dist/index.d.ts +3 -0
  4. package/dist/index.d.ts.map +1 -1
  5. package/dist/index.js +3 -1
  6. package/dist/index.js.map +1 -1
  7. package/dist/internal/auth-primitive/EazoAuthClient.js +1 -1
  8. package/dist/internal/auth-primitive/EazoAuthClient.js.map +1 -1
  9. package/dist/internal/banner-ui/app-info.d.ts +78 -0
  10. package/dist/internal/banner-ui/app-info.d.ts.map +1 -0
  11. package/dist/internal/banner-ui/app-info.js +62 -0
  12. package/dist/internal/banner-ui/app-info.js.map +1 -0
  13. package/dist/internal/banner-ui/icons.d.ts +18 -4
  14. package/dist/internal/banner-ui/icons.d.ts.map +1 -1
  15. package/dist/internal/banner-ui/icons.js +57 -4
  16. package/dist/internal/banner-ui/icons.js.map +1 -1
  17. package/dist/internal/banner-ui/index.d.ts +16 -3
  18. package/dist/internal/banner-ui/index.d.ts.map +1 -1
  19. package/dist/internal/banner-ui/index.js +336 -41
  20. package/dist/internal/banner-ui/index.js.map +1 -1
  21. package/dist/internal/banner-ui/initial-info.d.ts +4 -0
  22. package/dist/internal/banner-ui/initial-info.d.ts.map +1 -0
  23. package/dist/internal/banner-ui/initial-info.js +22 -0
  24. package/dist/internal/banner-ui/initial-info.js.map +1 -0
  25. package/dist/internal/banner-ui/qr.d.ts +22 -0
  26. package/dist/internal/banner-ui/qr.d.ts.map +1 -0
  27. package/dist/internal/banner-ui/qr.js +95 -0
  28. package/dist/internal/banner-ui/qr.js.map +1 -0
  29. package/dist/internal/banner-ui/store-links.d.ts +38 -0
  30. package/dist/internal/banner-ui/store-links.d.ts.map +1 -1
  31. package/dist/internal/banner-ui/store-links.js +49 -0
  32. package/dist/internal/banner-ui/store-links.js.map +1 -1
  33. package/dist/internal/banner-ui/styles.d.ts +4 -2
  34. package/dist/internal/banner-ui/styles.d.ts.map +1 -1
  35. package/dist/internal/banner-ui/styles.js +578 -66
  36. package/dist/internal/banner-ui/styles.js.map +1 -1
  37. package/dist/internal/bridge/protocol.d.ts +6 -0
  38. package/dist/internal/bridge/protocol.d.ts.map +1 -1
  39. package/dist/internal/bridge/protocol.js +5 -1
  40. package/dist/internal/bridge/protocol.js.map +1 -1
  41. package/dist/internal/capabilities/ai.js +1 -1
  42. package/dist/internal/capabilities/ai.js.map +1 -1
  43. package/dist/internal/capabilities/auth.d.ts +10 -5
  44. package/dist/internal/capabilities/auth.d.ts.map +1 -1
  45. package/dist/internal/capabilities/auth.js +29 -13
  46. package/dist/internal/capabilities/auth.js.map +1 -1
  47. package/dist/internal/capabilities/device.d.ts +0 -1
  48. package/dist/internal/capabilities/device.d.ts.map +1 -1
  49. package/dist/internal/capabilities/device.js +2 -6
  50. package/dist/internal/capabilities/device.js.map +1 -1
  51. package/dist/internal/capabilities/memory.d.ts +10 -15
  52. package/dist/internal/capabilities/memory.d.ts.map +1 -1
  53. package/dist/internal/capabilities/memory.js +9 -26
  54. package/dist/internal/capabilities/memory.js.map +1 -1
  55. package/dist/internal/capabilities/notifications.d.ts +41 -0
  56. package/dist/internal/capabilities/notifications.d.ts.map +1 -0
  57. package/dist/internal/capabilities/notifications.js +61 -0
  58. package/dist/internal/capabilities/notifications.js.map +1 -0
  59. package/dist/internal/capabilities/share.d.ts +4 -2
  60. package/dist/internal/capabilities/share.d.ts.map +1 -1
  61. package/dist/internal/capabilities/share.js +13 -9
  62. package/dist/internal/capabilities/share.js.map +1 -1
  63. package/dist/internal/capabilities/storage.d.ts +7 -11
  64. package/dist/internal/capabilities/storage.d.ts.map +1 -1
  65. package/dist/internal/capabilities/storage.js +5 -13
  66. package/dist/internal/capabilities/storage.js.map +1 -1
  67. package/dist/internal/config.d.ts +9 -12
  68. package/dist/internal/config.d.ts.map +1 -1
  69. package/dist/internal/config.js +53 -22
  70. package/dist/internal/config.js.map +1 -1
  71. package/dist/internal/store.d.ts.map +1 -1
  72. package/dist/internal/store.js +0 -1
  73. package/dist/internal/store.js.map +1 -1
  74. package/dist/react.d.ts +34 -5
  75. package/dist/react.d.ts.map +1 -1
  76. package/dist/react.js +26 -5
  77. package/dist/react.js.map +1 -1
  78. package/dist/react.server.d.ts +22 -0
  79. package/dist/react.server.d.ts.map +1 -0
  80. package/dist/react.server.js +118 -0
  81. package/dist/react.server.js.map +1 -0
  82. package/dist/server.d.ts +29 -0
  83. package/dist/server.d.ts.map +1 -1
  84. package/dist/server.js +158 -0
  85. package/dist/server.js.map +1 -1
  86. package/dist/types.d.ts +0 -1
  87. package/dist/types.d.ts.map +1 -1
  88. package/package.json +7 -2
@@ -37,75 +37,370 @@ Object.defineProperty(exports, "__esModule", { value: true });
37
37
  exports.EazoBrandBanner = EazoBrandBanner;
38
38
  const jsx_runtime_1 = require("react/jsx-runtime");
39
39
  const React = __importStar(require("react"));
40
+ const config_1 = require("../config");
40
41
  const env_1 = require("../env");
41
42
  const icons_1 = require("./icons");
43
+ const qr_1 = require("./qr");
44
+ const app_info_1 = require("./app-info");
45
+ const initial_info_1 = require("./initial-info");
42
46
  const store_links_1 = require("./store-links");
43
47
  const styles_1 = require("./styles");
44
- const DISMISS_KEY = "eazo:banner:dismissed";
48
+ // iOS Safari has no native fallback for an unhandled `eazo://` scheme;
49
+ // after this long we assume the app isn't installed and redirect to the
50
+ // store. Matches the value in `store-links.ts`.
51
+ const IOS_FALLBACK_TIMEOUT_MS = 1500;
45
52
  const MOBILE_BREAKPOINT_PX = 480;
46
- function readDismissed() {
47
- try {
48
- return window.sessionStorage.getItem(DISMISS_KEY) === "1";
49
- }
50
- catch {
51
- // Private mode / disabled storage — treat as not dismissed; the close
52
- // button will still hide it for the lifetime of the page.
53
+ // Delay before the center handoff modal appears — gives users a minute
54
+ // to actually use the app before the strong CTA pops up. The top and
55
+ // bottom banners stay visible from first paint; this only gates the
56
+ // center "Open in Eazo app" modal.
57
+ const MODAL_DELAY_MS = 60000;
58
+ function isMobile() {
59
+ if (typeof window === "undefined")
53
60
  return false;
54
- }
61
+ return window.innerWidth <= MOBILE_BREAKPOINT_PX;
55
62
  }
56
- function writeDismissed() {
57
- try {
58
- window.sessionStorage.setItem(DISMISS_KEY, "1");
59
- }
60
- catch {
61
- // Ignore: dismissal still works in-memory via React state.
62
- }
63
+ function topBannerHeightPx(mobile) {
64
+ return mobile ? styles_1.BANNER_HEIGHT_MOBILE : styles_1.BANNER_HEIGHT_DESKTOP;
63
65
  }
64
- function currentBannerHeight() {
65
- if (typeof window === "undefined")
66
- return styles_1.BANNER_HEIGHT_DESKTOP;
67
- return window.innerWidth <= MOBILE_BREAKPOINT_PX
68
- ? styles_1.BANNER_HEIGHT_MOBILE
69
- : styles_1.BANNER_HEIGHT_DESKTOP;
66
+ function bottomBannerHeightPx(mobile) {
67
+ return mobile ? styles_1.BOTTOM_HEIGHT_MOBILE : styles_1.BOTTOM_HEIGHT_DESKTOP;
68
+ }
69
+ function formatStat(n) {
70
+ if (typeof n !== "number" || !Number.isFinite(n) || n < 0)
71
+ return "0";
72
+ if (n < 1000)
73
+ return String(Math.floor(n));
74
+ if (n < 10000)
75
+ return `${(n / 1000).toFixed(1)}k`;
76
+ if (n < 1000000)
77
+ return `${Math.round(n / 1000)}k`;
78
+ return `${(n / 1000000).toFixed(1)}m`;
70
79
  }
71
80
  /**
72
- * Top-of-page promo banner that points users to the Eazo mobile app.
73
- * Mounted by `<EazoProvider>` and rendered only in pure-web environments
74
- * (not the eazoMobile WebView, not embedded iframes). Dismissal is per-tab.
81
+ * True when the string is shaped like a URL pointing at an image — covers
82
+ * the forms `creator_apps.icon` may carry: absolute http(s) URLs,
83
+ * protocol-relative URLs, server-relative paths, and inline `data:image/...`
84
+ * URIs. Anything else (emoji glyphs, single letters, etc.) renders as
85
+ * text in the monolith.
86
+ */
87
+ function isImageUrl(s) {
88
+ return (/^https?:\/\//i.test(s) ||
89
+ s.startsWith("//") ||
90
+ s.startsWith("/") ||
91
+ s.startsWith("data:image/"));
92
+ }
93
+ function deriveInitials(name) {
94
+ const parts = name.trim().split(/\s+/).filter(Boolean);
95
+ if (parts.length === 0)
96
+ return "·";
97
+ if (parts.length === 1)
98
+ return parts[0].slice(0, 2);
99
+ return (parts[0][0] + parts[1][0]).toUpperCase();
100
+ }
101
+ /**
102
+ * Web-only handoff overlay. Mounted by `<EazoProvider>` and visible only
103
+ * in pure-web environments (not the eazoMobile WebView, not embedded
104
+ * iframes). Three coordinated pieces:
105
+ *
106
+ * 1. Top banner — brand + "MOBILE REQUIRED" pill + domain + "Open in app" CTA.
107
+ * 2. Full-screen scrim with coral spotlight + center modal (orbiting
108
+ * capability icons, app identity, QR + primary CTA). Non-dismissible.
109
+ * 3. Bottom banner — capability rail + likes/comments stats + eazo.ai pill.
110
+ *
111
+ * App identity (name, tagline, likes, comments) is fetched once from
112
+ * `GET /apps-open/:appId`. The CTA + QR encode the `eazo://` deep link;
113
+ * the iOS click-handler falls back to the App Store after a short delay
114
+ * if the app isn't installed.
115
+ *
116
+ * Kept exported as `EazoBrandBanner` for backwards compatibility with
117
+ * `EazoProvider`, which mounts it by that name.
75
118
  */
76
119
  function EazoBrandBanner() {
77
- const [visible, setVisible] = React.useState(false);
78
- const [storeUrl, setStoreUrl] = React.useState("");
120
+ const [mounted, setMounted] = React.useState(false);
121
+ const [cta, setCta] = React.useState(null);
122
+ // Seed `info` from the prefetched value (if the host's Server
123
+ // Component passed `<EazoProvider initialAppInfo>`) so the modal
124
+ // renders real content on first paint without a skeleton flash.
125
+ // `useState(initializer)` runs the lazy initializer once at first
126
+ // render; `getInitialAppInfo()` reads what `EazoProvider` stashed
127
+ // synchronously in the SAME render pass.
128
+ const [info, setInfo] = React.useState(() => (0, initial_info_1.getInitialAppInfo)());
129
+ // `loading === true` until the public app-info fetch settles (success
130
+ // or failure). Skip the loading state entirely when a prefetched value
131
+ // is already in hand — no fetch is going to fire.
132
+ const [loading, setLoading] = React.useState(() => (0, initial_info_1.getInitialAppInfo)() === null);
133
+ const [mobile, setMobile] = React.useState(false);
134
+ // In-memory dismiss for the strong-CTA modal — intentionally NOT
135
+ // persisted. Every page load (navigation, refresh, new tab) re-engages
136
+ // the modal; the X / ESC just hides it for the current session of this
137
+ // page. The top + bottom banners stay regardless.
138
+ const [modalDismissed, setModalDismissed] = React.useState(false);
139
+ // Gate the modal behind a delay so users get to use the app for a
140
+ // minute before the strong CTA interrupts them. Flips once on mount;
141
+ // dismiss state above overrides this — once closed, the modal stays
142
+ // closed for this page load even if the timer hasn't fired yet.
143
+ const [modalReady, setModalReady] = React.useState(false);
144
+ // Resolved on mount in the browser. Encoded by the QR so a desktop
145
+ // scan opens the EXACT page on a phone (which then sends the user
146
+ // through the same handoff via the mobile route).
147
+ const [pageUrl, setPageUrl] = React.useState("");
79
148
  React.useEffect(() => {
80
149
  if ((0, env_1.getHost)() !== "web")
81
150
  return;
82
- if (readDismissed())
83
- return;
84
151
  (0, styles_1.ensureBannerStylesInjected)();
85
- setStoreUrl((0, store_links_1.resolveStoreUrl)());
86
- setVisible(true);
152
+ setCta((0, store_links_1.resolveBannerCta)());
153
+ setMobile(isMobile());
154
+ setPageUrl(typeof window !== "undefined" ? window.location.href : "");
155
+ setMounted(true);
156
+ }, []);
157
+ const dismissModal = React.useCallback(() => {
158
+ setModalDismissed(true);
87
159
  }, []);
160
+ // Flip `modalReady` after MODAL_DELAY_MS so the strong CTA only
161
+ // appears once the user has had time to engage with the app. Cleaned
162
+ // up on unmount so a quick navigation doesn't leak a timer that
163
+ // re-renders the (now stale) Provider.
164
+ React.useEffect(() => {
165
+ if (!mounted)
166
+ return;
167
+ const timer = window.setTimeout(() => {
168
+ setModalReady(true);
169
+ }, MODAL_DELAY_MS);
170
+ return () => window.clearTimeout(timer);
171
+ }, [mounted]);
172
+ // ESC closes the modal — same dismiss path as the X button. Only
173
+ // armed while the modal is actually rendered.
88
174
  React.useEffect(() => {
89
- if (!visible)
175
+ if (!mounted || modalDismissed || !modalReady)
176
+ return;
177
+ const onKeyDown = (e) => {
178
+ if (e.key === "Escape")
179
+ dismissModal();
180
+ };
181
+ document.addEventListener("keydown", onKeyDown);
182
+ return () => document.removeEventListener("keydown", onKeyDown);
183
+ }, [mounted, modalDismissed, modalReady, dismissModal]);
184
+ // Reserve top + bottom space on `<html>` so the host page's own layout
185
+ // doesn't tuck under the fixed banners. Restored on unmount.
186
+ React.useEffect(() => {
187
+ if (!mounted)
90
188
  return;
91
189
  const html = document.documentElement;
92
- const previousPaddingTop = html.style.paddingTop;
190
+ const previousTop = html.style.paddingTop;
191
+ const previousBottom = html.style.paddingBottom;
93
192
  const apply = () => {
94
- html.style.paddingTop = `${currentBannerHeight()}px`;
193
+ const m = isMobile();
194
+ setMobile(m);
195
+ html.style.paddingTop = `${topBannerHeightPx(m)}px`;
196
+ html.style.paddingBottom = `${bottomBannerHeightPx(m)}px`;
95
197
  };
96
198
  apply();
97
199
  window.addEventListener("resize", apply);
98
200
  return () => {
99
201
  window.removeEventListener("resize", apply);
100
- html.style.paddingTop = previousPaddingTop;
202
+ html.style.paddingTop = previousTop;
203
+ html.style.paddingBottom = previousBottom;
101
204
  };
102
- }, [visible]);
103
- if (!visible)
205
+ }, [mounted]);
206
+ // Fetch public app info on the client when the host didn't prefetch.
207
+ // If `initialAppInfo` was supplied via the Provider, `info` is already
208
+ // seeded above and `loading` is already false — skip the fetch entirely.
209
+ // The overlay still renders without info — the identity falls back to
210
+ // initials / generic copy. `loading` clears either way so the skeleton
211
+ // doesn't shimmer forever on fetch failure.
212
+ React.useEffect(() => {
213
+ if (!mounted)
214
+ return;
215
+ if (info)
216
+ return;
217
+ const appId = (0, config_1.getAppId)();
218
+ if (!appId) {
219
+ setLoading(false);
220
+ return;
221
+ }
222
+ const controller = new AbortController();
223
+ (0, app_info_1.fetchPublicAppInfo)(appId, { signal: controller.signal })
224
+ .then((data) => {
225
+ if (controller.signal.aborted)
226
+ return;
227
+ setInfo(data);
228
+ setLoading(false);
229
+ })
230
+ .catch(() => {
231
+ if (controller.signal.aborted)
232
+ return;
233
+ setLoading(false);
234
+ });
235
+ return () => controller.abort();
236
+ // `info` is captured via closure on first mount; intentionally not in
237
+ // deps — we only want to attempt the client fetch once, on
238
+ // mount, if no prefetch was supplied. Re-fetching when `info` later
239
+ // changes would be pointless.
240
+ // eslint-disable-next-line react-hooks/exhaustive-deps
241
+ }, [mounted]);
242
+ if (!mounted || !cta)
104
243
  return null;
105
- const dismiss = () => {
106
- writeDismissed();
107
- setVisible(false);
244
+ return ((0, jsx_runtime_1.jsxs)("div", { className: "eazo-handoff-root", children: [(0, jsx_runtime_1.jsx)(TopBanner, { cta: cta, pageUrl: pageUrl }), modalDismissed || !modalReady ? null : ((0, jsx_runtime_1.jsx)(Overlay, { info: info, cta: cta, loading: loading, pageUrl: pageUrl, onDismiss: dismissModal })), (0, jsx_runtime_1.jsx)(BottomBanner, { info: info, loading: loading, cta: cta })] }));
245
+ }
246
+ // ---------------------------------------------------------------------------
247
+ // CTA click handler — same scheme + iOS-timeout fallback used elsewhere
248
+ // in the SDK. Lives at module scope so both the top-bar button and the
249
+ // modal primary CTA share the exact same behaviour.
250
+ // ---------------------------------------------------------------------------
251
+ function bindCtaClick(cta) {
252
+ return () => {
253
+ if (!cta.needsTimeoutFallback)
254
+ return;
255
+ const start = Date.now();
256
+ let appOpened = false;
257
+ const onVisibilityChange = () => {
258
+ if (document.visibilityState === "hidden")
259
+ appOpened = true;
260
+ };
261
+ document.addEventListener("visibilitychange", onVisibilityChange);
262
+ window.setTimeout(() => {
263
+ document.removeEventListener("visibilitychange", onVisibilityChange);
264
+ if (!appOpened &&
265
+ document.visibilityState === "visible" &&
266
+ Date.now() - start < IOS_FALLBACK_TIMEOUT_MS + 500) {
267
+ window.location.href = cta.storeUrl;
268
+ }
269
+ }, IOS_FALLBACK_TIMEOUT_MS);
108
270
  };
109
- return ((0, jsx_runtime_1.jsxs)("div", { className: "eazo-banner-root", role: "region", "aria-label": "Eazo app promotion", children: [(0, jsx_runtime_1.jsx)("span", { className: "eazo-banner-brand", children: (0, jsx_runtime_1.jsx)(icons_1.EazoLogo, { width: 72, height: 20 }) }), (0, jsx_runtime_1.jsx)("span", { className: "eazo-banner-copy", children: "Get the full Eazo experience in our mobile app." }), (0, jsx_runtime_1.jsx)("a", { className: "eazo-banner-cta", href: storeUrl, target: "_blank", rel: "noreferrer noopener", children: "Get the app" }), (0, jsx_runtime_1.jsx)("button", { type: "button", className: "eazo-banner-close", "aria-label": "Dismiss banner", onClick: dismiss, children: (0, jsx_runtime_1.jsx)(icons_1.CloseIcon, { size: 16 }) })] }));
271
+ }
272
+ function TopBanner({ cta, pageUrl }) {
273
+ return ((0, jsx_runtime_1.jsxs)("div", { className: "eazo-banner-root", role: "region", "aria-label": "Eazo app promotion", children: [(0, jsx_runtime_1.jsx)("span", { className: "eazo-banner-brand", children: (0, jsx_runtime_1.jsx)(icons_1.EazoLogo, { width: 72, height: 20 }) }), (0, jsx_runtime_1.jsx)("span", { className: "eazo-banner-copy", children: "Get the full Eazo experience in our mobile app." }), (0, jsx_runtime_1.jsx)(TopBannerCta, { cta: cta, pageUrl: pageUrl })] }));
274
+ }
275
+ // Delay before hiding the hover popover after the cursor leaves both
276
+ // the CTA and the popover itself. Short enough to feel responsive but
277
+ // long enough that a user can move from one to the other without the
278
+ // popover snapping shut mid-travel.
279
+ const POPOVER_HIDE_DELAY_MS = 140;
280
+ /**
281
+ * Top-banner CTA with a hover/focus-triggered QR popover. The popover
282
+ * encodes the current page URL — a desktop visitor scanning with their
283
+ * phone lands on the same page on mobile, where the SDK's mobile-path
284
+ * deep-link kicks in (or the App-Store fallback if the app isn't
285
+ * installed). Falls back to a plain link click on touch devices, where
286
+ * `hover` never resolves and the popover stays suppressed by media query.
287
+ */
288
+ function TopBannerCta({ cta, pageUrl, }) {
289
+ const onClick = React.useMemo(() => bindCtaClick(cta), [cta]);
290
+ const [open, setOpen] = React.useState(false);
291
+ const hideTimerRef = React.useRef(null);
292
+ const show = React.useCallback(() => {
293
+ if (hideTimerRef.current !== null) {
294
+ window.clearTimeout(hideTimerRef.current);
295
+ hideTimerRef.current = null;
296
+ }
297
+ setOpen(true);
298
+ }, []);
299
+ const queueHide = React.useCallback(() => {
300
+ if (hideTimerRef.current !== null) {
301
+ window.clearTimeout(hideTimerRef.current);
302
+ }
303
+ hideTimerRef.current = window.setTimeout(() => {
304
+ setOpen(false);
305
+ hideTimerRef.current = null;
306
+ }, POPOVER_HIDE_DELAY_MS);
307
+ }, []);
308
+ React.useEffect(() => () => {
309
+ if (hideTimerRef.current !== null) {
310
+ window.clearTimeout(hideTimerRef.current);
311
+ }
312
+ }, []);
313
+ return ((0, jsx_runtime_1.jsxs)("span", { className: "eazo-banner-cta-wrap", onMouseEnter: show, onMouseLeave: queueHide, onFocusCapture: show, onBlurCapture: queueHide, children: [(0, jsx_runtime_1.jsx)("a", { className: "eazo-banner-cta", href: cta.href, rel: "noreferrer noopener", onClick: onClick, "aria-describedby": open ? "eazo-banner-cta-popover" : undefined, children: "Open in app" }), open && pageUrl ? ((0, jsx_runtime_1.jsxs)("div", { id: "eazo-banner-cta-popover", className: "eazo-banner-cta-popover", role: "tooltip", children: [(0, jsx_runtime_1.jsx)("span", { className: "eazo-banner-cta-popover-arrow", "aria-hidden": "true" }), (0, jsx_runtime_1.jsx)("div", { className: "eazo-banner-cta-popover-qr", children: (0, jsx_runtime_1.jsx)(qr_1.QrSvg, { value: pageUrl, size: 140 }) }), (0, jsx_runtime_1.jsx)("div", { className: "eazo-banner-cta-popover-caption", children: "Scan to open in the Eazo app." })] })) : null] }));
314
+ }
315
+ function Overlay({ cta, info, loading, pageUrl, onDismiss }) {
316
+ const onClick = React.useMemo(() => bindCtaClick(cta), [cta]);
317
+ // While loading we still want SOMETHING in the monolith; initials of
318
+ // "Eazo app" reads better than a literal placeholder. Once `info`
319
+ // resolves, the real name's initials or cover image take over.
320
+ const initials = deriveInitials(info?.app.name ?? "Eazo app");
321
+ // `app.icon` carries either an image URL or a short text glyph (emoji,
322
+ // single letter, etc.). The orbit center swaps in an <img> for URL-shaped
323
+ // values and falls back to the typographic slot for glyphs and when the
324
+ // field is missing altogether. URL detection accepts the full set the
325
+ // backend may emit: absolute http(s), protocol-relative, server-relative,
326
+ // and inline data:image URLs.
327
+ const rawIcon = info?.app.icon?.trim();
328
+ const iconUrl = rawIcon && isImageUrl(rawIcon) ? rawIcon : undefined;
329
+ const iconGlyph = rawIcon && !iconUrl ? rawIcon : undefined;
330
+ return ((0, jsx_runtime_1.jsxs)("div", { className: "eazo-handoff-overlay", role: "dialog", "aria-modal": "true", "aria-labelledby": "eazo-handoff-title", children: [(0, jsx_runtime_1.jsx)("div", { className: "eazo-handoff-overlay-dim" }), (0, jsx_runtime_1.jsx)("div", { className: "eazo-handoff-overlay-spot" }), (0, jsx_runtime_1.jsxs)("div", { className: "eazo-modal", children: [(0, jsx_runtime_1.jsx)("button", { type: "button", className: "eazo-modal-close", "aria-label": "Dismiss", onClick: onDismiss, children: (0, jsx_runtime_1.jsx)("svg", { width: 14, height: 14, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.2", strokeLinecap: "round", strokeLinejoin: "round", children: (0, jsx_runtime_1.jsx)("path", { d: "M6 6l12 12M18 6L6 18" }) }) }), (0, jsx_runtime_1.jsx)(Orbit, { initials: iconGlyph ?? initials, iconUrl: iconUrl, loading: loading }), (0, jsx_runtime_1.jsx)("div", { className: "eazo-modal-eyebrow", children: "Now showing in Eazo" }), loading ? (
331
+ // Two-line skeleton stand-in for title + tagline. Width
332
+ // ratios match a typical 2-word app name / one-sentence
333
+ // tagline so the modal doesn't visibly resize when real
334
+ // copy lands.
335
+ (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("span", { className: "eazo-skel eazo-skel-title", role: "status", "aria-label": "Loading app info" }), (0, jsx_runtime_1.jsxs)("div", { style: { width: "100%", maxWidth: 360, textAlign: "center" }, children: [(0, jsx_runtime_1.jsx)("span", { className: "eazo-skel eazo-skel-sub-1" }), (0, jsx_runtime_1.jsx)("br", {}), (0, jsx_runtime_1.jsx)("span", { className: "eazo-skel eazo-skel-sub-2" })] })] })) : ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("h2", { id: "eazo-handoff-title", className: "eazo-modal-title", children: info?.app.name ?? "This app" }), (0, jsx_runtime_1.jsx)("p", { className: "eazo-modal-sub", children: info?.app.tagline ??
336
+ info?.app.description ??
337
+ "Open the mobile app for the full experience." })] })), (0, jsx_runtime_1.jsxs)("div", { className: "eazo-cta-row", children: [(0, jsx_runtime_1.jsx)("div", { className: "eazo-qr-tile", children: pageUrl ? (0, jsx_runtime_1.jsx)(qr_1.QrSvg, { value: pageUrl, size: 88 }) : null }), (0, jsx_runtime_1.jsxs)("div", { className: "eazo-cta-body", children: [(0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("div", { className: "eazo-cta-headline", children: "Scan to open" }), (0, jsx_runtime_1.jsx)("div", { className: "eazo-cta-fine", children: "Scan to continue this page on your phone, or tap to open in Eazo." })] }), (0, jsx_runtime_1.jsxs)("a", { className: "eazo-cta-primary", href: cta.href, rel: "noreferrer noopener", onClick: onClick, children: ["Open in Eazo app", (0, jsx_runtime_1.jsx)(icons_1.ArrowRightIcon, { size: 12 })] })] })] })] })] }));
338
+ }
339
+ function Orbit({ initials, iconUrl, loading = false }) {
340
+ // All geometry runs in a 280-unit coordinate space. The SVG uses
341
+ // `viewBox` so its rings scale to whatever pixel size the parent is
342
+ // (280 desktop / 220 mobile). The capability nodes are positioned via
343
+ // percentage `left/top` on the rotating track, and centered on those
344
+ // points by the negative-margin trick in CSS (margin trick avoids
345
+ // colliding with the track's rotate animation, unlike a transform
346
+ // would).
347
+ const SIDE = 280;
348
+ const RADIUS = 102;
349
+ const CENTER = SIDE / 2;
350
+ // Radius as a percentage of half the box — used to convert polar
351
+ // coordinates to percentage `left/top` on the track.
352
+ const RADIUS_PCT = (RADIUS / CENTER) * 50;
353
+ return ((0, jsx_runtime_1.jsxs)("div", { className: "eazo-orbit", children: [(0, jsx_runtime_1.jsxs)("svg", { className: "eazo-orbit-rings", viewBox: `0 0 ${SIDE} ${SIDE}`, preserveAspectRatio: "xMidYMid meet", "aria-hidden": "true", children: [(0, jsx_runtime_1.jsx)("circle", { cx: CENTER, cy: CENTER, r: 132, fill: "none", stroke: "rgba(17,19,15,0.06)" }), (0, jsx_runtime_1.jsx)("circle", { cx: CENTER, cy: CENTER, r: 102, fill: "none", stroke: "rgba(17,19,15,0.08)", strokeDasharray: "2 6" }), (0, jsx_runtime_1.jsx)("circle", { cx: CENTER, cy: CENTER, r: 74, fill: "none", stroke: "rgba(212,97,74,0.30)" })] }), (0, jsx_runtime_1.jsx)("div", { className: "eazo-orbit-track", children: icons_1.CAPABILITIES.map((c, i) => {
354
+ // Distribute nodes evenly around the ring, starting from the
355
+ // top (`-Math.PI / 2`).
356
+ const angle = (i / icons_1.CAPABILITIES.length) * Math.PI * 2 - Math.PI / 2;
357
+ const leftPct = 50 + Math.cos(angle) * RADIUS_PCT;
358
+ const topPct = 50 + Math.sin(angle) * RADIUS_PCT;
359
+ return ((0, jsx_runtime_1.jsx)("div", { className: "eazo-orbit-node", style: { left: `${leftPct}%`, top: `${topPct}%` }, "aria-label": c.label, children: (0, jsx_runtime_1.jsx)(icons_1.CapIcon, { k: c.key, size: 14 }) }, c.key));
360
+ }) }), (0, jsx_runtime_1.jsx)(Monolith, { initials: initials, iconUrl: iconUrl, loading: loading })] }));
361
+ }
362
+ function Monolith({ initials, iconUrl, loading }) {
363
+ const [imgState, setImgState] = React.useState(iconUrl ? "pending" : "loaded");
364
+ // Reset whenever the URL changes — covers Provider remounts and
365
+ // hot-reload paths where the icon swaps without a fresh component.
366
+ React.useEffect(() => {
367
+ setImgState(iconUrl ? "pending" : "loaded");
368
+ }, [iconUrl]);
369
+ const hasUsableImg = !!iconUrl && imgState !== "errored";
370
+ const showShimmer = loading || (hasUsableImg && imgState === "pending");
371
+ // Text falls in when there's nothing to show as a picture: not loading,
372
+ // and either no URL or the URL failed to load.
373
+ const showText = !loading && !hasUsableImg;
374
+ return ((0, jsx_runtime_1.jsxs)("div", { className: "eazo-monolith", "aria-hidden": "true", children: [hasUsableImg ? ((0, jsx_runtime_1.jsx)("img", { className: `eazo-monolith-img${imgState === "loaded" ? " is-loaded" : ""}`, src: iconUrl, alt: "", onLoad: () => setImgState("loaded"), onError: () => setImgState("errored") })) : null, showText ? ((0, jsx_runtime_1.jsx)("span", { style: { transform: "translateY(-1px)" }, children: initials })) : null, showShimmer ? (0, jsx_runtime_1.jsx)("div", { className: "eazo-monolith-skel" }) : null] }));
375
+ }
376
+ function BottomBanner({ info, loading, cta, }) {
377
+ // Source-of-truth stats come from the public app endpoint. Surface
378
+ // only metrics the backend exposes today AND that read meaningfully
379
+ // for a host-app promo surface — likes and comments. `uv` is in the
380
+ // DTO but reads as ambient web-traffic, not social proof, so it's
381
+ // intentionally not on this rail. Installs / rating / trend appeared
382
+ // in the V5 design canvas but require new backend fields — adding
383
+ // them is a backend change, not a banner change.
384
+ const stats = [
385
+ {
386
+ key: "likes",
387
+ icon: (0, jsx_runtime_1.jsx)(icons_1.HeartIcon, { size: 16 }),
388
+ filled: true,
389
+ value: loading ? null : formatStat(info?.app.likeNum),
390
+ label: "likes",
391
+ },
392
+ {
393
+ key: "comments",
394
+ icon: (0, jsx_runtime_1.jsx)(icons_1.ChatIcon, { size: 16 }),
395
+ value: loading ? null : formatStat(info?.app.commentsCount),
396
+ label: "comments",
397
+ },
398
+ ];
399
+ // Remix tap reuses the same deeplink + iOS-store-timeout flow as the
400
+ // top banner — both point at `eazo://app/<appId>` so the mobile shell
401
+ // can route to the right surface (the Remix vs Open intent split is
402
+ // up to the host app to wire from the URL params, not this banner).
403
+ const onRemixClick = React.useMemo(() => bindCtaClick(cta), [cta]);
404
+ return ((0, jsx_runtime_1.jsxs)("div", { className: "eazo-bottom-root", role: "contentinfo", children: [(0, jsx_runtime_1.jsx)("div", { className: "eazo-bottom-stats", "aria-label": loading ? "Loading app stats" : "App stats", children: stats.map((s, i) => ((0, jsx_runtime_1.jsxs)(React.Fragment, { children: [i > 0 && ((0, jsx_runtime_1.jsx)("span", { className: "eazo-bottom-stat-divider", "aria-hidden": "true" })), (0, jsx_runtime_1.jsxs)("span", { className: "eazo-bottom-stat", children: [(0, jsx_runtime_1.jsx)("span", { className: `eazo-bottom-stat-icon${s.filled ? "" : " is-line"}`, children: s.icon }), (0, jsx_runtime_1.jsxs)("span", { className: "eazo-bottom-stat-text", children: [s.value === null ? ((0, jsx_runtime_1.jsx)("span", { className: "eazo-bottom-skel" })) : ((0, jsx_runtime_1.jsx)("span", { className: "eazo-bottom-stat-value", children: s.value })), (0, jsx_runtime_1.jsx)("span", { className: "eazo-bottom-stat-label", children: s.label })] })] })] }, s.key))) }), (0, jsx_runtime_1.jsxs)("div", { className: "eazo-bottom-actions", children: [(0, jsx_runtime_1.jsxs)("a", { className: "eazo-bottom-site", href: "https://eazo.ai/", target: "_blank", rel: "noreferrer noopener", children: [(0, jsx_runtime_1.jsx)("b", { children: "eazo.ai" }), (0, jsx_runtime_1.jsx)("svg", { width: 10, height: 10, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.4", strokeLinecap: "round", strokeLinejoin: "round", children: (0, jsx_runtime_1.jsx)("path", { d: "M7 17 17 7M9 7h8v8" }) })] }), (0, jsx_runtime_1.jsxs)("a", { className: "eazo-bottom-remix", href: cta.href, onClick: onRemixClick, "aria-label": "Remix this app", children: [(0, jsx_runtime_1.jsx)(icons_1.RemixIcon, { size: 17 }), "Remix", (0, jsx_runtime_1.jsx)("span", { className: "eazo-bottom-remix-suffix", children: "\u00A0this app" })] })] })] }));
110
405
  }
111
406
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/internal/banner-ui/index.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/internal/banner-ui/index.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { PublicAppInfo } from "./app-info";
2
+ export declare function setInitialAppInfo(info: PublicAppInfo | null): void;
3
+ export declare function getInitialAppInfo(): PublicAppInfo | null;
4
+ //# sourceMappingURL=initial-info.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"initial-info.d.ts","sourceRoot":"","sources":["../../../src/internal/banner-ui/initial-info.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAchD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,aAAa,GAAG,IAAI,GAAG,IAAI,CAElE;AAED,wBAAgB,iBAAiB,IAAI,aAAa,GAAG,IAAI,CAExD"}
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.setInitialAppInfo = setInitialAppInfo;
4
+ exports.getInitialAppInfo = getInitialAppInfo;
5
+ /**
6
+ * Optional prefetched `PublicAppInfo` handed in by the host app's server
7
+ * (Next.js layout, Remix loader, etc.) via `<EazoProvider initialAppInfo>`.
8
+ * When present, the handoff banner skips its client-side fetch and renders
9
+ * real content on first paint — no skeleton flash.
10
+ *
11
+ * Module-level state mirrors the `setAppId` / `getAppId` pattern in
12
+ * `internal/config.ts`. Safe because `EazoProvider` is `"use client"`:
13
+ * the setter only runs in the browser, never in a shared server process.
14
+ */
15
+ let initialAppInfo = null;
16
+ function setInitialAppInfo(info) {
17
+ initialAppInfo = info;
18
+ }
19
+ function getInitialAppInfo() {
20
+ return initialAppInfo;
21
+ }
22
+ //# sourceMappingURL=initial-info.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"initial-info.js","sourceRoot":"","sources":["../../../src/internal/banner-ui/initial-info.ts"],"names":[],"mappings":";;AAcA,8CAEC;AAED,8CAEC;AAlBD;;;;;;;;;GASG;AACH,IAAI,cAAc,GAAyB,IAAI,CAAC;AAEhD,SAAgB,iBAAiB,CAAC,IAA0B;IAC1D,cAAc,GAAG,IAAI,CAAC;AACxB,CAAC;AAED,SAAgB,iBAAiB;IAC/B,OAAO,cAAc,CAAC;AACxB,CAAC"}
@@ -0,0 +1,22 @@
1
+ import * as React from "react";
2
+ interface QrSvgProps {
3
+ /** Payload to encode. URLs work as expected; arbitrary strings encode too. */
4
+ value: string;
5
+ /** Total SVG side length in CSS px. */
6
+ size?: number;
7
+ /** Foreground / module color. */
8
+ fg?: string;
9
+ /** Background color, paints behind the modules. */
10
+ bg?: string;
11
+ /** Border-radius applied to the SVG host. */
12
+ radius?: number;
13
+ }
14
+ /**
15
+ * Renders a real, scannable QR code as inline SVG. Used by the web-only
16
+ * handoff overlay to encode the `eazo://` deep link for the host app so
17
+ * users on a desktop browser can pop their phone over the screen to open
18
+ * the app directly.
19
+ */
20
+ export declare function QrSvg({ value, size, fg, bg, radius, }: QrSvgProps): React.ReactElement | null;
21
+ export {};
22
+ //# sourceMappingURL=qr.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"qr.d.ts","sourceRoot":"","sources":["../../../src/internal/banner-ui/qr.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAM/B,UAAU,UAAU;IAClB,8EAA8E;IAC9E,KAAK,EAAE,MAAM,CAAC;IACd,uCAAuC;IACvC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,iCAAiC;IACjC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,mDAAmD;IACnD,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,6CAA6C;IAC7C,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;GAKG;AACH,wBAAgB,KAAK,CAAC,EACpB,KAAK,EACL,IAAS,EACT,EAAc,EACd,EAAc,EACd,MAAU,GACX,EAAE,UAAU,GAAG,KAAK,CAAC,YAAY,GAAG,IAAI,CA+DxC"}
@@ -0,0 +1,95 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.QrSvg = QrSvg;
40
+ const jsx_runtime_1 = require("react/jsx-runtime");
41
+ const React = __importStar(require("react"));
42
+ // `qrcode-generator` is a zero-dep, browser-friendly QR encoder. CJS-only
43
+ // default export — we import via require shim to avoid the ES-interop
44
+ // landmines that come with its UMD shape.
45
+ const qrcode_generator_1 = __importDefault(require("qrcode-generator"));
46
+ /**
47
+ * Renders a real, scannable QR code as inline SVG. Used by the web-only
48
+ * handoff overlay to encode the `eazo://` deep link for the host app so
49
+ * users on a desktop browser can pop their phone over the screen to open
50
+ * the app directly.
51
+ */
52
+ function QrSvg({ value, size = 88, fg = "#11130f", bg = "#ffffff", radius = 6, }) {
53
+ // Memoize the encode — fairly cheap, but the SVG can re-render often
54
+ // (the parent banner re-renders on resize / state changes) and the
55
+ // encoder is deterministic for a given `value`.
56
+ const matrix = React.useMemo(() => {
57
+ if (!value)
58
+ return null;
59
+ // Type-number 0 = "auto-pick smallest that fits" given the data + ECC.
60
+ // Error-correction level M is a sensible default for promo URLs:
61
+ // resilient to ~15% damage but still compact enough for a 25px-ish
62
+ // module count at 88px box.
63
+ const qr = (0, qrcode_generator_1.default)(0, "M");
64
+ qr.addData(value);
65
+ qr.make();
66
+ const count = qr.getModuleCount();
67
+ const rows = [];
68
+ for (let r = 0; r < count; r += 1) {
69
+ const row = [];
70
+ for (let c = 0; c < count; c += 1) {
71
+ row.push(qr.isDark(r, c));
72
+ }
73
+ rows.push(row);
74
+ }
75
+ return { rows, count };
76
+ }, [value]);
77
+ if (!matrix)
78
+ return null;
79
+ const { rows, count } = matrix;
80
+ // Reserve a 2-module quiet zone on each side so scanners can lock on
81
+ // even when the SVG sits flush against neighboring chrome.
82
+ const quiet = 2;
83
+ const totalCells = count + quiet * 2;
84
+ const cell = size / totalCells;
85
+ const rects = [];
86
+ for (let r = 0; r < count; r += 1) {
87
+ for (let c = 0; c < count; c += 1) {
88
+ if (!rows[r][c])
89
+ continue;
90
+ rects.push((0, jsx_runtime_1.jsx)("rect", { x: (c + quiet) * cell, y: (r + quiet) * cell, width: cell, height: cell, fill: fg }, `${r}-${c}`));
91
+ }
92
+ }
93
+ return ((0, jsx_runtime_1.jsx)("svg", { width: size, height: size, viewBox: `0 0 ${size} ${size}`, style: { background: bg, borderRadius: radius, display: "block" }, "aria-label": "QR code", role: "img", children: rects }));
94
+ }
95
+ //# sourceMappingURL=qr.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"qr.js","sourceRoot":"","sources":["../../../src/internal/banner-ui/qr.tsx"],"names":[],"mappings":"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"}