@wix/himalaya-cli 0.1145.0 → 0.1146.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 +0 -2
- package/guides/sdk-reference.json +13 -1
- 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-store-product/index.ts +35 -4
- package/templates/beauty-salon-owner/tier5-src/_shared/rich-body.ts +10 -4
- 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-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-events-detail/index.ts +40 -3
- package/templates/community-club-owner/tier5-src/_shared/rich-body.ts +10 -4
- 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-events-detail/index.ts +40 -3
- package/templates/events-meetups-owner/tier5-src/_shared/rich-body.ts +10 -4
- 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-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/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-events-detail/index.ts +40 -3
- package/templates/nonprofit-cause-owner/tier5-src/_shared/rich-body.ts +10 -4
- package/templates/owner-lite/tier5-src/_shared/rich-body.ts +10 -4
- 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-events-detail/index.ts +40 -3
- package/templates/podcast-creator-owner/tier5-src/_shared/rich-body.ts +10 -4
- 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-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/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-events-detail/index.ts +40 -3
- package/templates/restaurant-owner/tier5-src/_shared/rich-body.ts +10 -4
- 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-store-product/index.ts +35 -4
- package/templates/retail-store-owner/tier5-src/_shared/rich-body.ts +10 -4
- 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-events-detail/index.ts +40 -3
- package/templates/yoga-studio-owner/tier5-src/_shared/rich-body.ts +10 -4
|
@@ -5619,7 +5619,32 @@ const SCREENS = runtimeSetting({
|
|
|
5619
5619
|
}
|
|
5620
5620
|
},
|
|
5621
5621
|
{
|
|
5622
|
-
"id": "",
|
|
5622
|
+
"id": "feed_body_$item.id",
|
|
5623
|
+
"body": {
|
|
5624
|
+
"package": "himalaya",
|
|
5625
|
+
"type": "RichContent",
|
|
5626
|
+
"props": {
|
|
5627
|
+
"documentJsonPath": "$item.bodyJson",
|
|
5628
|
+
"onLink": {
|
|
5629
|
+
"actionId": "tier5.himiBrandedFeed.openLink"
|
|
5630
|
+
},
|
|
5631
|
+
"fallback": {
|
|
5632
|
+
"id": "",
|
|
5633
|
+
"body": {
|
|
5634
|
+
"package": "himalaya",
|
|
5635
|
+
"type": "Text",
|
|
5636
|
+
"props": {
|
|
5637
|
+
"text": "$item.text",
|
|
5638
|
+
"style": "body",
|
|
5639
|
+
"maxLines": 6
|
|
5640
|
+
}
|
|
5641
|
+
}
|
|
5642
|
+
}
|
|
5643
|
+
}
|
|
5644
|
+
}
|
|
5645
|
+
},
|
|
5646
|
+
{
|
|
5647
|
+
"id": "feed_body_text_$item.id",
|
|
5623
5648
|
"body": {
|
|
5624
5649
|
"package": "himalaya",
|
|
5625
5650
|
"type": "Text",
|
|
@@ -5628,6 +5653,9 @@ const SCREENS = runtimeSetting({
|
|
|
5628
5653
|
"style": "body",
|
|
5629
5654
|
"maxLines": 6
|
|
5630
5655
|
}
|
|
5656
|
+
},
|
|
5657
|
+
"modifiers": {
|
|
5658
|
+
"hiddenPath": "$item.hasBodyJson"
|
|
5631
5659
|
}
|
|
5632
5660
|
},
|
|
5633
5661
|
{
|
|
@@ -5824,7 +5852,8 @@ const SCREENS = runtimeSetting({
|
|
|
5824
5852
|
"integrity": "",
|
|
5825
5853
|
"contentType": "application/javascript+ts-bundle",
|
|
5826
5854
|
"declaredCapabilities": [
|
|
5827
|
-
"wix_api"
|
|
5855
|
+
"wix_api",
|
|
5856
|
+
"open_url"
|
|
5828
5857
|
],
|
|
5829
5858
|
"minBinaryVersion": "0.1.0",
|
|
5830
5859
|
"bundleVersion": "0.0.1"
|
|
@@ -15471,7 +15500,33 @@ const TEMPLATED: { pattern: string; display: string; liveSeed?: LiveSeed; static
|
|
|
15471
15500
|
}
|
|
15472
15501
|
},
|
|
15473
15502
|
{
|
|
15474
|
-
"id": "",
|
|
15503
|
+
"id": "event_body",
|
|
15504
|
+
"body": {
|
|
15505
|
+
"package": "himalaya",
|
|
15506
|
+
"type": "RichContent",
|
|
15507
|
+
"props": {
|
|
15508
|
+
"documentJsonPath": "$service:himiEventDetail.descriptionJson",
|
|
15509
|
+
"onLink": {
|
|
15510
|
+
"actionId": "tier5.himiEventDetail.openLink"
|
|
15511
|
+
},
|
|
15512
|
+
"fallback": {
|
|
15513
|
+
"id": "",
|
|
15514
|
+
"body": {
|
|
15515
|
+
"package": "himalaya",
|
|
15516
|
+
"type": "Text",
|
|
15517
|
+
"props": {
|
|
15518
|
+
"text": "$service:himiEventDetail.description",
|
|
15519
|
+
"style": "body",
|
|
15520
|
+
"color": "textSecondary",
|
|
15521
|
+
"collapseWhenEmpty": true
|
|
15522
|
+
}
|
|
15523
|
+
}
|
|
15524
|
+
}
|
|
15525
|
+
}
|
|
15526
|
+
}
|
|
15527
|
+
},
|
|
15528
|
+
{
|
|
15529
|
+
"id": "event_body_text",
|
|
15475
15530
|
"body": {
|
|
15476
15531
|
"package": "himalaya",
|
|
15477
15532
|
"type": "Text",
|
|
@@ -15481,6 +15536,9 @@ const TEMPLATED: { pattern: string; display: string; liveSeed?: LiveSeed; static
|
|
|
15481
15536
|
"color": "textSecondary",
|
|
15482
15537
|
"collapseWhenEmpty": true
|
|
15483
15538
|
}
|
|
15539
|
+
},
|
|
15540
|
+
"modifiers": {
|
|
15541
|
+
"hiddenPath": "$service:himiEventDetail.hasDescriptionJson"
|
|
15484
15542
|
}
|
|
15485
15543
|
}
|
|
15486
15544
|
]
|
|
@@ -17375,7 +17433,33 @@ const TEMPLATED: { pattern: string; display: string; liveSeed?: LiveSeed; static
|
|
|
17375
17433
|
}
|
|
17376
17434
|
},
|
|
17377
17435
|
{
|
|
17378
|
-
"id": "",
|
|
17436
|
+
"id": "comment_body_$item.id",
|
|
17437
|
+
"body": {
|
|
17438
|
+
"package": "himalaya",
|
|
17439
|
+
"type": "RichContent",
|
|
17440
|
+
"props": {
|
|
17441
|
+
"documentJsonPath": "$item.bodyJson",
|
|
17442
|
+
"onLink": {
|
|
17443
|
+
"actionId": "tier5.himiBlogPost.openLink"
|
|
17444
|
+
},
|
|
17445
|
+
"fallback": {
|
|
17446
|
+
"id": "",
|
|
17447
|
+
"body": {
|
|
17448
|
+
"package": "himalaya",
|
|
17449
|
+
"type": "Text",
|
|
17450
|
+
"props": {
|
|
17451
|
+
"text": "$item.text",
|
|
17452
|
+
"style": "body",
|
|
17453
|
+
"color": "textSecondary",
|
|
17454
|
+
"collapseWhenEmpty": true
|
|
17455
|
+
}
|
|
17456
|
+
}
|
|
17457
|
+
}
|
|
17458
|
+
}
|
|
17459
|
+
}
|
|
17460
|
+
},
|
|
17461
|
+
{
|
|
17462
|
+
"id": "comment_body_text_$item.id",
|
|
17379
17463
|
"body": {
|
|
17380
17464
|
"package": "himalaya",
|
|
17381
17465
|
"type": "Text",
|
|
@@ -17385,6 +17469,9 @@ const TEMPLATED: { pattern: string; display: string; liveSeed?: LiveSeed; static
|
|
|
17385
17469
|
"color": "textSecondary",
|
|
17386
17470
|
"collapseWhenEmpty": true
|
|
17387
17471
|
}
|
|
17472
|
+
},
|
|
17473
|
+
"modifiers": {
|
|
17474
|
+
"hiddenPath": "$item.hasBodyJson"
|
|
17388
17475
|
}
|
|
17389
17476
|
}
|
|
17390
17477
|
]
|
|
@@ -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
|
|
|
@@ -23,6 +23,8 @@ import { signedInEmail } from "../_shared/himi-account";
|
|
|
23
23
|
import { initials } from "../_shared/himi-text.js";
|
|
24
24
|
import { copyParam, stashCopy } from "../_shared/himi-copy.js";
|
|
25
25
|
import { formatMonthDay } from "../_shared/engine-intl.js";
|
|
26
|
+
import { openRichLink } from "../_shared/rich-content-link.js";
|
|
27
|
+
import { richBody, ROW_IMAGE_WIDTH } from "../_shared/rich-body.js";
|
|
26
28
|
|
|
27
29
|
interface FeedRow {
|
|
28
30
|
id: string;
|
|
@@ -33,8 +35,15 @@ interface FeedRow {
|
|
|
33
35
|
avatar: string;
|
|
34
36
|
hasAvatar: boolean;
|
|
35
37
|
noAvatar: boolean;
|
|
38
|
+
/** The post's plain text: RichContent's fallback, and what shows for a post with no Ricos document. */
|
|
36
39
|
text: string;
|
|
37
|
-
/**
|
|
40
|
+
/** [rico] #3372 — a Ricos post's `content` as ONE document string for the row's RichContent; "" for a
|
|
41
|
+
* DraftJS-blocks post, a lean one, or a document the encoder rejected. */
|
|
42
|
+
bodyJson: string;
|
|
43
|
+
/** bodyJson !== "" — gates the row's plain text, because RichContent draws nothing for "". */
|
|
44
|
+
hasBodyJson: boolean;
|
|
45
|
+
/** First inline IMAGE node in the post content ("" for text-only posts). Shown only for a row with no
|
|
46
|
+
* document: RichContent draws the document's images itself. */
|
|
38
47
|
image: string;
|
|
39
48
|
hasImage: boolean;
|
|
40
49
|
noImage: boolean;
|
|
@@ -161,7 +170,10 @@ function feedRow(item: WixFeedItem, profiles: WixFeedProfile[]): FeedRow {
|
|
|
161
170
|
const author = authorName(item, profiles);
|
|
162
171
|
const count = Array.isArray(item.reactionsList) ? item.reactionsList.length : 0;
|
|
163
172
|
const avatar = authorAvatar(item, profiles);
|
|
164
|
-
|
|
173
|
+
// A Ricos post's plain text is the whole document's (every node level), not feedText's one-level read.
|
|
174
|
+
const { bodyJson, bodyText: text } = richBody(item.content, feedText(item), ROW_IMAGE_WIDTH);
|
|
175
|
+
// A Ricos post draws its own images in RichContent, so the separate row image would repeat the first one.
|
|
176
|
+
const image = bodyJson ? "" : contentImage(item);
|
|
165
177
|
return {
|
|
166
178
|
id: item.feedItemId || "",
|
|
167
179
|
author,
|
|
@@ -169,7 +181,9 @@ function feedRow(item: WixFeedItem, profiles: WixFeedProfile[]): FeedRow {
|
|
|
169
181
|
avatar,
|
|
170
182
|
hasAvatar: !!avatar,
|
|
171
183
|
noAvatar: !avatar,
|
|
172
|
-
text
|
|
184
|
+
text,
|
|
185
|
+
bodyJson,
|
|
186
|
+
hasBodyJson: bodyJson !== "",
|
|
173
187
|
image,
|
|
174
188
|
hasImage: !!image,
|
|
175
189
|
noImage: !image,
|
|
@@ -292,6 +306,8 @@ const svc = defineService<State, {
|
|
|
292
306
|
filter: (state: State, arg?: unknown) => State;
|
|
293
307
|
post: (state: State, arg?: unknown) => Promise<State>;
|
|
294
308
|
react: (state: State, arg?: unknown) => Promise<State>;
|
|
309
|
+
/** [rico] #3372 — a row RichContent's on_link: `{ url }` of the tapped link. */
|
|
310
|
+
openLink: (state: State, arg?: unknown) => Promise<State>;
|
|
295
311
|
}>("himiBrandedFeed", {
|
|
296
312
|
state: derive({
|
|
297
313
|
status: "loading",
|
|
@@ -367,6 +383,10 @@ const svc = defineService<State, {
|
|
|
367
383
|
return state;
|
|
368
384
|
}
|
|
369
385
|
},
|
|
386
|
+
// Only http(s), mailto and tel links reach open_url; one that does not open says so in the message line.
|
|
387
|
+
openLink: async (state, arg) => ((await openRichLink(arg))
|
|
388
|
+
? state
|
|
389
|
+
: { ...state, message: copyParam("feed.linkOpenFailed", "This link could not be opened.") }),
|
|
370
390
|
},
|
|
371
391
|
});
|
|
372
392
|
|
|
@@ -35,6 +35,8 @@ import {
|
|
|
35
35
|
} from "../_shared/himi-events";
|
|
36
36
|
import { initials } from "../_shared/himi-text.js";
|
|
37
37
|
import { stashCopy, copyParam, copyTemplate } from "../_shared/himi-copy.js";
|
|
38
|
+
import { openRichLink } from "../_shared/rich-content-link.js";
|
|
39
|
+
import { richBody } from "../_shared/rich-body.js";
|
|
38
40
|
|
|
39
41
|
interface MapMarker {
|
|
40
42
|
latitude: number;
|
|
@@ -88,7 +90,13 @@ interface S {
|
|
|
88
90
|
initial: string;
|
|
89
91
|
when: string;
|
|
90
92
|
location: string;
|
|
93
|
+
/** The plain-text description: RichContent's fallback, the calendar notes, and what shows with no document. */
|
|
91
94
|
description: string;
|
|
95
|
+
/** [rico] #3372 — the v3 Ricos `description` (read with `fields=TEXTS`) as ONE document string for
|
|
96
|
+
* RichContent; "" when the event has none or the encoder rejected it. */
|
|
97
|
+
descriptionJson: string;
|
|
98
|
+
/** descriptionJson !== "" — gates the plain text, because RichContent draws nothing for "". */
|
|
99
|
+
hasDescriptionJson: boolean;
|
|
92
100
|
image: string;
|
|
93
101
|
hasImage: boolean;
|
|
94
102
|
noImage: boolean;
|
|
@@ -212,6 +220,7 @@ function derive(s: S): S {
|
|
|
212
220
|
const hasAttendees = s.attendeeAvatars.length > 0;
|
|
213
221
|
return {
|
|
214
222
|
...s,
|
|
223
|
+
hasDescriptionJson: s.descriptionJson !== "",
|
|
215
224
|
noMap: !s.mapUrl,
|
|
216
225
|
hasMapMarkers,
|
|
217
226
|
noMapMarkers: !hasMapMarkers,
|
|
@@ -357,6 +366,14 @@ async function attendeeSummary(eventId: string): Promise<{ goingLabel: string; a
|
|
|
357
366
|
}
|
|
358
367
|
}
|
|
359
368
|
|
|
369
|
+
/** The description pair: the v3 Ricos `description` for RichContent, and its plain text. A string description
|
|
370
|
+
* (or none) keeps `eventDescription`'s legacy read, with no document. */
|
|
371
|
+
function eventBody(e: WixEvent): { description: string; descriptionJson: string } {
|
|
372
|
+
const legacy = eventDescription(e);
|
|
373
|
+
const { bodyJson, bodyText } = richBody((e as unknown as { description?: unknown }).description, legacy);
|
|
374
|
+
return { description: bodyText, descriptionJson: bodyJson };
|
|
375
|
+
}
|
|
376
|
+
|
|
360
377
|
/** getEvent returns the slim BASE fieldset (no `registration`); enrich from the
|
|
361
378
|
* richer query when the type is unknown — best-effort, find-by-id. */
|
|
362
379
|
async function enrichRegistration(id: string, e: WixEvent): Promise<WixEvent> {
|
|
@@ -364,7 +381,11 @@ async function enrichRegistration(id: string, e: WixEvent): Promise<WixEvent> {
|
|
|
364
381
|
try {
|
|
365
382
|
const list = await queryEvents({ limit: 100 });
|
|
366
383
|
const match = (list.events ?? []).find((candidate) => candidate.id === id);
|
|
367
|
-
|
|
384
|
+
if (!match) return e;
|
|
385
|
+
// [rico] #3372 — the query's rows are read without TEXTS, so they carry no Ricos `description`: keep the
|
|
386
|
+
// one this detail fetched, or the enrichment would silently drop the document on every real site.
|
|
387
|
+
const description = (e as unknown as { description?: unknown }).description;
|
|
388
|
+
return description === undefined ? match : ({ ...match, description } as unknown as WixEvent);
|
|
368
389
|
} catch {
|
|
369
390
|
return e;
|
|
370
391
|
}
|
|
@@ -377,6 +398,8 @@ const svc = defineService<S, {
|
|
|
377
398
|
openRegistration: (s: S) => Promise<S>;
|
|
378
399
|
share: (s: S) => Promise<S>;
|
|
379
400
|
addToCalendar: (s: S) => Promise<S>;
|
|
401
|
+
/** [rico] #3372 — RichContent's on_link: `{ url }` of the tapped link. */
|
|
402
|
+
openLink: (s: S, arg?: unknown) => Promise<S>;
|
|
380
403
|
}>("himiEventDetail", {
|
|
381
404
|
state: derive({
|
|
382
405
|
status: "loading",
|
|
@@ -386,6 +409,8 @@ const svc = defineService<S, {
|
|
|
386
409
|
when: "",
|
|
387
410
|
location: "",
|
|
388
411
|
description: "",
|
|
412
|
+
descriptionJson: "",
|
|
413
|
+
hasDescriptionJson: false,
|
|
389
414
|
image: "",
|
|
390
415
|
hasImage: false,
|
|
391
416
|
noImage: true,
|
|
@@ -433,7 +458,8 @@ const svc = defineService<S, {
|
|
|
433
458
|
const id = s.id || inputId();
|
|
434
459
|
if (!id) return derive({ ...s, status: "ready", errored: true });
|
|
435
460
|
try {
|
|
436
|
-
|
|
461
|
+
// TEXTS adds the Ricos `description` to the base fieldset (a bare read returns none).
|
|
462
|
+
const res = await getEvent(id, { fields: ["TEXTS"] });
|
|
437
463
|
let e = ((res as unknown as { event?: WixEvent }).event ?? res) as WixEvent;
|
|
438
464
|
e = await enrichRegistration(id, e);
|
|
439
465
|
const attendees = await attendeeSummary(id);
|
|
@@ -460,7 +486,9 @@ const svc = defineService<S, {
|
|
|
460
486
|
initial: (title.trim()[0] || "E").toUpperCase(),
|
|
461
487
|
when: eventWhen(e),
|
|
462
488
|
location: eventLocation(e),
|
|
463
|
-
description
|
|
489
|
+
// The Ricos description when the event has one (its own text is the plain copy); the legacy
|
|
490
|
+
// string fields otherwise.
|
|
491
|
+
...eventBody(e),
|
|
464
492
|
image,
|
|
465
493
|
hasImage: !!image,
|
|
466
494
|
noImage: !image,
|
|
@@ -491,6 +519,9 @@ const svc = defineService<S, {
|
|
|
491
519
|
initial: (title.trim()[0] || "E").toUpperCase(),
|
|
492
520
|
when: cached.dateLine,
|
|
493
521
|
location: cached.location,
|
|
522
|
+
// The cached list row carries no description: an offline retry of THIS event keeps the pair it
|
|
523
|
+
// already shows, and any other event's is cleared together, so neither half can linger alone.
|
|
524
|
+
...(s.id === id ? {} : { description: "", descriptionJson: "" }),
|
|
494
525
|
image: cached.image,
|
|
495
526
|
hasImage: !!cached.image,
|
|
496
527
|
noImage: !cached.image,
|
|
@@ -665,6 +696,12 @@ const svc = defineService<S, {
|
|
|
665
696
|
return derive({ ...s, actionMessage: copyParam("event.calendarAddFailed", "Could not add this event to calendar."), isAddingCalendar: false });
|
|
666
697
|
}
|
|
667
698
|
},
|
|
699
|
+
// Only http(s), mailto and tel links reach open_url; a refused link, or one nothing opened, says so, and a
|
|
700
|
+
// link that opens clears an earlier message.
|
|
701
|
+
openLink: async (s, arg) => derive({
|
|
702
|
+
...s,
|
|
703
|
+
actionMessage: (await openRichLink(arg)) ? "" : copyParam("event.linkOpenFailed", "This link could not be opened."),
|
|
704
|
+
}),
|
|
668
705
|
},
|
|
669
706
|
});
|
|
670
707
|
svc.load();
|
|
@@ -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
|
}
|
|
@@ -29361,7 +29361,33 @@ const TEMPLATED: { pattern: string; display: string; liveSeed?: LiveSeed; static
|
|
|
29361
29361
|
}
|
|
29362
29362
|
},
|
|
29363
29363
|
{
|
|
29364
|
-
"id": "",
|
|
29364
|
+
"id": "product_body",
|
|
29365
|
+
"body": {
|
|
29366
|
+
"package": "himalaya",
|
|
29367
|
+
"type": "RichContent",
|
|
29368
|
+
"props": {
|
|
29369
|
+
"documentJsonPath": "$service:himiStoreProduct.descriptionJson",
|
|
29370
|
+
"onLink": {
|
|
29371
|
+
"actionId": "tier5.himiStoreProduct.openLink"
|
|
29372
|
+
},
|
|
29373
|
+
"fallback": {
|
|
29374
|
+
"id": "",
|
|
29375
|
+
"body": {
|
|
29376
|
+
"package": "himalaya",
|
|
29377
|
+
"type": "Text",
|
|
29378
|
+
"props": {
|
|
29379
|
+
"text": "$service:himiStoreProduct.description",
|
|
29380
|
+
"style": "body",
|
|
29381
|
+
"color": "textSecondary",
|
|
29382
|
+
"collapseWhenEmpty": true
|
|
29383
|
+
}
|
|
29384
|
+
}
|
|
29385
|
+
}
|
|
29386
|
+
}
|
|
29387
|
+
}
|
|
29388
|
+
},
|
|
29389
|
+
{
|
|
29390
|
+
"id": "product_body_text",
|
|
29365
29391
|
"body": {
|
|
29366
29392
|
"package": "himalaya",
|
|
29367
29393
|
"type": "Text",
|
|
@@ -29371,6 +29397,9 @@ const TEMPLATED: { pattern: string; display: string; liveSeed?: LiveSeed; static
|
|
|
29371
29397
|
"color": "textSecondary",
|
|
29372
29398
|
"collapseWhenEmpty": true
|
|
29373
29399
|
}
|
|
29400
|
+
},
|
|
29401
|
+
"modifiers": {
|
|
29402
|
+
"hiddenPath": "$service:himiStoreProduct.hasDescriptionJson"
|
|
29374
29403
|
}
|
|
29375
29404
|
}
|
|
29376
29405
|
]
|
|
@@ -29865,7 +29894,8 @@ const TEMPLATED: { pattern: string; display: string; liveSeed?: LiveSeed; static
|
|
|
29865
29894
|
"declaredCapabilities": [
|
|
29866
29895
|
"wix_api",
|
|
29867
29896
|
"share",
|
|
29868
|
-
"local_database"
|
|
29897
|
+
"local_database",
|
|
29898
|
+
"open_url"
|
|
29869
29899
|
],
|
|
29870
29900
|
"minBinaryVersion": "0.1.0",
|
|
29871
29901
|
"bundleVersion": "0.0.1"
|
|
@@ -32069,7 +32099,33 @@ const TEMPLATED: { pattern: string; display: string; liveSeed?: LiveSeed; static
|
|
|
32069
32099
|
}
|
|
32070
32100
|
},
|
|
32071
32101
|
{
|
|
32072
|
-
"id": "",
|
|
32102
|
+
"id": "event_body",
|
|
32103
|
+
"body": {
|
|
32104
|
+
"package": "himalaya",
|
|
32105
|
+
"type": "RichContent",
|
|
32106
|
+
"props": {
|
|
32107
|
+
"documentJsonPath": "$service:himiEventDetail.descriptionJson",
|
|
32108
|
+
"onLink": {
|
|
32109
|
+
"actionId": "tier5.himiEventDetail.openLink"
|
|
32110
|
+
},
|
|
32111
|
+
"fallback": {
|
|
32112
|
+
"id": "",
|
|
32113
|
+
"body": {
|
|
32114
|
+
"package": "himalaya",
|
|
32115
|
+
"type": "Text",
|
|
32116
|
+
"props": {
|
|
32117
|
+
"text": "$service:himiEventDetail.description",
|
|
32118
|
+
"style": "body",
|
|
32119
|
+
"color": "textSecondary",
|
|
32120
|
+
"collapseWhenEmpty": true
|
|
32121
|
+
}
|
|
32122
|
+
}
|
|
32123
|
+
}
|
|
32124
|
+
}
|
|
32125
|
+
}
|
|
32126
|
+
},
|
|
32127
|
+
{
|
|
32128
|
+
"id": "event_body_text",
|
|
32073
32129
|
"body": {
|
|
32074
32130
|
"package": "himalaya",
|
|
32075
32131
|
"type": "Text",
|
|
@@ -32079,6 +32135,9 @@ const TEMPLATED: { pattern: string; display: string; liveSeed?: LiveSeed; static
|
|
|
32079
32135
|
"color": "textSecondary",
|
|
32080
32136
|
"collapseWhenEmpty": true
|
|
32081
32137
|
}
|
|
32138
|
+
},
|
|
32139
|
+
"modifiers": {
|
|
32140
|
+
"hiddenPath": "$service:himiEventDetail.hasDescriptionJson"
|
|
32082
32141
|
}
|
|
32083
32142
|
}
|
|
32084
32143
|
]
|
|
@@ -33973,7 +34032,33 @@ const TEMPLATED: { pattern: string; display: string; liveSeed?: LiveSeed; static
|
|
|
33973
34032
|
}
|
|
33974
34033
|
},
|
|
33975
34034
|
{
|
|
33976
|
-
"id": "",
|
|
34035
|
+
"id": "comment_body_$item.id",
|
|
34036
|
+
"body": {
|
|
34037
|
+
"package": "himalaya",
|
|
34038
|
+
"type": "RichContent",
|
|
34039
|
+
"props": {
|
|
34040
|
+
"documentJsonPath": "$item.bodyJson",
|
|
34041
|
+
"onLink": {
|
|
34042
|
+
"actionId": "tier5.himiBlogPost.openLink"
|
|
34043
|
+
},
|
|
34044
|
+
"fallback": {
|
|
34045
|
+
"id": "",
|
|
34046
|
+
"body": {
|
|
34047
|
+
"package": "himalaya",
|
|
34048
|
+
"type": "Text",
|
|
34049
|
+
"props": {
|
|
34050
|
+
"text": "$item.text",
|
|
34051
|
+
"style": "body",
|
|
34052
|
+
"color": "textSecondary",
|
|
34053
|
+
"collapseWhenEmpty": true
|
|
34054
|
+
}
|
|
34055
|
+
}
|
|
34056
|
+
}
|
|
34057
|
+
}
|
|
34058
|
+
}
|
|
34059
|
+
},
|
|
34060
|
+
{
|
|
34061
|
+
"id": "comment_body_text_$item.id",
|
|
33977
34062
|
"body": {
|
|
33978
34063
|
"package": "himalaya",
|
|
33979
34064
|
"type": "Text",
|
|
@@ -33983,6 +34068,9 @@ const TEMPLATED: { pattern: string; display: string; liveSeed?: LiveSeed; static
|
|
|
33983
34068
|
"color": "textSecondary",
|
|
33984
34069
|
"collapseWhenEmpty": true
|
|
33985
34070
|
}
|
|
34071
|
+
},
|
|
34072
|
+
"modifiers": {
|
|
34073
|
+
"hiddenPath": "$item.hasBodyJson"
|
|
33986
34074
|
}
|
|
33987
34075
|
}
|
|
33988
34076
|
]
|
|
@@ -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
|
|