@wix/himalaya-cli 0.1145.0 → 0.1147.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.
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/comments-v1/src/extensions.d.ts +4 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/forum/src/extensions.d.ts +10 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-comments.mjs +5 -2
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-forum.mjs +13 -0
- package/dist/cli.mjs +75 -19
- package/dist/preview-assets.generated.bin +0 -0
- package/guides/headless-loop.md +34 -0
- package/guides/himi-mcp.md +2 -0
- package/guides/sdk-reference.json +13 -1
- package/guides/tier-5-add-a-screen.md +4 -2
- package/package.json +2 -2
- package/templates/beauty-salon/dev/index.ts +62 -3
- package/templates/beauty-salon/tier5-src/_shared/rich-body.ts +10 -4
- package/templates/beauty-salon/tier5-src/himi-blog-post/index.ts +12 -2
- package/templates/beauty-salon/tier5-src/himi-branded-lite-home/index.ts +6 -1
- package/templates/beauty-salon/tier5-src/himi-store-product/index.ts +35 -4
- package/templates/beauty-salon-owner/tier5-src/_shared/rich-body.ts +10 -4
- package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-home/index.ts +6 -1
- package/templates/branded-lite/dev/index.ts +273 -12
- package/templates/branded-lite/tier5-src/_shared/rich-body.ts +10 -4
- package/templates/branded-lite/tier5-src/himi-blog-post/index.ts +12 -2
- package/templates/branded-lite/tier5-src/himi-branded-lite-cms-collection/index.ts +43 -3
- package/templates/branded-lite/tier5-src/himi-branded-lite-faq/index.ts +69 -13
- package/templates/branded-lite/tier5-src/himi-branded-lite-feed/index.ts +23 -3
- package/templates/branded-lite/tier5-src/himi-branded-lite-home/index.ts +6 -1
- package/templates/branded-lite/tier5-src/himi-events-detail/index.ts +40 -3
- package/templates/branded-lite/tier5-src/himi-store-product/index.ts +35 -4
- package/templates/branded-lite/tier5-src/wix-spaces-forum-post/index.ts +29 -5
- package/templates/community-club/dev/index.ts +135 -5
- package/templates/community-club/tier5-src/_shared/rich-body.ts +10 -4
- package/templates/community-club/tier5-src/himi-blog-post/index.ts +12 -2
- package/templates/community-club/tier5-src/himi-branded-lite-cms-collection/index.ts +43 -3
- package/templates/community-club/tier5-src/himi-branded-lite-feed/index.ts +23 -3
- package/templates/community-club/tier5-src/himi-branded-lite-home/index.ts +6 -1
- package/templates/community-club/tier5-src/himi-events-detail/index.ts +40 -3
- package/templates/community-club-owner/tier5-src/_shared/rich-body.ts +10 -4
- package/templates/community-club-owner/tier5-src/himi-owner-lite-home/index.ts +6 -1
- package/templates/events-meetups/dev/index.ts +91 -4
- package/templates/events-meetups/tier5-src/_shared/rich-body.ts +10 -4
- package/templates/events-meetups/tier5-src/himi-blog-post/index.ts +12 -2
- package/templates/events-meetups/tier5-src/himi-branded-lite-feed/index.ts +23 -3
- package/templates/events-meetups/tier5-src/himi-branded-lite-home/index.ts +6 -1
- package/templates/events-meetups/tier5-src/himi-events-detail/index.ts +40 -3
- package/templates/events-meetups-owner/tier5-src/_shared/rich-body.ts +10 -4
- package/templates/events-meetups-owner/tier5-src/himi-owner-lite-home/index.ts +6 -1
- package/templates/gym-fitness/dev/index.ts +92 -4
- package/templates/gym-fitness/tier5-src/_shared/rich-body.ts +10 -4
- package/templates/gym-fitness/tier5-src/himi-blog-post/index.ts +12 -2
- package/templates/gym-fitness/tier5-src/himi-branded-lite-home/index.ts +6 -1
- package/templates/gym-fitness/tier5-src/himi-events-detail/index.ts +40 -3
- package/templates/gym-fitness/tier5-src/himi-store-product/index.ts +35 -4
- package/templates/gym-fitness-owner/tier5-src/_shared/rich-body.ts +10 -4
- package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-home/index.ts +6 -1
- package/templates/nonprofit-cause/dev/index.ts +91 -4
- package/templates/nonprofit-cause/tier5-src/_shared/rich-body.ts +10 -4
- package/templates/nonprofit-cause/tier5-src/himi-blog-post/index.ts +12 -2
- package/templates/nonprofit-cause/tier5-src/himi-branded-lite-feed/index.ts +23 -3
- package/templates/nonprofit-cause/tier5-src/himi-branded-lite-home/index.ts +6 -1
- package/templates/nonprofit-cause/tier5-src/himi-events-detail/index.ts +40 -3
- package/templates/nonprofit-cause-owner/tier5-src/_shared/rich-body.ts +10 -4
- package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-home/index.ts +6 -1
- package/templates/owner-lite/tier5-src/_shared/rich-body.ts +10 -4
- package/templates/owner-lite/tier5-src/himi-owner-lite-home/index.ts +6 -1
- package/templates/podcast-creator/dev/index.ts +91 -4
- package/templates/podcast-creator/tier5-src/_shared/rich-body.ts +10 -4
- package/templates/podcast-creator/tier5-src/himi-blog-post/index.ts +12 -2
- package/templates/podcast-creator/tier5-src/himi-branded-lite-feed/index.ts +23 -3
- package/templates/podcast-creator/tier5-src/himi-branded-lite-home/index.ts +6 -1
- package/templates/podcast-creator/tier5-src/himi-events-detail/index.ts +40 -3
- package/templates/podcast-creator-owner/tier5-src/_shared/rich-body.ts +10 -4
- package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-home/index.ts +6 -1
- package/templates/portfolio-creative/dev/index.ts +92 -4
- package/templates/portfolio-creative/tier5-src/_shared/rich-body.ts +10 -4
- package/templates/portfolio-creative/tier5-src/himi-blog-post/index.ts +12 -2
- package/templates/portfolio-creative/tier5-src/himi-branded-lite-home/index.ts +6 -1
- package/templates/portfolio-creative/tier5-src/himi-events-detail/index.ts +40 -3
- package/templates/portfolio-creative/tier5-src/himi-store-product/index.ts +35 -4
- package/templates/portfolio-creative-owner/tier5-src/_shared/rich-body.ts +10 -4
- package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-home/index.ts +6 -1
- package/templates/restaurant/dev/index.ts +60 -2
- package/templates/restaurant/tier5-src/_shared/rich-body.ts +10 -4
- package/templates/restaurant/tier5-src/himi-blog-post/index.ts +12 -2
- package/templates/restaurant/tier5-src/himi-branded-lite-home/index.ts +6 -1
- package/templates/restaurant/tier5-src/himi-events-detail/index.ts +40 -3
- package/templates/restaurant-owner/tier5-src/_shared/rich-body.ts +10 -4
- package/templates/restaurant-owner/tier5-src/himi-owner-lite-home/index.ts +6 -1
- package/templates/retail-store/dev/index.ts +62 -3
- package/templates/retail-store/tier5-src/_shared/rich-body.ts +10 -4
- package/templates/retail-store/tier5-src/himi-blog-post/index.ts +12 -2
- package/templates/retail-store/tier5-src/himi-branded-lite-home/index.ts +6 -1
- package/templates/retail-store/tier5-src/himi-store-product/index.ts +35 -4
- package/templates/retail-store-owner/tier5-src/_shared/rich-body.ts +10 -4
- package/templates/retail-store-owner/tier5-src/himi-owner-lite-home/index.ts +6 -1
- package/templates/yoga-studio/dev/index.ts +60 -2
- package/templates/yoga-studio/tier5-src/_shared/rich-body.ts +10 -4
- package/templates/yoga-studio/tier5-src/himi-blog-post/index.ts +12 -2
- package/templates/yoga-studio/tier5-src/himi-branded-lite-home/index.ts +6 -1
- package/templates/yoga-studio/tier5-src/himi-events-detail/index.ts +40 -3
- package/templates/yoga-studio-owner/tier5-src/_shared/rich-body.ts +10 -4
- package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-home/index.ts +6 -1
|
@@ -10,6 +10,8 @@ import { cleanTitle } from "../_shared/himi-text.js";
|
|
|
10
10
|
import { stashCopy, copyParam, copyTemplate } from "../_shared/himi-copy.js";
|
|
11
11
|
import { isBridgeUnavailable } from "../_shared/owner-load-error.js";
|
|
12
12
|
import { isProductSaved, toggleSavedProduct } from "../_shared/himi-store-saved.js";
|
|
13
|
+
import { openRichLink } from "../_shared/rich-content-link.js";
|
|
14
|
+
import { richBody } from "../_shared/rich-body.js";
|
|
13
15
|
|
|
14
16
|
// Offline-first (data-offline): the detail is a public READ-THROUGH — when the live
|
|
15
17
|
// product fetch fails (offline) fall back to the last-synced row the catalog cached
|
|
@@ -120,11 +122,27 @@ function optionsHint(groups: StoreOption[], selection: StoreOptionSelection): st
|
|
|
120
122
|
return copyTemplate("product.optionsChoose", "Choose {options}", { options: missing.join(", ") });
|
|
121
123
|
}
|
|
122
124
|
|
|
125
|
+
/** The description pair. V3's `description` is a Ricos OBJECT (the HTML `plainText` would throw on it): it
|
|
126
|
+
* becomes the RichContent document, and `plainDescription` (or the document's own text) the plain copy. A V1
|
|
127
|
+
* `description` is an HTML string: stripped text, no document. */
|
|
128
|
+
function productBody(p: StoreProduct): { description: string; descriptionJson: string } {
|
|
129
|
+
const raw = (p as { description?: unknown }).description;
|
|
130
|
+
const html = plainText(p.plainDescription || (typeof raw === "string" ? raw : ""));
|
|
131
|
+
const { bodyJson, bodyText } = richBody(typeof raw === "string" ? null : raw, html);
|
|
132
|
+
return { description: html || bodyText, descriptionJson: bodyJson };
|
|
133
|
+
}
|
|
134
|
+
|
|
123
135
|
interface S {
|
|
124
136
|
status: "loading" | "ready" | "error";
|
|
125
137
|
name: string;
|
|
126
138
|
price: string;
|
|
139
|
+
/** The plain-text description: RichContent's fallback, and what shows with no document. */
|
|
127
140
|
description: string;
|
|
141
|
+
/** [rico] #3372 — a V3 product's Ricos `description` (read with `fields=DESCRIPTION`) as ONE document string
|
|
142
|
+
* for RichContent; "" for a V1 HTML description, none, or a document the encoder rejected. */
|
|
143
|
+
descriptionJson: string;
|
|
144
|
+
/** descriptionJson !== "" — gates the plain text, because RichContent draws nothing for "". */
|
|
145
|
+
hasDescriptionJson: boolean;
|
|
128
146
|
image: string;
|
|
129
147
|
/** FULL media gallery (media.items[] with the main image first) — the detail
|
|
130
148
|
* screen renders a Carousel over it when 2+ images exist. */
|
|
@@ -253,6 +271,7 @@ function derive(s: S): S {
|
|
|
253
271
|
const overflow = groups.length > OPTION_SLOTS;
|
|
254
272
|
return {
|
|
255
273
|
...s,
|
|
274
|
+
hasDescriptionJson: s.descriptionJson !== "",
|
|
256
275
|
...slotsOf(groups, s.selection),
|
|
257
276
|
hasOptions: groups.length > 0,
|
|
258
277
|
noOptions: groups.length === 0,
|
|
@@ -296,12 +315,16 @@ const svc = defineService<S, {
|
|
|
296
315
|
setCartCount: (s: S, arg?: unknown) => S;
|
|
297
316
|
share: (s: S) => Promise<S>;
|
|
298
317
|
toggleSave: (s: S) => S;
|
|
318
|
+
/** [rico] #3372 — RichContent's on_link: `{ url }` of the tapped link. */
|
|
319
|
+
openLink: (s: S, arg?: unknown) => Promise<S>;
|
|
299
320
|
}>("himiStoreProduct", {
|
|
300
321
|
state: derive({
|
|
301
322
|
status: "loading",
|
|
302
323
|
name: "",
|
|
303
324
|
price: "",
|
|
304
325
|
description: "",
|
|
326
|
+
descriptionJson: "",
|
|
327
|
+
hasDescriptionJson: false,
|
|
305
328
|
image: "",
|
|
306
329
|
gallery: [],
|
|
307
330
|
hasGallery: false,
|
|
@@ -354,7 +377,7 @@ const svc = defineService<S, {
|
|
|
354
377
|
if (!id) {
|
|
355
378
|
lastProduct = undefined;
|
|
356
379
|
lastLoadedId = undefined;
|
|
357
|
-
return derive({ ...s, status: "ready", quantity: 1, optionGroups: [], selection: {}, optionsUnknown: false, emptyText: copyParam("product.notFoundText", "Product not found.") });
|
|
380
|
+
return derive({ ...s, status: "ready", quantity: 1, optionGroups: [], selection: {}, optionsUnknown: false, descriptionJson: "", emptyText: copyParam("product.notFoundText", "Product not found.") });
|
|
358
381
|
}
|
|
359
382
|
// The cart count only feeds the top-bar badge: ask for it NOW, beside the product, instead
|
|
360
383
|
// of after it — it used to add a whole cart round trip before the page could paint.
|
|
@@ -365,7 +388,8 @@ const svc = defineService<S, {
|
|
|
365
388
|
void cartCount.then((n) => { cartKnown = n; }, () => {});
|
|
366
389
|
// The live product read goes out FIRST too — the local-db read below must never delay it.
|
|
367
390
|
// Settled into a value so a failure is handled where it is awaited, never unhandled.
|
|
368
|
-
|
|
391
|
+
// DESCRIPTION widens the default fieldset with the V3 Ricos description (a V1 catalog ignores it).
|
|
392
|
+
const live = getStoreProduct(id, ["DESCRIPTION"]).then(
|
|
369
393
|
(r) => ({ ok: true as const, r }),
|
|
370
394
|
() => ({ ok: false as const }),
|
|
371
395
|
);
|
|
@@ -424,7 +448,7 @@ const svc = defineService<S, {
|
|
|
424
448
|
optionsUnknown: false,
|
|
425
449
|
name,
|
|
426
450
|
price: productPrice(p),
|
|
427
|
-
|
|
451
|
+
...productBody(p),
|
|
428
452
|
image,
|
|
429
453
|
gallery: productGallery(p),
|
|
430
454
|
initial: (name[0] || "#").toUpperCase(),
|
|
@@ -455,6 +479,7 @@ const svc = defineService<S, {
|
|
|
455
479
|
name,
|
|
456
480
|
price: String(synced.subtitle ?? ""),
|
|
457
481
|
description: "",
|
|
482
|
+
descriptionJson: "",
|
|
458
483
|
image,
|
|
459
484
|
initial: String(synced.initial ?? "") || (name[0] || "#").toUpperCase(),
|
|
460
485
|
cartHint: copyParam("product.cartHintOffline", "Reconnect to choose options and add this to your cart."),
|
|
@@ -464,7 +489,7 @@ const svc = defineService<S, {
|
|
|
464
489
|
}
|
|
465
490
|
lastProduct = undefined;
|
|
466
491
|
lastLoadedId = undefined;
|
|
467
|
-
return derive({ ...s, status: "error", optionGroups: [], selection: {}, optionsUnknown: false, emptyText: copyParam("product.errorText", "Product could not load.") });
|
|
492
|
+
return derive({ ...s, status: "error", optionGroups: [], selection: {}, optionsUnknown: false, descriptionJson: "", emptyText: copyParam("product.errorText", "Product could not load.") });
|
|
468
493
|
},
|
|
469
494
|
// The stepper fires onChange with { value } on every tap; clamp 1–99 and
|
|
470
495
|
// ignore unparsable/garbage args instead of silently zeroing the quantity.
|
|
@@ -519,6 +544,7 @@ const svc = defineService<S, {
|
|
|
519
544
|
name,
|
|
520
545
|
price: String(row.subtitle ?? ""),
|
|
521
546
|
description: "",
|
|
547
|
+
descriptionJson: "",
|
|
522
548
|
image: String(row.image ?? ""),
|
|
523
549
|
gallery: [],
|
|
524
550
|
initial: String(row.initial ?? "") || (name[0] || "#").toUpperCase(),
|
|
@@ -605,6 +631,11 @@ const svc = defineService<S, {
|
|
|
605
631
|
return derive({ ...s, added: false, cartHint: copyParam("product.shareUnavailable", "Sharing is not available on this device.") });
|
|
606
632
|
}
|
|
607
633
|
},
|
|
634
|
+
// Only http(s), mailto and tel links reach open_url; a refused link, or one nothing opened, says so in the
|
|
635
|
+
// hint line (`added: false`, as for share, so it never renders inside the add-to-cart confirmation).
|
|
636
|
+
openLink: async (s, arg) => ((await openRichLink(arg))
|
|
637
|
+
? s
|
|
638
|
+
: derive({ ...s, added: false, cartHint: copyParam("product.linkOpenFailed", "This link could not be opened.") })),
|
|
608
639
|
},
|
|
609
640
|
});
|
|
610
641
|
|
|
@@ -14,15 +14,21 @@ export interface RichBody {
|
|
|
14
14
|
bodyText: string;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
+
/** [rico] #3372 — the media width for a document drawn in a LIST row (a feed post, a comment, a CMS item): the
|
|
18
|
+
* list-image size (WIX_LIST_IMAGE), so a scrolling list never downloads every image at detail size. */
|
|
19
|
+
export const ROW_IMAGE_WIDTH = 1000;
|
|
20
|
+
|
|
17
21
|
/** Prepares `richContent` (a Ricos document, as a Wix API returns it, or its JSON string). No document, or one
|
|
18
22
|
* that is not a document, gives `{ bodyJson: "", bodyText: fallback }`. A document past the viewer's limits
|
|
19
23
|
* gives bodyJson "" and its plain text — except one rejected as too deep, which is not walked again (the
|
|
20
|
-
* plain-text walk has no depth limit), so `fallback` stands in for it.
|
|
21
|
-
|
|
24
|
+
* plain-text walk has no depth limit), so `fallback` stands in for it. `imageWidth` sizes its media (default
|
|
25
|
+
* the 1400 px detail budget). */
|
|
26
|
+
export function richBody(richContent: unknown, fallback = "", imageWidth = 1400): RichBody {
|
|
22
27
|
const doc = parseRicosJson(richContent);
|
|
23
28
|
if (!doc) return { bodyJson: "", bodyText: fallback };
|
|
24
|
-
// 1400 px — the detail-image budget, which is also the encoder's maximum
|
|
25
|
-
|
|
29
|
+
// 1400 px by default — the detail-image budget, which is also the encoder's maximum; list rows pass
|
|
30
|
+
// ROW_IMAGE_WIDTH.
|
|
31
|
+
const { json, rejected } = encodeRichContent(doc, { imageWidth });
|
|
26
32
|
const text = rejected === "too_deep" ? "" : ricosToPlainText(doc);
|
|
27
33
|
return { bodyJson: json, bodyText: text || fallback };
|
|
28
34
|
}
|
|
@@ -309,7 +309,12 @@ async function measuredRevenue7d(
|
|
|
309
309
|
if (typeof measure.total === "number") return measure.total;
|
|
310
310
|
const values = measure.values ?? [];
|
|
311
311
|
return values.length ? values.reduce((sum, v) => sum + (v.value || 0), 0) : undefined;
|
|
312
|
-
} catch {
|
|
312
|
+
} catch (e) {
|
|
313
|
+
// The fallback is silent on screen (Home shows the order-row sum), so say it where
|
|
314
|
+
// an agent looks: the DEV panel's Console tab and `himi logs`. The status only — a Wix
|
|
315
|
+
// failure's message carries part of the upstream body, which may hold personal data.
|
|
316
|
+
const status = (e as { status?: unknown } | null)?.status ?? /\bHTTP (\d{3})\b/.exec(String(e))?.[1];
|
|
317
|
+
console.warn("[home.revenue] analytics failed; showing the order-row sum", status !== undefined ? `HTTP ${String(status)}` : "");
|
|
313
318
|
return undefined;
|
|
314
319
|
}
|
|
315
320
|
}
|
|
@@ -28190,7 +28190,32 @@ const SCREENS = runtimeSetting({
|
|
|
28190
28190
|
}
|
|
28191
28191
|
},
|
|
28192
28192
|
{
|
|
28193
|
-
"id": "",
|
|
28193
|
+
"id": "feed_body_$item.id",
|
|
28194
|
+
"body": {
|
|
28195
|
+
"package": "himalaya",
|
|
28196
|
+
"type": "RichContent",
|
|
28197
|
+
"props": {
|
|
28198
|
+
"documentJsonPath": "$item.bodyJson",
|
|
28199
|
+
"onLink": {
|
|
28200
|
+
"actionId": "tier5.himiBrandedFeed.openLink"
|
|
28201
|
+
},
|
|
28202
|
+
"fallback": {
|
|
28203
|
+
"id": "",
|
|
28204
|
+
"body": {
|
|
28205
|
+
"package": "himalaya",
|
|
28206
|
+
"type": "Text",
|
|
28207
|
+
"props": {
|
|
28208
|
+
"text": "$item.text",
|
|
28209
|
+
"style": "body",
|
|
28210
|
+
"maxLines": 6
|
|
28211
|
+
}
|
|
28212
|
+
}
|
|
28213
|
+
}
|
|
28214
|
+
}
|
|
28215
|
+
}
|
|
28216
|
+
},
|
|
28217
|
+
{
|
|
28218
|
+
"id": "feed_body_text_$item.id",
|
|
28194
28219
|
"body": {
|
|
28195
28220
|
"package": "himalaya",
|
|
28196
28221
|
"type": "Text",
|
|
@@ -28199,6 +28224,9 @@ const SCREENS = runtimeSetting({
|
|
|
28199
28224
|
"style": "body",
|
|
28200
28225
|
"maxLines": 6
|
|
28201
28226
|
}
|
|
28227
|
+
},
|
|
28228
|
+
"modifiers": {
|
|
28229
|
+
"hiddenPath": "$item.hasBodyJson"
|
|
28202
28230
|
}
|
|
28203
28231
|
},
|
|
28204
28232
|
{
|
|
@@ -28392,7 +28420,8 @@ const SCREENS = runtimeSetting({
|
|
|
28392
28420
|
"integrity": "",
|
|
28393
28421
|
"contentType": "application/javascript+ts-bundle",
|
|
28394
28422
|
"declaredCapabilities": [
|
|
28395
|
-
"wix_api"
|
|
28423
|
+
"wix_api",
|
|
28424
|
+
"open_url"
|
|
28396
28425
|
],
|
|
28397
28426
|
"minBinaryVersion": "0.1.0",
|
|
28398
28427
|
"bundleVersion": "0.0.1"
|
|
@@ -48300,7 +48329,32 @@ const SCREENS = runtimeSetting({
|
|
|
48300
48329
|
}
|
|
48301
48330
|
},
|
|
48302
48331
|
{
|
|
48303
|
-
"id": "",
|
|
48332
|
+
"id": "forum_body",
|
|
48333
|
+
"body": {
|
|
48334
|
+
"package": "himalaya",
|
|
48335
|
+
"type": "RichContent",
|
|
48336
|
+
"props": {
|
|
48337
|
+
"documentJsonPath": "$service:spacesForumPost.bodyJson",
|
|
48338
|
+
"onLink": {
|
|
48339
|
+
"actionId": "tier5.spacesForumPost.openLink"
|
|
48340
|
+
},
|
|
48341
|
+
"fallback": {
|
|
48342
|
+
"id": "",
|
|
48343
|
+
"body": {
|
|
48344
|
+
"package": "himalaya",
|
|
48345
|
+
"type": "Text",
|
|
48346
|
+
"props": {
|
|
48347
|
+
"text": "$service:spacesForumPost.body",
|
|
48348
|
+
"style": "body",
|
|
48349
|
+
"collapseWhenEmpty": true
|
|
48350
|
+
}
|
|
48351
|
+
}
|
|
48352
|
+
}
|
|
48353
|
+
}
|
|
48354
|
+
}
|
|
48355
|
+
},
|
|
48356
|
+
{
|
|
48357
|
+
"id": "forum_body_text",
|
|
48304
48358
|
"body": {
|
|
48305
48359
|
"package": "himalaya",
|
|
48306
48360
|
"type": "Text",
|
|
@@ -48309,6 +48363,9 @@ const SCREENS = runtimeSetting({
|
|
|
48309
48363
|
"style": "body",
|
|
48310
48364
|
"collapseWhenEmpty": true
|
|
48311
48365
|
}
|
|
48366
|
+
},
|
|
48367
|
+
"modifiers": {
|
|
48368
|
+
"hiddenPath": "$service:spacesForumPost.hasBodyJson"
|
|
48312
48369
|
}
|
|
48313
48370
|
}
|
|
48314
48371
|
]
|
|
@@ -48584,7 +48641,8 @@ const SCREENS = runtimeSetting({
|
|
|
48584
48641
|
"integrity": "",
|
|
48585
48642
|
"contentType": "application/javascript+ts-bundle",
|
|
48586
48643
|
"declaredCapabilities": [
|
|
48587
|
-
"wix_api"
|
|
48644
|
+
"wix_api",
|
|
48645
|
+
"open_url"
|
|
48588
48646
|
],
|
|
48589
48647
|
"minBinaryVersion": "0.1.0",
|
|
48590
48648
|
"bundleVersion": "0.0.1"
|
|
@@ -57815,7 +57873,32 @@ const SCREENS = runtimeSetting({
|
|
|
57815
57873
|
"expandedPath": "$item.expanded",
|
|
57816
57874
|
"content": [
|
|
57817
57875
|
{
|
|
57818
|
-
"id": "",
|
|
57876
|
+
"id": "faq_answer_$item.id",
|
|
57877
|
+
"body": {
|
|
57878
|
+
"package": "himalaya",
|
|
57879
|
+
"type": "RichContent",
|
|
57880
|
+
"props": {
|
|
57881
|
+
"documentJsonPath": "$item.answerJson",
|
|
57882
|
+
"onLink": {
|
|
57883
|
+
"actionId": "tier5.himiBrandedFaq.openLink"
|
|
57884
|
+
},
|
|
57885
|
+
"fallback": {
|
|
57886
|
+
"id": "",
|
|
57887
|
+
"body": {
|
|
57888
|
+
"package": "himalaya",
|
|
57889
|
+
"type": "Text",
|
|
57890
|
+
"props": {
|
|
57891
|
+
"text": "$item.answer",
|
|
57892
|
+
"style": "body",
|
|
57893
|
+
"color": "textSecondary"
|
|
57894
|
+
}
|
|
57895
|
+
}
|
|
57896
|
+
}
|
|
57897
|
+
}
|
|
57898
|
+
}
|
|
57899
|
+
},
|
|
57900
|
+
{
|
|
57901
|
+
"id": "faq_answer_text_$item.id",
|
|
57819
57902
|
"body": {
|
|
57820
57903
|
"package": "himalaya",
|
|
57821
57904
|
"type": "Text",
|
|
@@ -57824,6 +57907,9 @@ const SCREENS = runtimeSetting({
|
|
|
57824
57907
|
"style": "body",
|
|
57825
57908
|
"color": "textSecondary"
|
|
57826
57909
|
}
|
|
57910
|
+
},
|
|
57911
|
+
"modifiers": {
|
|
57912
|
+
"hiddenPath": "$item.hasAnswerJson"
|
|
57827
57913
|
}
|
|
57828
57914
|
}
|
|
57829
57915
|
],
|
|
@@ -58127,7 +58213,8 @@ const SCREENS = runtimeSetting({
|
|
|
58127
58213
|
"integrity": "",
|
|
58128
58214
|
"contentType": "application/javascript+ts-bundle",
|
|
58129
58215
|
"declaredCapabilities": [
|
|
58130
|
-
"wix_api"
|
|
58216
|
+
"wix_api",
|
|
58217
|
+
"open_url"
|
|
58131
58218
|
],
|
|
58132
58219
|
"minBinaryVersion": "0.1.0",
|
|
58133
58220
|
"bundleVersion": "0.0.1"
|
|
@@ -79110,6 +79197,48 @@ const SCREENS = runtimeSetting({
|
|
|
79110
79197
|
]
|
|
79111
79198
|
}
|
|
79112
79199
|
}
|
|
79200
|
+
},
|
|
79201
|
+
{
|
|
79202
|
+
"id": "cms_body_$item.id",
|
|
79203
|
+
"body": {
|
|
79204
|
+
"package": "himalaya",
|
|
79205
|
+
"type": "RichContent",
|
|
79206
|
+
"props": {
|
|
79207
|
+
"documentJsonPath": "$item.bodyJson",
|
|
79208
|
+
"onLink": {
|
|
79209
|
+
"actionId": "tier5.himiBrandedCmsCollection.openLink"
|
|
79210
|
+
},
|
|
79211
|
+
"fallback": {
|
|
79212
|
+
"id": "",
|
|
79213
|
+
"body": {
|
|
79214
|
+
"package": "himalaya",
|
|
79215
|
+
"type": "Text",
|
|
79216
|
+
"props": {
|
|
79217
|
+
"text": "$item.bodyText",
|
|
79218
|
+
"style": "body",
|
|
79219
|
+
"color": "textSecondary",
|
|
79220
|
+
"collapseWhenEmpty": true
|
|
79221
|
+
}
|
|
79222
|
+
}
|
|
79223
|
+
}
|
|
79224
|
+
}
|
|
79225
|
+
}
|
|
79226
|
+
},
|
|
79227
|
+
{
|
|
79228
|
+
"id": "cms_body_text_$item.id",
|
|
79229
|
+
"body": {
|
|
79230
|
+
"package": "himalaya",
|
|
79231
|
+
"type": "Text",
|
|
79232
|
+
"props": {
|
|
79233
|
+
"text": "$item.bodyText",
|
|
79234
|
+
"style": "body",
|
|
79235
|
+
"color": "textSecondary",
|
|
79236
|
+
"collapseWhenEmpty": true
|
|
79237
|
+
}
|
|
79238
|
+
},
|
|
79239
|
+
"modifiers": {
|
|
79240
|
+
"hiddenPath": "$item.hasBodyJson"
|
|
79241
|
+
}
|
|
79113
79242
|
}
|
|
79114
79243
|
]
|
|
79115
79244
|
}
|
|
@@ -79212,7 +79341,8 @@ const SCREENS = runtimeSetting({
|
|
|
79212
79341
|
"contentType": "application/javascript+ts-bundle",
|
|
79213
79342
|
"declaredCapabilities": [
|
|
79214
79343
|
"wix_api",
|
|
79215
|
-
"local_database"
|
|
79344
|
+
"local_database",
|
|
79345
|
+
"open_url"
|
|
79216
79346
|
],
|
|
79217
79347
|
"minBinaryVersion": "0.1.0",
|
|
79218
79348
|
"bundleVersion": "0.0.1"
|
|
@@ -80501,7 +80631,33 @@ const TEMPLATED: { pattern: string; display: string; liveSeed?: LiveSeed; static
|
|
|
80501
80631
|
}
|
|
80502
80632
|
},
|
|
80503
80633
|
{
|
|
80504
|
-
"id": "",
|
|
80634
|
+
"id": "product_body",
|
|
80635
|
+
"body": {
|
|
80636
|
+
"package": "himalaya",
|
|
80637
|
+
"type": "RichContent",
|
|
80638
|
+
"props": {
|
|
80639
|
+
"documentJsonPath": "$service:himiStoreProduct.descriptionJson",
|
|
80640
|
+
"onLink": {
|
|
80641
|
+
"actionId": "tier5.himiStoreProduct.openLink"
|
|
80642
|
+
},
|
|
80643
|
+
"fallback": {
|
|
80644
|
+
"id": "",
|
|
80645
|
+
"body": {
|
|
80646
|
+
"package": "himalaya",
|
|
80647
|
+
"type": "Text",
|
|
80648
|
+
"props": {
|
|
80649
|
+
"text": "$service:himiStoreProduct.description",
|
|
80650
|
+
"style": "body",
|
|
80651
|
+
"color": "textSecondary",
|
|
80652
|
+
"collapseWhenEmpty": true
|
|
80653
|
+
}
|
|
80654
|
+
}
|
|
80655
|
+
}
|
|
80656
|
+
}
|
|
80657
|
+
}
|
|
80658
|
+
},
|
|
80659
|
+
{
|
|
80660
|
+
"id": "product_body_text",
|
|
80505
80661
|
"body": {
|
|
80506
80662
|
"package": "himalaya",
|
|
80507
80663
|
"type": "Text",
|
|
@@ -80511,6 +80667,9 @@ const TEMPLATED: { pattern: string; display: string; liveSeed?: LiveSeed; static
|
|
|
80511
80667
|
"color": "textSecondary",
|
|
80512
80668
|
"collapseWhenEmpty": true
|
|
80513
80669
|
}
|
|
80670
|
+
},
|
|
80671
|
+
"modifiers": {
|
|
80672
|
+
"hiddenPath": "$service:himiStoreProduct.hasDescriptionJson"
|
|
80514
80673
|
}
|
|
80515
80674
|
}
|
|
80516
80675
|
]
|
|
@@ -81005,7 +81164,8 @@ const TEMPLATED: { pattern: string; display: string; liveSeed?: LiveSeed; static
|
|
|
81005
81164
|
"declaredCapabilities": [
|
|
81006
81165
|
"wix_api",
|
|
81007
81166
|
"share",
|
|
81008
|
-
"local_database"
|
|
81167
|
+
"local_database",
|
|
81168
|
+
"open_url"
|
|
81009
81169
|
],
|
|
81010
81170
|
"minBinaryVersion": "0.1.0",
|
|
81011
81171
|
"bundleVersion": "0.0.1"
|
|
@@ -84329,7 +84489,33 @@ const TEMPLATED: { pattern: string; display: string; liveSeed?: LiveSeed; static
|
|
|
84329
84489
|
}
|
|
84330
84490
|
},
|
|
84331
84491
|
{
|
|
84332
|
-
"id": "",
|
|
84492
|
+
"id": "event_body",
|
|
84493
|
+
"body": {
|
|
84494
|
+
"package": "himalaya",
|
|
84495
|
+
"type": "RichContent",
|
|
84496
|
+
"props": {
|
|
84497
|
+
"documentJsonPath": "$service:himiEventDetail.descriptionJson",
|
|
84498
|
+
"onLink": {
|
|
84499
|
+
"actionId": "tier5.himiEventDetail.openLink"
|
|
84500
|
+
},
|
|
84501
|
+
"fallback": {
|
|
84502
|
+
"id": "",
|
|
84503
|
+
"body": {
|
|
84504
|
+
"package": "himalaya",
|
|
84505
|
+
"type": "Text",
|
|
84506
|
+
"props": {
|
|
84507
|
+
"text": "$service:himiEventDetail.description",
|
|
84508
|
+
"style": "body",
|
|
84509
|
+
"color": "textSecondary",
|
|
84510
|
+
"collapseWhenEmpty": true
|
|
84511
|
+
}
|
|
84512
|
+
}
|
|
84513
|
+
}
|
|
84514
|
+
}
|
|
84515
|
+
}
|
|
84516
|
+
},
|
|
84517
|
+
{
|
|
84518
|
+
"id": "event_body_text",
|
|
84333
84519
|
"body": {
|
|
84334
84520
|
"package": "himalaya",
|
|
84335
84521
|
"type": "Text",
|
|
@@ -84339,6 +84525,9 @@ const TEMPLATED: { pattern: string; display: string; liveSeed?: LiveSeed; static
|
|
|
84339
84525
|
"color": "textSecondary",
|
|
84340
84526
|
"collapseWhenEmpty": true
|
|
84341
84527
|
}
|
|
84528
|
+
},
|
|
84529
|
+
"modifiers": {
|
|
84530
|
+
"hiddenPath": "$service:himiEventDetail.hasDescriptionJson"
|
|
84342
84531
|
}
|
|
84343
84532
|
}
|
|
84344
84533
|
]
|
|
@@ -86233,7 +86422,33 @@ const TEMPLATED: { pattern: string; display: string; liveSeed?: LiveSeed; static
|
|
|
86233
86422
|
}
|
|
86234
86423
|
},
|
|
86235
86424
|
{
|
|
86236
|
-
"id": "",
|
|
86425
|
+
"id": "comment_body_$item.id",
|
|
86426
|
+
"body": {
|
|
86427
|
+
"package": "himalaya",
|
|
86428
|
+
"type": "RichContent",
|
|
86429
|
+
"props": {
|
|
86430
|
+
"documentJsonPath": "$item.bodyJson",
|
|
86431
|
+
"onLink": {
|
|
86432
|
+
"actionId": "tier5.himiBlogPost.openLink"
|
|
86433
|
+
},
|
|
86434
|
+
"fallback": {
|
|
86435
|
+
"id": "",
|
|
86436
|
+
"body": {
|
|
86437
|
+
"package": "himalaya",
|
|
86438
|
+
"type": "Text",
|
|
86439
|
+
"props": {
|
|
86440
|
+
"text": "$item.text",
|
|
86441
|
+
"style": "body",
|
|
86442
|
+
"color": "textSecondary",
|
|
86443
|
+
"collapseWhenEmpty": true
|
|
86444
|
+
}
|
|
86445
|
+
}
|
|
86446
|
+
}
|
|
86447
|
+
}
|
|
86448
|
+
}
|
|
86449
|
+
},
|
|
86450
|
+
{
|
|
86451
|
+
"id": "comment_body_text_$item.id",
|
|
86237
86452
|
"body": {
|
|
86238
86453
|
"package": "himalaya",
|
|
86239
86454
|
"type": "Text",
|
|
@@ -86243,6 +86458,9 @@ const TEMPLATED: { pattern: string; display: string; liveSeed?: LiveSeed; static
|
|
|
86243
86458
|
"color": "textSecondary",
|
|
86244
86459
|
"collapseWhenEmpty": true
|
|
86245
86460
|
}
|
|
86461
|
+
},
|
|
86462
|
+
"modifiers": {
|
|
86463
|
+
"hiddenPath": "$item.hasBodyJson"
|
|
86246
86464
|
}
|
|
86247
86465
|
}
|
|
86248
86466
|
]
|
|
@@ -87029,6 +87247,48 @@ const TEMPLATED: { pattern: string; display: string; liveSeed?: LiveSeed; static
|
|
|
87029
87247
|
]
|
|
87030
87248
|
}
|
|
87031
87249
|
}
|
|
87250
|
+
},
|
|
87251
|
+
{
|
|
87252
|
+
"id": "cms_body_$item.id",
|
|
87253
|
+
"body": {
|
|
87254
|
+
"package": "himalaya",
|
|
87255
|
+
"type": "RichContent",
|
|
87256
|
+
"props": {
|
|
87257
|
+
"documentJsonPath": "$item.bodyJson",
|
|
87258
|
+
"onLink": {
|
|
87259
|
+
"actionId": "tier5.himiBrandedCmsCollection.openLink"
|
|
87260
|
+
},
|
|
87261
|
+
"fallback": {
|
|
87262
|
+
"id": "",
|
|
87263
|
+
"body": {
|
|
87264
|
+
"package": "himalaya",
|
|
87265
|
+
"type": "Text",
|
|
87266
|
+
"props": {
|
|
87267
|
+
"text": "$item.bodyText",
|
|
87268
|
+
"style": "body",
|
|
87269
|
+
"color": "textSecondary",
|
|
87270
|
+
"collapseWhenEmpty": true
|
|
87271
|
+
}
|
|
87272
|
+
}
|
|
87273
|
+
}
|
|
87274
|
+
}
|
|
87275
|
+
}
|
|
87276
|
+
},
|
|
87277
|
+
{
|
|
87278
|
+
"id": "cms_body_text_$item.id",
|
|
87279
|
+
"body": {
|
|
87280
|
+
"package": "himalaya",
|
|
87281
|
+
"type": "Text",
|
|
87282
|
+
"props": {
|
|
87283
|
+
"text": "$item.bodyText",
|
|
87284
|
+
"style": "body",
|
|
87285
|
+
"color": "textSecondary",
|
|
87286
|
+
"collapseWhenEmpty": true
|
|
87287
|
+
}
|
|
87288
|
+
},
|
|
87289
|
+
"modifiers": {
|
|
87290
|
+
"hiddenPath": "$item.hasBodyJson"
|
|
87291
|
+
}
|
|
87032
87292
|
}
|
|
87033
87293
|
]
|
|
87034
87294
|
}
|
|
@@ -87131,7 +87391,8 @@ const TEMPLATED: { pattern: string; display: string; liveSeed?: LiveSeed; static
|
|
|
87131
87391
|
"contentType": "application/javascript+ts-bundle",
|
|
87132
87392
|
"declaredCapabilities": [
|
|
87133
87393
|
"wix_api",
|
|
87134
|
-
"local_database"
|
|
87394
|
+
"local_database",
|
|
87395
|
+
"open_url"
|
|
87135
87396
|
],
|
|
87136
87397
|
"minBinaryVersion": "0.1.0",
|
|
87137
87398
|
"bundleVersion": "0.0.1"
|
|
@@ -14,15 +14,21 @@ export interface RichBody {
|
|
|
14
14
|
bodyText: string;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
+
/** [rico] #3372 — the media width for a document drawn in a LIST row (a feed post, a comment, a CMS item): the
|
|
18
|
+
* list-image size (WIX_LIST_IMAGE), so a scrolling list never downloads every image at detail size. */
|
|
19
|
+
export const ROW_IMAGE_WIDTH = 1000;
|
|
20
|
+
|
|
17
21
|
/** Prepares `richContent` (a Ricos document, as a Wix API returns it, or its JSON string). No document, or one
|
|
18
22
|
* that is not a document, gives `{ bodyJson: "", bodyText: fallback }`. A document past the viewer's limits
|
|
19
23
|
* gives bodyJson "" and its plain text — except one rejected as too deep, which is not walked again (the
|
|
20
|
-
* plain-text walk has no depth limit), so `fallback` stands in for it.
|
|
21
|
-
|
|
24
|
+
* plain-text walk has no depth limit), so `fallback` stands in for it. `imageWidth` sizes its media (default
|
|
25
|
+
* the 1400 px detail budget). */
|
|
26
|
+
export function richBody(richContent: unknown, fallback = "", imageWidth = 1400): RichBody {
|
|
22
27
|
const doc = parseRicosJson(richContent);
|
|
23
28
|
if (!doc) return { bodyJson: "", bodyText: fallback };
|
|
24
|
-
// 1400 px — the detail-image budget, which is also the encoder's maximum
|
|
25
|
-
|
|
29
|
+
// 1400 px by default — the detail-image budget, which is also the encoder's maximum; list rows pass
|
|
30
|
+
// ROW_IMAGE_WIDTH.
|
|
31
|
+
const { json, rejected } = encodeRichContent(doc, { imageWidth });
|
|
26
32
|
const text = rejected === "too_deep" ? "" : ricosToPlainText(doc);
|
|
27
33
|
return { bodyJson: json, bodyText: text || fallback };
|
|
28
34
|
}
|
|
@@ -8,7 +8,7 @@ import { isSavedId, toggleSavedId } from "../_shared/himi-blog-saved";
|
|
|
8
8
|
import { stashCopy, copyParam, copyTemplate } from "../_shared/himi-copy.js";
|
|
9
9
|
import { formatDateMedium, formatMonthDay } from "../_shared/engine-intl.js";
|
|
10
10
|
import { openRichLink } from "../_shared/rich-content-link.js";
|
|
11
|
-
import { richBody } from "../_shared/rich-body.js";
|
|
11
|
+
import { richBody, ROW_IMAGE_WIDTH } from "../_shared/rich-body.js";
|
|
12
12
|
|
|
13
13
|
// Offline-first (data-offline): the post body is a public read-through — when the
|
|
14
14
|
// live fetch fails (offline) fall back to the last-synced row the feed cached under
|
|
@@ -23,8 +23,14 @@ async function readCachedPost(id: string): Promise<DbEntity | null> {
|
|
|
23
23
|
interface CommentRow {
|
|
24
24
|
id: string;
|
|
25
25
|
authorName: string;
|
|
26
|
+
/** The comment's plain text: the row RichContent's fallback. */
|
|
26
27
|
text: string;
|
|
27
28
|
meta: string;
|
|
29
|
+
/** [rico] #3372 — the comment's Ricos document as ONE string for the row's RichContent; "" when it has none
|
|
30
|
+
* or the encoder rejected it. */
|
|
31
|
+
bodyJson: string;
|
|
32
|
+
/** bodyJson !== "" — gates the row's plain text, because RichContent draws nothing for "". */
|
|
33
|
+
hasBodyJson: boolean;
|
|
28
34
|
}
|
|
29
35
|
|
|
30
36
|
interface S {
|
|
@@ -168,11 +174,15 @@ function commentMeta(row: WixBlogCommentRow): string {
|
|
|
168
174
|
}
|
|
169
175
|
|
|
170
176
|
function toCommentRow(row: WixBlogCommentRow): CommentRow {
|
|
177
|
+
// The plain text is the document's own (runs joined as written, not space-separated) when it has one.
|
|
178
|
+
const { bodyJson, bodyText } = richBody(row.richContent, row.text || "Comment", ROW_IMAGE_WIDTH);
|
|
171
179
|
return {
|
|
172
180
|
id: row.id,
|
|
173
181
|
authorName: row.authorName || "Member",
|
|
174
|
-
text:
|
|
182
|
+
text: bodyText,
|
|
175
183
|
meta: commentMeta(row),
|
|
184
|
+
bodyJson,
|
|
185
|
+
hasBodyJson: bodyJson !== "",
|
|
176
186
|
};
|
|
177
187
|
}
|
|
178
188
|
|