@wix/himalaya-cli 0.1599.0 → 0.1601.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/cli.mjs +1351 -978
- package/guides/himi-json-output.md +25 -1
- package/guides/one-app-to-himi-app.md +33 -11
- package/package.json +2 -2
- package/templates/beauty-salon/dev/index.ts +182 -0
- package/templates/beauty-salon/tier5-src/_shared/himi-blog-hidden.ts +66 -0
- package/templates/beauty-salon/tier5-src/himi-blog-feed/index.ts +3 -1
- package/templates/beauty-salon/tier5-src/himi-blog-post/index.ts +42 -0
- package/templates/beauty-salon/tier5-src/himi-blog-saved/index.ts +4 -1
- package/templates/beauty-salon/tier5-src/himi-branded-lite-home/index.ts +5 -2
- package/templates/branded-lite/dev/index.ts +182 -0
- package/templates/branded-lite/l10n/en.json +10 -7
- package/templates/branded-lite/tier5-src/_shared/header-badges.ts +113 -0
- package/templates/branded-lite/tier5-src/_shared/himi-blog-hidden.ts +66 -0
- package/templates/branded-lite/tier5-src/_shared/source-badges.ts +70 -0
- package/templates/branded-lite/tier5-src/himi-blog-feed/index.ts +3 -1
- package/templates/branded-lite/tier5-src/himi-blog-post/index.ts +42 -0
- package/templates/branded-lite/tier5-src/himi-blog-saved/index.ts +4 -1
- package/templates/branded-lite/tier5-src/himi-branded-lite-header-badges/index.ts +38 -0
- package/templates/branded-lite/tier5-src/himi-branded-lite-home/index.ts +5 -2
- package/templates/community-club/dev/index.ts +182 -0
- package/templates/community-club/tier5-src/_shared/himi-blog-hidden.ts +66 -0
- package/templates/community-club/tier5-src/himi-blog-feed/index.ts +3 -1
- package/templates/community-club/tier5-src/himi-blog-post/index.ts +42 -0
- package/templates/community-club/tier5-src/himi-blog-saved/index.ts +4 -1
- package/templates/community-club/tier5-src/himi-branded-lite-home/index.ts +5 -2
- package/templates/events-meetups/dev/index.ts +182 -0
- package/templates/events-meetups/tier5-src/_shared/himi-blog-hidden.ts +66 -0
- package/templates/events-meetups/tier5-src/himi-blog-feed/index.ts +3 -1
- package/templates/events-meetups/tier5-src/himi-blog-post/index.ts +42 -0
- package/templates/events-meetups/tier5-src/himi-blog-saved/index.ts +4 -1
- package/templates/events-meetups/tier5-src/himi-branded-lite-home/index.ts +5 -2
- package/templates/gym-fitness/dev/index.ts +182 -0
- package/templates/gym-fitness/tier5-src/_shared/himi-blog-hidden.ts +66 -0
- package/templates/gym-fitness/tier5-src/himi-blog-feed/index.ts +3 -1
- package/templates/gym-fitness/tier5-src/himi-blog-post/index.ts +42 -0
- package/templates/gym-fitness/tier5-src/himi-blog-saved/index.ts +4 -1
- package/templates/gym-fitness/tier5-src/himi-branded-lite-home/index.ts +5 -2
- package/templates/nonprofit-cause/dev/index.ts +182 -0
- package/templates/nonprofit-cause/tier5-src/_shared/himi-blog-hidden.ts +66 -0
- package/templates/nonprofit-cause/tier5-src/himi-blog-feed/index.ts +3 -1
- package/templates/nonprofit-cause/tier5-src/himi-blog-post/index.ts +42 -0
- package/templates/nonprofit-cause/tier5-src/himi-blog-saved/index.ts +4 -1
- package/templates/nonprofit-cause/tier5-src/himi-branded-lite-home/index.ts +5 -2
- package/templates/podcast-creator/dev/index.ts +182 -0
- package/templates/podcast-creator/tier5-src/_shared/himi-blog-hidden.ts +66 -0
- package/templates/podcast-creator/tier5-src/himi-blog-feed/index.ts +3 -1
- package/templates/podcast-creator/tier5-src/himi-blog-post/index.ts +42 -0
- package/templates/podcast-creator/tier5-src/himi-blog-saved/index.ts +4 -1
- package/templates/podcast-creator/tier5-src/himi-branded-lite-home/index.ts +5 -2
- package/templates/portfolio-creative/dev/index.ts +182 -0
- package/templates/portfolio-creative/tier5-src/_shared/himi-blog-hidden.ts +66 -0
- package/templates/portfolio-creative/tier5-src/himi-blog-feed/index.ts +3 -1
- package/templates/portfolio-creative/tier5-src/himi-blog-post/index.ts +42 -0
- package/templates/portfolio-creative/tier5-src/himi-blog-saved/index.ts +4 -1
- package/templates/portfolio-creative/tier5-src/himi-branded-lite-home/index.ts +5 -2
- package/templates/restaurant/dev/index.ts +182 -0
- package/templates/restaurant/tier5-src/_shared/himi-blog-hidden.ts +66 -0
- package/templates/restaurant/tier5-src/himi-blog-feed/index.ts +3 -1
- package/templates/restaurant/tier5-src/himi-blog-post/index.ts +42 -0
- package/templates/restaurant/tier5-src/himi-blog-saved/index.ts +4 -1
- package/templates/restaurant/tier5-src/himi-branded-lite-home/index.ts +5 -2
- package/templates/retail-store/dev/index.ts +182 -0
- package/templates/retail-store/tier5-src/_shared/himi-blog-hidden.ts +66 -0
- package/templates/retail-store/tier5-src/himi-blog-feed/index.ts +3 -1
- package/templates/retail-store/tier5-src/himi-blog-post/index.ts +42 -0
- package/templates/retail-store/tier5-src/himi-blog-saved/index.ts +4 -1
- package/templates/retail-store/tier5-src/himi-branded-lite-home/index.ts +5 -2
- package/templates/yoga-studio/dev/index.ts +182 -0
- package/templates/yoga-studio/tier5-src/_shared/himi-blog-hidden.ts +66 -0
- package/templates/yoga-studio/tier5-src/himi-blog-feed/index.ts +3 -1
- package/templates/yoga-studio/tier5-src/himi-blog-post/index.ts +42 -0
- package/templates/yoga-studio/tier5-src/himi-blog-saved/index.ts +4 -1
- package/templates/yoga-studio/tier5-src/himi-branded-lite-home/index.ts +5 -2
|
@@ -27340,6 +27340,72 @@ const TEMPLATED: { pattern: string; display: string; liveSeed?: LiveSeed; static
|
|
|
27340
27340
|
}
|
|
27341
27341
|
}
|
|
27342
27342
|
}
|
|
27343
|
+
},
|
|
27344
|
+
{
|
|
27345
|
+
"id": "",
|
|
27346
|
+
"body": {
|
|
27347
|
+
"package": "himalaya",
|
|
27348
|
+
"type": "HStack",
|
|
27349
|
+
"props": {
|
|
27350
|
+
"spacing": 8,
|
|
27351
|
+
"children": [
|
|
27352
|
+
{
|
|
27353
|
+
"id": "himi_blog_post.report",
|
|
27354
|
+
"body": {
|
|
27355
|
+
"package": "himalaya",
|
|
27356
|
+
"type": "Button",
|
|
27357
|
+
"props": {
|
|
27358
|
+
"title": "Report",
|
|
27359
|
+
"style": "secondary",
|
|
27360
|
+
"fullWidth": true,
|
|
27361
|
+
"action": {
|
|
27362
|
+
"actionId": "tier5.himiBlogPost.report"
|
|
27363
|
+
}
|
|
27364
|
+
}
|
|
27365
|
+
},
|
|
27366
|
+
"modifiers": {
|
|
27367
|
+
"hiddenPath": "$service:himiBlogPost.reported"
|
|
27368
|
+
}
|
|
27369
|
+
},
|
|
27370
|
+
{
|
|
27371
|
+
"id": "himi_blog_post.hide",
|
|
27372
|
+
"body": {
|
|
27373
|
+
"package": "himalaya",
|
|
27374
|
+
"type": "Button",
|
|
27375
|
+
"props": {
|
|
27376
|
+
"title": "Hide post",
|
|
27377
|
+
"style": "secondary",
|
|
27378
|
+
"fullWidth": true,
|
|
27379
|
+
"action": {
|
|
27380
|
+
"actionId": "tier5.himiBlogPost.openHide"
|
|
27381
|
+
}
|
|
27382
|
+
}
|
|
27383
|
+
},
|
|
27384
|
+
"modifiers": {
|
|
27385
|
+
"hiddenPath": "$service:himiBlogPost.hidden"
|
|
27386
|
+
}
|
|
27387
|
+
},
|
|
27388
|
+
{
|
|
27389
|
+
"id": "himi_blog_post.unhide",
|
|
27390
|
+
"body": {
|
|
27391
|
+
"package": "himalaya",
|
|
27392
|
+
"type": "Button",
|
|
27393
|
+
"props": {
|
|
27394
|
+
"title": "Undo hide",
|
|
27395
|
+
"style": "secondary",
|
|
27396
|
+
"fullWidth": true,
|
|
27397
|
+
"action": {
|
|
27398
|
+
"actionId": "tier5.himiBlogPost.unhide"
|
|
27399
|
+
}
|
|
27400
|
+
}
|
|
27401
|
+
},
|
|
27402
|
+
"modifiers": {
|
|
27403
|
+
"hiddenPath": "$service:himiBlogPost.notHidden"
|
|
27404
|
+
}
|
|
27405
|
+
}
|
|
27406
|
+
]
|
|
27407
|
+
}
|
|
27408
|
+
}
|
|
27343
27409
|
}
|
|
27344
27410
|
]
|
|
27345
27411
|
}
|
|
@@ -27598,6 +27664,122 @@ const TEMPLATED: { pattern: string; display: string; liveSeed?: LiveSeed; static
|
|
|
27598
27664
|
"hiddenPath": "$service:himiBlogPost.noPost"
|
|
27599
27665
|
}
|
|
27600
27666
|
},
|
|
27667
|
+
{
|
|
27668
|
+
"id": "himi_blog_post.hide_sheet",
|
|
27669
|
+
"body": {
|
|
27670
|
+
"package": "himalaya",
|
|
27671
|
+
"type": "BottomSheet",
|
|
27672
|
+
"props": {
|
|
27673
|
+
"presentedPath": "$service:himiBlogPost.hideSheetOpen",
|
|
27674
|
+
"dismissible": true,
|
|
27675
|
+
"showGrabber": true,
|
|
27676
|
+
"onDismiss": {
|
|
27677
|
+
"actionId": "tier5.himiBlogPost.closeHide"
|
|
27678
|
+
},
|
|
27679
|
+
"content": {
|
|
27680
|
+
"id": "",
|
|
27681
|
+
"body": {
|
|
27682
|
+
"package": "himalaya",
|
|
27683
|
+
"type": "VStack",
|
|
27684
|
+
"props": {
|
|
27685
|
+
"spacing": 12,
|
|
27686
|
+
"alignment": "leading",
|
|
27687
|
+
"children": [
|
|
27688
|
+
{
|
|
27689
|
+
"id": "",
|
|
27690
|
+
"body": {
|
|
27691
|
+
"package": "himalaya",
|
|
27692
|
+
"type": "Text",
|
|
27693
|
+
"props": {
|
|
27694
|
+
"text": "Why are you hiding this post?",
|
|
27695
|
+
"style": "title3"
|
|
27696
|
+
}
|
|
27697
|
+
}
|
|
27698
|
+
},
|
|
27699
|
+
{
|
|
27700
|
+
"id": "himi_blog_post.hide_offensive",
|
|
27701
|
+
"body": {
|
|
27702
|
+
"package": "himalaya",
|
|
27703
|
+
"type": "Button",
|
|
27704
|
+
"props": {
|
|
27705
|
+
"title": "It is offensive",
|
|
27706
|
+
"style": "secondary",
|
|
27707
|
+
"fullWidth": true,
|
|
27708
|
+
"action": {
|
|
27709
|
+
"actionId": "tier5.himiBlogPost.hide",
|
|
27710
|
+
"params": {
|
|
27711
|
+
"reason": "offensive"
|
|
27712
|
+
}
|
|
27713
|
+
}
|
|
27714
|
+
}
|
|
27715
|
+
}
|
|
27716
|
+
},
|
|
27717
|
+
{
|
|
27718
|
+
"id": "himi_blog_post.hide_misleading",
|
|
27719
|
+
"body": {
|
|
27720
|
+
"package": "himalaya",
|
|
27721
|
+
"type": "Button",
|
|
27722
|
+
"props": {
|
|
27723
|
+
"title": "It is misleading",
|
|
27724
|
+
"style": "secondary",
|
|
27725
|
+
"fullWidth": true,
|
|
27726
|
+
"action": {
|
|
27727
|
+
"actionId": "tier5.himiBlogPost.hide",
|
|
27728
|
+
"params": {
|
|
27729
|
+
"reason": "misleading"
|
|
27730
|
+
}
|
|
27731
|
+
}
|
|
27732
|
+
}
|
|
27733
|
+
}
|
|
27734
|
+
},
|
|
27735
|
+
{
|
|
27736
|
+
"id": "himi_blog_post.hide_other",
|
|
27737
|
+
"body": {
|
|
27738
|
+
"package": "himalaya",
|
|
27739
|
+
"type": "Button",
|
|
27740
|
+
"props": {
|
|
27741
|
+
"title": "Something else",
|
|
27742
|
+
"style": "secondary",
|
|
27743
|
+
"fullWidth": true,
|
|
27744
|
+
"action": {
|
|
27745
|
+
"actionId": "tier5.himiBlogPost.hide",
|
|
27746
|
+
"params": {
|
|
27747
|
+
"reason": "other"
|
|
27748
|
+
}
|
|
27749
|
+
}
|
|
27750
|
+
}
|
|
27751
|
+
}
|
|
27752
|
+
},
|
|
27753
|
+
{
|
|
27754
|
+
"id": "himi_blog_post.hide_cancel",
|
|
27755
|
+
"body": {
|
|
27756
|
+
"package": "himalaya",
|
|
27757
|
+
"type": "Button",
|
|
27758
|
+
"props": {
|
|
27759
|
+
"title": "Cancel",
|
|
27760
|
+
"style": "secondary",
|
|
27761
|
+
"fullWidth": true,
|
|
27762
|
+
"action": {
|
|
27763
|
+
"actionId": "tier5.himiBlogPost.closeHide"
|
|
27764
|
+
}
|
|
27765
|
+
}
|
|
27766
|
+
}
|
|
27767
|
+
}
|
|
27768
|
+
]
|
|
27769
|
+
}
|
|
27770
|
+
},
|
|
27771
|
+
"modifiers": {
|
|
27772
|
+
"padding": {
|
|
27773
|
+
"leading": 20,
|
|
27774
|
+
"trailing": 20,
|
|
27775
|
+
"top": 16,
|
|
27776
|
+
"bottom": 24
|
|
27777
|
+
}
|
|
27778
|
+
}
|
|
27779
|
+
}
|
|
27780
|
+
}
|
|
27781
|
+
}
|
|
27782
|
+
},
|
|
27601
27783
|
{
|
|
27602
27784
|
"id": "",
|
|
27603
27785
|
"body": {
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
// The posts this device's reader chose to hide, as the One App blog does: a client-side list of post ids that the
|
|
2
|
+
// blog feed, the Home cards and Saved leave out. Nothing is sent to the site, and another device or account does not
|
|
3
|
+
// share it. It is the saved-posts store's twin (see himi-blog-saved.ts) and reads storage the same way: native workers
|
|
4
|
+
// have only the sync `himalaya.storage` KV, a browser has `localStorage`, and each screen runs its own worker, so
|
|
5
|
+
// the durable arm is what lets a Hide on the post screen reach the feed's worker.
|
|
6
|
+
const KEY = "himi-blog:hidden-posts:v1";
|
|
7
|
+
|
|
8
|
+
type StorageLike = {
|
|
9
|
+
getItem: (key: string) => string | null;
|
|
10
|
+
setItem: (key: string, value: string) => void;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
type HiddenHost = typeof globalThis & {
|
|
14
|
+
himalaya?: { storage?: StorageLike };
|
|
15
|
+
localStorage?: StorageLike;
|
|
16
|
+
__himiBlogHiddenIds?: string[];
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const host = globalThis as HiddenHost;
|
|
20
|
+
|
|
21
|
+
function storage(): StorageLike | undefined {
|
|
22
|
+
return host.himalaya?.storage ?? host.localStorage;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const unique = (ids: string[]): string[] => Array.from(new Set(ids.map((id) => id.trim()).filter(Boolean)));
|
|
26
|
+
|
|
27
|
+
export function readHiddenIds(): string[] {
|
|
28
|
+
try {
|
|
29
|
+
const raw = storage()?.getItem(KEY);
|
|
30
|
+
if (raw) {
|
|
31
|
+
const parsed = JSON.parse(raw);
|
|
32
|
+
if (Array.isArray(parsed)) return unique(parsed.filter((id): id is string => typeof id === "string"));
|
|
33
|
+
}
|
|
34
|
+
} catch {
|
|
35
|
+
// Unreadable storage: fall back to what this worker context holds in memory.
|
|
36
|
+
}
|
|
37
|
+
return unique(host.__himiBlogHiddenIds ?? []);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function writeHiddenIds(ids: string[]): void {
|
|
41
|
+
const next = unique(ids);
|
|
42
|
+
host.__himiBlogHiddenIds = next;
|
|
43
|
+
try {
|
|
44
|
+
storage()?.setItem(KEY, JSON.stringify(next));
|
|
45
|
+
} catch {
|
|
46
|
+
// Storage-less hosts keep the in-memory arm only.
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export function isHiddenId(id: string): boolean {
|
|
51
|
+
return readHiddenIds().includes(id);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export function hideId(id: string): void {
|
|
55
|
+
writeHiddenIds([id, ...readHiddenIds()]);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export function unhideId(id: string): void {
|
|
59
|
+
writeHiddenIds(readHiddenIds().filter((hiddenId) => hiddenId !== id));
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/** The items a list may show: every one whose `id` this device has not hidden. */
|
|
63
|
+
export function withoutHidden<T extends { id?: string | null }>(items: T[]): T[] {
|
|
64
|
+
const hidden = new Set(readHiddenIds());
|
|
65
|
+
return hidden.size ? items.filter((item) => !item.id || !hidden.has(item.id)) : items;
|
|
66
|
+
}
|
|
@@ -4,6 +4,7 @@ import { queryCategories, queryPosts, type WixPost } from "@himalaya/wix-blog";
|
|
|
4
4
|
import { stashCopy, copyParam } from "../_shared/himi-copy.js";
|
|
5
5
|
import { getAll, upsert, type DbEntity } from "@himalaya/local-db";
|
|
6
6
|
import { formatDateMedium } from "../_shared/engine-intl.js";
|
|
7
|
+
import { withoutHidden } from "../_shared/himi-blog-hidden.js";
|
|
7
8
|
|
|
8
9
|
const PAGE_SIZE = 20;
|
|
9
10
|
|
|
@@ -137,7 +138,8 @@ function normalize(post: WixPost, categoryMap: Map<string, string>): PostRow {
|
|
|
137
138
|
|
|
138
139
|
function applyFilters(s: S): S {
|
|
139
140
|
const needle = s.query.trim().toLowerCase();
|
|
140
|
-
|
|
141
|
+
// Posts this device's reader hid (on the post screen) never show, whatever the cache or the live page holds.
|
|
142
|
+
const posts = withoutHidden(s.allPosts).filter((post) => {
|
|
141
143
|
const categoryOk = !s.selectedCategoryId || post.categoryId === s.selectedCategoryId;
|
|
142
144
|
const queryOk =
|
|
143
145
|
!needle ||
|
|
@@ -5,6 +5,7 @@ import { getPost, likePost, unlikePost, type WixPost, type WixPostWithContent }
|
|
|
5
5
|
import { comments, BLOG_COMMENTS_APP_ID, blogCommentRow, listBlogComments, type WixBlogCommentRow } from "@himalaya/wix-comments";
|
|
6
6
|
import { get, type DbEntity } from "@himalaya/local-db";
|
|
7
7
|
import { isSavedId, toggleSavedId } from "../_shared/himi-blog-saved";
|
|
8
|
+
import { hideId, isHiddenId, unhideId } from "../_shared/himi-blog-hidden";
|
|
8
9
|
import { stashCopy, copyParam, copyTemplate } from "../_shared/himi-copy.js";
|
|
9
10
|
import { formatDateMedium, formatMonthDay } from "../_shared/engine-intl.js";
|
|
10
11
|
import { openRichLink } from "../_shared/rich-content-link.js";
|
|
@@ -64,6 +65,14 @@ interface S {
|
|
|
64
65
|
notLiked: boolean;
|
|
65
66
|
saved: boolean;
|
|
66
67
|
notSaved: boolean;
|
|
68
|
+
/** This device's reader hid the post: the feed, Home and Saved leave it out, and this screen offers Undo. */
|
|
69
|
+
hidden: boolean;
|
|
70
|
+
notHidden: boolean;
|
|
71
|
+
/** The reason sheet (offensive / misleading / other) is open. */
|
|
72
|
+
hideSheetOpen: boolean;
|
|
73
|
+
/** The reader reported the post this visit; the report button then says so and stops sending. */
|
|
74
|
+
reported: boolean;
|
|
75
|
+
notReported: boolean;
|
|
67
76
|
commentDraft: string;
|
|
68
77
|
comments: CommentRow[];
|
|
69
78
|
commentsUnavailable: boolean;
|
|
@@ -212,6 +221,8 @@ function derive(s: S): S {
|
|
|
212
221
|
hasBodyJson: s.bodyJson !== "",
|
|
213
222
|
notLiked: !s.liked,
|
|
214
223
|
notSaved: !s.saved,
|
|
224
|
+
notHidden: !s.hidden,
|
|
225
|
+
notReported: !s.reported,
|
|
215
226
|
commentsAvailable: !s.commentsUnavailable,
|
|
216
227
|
};
|
|
217
228
|
}
|
|
@@ -238,6 +249,11 @@ const baseState: S = derive({
|
|
|
238
249
|
notLiked: true,
|
|
239
250
|
saved: false,
|
|
240
251
|
notSaved: true,
|
|
252
|
+
hidden: false,
|
|
253
|
+
notHidden: true,
|
|
254
|
+
hideSheetOpen: false,
|
|
255
|
+
reported: false,
|
|
256
|
+
notReported: true,
|
|
241
257
|
commentDraft: "",
|
|
242
258
|
comments: [],
|
|
243
259
|
commentsUnavailable: false,
|
|
@@ -278,6 +294,7 @@ async function cachedPostState(s: S, id: string): Promise<S> {
|
|
|
278
294
|
initial: String(cached.initial ?? "") || (title[0] || "#").toUpperCase(),
|
|
279
295
|
liked: false,
|
|
280
296
|
saved: isSavedId(id),
|
|
297
|
+
hidden: isHiddenId(id),
|
|
281
298
|
comments: [],
|
|
282
299
|
commentsUnavailable: true,
|
|
283
300
|
commentStatusText: copyParam("blogPost.commentsUnavailable", "Comments are unavailable right now."),
|
|
@@ -331,6 +348,7 @@ async function loadPostState(s: S): Promise<S | undefined> {
|
|
|
331
348
|
initial: (title[0] || "#").toUpperCase(),
|
|
332
349
|
liked: Boolean(post.memberInteraction?.liked),
|
|
333
350
|
saved: isSavedId(id),
|
|
351
|
+
hidden: isHiddenId(id),
|
|
334
352
|
comments,
|
|
335
353
|
commentsUnavailable,
|
|
336
354
|
commentStatusText: commentsUnavailable
|
|
@@ -359,6 +377,14 @@ const svc = defineService<S, {
|
|
|
359
377
|
like: (s: S) => Promise<S>;
|
|
360
378
|
unlike: (s: S) => Promise<S>;
|
|
361
379
|
toggleSave: (s: S) => S;
|
|
380
|
+
/** Report the post: no site API takes a member's report, so the reader is thanked and the tap is the signal. */
|
|
381
|
+
report: (s: S) => S;
|
|
382
|
+
openHide: (s: S) => S;
|
|
383
|
+
closeHide: (s: S) => S;
|
|
384
|
+
/** Hide the post on this device. The sheet's three reasons (offensive, misleading, other) are asked for as the One
|
|
385
|
+
* App asks them, but the list keeps only the id and the site is told nothing, so the worker does not read the reason. */
|
|
386
|
+
hide: (s: S) => S;
|
|
387
|
+
unhide: (s: S) => S;
|
|
362
388
|
share: (s: S) => Promise<S>;
|
|
363
389
|
setComment: (s: S, arg?: unknown) => S;
|
|
364
390
|
submitComment: (s: S) => Promise<S>;
|
|
@@ -397,6 +423,22 @@ const svc = defineService<S, {
|
|
|
397
423
|
const saved = toggleSavedId(s.id);
|
|
398
424
|
return derive({ ...s, saved, actionMessage: saved ? copyParam("blogPost.savedMessage", "Saved for later") : copyParam("blogPost.unsavedMessage", "Removed from saved") });
|
|
399
425
|
},
|
|
426
|
+
report: (s) => {
|
|
427
|
+
if (!s.id || s.reported) return s;
|
|
428
|
+
return derive({ ...s, reported: true, actionMessage: copyParam("blogPost.reportedMessage", "Post reported") });
|
|
429
|
+
},
|
|
430
|
+
openHide: (s) => s.id ? derive({ ...s, hideSheetOpen: true }) : s,
|
|
431
|
+
closeHide: (s) => derive({ ...s, hideSheetOpen: false }),
|
|
432
|
+
hide: (s) => {
|
|
433
|
+
if (!s.id) return s;
|
|
434
|
+
hideId(s.id);
|
|
435
|
+
return derive({ ...s, hidden: true, hideSheetOpen: false, actionMessage: copyParam("blogPost.hiddenMessage", "Post hidden. It will not show in your feeds.") });
|
|
436
|
+
},
|
|
437
|
+
unhide: (s) => {
|
|
438
|
+
if (!s.id) return s;
|
|
439
|
+
unhideId(s.id);
|
|
440
|
+
return derive({ ...s, hidden: false, actionMessage: copyParam("blogPost.unhiddenMessage", "Post is visible again") });
|
|
441
|
+
},
|
|
400
442
|
share: async (s) => {
|
|
401
443
|
if (!s.title) return s;
|
|
402
444
|
try {
|
|
@@ -3,6 +3,7 @@ import { defineService } from "@himalaya/state";
|
|
|
3
3
|
import { getPost, type WixPost } from "@himalaya/wix-blog";
|
|
4
4
|
import { get, type DbEntity } from "@himalaya/local-db";
|
|
5
5
|
import { readSavedIds, writeSavedIds } from "../_shared/himi-blog-saved";
|
|
6
|
+
import { readHiddenIds } from "../_shared/himi-blog-hidden";
|
|
6
7
|
import { stashCopy, copyParam } from "../_shared/himi-copy.js";
|
|
7
8
|
import { formatDateMedium } from "../_shared/engine-intl.js";
|
|
8
9
|
|
|
@@ -144,7 +145,9 @@ const baseState: S = derive({
|
|
|
144
145
|
});
|
|
145
146
|
|
|
146
147
|
async function loadSavedState(s: S): Promise<S> {
|
|
147
|
-
|
|
148
|
+
// A saved post this device's reader also hid stays in the saved list (Undo brings it back) but is not shown.
|
|
149
|
+
const hidden = new Set(readHiddenIds());
|
|
150
|
+
const ids = readSavedIds().filter((id) => !hidden.has(id));
|
|
148
151
|
if (!ids.length) {
|
|
149
152
|
return derive({ ...s, status: "ready", posts: [], emptyText: copyParam("saved.emptyText", "No saved posts yet.") });
|
|
150
153
|
}
|
|
@@ -26,6 +26,7 @@ import { formatDateMedium } from "../_shared/engine-intl.js";
|
|
|
26
26
|
import { readSavedProducts, type SavedProduct } from "../_shared/himi-store-saved.js";
|
|
27
27
|
import { loadStoreCategories, type StoreCategoryCard } from "../_shared/himi-store-categories.js";
|
|
28
28
|
import { readSavedIds } from "../_shared/himi-blog-saved.js";
|
|
29
|
+
import { withoutHidden } from "../_shared/himi-blog-hidden.js";
|
|
29
30
|
import { wixMediaUrl } from "@himalaya/wix-media";
|
|
30
31
|
import { groupImage, programImage } from "../_shared/himi-media.js";
|
|
31
32
|
import { isWixVideoWebRefusal, listLatestVideos, videoCard, type WixVideoCard } from "@himalaya/wix-video";
|
|
@@ -770,8 +771,10 @@ async function fetchExtrasSignal(arg: unknown): Promise<ExtrasSignal> {
|
|
|
770
771
|
// read used to make; a failure collapses both blocks silently.
|
|
771
772
|
jobs.push(queryPosts({ query: { paging: { limit: 8 }, sort: [{ fieldName: "firstPublishedDate", order: "DESC" }] } })
|
|
772
773
|
.then((response) => {
|
|
773
|
-
|
|
774
|
-
|
|
774
|
+
// Posts this device's reader hid on the post screen are left out of both blocks.
|
|
775
|
+
const posts = withoutHidden(response.posts ?? []);
|
|
776
|
+
extras.announcementTitle = cleanTitle(posts[0]?.title);
|
|
777
|
+
extras.postCards = posts.filter((post) => post.id).slice(0, 6).map(postCard);
|
|
775
778
|
})
|
|
776
779
|
.catch(() => { /* collapse silently */ }));
|
|
777
780
|
}
|
|
@@ -36676,6 +36676,72 @@ const TEMPLATED: { pattern: string; display: string; liveSeed?: LiveSeed; static
|
|
|
36676
36676
|
}
|
|
36677
36677
|
}
|
|
36678
36678
|
}
|
|
36679
|
+
},
|
|
36680
|
+
{
|
|
36681
|
+
"id": "",
|
|
36682
|
+
"body": {
|
|
36683
|
+
"package": "himalaya",
|
|
36684
|
+
"type": "HStack",
|
|
36685
|
+
"props": {
|
|
36686
|
+
"spacing": 8,
|
|
36687
|
+
"children": [
|
|
36688
|
+
{
|
|
36689
|
+
"id": "himi_blog_post.report",
|
|
36690
|
+
"body": {
|
|
36691
|
+
"package": "himalaya",
|
|
36692
|
+
"type": "Button",
|
|
36693
|
+
"props": {
|
|
36694
|
+
"title": "Report",
|
|
36695
|
+
"style": "secondary",
|
|
36696
|
+
"fullWidth": true,
|
|
36697
|
+
"action": {
|
|
36698
|
+
"actionId": "tier5.himiBlogPost.report"
|
|
36699
|
+
}
|
|
36700
|
+
}
|
|
36701
|
+
},
|
|
36702
|
+
"modifiers": {
|
|
36703
|
+
"hiddenPath": "$service:himiBlogPost.reported"
|
|
36704
|
+
}
|
|
36705
|
+
},
|
|
36706
|
+
{
|
|
36707
|
+
"id": "himi_blog_post.hide",
|
|
36708
|
+
"body": {
|
|
36709
|
+
"package": "himalaya",
|
|
36710
|
+
"type": "Button",
|
|
36711
|
+
"props": {
|
|
36712
|
+
"title": "Hide post",
|
|
36713
|
+
"style": "secondary",
|
|
36714
|
+
"fullWidth": true,
|
|
36715
|
+
"action": {
|
|
36716
|
+
"actionId": "tier5.himiBlogPost.openHide"
|
|
36717
|
+
}
|
|
36718
|
+
}
|
|
36719
|
+
},
|
|
36720
|
+
"modifiers": {
|
|
36721
|
+
"hiddenPath": "$service:himiBlogPost.hidden"
|
|
36722
|
+
}
|
|
36723
|
+
},
|
|
36724
|
+
{
|
|
36725
|
+
"id": "himi_blog_post.unhide",
|
|
36726
|
+
"body": {
|
|
36727
|
+
"package": "himalaya",
|
|
36728
|
+
"type": "Button",
|
|
36729
|
+
"props": {
|
|
36730
|
+
"title": "Undo hide",
|
|
36731
|
+
"style": "secondary",
|
|
36732
|
+
"fullWidth": true,
|
|
36733
|
+
"action": {
|
|
36734
|
+
"actionId": "tier5.himiBlogPost.unhide"
|
|
36735
|
+
}
|
|
36736
|
+
}
|
|
36737
|
+
},
|
|
36738
|
+
"modifiers": {
|
|
36739
|
+
"hiddenPath": "$service:himiBlogPost.notHidden"
|
|
36740
|
+
}
|
|
36741
|
+
}
|
|
36742
|
+
]
|
|
36743
|
+
}
|
|
36744
|
+
}
|
|
36679
36745
|
}
|
|
36680
36746
|
]
|
|
36681
36747
|
}
|
|
@@ -36934,6 +37000,122 @@ const TEMPLATED: { pattern: string; display: string; liveSeed?: LiveSeed; static
|
|
|
36934
37000
|
"hiddenPath": "$service:himiBlogPost.noPost"
|
|
36935
37001
|
}
|
|
36936
37002
|
},
|
|
37003
|
+
{
|
|
37004
|
+
"id": "himi_blog_post.hide_sheet",
|
|
37005
|
+
"body": {
|
|
37006
|
+
"package": "himalaya",
|
|
37007
|
+
"type": "BottomSheet",
|
|
37008
|
+
"props": {
|
|
37009
|
+
"presentedPath": "$service:himiBlogPost.hideSheetOpen",
|
|
37010
|
+
"dismissible": true,
|
|
37011
|
+
"showGrabber": true,
|
|
37012
|
+
"onDismiss": {
|
|
37013
|
+
"actionId": "tier5.himiBlogPost.closeHide"
|
|
37014
|
+
},
|
|
37015
|
+
"content": {
|
|
37016
|
+
"id": "",
|
|
37017
|
+
"body": {
|
|
37018
|
+
"package": "himalaya",
|
|
37019
|
+
"type": "VStack",
|
|
37020
|
+
"props": {
|
|
37021
|
+
"spacing": 12,
|
|
37022
|
+
"alignment": "leading",
|
|
37023
|
+
"children": [
|
|
37024
|
+
{
|
|
37025
|
+
"id": "",
|
|
37026
|
+
"body": {
|
|
37027
|
+
"package": "himalaya",
|
|
37028
|
+
"type": "Text",
|
|
37029
|
+
"props": {
|
|
37030
|
+
"text": "Why are you hiding this post?",
|
|
37031
|
+
"style": "title3"
|
|
37032
|
+
}
|
|
37033
|
+
}
|
|
37034
|
+
},
|
|
37035
|
+
{
|
|
37036
|
+
"id": "himi_blog_post.hide_offensive",
|
|
37037
|
+
"body": {
|
|
37038
|
+
"package": "himalaya",
|
|
37039
|
+
"type": "Button",
|
|
37040
|
+
"props": {
|
|
37041
|
+
"title": "It is offensive",
|
|
37042
|
+
"style": "secondary",
|
|
37043
|
+
"fullWidth": true,
|
|
37044
|
+
"action": {
|
|
37045
|
+
"actionId": "tier5.himiBlogPost.hide",
|
|
37046
|
+
"params": {
|
|
37047
|
+
"reason": "offensive"
|
|
37048
|
+
}
|
|
37049
|
+
}
|
|
37050
|
+
}
|
|
37051
|
+
}
|
|
37052
|
+
},
|
|
37053
|
+
{
|
|
37054
|
+
"id": "himi_blog_post.hide_misleading",
|
|
37055
|
+
"body": {
|
|
37056
|
+
"package": "himalaya",
|
|
37057
|
+
"type": "Button",
|
|
37058
|
+
"props": {
|
|
37059
|
+
"title": "It is misleading",
|
|
37060
|
+
"style": "secondary",
|
|
37061
|
+
"fullWidth": true,
|
|
37062
|
+
"action": {
|
|
37063
|
+
"actionId": "tier5.himiBlogPost.hide",
|
|
37064
|
+
"params": {
|
|
37065
|
+
"reason": "misleading"
|
|
37066
|
+
}
|
|
37067
|
+
}
|
|
37068
|
+
}
|
|
37069
|
+
}
|
|
37070
|
+
},
|
|
37071
|
+
{
|
|
37072
|
+
"id": "himi_blog_post.hide_other",
|
|
37073
|
+
"body": {
|
|
37074
|
+
"package": "himalaya",
|
|
37075
|
+
"type": "Button",
|
|
37076
|
+
"props": {
|
|
37077
|
+
"title": "Something else",
|
|
37078
|
+
"style": "secondary",
|
|
37079
|
+
"fullWidth": true,
|
|
37080
|
+
"action": {
|
|
37081
|
+
"actionId": "tier5.himiBlogPost.hide",
|
|
37082
|
+
"params": {
|
|
37083
|
+
"reason": "other"
|
|
37084
|
+
}
|
|
37085
|
+
}
|
|
37086
|
+
}
|
|
37087
|
+
}
|
|
37088
|
+
},
|
|
37089
|
+
{
|
|
37090
|
+
"id": "himi_blog_post.hide_cancel",
|
|
37091
|
+
"body": {
|
|
37092
|
+
"package": "himalaya",
|
|
37093
|
+
"type": "Button",
|
|
37094
|
+
"props": {
|
|
37095
|
+
"title": "Cancel",
|
|
37096
|
+
"style": "secondary",
|
|
37097
|
+
"fullWidth": true,
|
|
37098
|
+
"action": {
|
|
37099
|
+
"actionId": "tier5.himiBlogPost.closeHide"
|
|
37100
|
+
}
|
|
37101
|
+
}
|
|
37102
|
+
}
|
|
37103
|
+
}
|
|
37104
|
+
]
|
|
37105
|
+
}
|
|
37106
|
+
},
|
|
37107
|
+
"modifiers": {
|
|
37108
|
+
"padding": {
|
|
37109
|
+
"leading": 20,
|
|
37110
|
+
"trailing": 20,
|
|
37111
|
+
"top": 16,
|
|
37112
|
+
"bottom": 24
|
|
37113
|
+
}
|
|
37114
|
+
}
|
|
37115
|
+
}
|
|
37116
|
+
}
|
|
37117
|
+
}
|
|
37118
|
+
},
|
|
36937
37119
|
{
|
|
36938
37120
|
"id": "",
|
|
36939
37121
|
"body": {
|