@wix/himalaya-cli 0.1029.0 → 0.1031.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/core/dev-server/src/app-config.d.ts +7 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/dev-server/src/wix-gateway.d.ts +32 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/dev-server/src/wix-gateway.rules.d.ts +2 -1
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/ts/src/define-app.d.ts +7 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/genie-chat/src/index.d.ts +64 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-genie-chat.mjs +41 -1
- package/dist/cli.mjs +298 -114
- package/dist/preview-assets.generated.bin +0 -0
- package/guides/component-reference.json +0 -7
- package/guides/component-reference.md +0 -2
- package/guides/sdk-reference.json +50 -2
- package/package.json +2 -2
- package/templates/beauty-salon/dev/index.ts +575 -214
- package/templates/beauty-salon/tier5-src/_shared/collection-contract.ts +4 -1
- package/templates/beauty-salon/tier5-src/_shared/owner-load-error.ts +7 -1
- package/templates/beauty-salon/tier5-src/himi-branded-lite-appearance/index.ts +12 -1
- package/templates/beauty-salon/tier5-src/himi-store-product/index.ts +36 -5
- package/templates/beauty-salon/tier5-src/wix-spaces-app-language/index.ts +4 -2
- package/templates/beauty-salon-owner/config.ts +1 -1
- package/templates/beauty-salon-owner/dev/index.ts +247 -9
- package/templates/beauty-salon-owner/tier5-src/_shared/aria-attachments.ts +179 -0
- package/templates/beauty-salon-owner/tier5-src/_shared/aria-chat.ts +405 -20
- package/templates/beauty-salon-owner/tier5-src/_shared/collection-contract.ts +4 -1
- package/templates/beauty-salon-owner/tier5-src/_shared/owner-bookings.ts +20 -0
- package/templates/beauty-salon-owner/tier5-src/_shared/owner-load-error.ts +7 -1
- package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-aria/index.ts +40 -1
- package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-home/index.ts +2 -12
- package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-manage/index.ts +10 -4
- package/templates/branded-lite/dev/index.ts +699 -228
- package/templates/branded-lite/tier5-src/_shared/collection-contract.ts +4 -1
- package/templates/branded-lite/tier5-src/_shared/owner-load-error.ts +7 -1
- package/templates/branded-lite/tier5-src/himi-branded-lite-appearance/index.ts +12 -1
- package/templates/branded-lite/tier5-src/himi-branded-lite-notifsettings/index.ts +11 -6
- package/templates/branded-lite/tier5-src/himi-branded-lite-reviews/index.ts +11 -6
- package/templates/branded-lite/tier5-src/himi-store-product/index.ts +36 -5
- package/templates/branded-lite/tier5-src/wix-spaces-app-language/index.ts +4 -2
- package/templates/community-club/dev/index.ts +451 -204
- package/templates/community-club/tier5-src/_shared/collection-contract.ts +4 -1
- package/templates/community-club/tier5-src/_shared/owner-load-error.ts +7 -1
- package/templates/community-club/tier5-src/himi-branded-lite-appearance/index.ts +12 -1
- package/templates/community-club/tier5-src/wix-spaces-app-language/index.ts +4 -2
- package/templates/community-club-owner/config.ts +1 -1
- package/templates/community-club-owner/dev/index.ts +247 -9
- package/templates/community-club-owner/tier5-src/_shared/aria-attachments.ts +179 -0
- package/templates/community-club-owner/tier5-src/_shared/aria-chat.ts +405 -20
- package/templates/community-club-owner/tier5-src/_shared/collection-contract.ts +4 -1
- package/templates/community-club-owner/tier5-src/_shared/owner-bookings.ts +20 -0
- package/templates/community-club-owner/tier5-src/_shared/owner-load-error.ts +7 -1
- package/templates/community-club-owner/tier5-src/himi-owner-lite-aria/index.ts +40 -1
- package/templates/community-club-owner/tier5-src/himi-owner-lite-home/index.ts +2 -12
- package/templates/community-club-owner/tier5-src/himi-owner-lite-manage/index.ts +10 -4
- package/templates/events-meetups/dev/index.ts +451 -204
- package/templates/events-meetups/tier5-src/_shared/collection-contract.ts +4 -1
- package/templates/events-meetups/tier5-src/_shared/owner-load-error.ts +7 -1
- package/templates/events-meetups/tier5-src/himi-branded-lite-appearance/index.ts +12 -1
- package/templates/events-meetups/tier5-src/wix-spaces-app-language/index.ts +4 -2
- package/templates/events-meetups-owner/config.ts +1 -1
- package/templates/events-meetups-owner/dev/index.ts +247 -9
- package/templates/events-meetups-owner/tier5-src/_shared/aria-attachments.ts +179 -0
- package/templates/events-meetups-owner/tier5-src/_shared/aria-chat.ts +405 -20
- package/templates/events-meetups-owner/tier5-src/_shared/collection-contract.ts +4 -1
- package/templates/events-meetups-owner/tier5-src/_shared/owner-bookings.ts +20 -0
- package/templates/events-meetups-owner/tier5-src/_shared/owner-load-error.ts +7 -1
- package/templates/events-meetups-owner/tier5-src/himi-owner-lite-aria/index.ts +40 -1
- package/templates/events-meetups-owner/tier5-src/himi-owner-lite-home/index.ts +2 -12
- package/templates/events-meetups-owner/tier5-src/himi-owner-lite-manage/index.ts +10 -4
- package/templates/gym-fitness/dev/index.ts +575 -214
- package/templates/gym-fitness/tier5-src/_shared/collection-contract.ts +4 -1
- package/templates/gym-fitness/tier5-src/_shared/owner-load-error.ts +7 -1
- package/templates/gym-fitness/tier5-src/himi-branded-lite-appearance/index.ts +12 -1
- package/templates/gym-fitness/tier5-src/himi-store-product/index.ts +36 -5
- package/templates/gym-fitness/tier5-src/wix-spaces-app-language/index.ts +4 -2
- package/templates/gym-fitness-owner/config.ts +1 -1
- package/templates/gym-fitness-owner/dev/index.ts +247 -9
- package/templates/gym-fitness-owner/tier5-src/_shared/aria-attachments.ts +179 -0
- package/templates/gym-fitness-owner/tier5-src/_shared/aria-chat.ts +405 -20
- package/templates/gym-fitness-owner/tier5-src/_shared/collection-contract.ts +4 -1
- package/templates/gym-fitness-owner/tier5-src/_shared/owner-bookings.ts +20 -0
- package/templates/gym-fitness-owner/tier5-src/_shared/owner-load-error.ts +7 -1
- package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-aria/index.ts +40 -1
- package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-home/index.ts +2 -12
- package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-manage/index.ts +10 -4
- package/templates/himi-chat/tier5-src/_shared/owner-load-error.ts +7 -1
- package/templates/nonprofit-cause/dev/index.ts +451 -204
- package/templates/nonprofit-cause/tier5-src/_shared/collection-contract.ts +4 -1
- package/templates/nonprofit-cause/tier5-src/_shared/owner-load-error.ts +7 -1
- package/templates/nonprofit-cause/tier5-src/himi-branded-lite-appearance/index.ts +12 -1
- package/templates/nonprofit-cause/tier5-src/wix-spaces-app-language/index.ts +4 -2
- package/templates/nonprofit-cause-owner/config.ts +1 -1
- package/templates/nonprofit-cause-owner/dev/index.ts +247 -9
- package/templates/nonprofit-cause-owner/tier5-src/_shared/aria-attachments.ts +179 -0
- package/templates/nonprofit-cause-owner/tier5-src/_shared/aria-chat.ts +405 -20
- package/templates/nonprofit-cause-owner/tier5-src/_shared/collection-contract.ts +4 -1
- package/templates/nonprofit-cause-owner/tier5-src/_shared/owner-bookings.ts +20 -0
- package/templates/nonprofit-cause-owner/tier5-src/_shared/owner-load-error.ts +7 -1
- package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-aria/index.ts +40 -1
- package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-home/index.ts +2 -12
- package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-manage/index.ts +10 -4
- package/templates/owner-lite/config.ts +1 -1
- package/templates/owner-lite/dev/index.ts +247 -9
- package/templates/owner-lite/tier5-src/_shared/aria-attachments.ts +179 -0
- package/templates/owner-lite/tier5-src/_shared/aria-chat.ts +405 -20
- package/templates/owner-lite/tier5-src/_shared/collection-contract.ts +4 -1
- package/templates/owner-lite/tier5-src/_shared/owner-bookings.ts +20 -0
- package/templates/owner-lite/tier5-src/_shared/owner-load-error.ts +7 -1
- package/templates/owner-lite/tier5-src/himi-owner-lite-aria/index.ts +40 -1
- package/templates/owner-lite/tier5-src/himi-owner-lite-home/index.ts +2 -12
- package/templates/owner-lite/tier5-src/himi-owner-lite-manage/index.ts +10 -4
- package/templates/podcast-creator/dev/index.ts +451 -204
- package/templates/podcast-creator/tier5-src/_shared/collection-contract.ts +4 -1
- package/templates/podcast-creator/tier5-src/_shared/owner-load-error.ts +7 -1
- package/templates/podcast-creator/tier5-src/himi-branded-lite-appearance/index.ts +12 -1
- package/templates/podcast-creator/tier5-src/wix-spaces-app-language/index.ts +4 -2
- package/templates/podcast-creator-owner/config.ts +1 -1
- package/templates/podcast-creator-owner/dev/index.ts +247 -9
- package/templates/podcast-creator-owner/tier5-src/_shared/aria-attachments.ts +179 -0
- package/templates/podcast-creator-owner/tier5-src/_shared/aria-chat.ts +405 -20
- package/templates/podcast-creator-owner/tier5-src/_shared/collection-contract.ts +4 -1
- package/templates/podcast-creator-owner/tier5-src/_shared/owner-bookings.ts +20 -0
- package/templates/podcast-creator-owner/tier5-src/_shared/owner-load-error.ts +7 -1
- package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-aria/index.ts +40 -1
- package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-home/index.ts +2 -12
- package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-manage/index.ts +10 -4
- package/templates/portfolio-creative/dev/index.ts +575 -214
- package/templates/portfolio-creative/tier5-src/_shared/collection-contract.ts +4 -1
- package/templates/portfolio-creative/tier5-src/_shared/owner-load-error.ts +7 -1
- package/templates/portfolio-creative/tier5-src/himi-branded-lite-appearance/index.ts +12 -1
- package/templates/portfolio-creative/tier5-src/himi-store-product/index.ts +36 -5
- package/templates/portfolio-creative/tier5-src/wix-spaces-app-language/index.ts +4 -2
- package/templates/portfolio-creative-owner/config.ts +1 -1
- package/templates/portfolio-creative-owner/dev/index.ts +247 -9
- package/templates/portfolio-creative-owner/tier5-src/_shared/aria-attachments.ts +179 -0
- package/templates/portfolio-creative-owner/tier5-src/_shared/aria-chat.ts +405 -20
- package/templates/portfolio-creative-owner/tier5-src/_shared/collection-contract.ts +4 -1
- package/templates/portfolio-creative-owner/tier5-src/_shared/owner-bookings.ts +20 -0
- package/templates/portfolio-creative-owner/tier5-src/_shared/owner-load-error.ts +7 -1
- package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-aria/index.ts +40 -1
- package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-home/index.ts +2 -12
- package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-manage/index.ts +10 -4
- package/templates/restaurant/dev/index.ts +451 -204
- package/templates/restaurant/tier5-src/_shared/collection-contract.ts +4 -1
- package/templates/restaurant/tier5-src/_shared/owner-load-error.ts +7 -1
- package/templates/restaurant/tier5-src/himi-branded-lite-appearance/index.ts +12 -1
- package/templates/restaurant/tier5-src/wix-spaces-app-language/index.ts +4 -2
- package/templates/restaurant-owner/config.ts +1 -1
- package/templates/restaurant-owner/dev/index.ts +247 -9
- package/templates/restaurant-owner/tier5-src/_shared/aria-attachments.ts +179 -0
- package/templates/restaurant-owner/tier5-src/_shared/aria-chat.ts +405 -20
- package/templates/restaurant-owner/tier5-src/_shared/collection-contract.ts +4 -1
- package/templates/restaurant-owner/tier5-src/_shared/owner-bookings.ts +20 -0
- package/templates/restaurant-owner/tier5-src/_shared/owner-load-error.ts +7 -1
- package/templates/restaurant-owner/tier5-src/himi-owner-lite-aria/index.ts +40 -1
- package/templates/restaurant-owner/tier5-src/himi-owner-lite-home/index.ts +2 -12
- package/templates/restaurant-owner/tier5-src/himi-owner-lite-manage/index.ts +10 -4
- package/templates/retail-store/dev/index.ts +575 -214
- package/templates/retail-store/tier5-src/_shared/collection-contract.ts +4 -1
- package/templates/retail-store/tier5-src/_shared/owner-load-error.ts +7 -1
- package/templates/retail-store/tier5-src/himi-branded-lite-appearance/index.ts +12 -1
- package/templates/retail-store/tier5-src/himi-store-product/index.ts +36 -5
- package/templates/retail-store/tier5-src/wix-spaces-app-language/index.ts +4 -2
- package/templates/retail-store-owner/config.ts +1 -1
- package/templates/retail-store-owner/dev/index.ts +247 -9
- package/templates/retail-store-owner/tier5-src/_shared/aria-attachments.ts +179 -0
- package/templates/retail-store-owner/tier5-src/_shared/aria-chat.ts +405 -20
- package/templates/retail-store-owner/tier5-src/_shared/collection-contract.ts +4 -1
- package/templates/retail-store-owner/tier5-src/_shared/owner-bookings.ts +20 -0
- package/templates/retail-store-owner/tier5-src/_shared/owner-load-error.ts +7 -1
- package/templates/retail-store-owner/tier5-src/himi-owner-lite-aria/index.ts +40 -1
- package/templates/retail-store-owner/tier5-src/himi-owner-lite-home/index.ts +2 -12
- package/templates/retail-store-owner/tier5-src/himi-owner-lite-manage/index.ts +10 -4
- package/templates/yoga-studio/dev/index.ts +451 -204
- package/templates/yoga-studio/tier5-src/_shared/collection-contract.ts +4 -1
- package/templates/yoga-studio/tier5-src/_shared/owner-load-error.ts +7 -1
- package/templates/yoga-studio/tier5-src/himi-branded-lite-appearance/index.ts +12 -1
- package/templates/yoga-studio/tier5-src/wix-spaces-app-language/index.ts +4 -2
- package/templates/yoga-studio-owner/config.ts +1 -1
- package/templates/yoga-studio-owner/dev/index.ts +247 -9
- package/templates/yoga-studio-owner/tier5-src/_shared/aria-attachments.ts +179 -0
- package/templates/yoga-studio-owner/tier5-src/_shared/aria-chat.ts +405 -20
- package/templates/yoga-studio-owner/tier5-src/_shared/collection-contract.ts +4 -1
- package/templates/yoga-studio-owner/tier5-src/_shared/owner-bookings.ts +20 -0
- package/templates/yoga-studio-owner/tier5-src/_shared/owner-load-error.ts +7 -1
- package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-aria/index.ts +40 -1
- package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-home/index.ts +2 -12
- package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-manage/index.ts +10 -4
|
@@ -14,6 +14,9 @@ export interface CollectionConfig {
|
|
|
14
14
|
searchPlaceholder?: string;
|
|
15
15
|
sortLabels?: { default: string; az: string; za: string };
|
|
16
16
|
metadata?: string[];
|
|
17
|
+
/** Numeric 0–5 row field rendered as a Rating (accessible "N out of 5") instead of
|
|
18
|
+
* folding a "★★★★☆" glyph string into the metadata line, so screen readers get a value. */
|
|
19
|
+
rating?: string;
|
|
17
20
|
sectioned?: boolean;
|
|
18
21
|
view: 'list' | 'grid';
|
|
19
22
|
backendQuery?: boolean;
|
|
@@ -58,7 +61,7 @@ export const COLLECTIONS: Record<string, CollectionConfig> = {
|
|
|
58
61
|
himiBrandedCoupons: { rows: 'coupons', title: 'name', subtitle: 'subtitle', view: 'list', primaryVerb: { label: 'Get code' } },
|
|
59
62
|
himiBrandedNotifications: { rows: 'items', title: 'name', subtitle: 'subtitle', image: 'photo', metadata: ['unreadDot'], view: 'list' },
|
|
60
63
|
himiBrandedLoyalty: { rows: 'rewards', title: 'name', subtitle: 'description', view: 'grid', primaryVerb: { label: 'Redeem' } },
|
|
61
|
-
himiBrandedReviews: { rows: 'reviews', title: 'title', subtitle: 'body', metadata: ['author', '
|
|
64
|
+
himiBrandedReviews: { rows: 'reviews', title: 'title', subtitle: 'body', metadata: ['author'], rating: 'rating', view: 'list' },
|
|
62
65
|
himiBrandedPortfolio: { rows: 'projects', title: 'title', subtitle: 'subtitle', image: 'image', view: 'grid', gridImageHeight: 180 },
|
|
63
66
|
himiBrandedInvoices: { rows: 'invoices', title: 'title', subtitle: 'subtitle', view: 'list' },
|
|
64
67
|
himiBrandedBadges: { rows: 'badges', title: 'name', subtitle: 'description', view: 'grid' },
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import { copyParam } from "./himi-copy.js";
|
|
2
2
|
|
|
3
|
-
/** Host-owned preview input. Absent on native and older hosts.
|
|
3
|
+
/** Host-owned preview input. Absent on native and older hosts.
|
|
4
|
+
*
|
|
5
|
+
* `"sample"` — the built-in demo records; `"live"` — the viewer's own business over the
|
|
6
|
+
* owner rung; `"fixtures"` — a DEV web host over a sealed hermetic gateway, where
|
|
7
|
+
* the dev fixtures are the sample data. `"fixtures"` is neither live nor demo, so a
|
|
8
|
+
* worker READS through the bridge as it does on a device; it is still a preview host
|
|
9
|
+
* (`isOwnerPreviewHost`), so failure copy may name the web preview. */
|
|
4
10
|
function ownerPreviewMode(): unknown {
|
|
5
11
|
return (globalThis as unknown as { himalaya?: { input?: Record<string, unknown> } }).himalaya?.input?.__himiOwnerPreview;
|
|
6
12
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { defineService } from "@himalaya/state";
|
|
2
2
|
import {
|
|
3
|
+
ACCENT_IDS,
|
|
3
4
|
ACCENT_KEY,
|
|
4
5
|
ACCENT_META,
|
|
5
6
|
DEFAULT_ACCENT,
|
|
@@ -29,6 +30,10 @@ interface State {
|
|
|
29
30
|
accentHex_sage: string;
|
|
30
31
|
accentHex_plum: string;
|
|
31
32
|
accentHex_ocean: string;
|
|
33
|
+
// Per-accent selection flags for the radio group (`selected_<id>`) and the
|
|
34
|
+
// check mark on the swatch (`notSelected_<id>`, hiddenWhen hides on TRUE). Flat
|
|
35
|
+
// fields for the same reason as the hex ones: the swatches are static nodes.
|
|
36
|
+
[flag: `selected_${string}` | `notSelected_${string}`]: boolean | string;
|
|
32
37
|
}
|
|
33
38
|
|
|
34
39
|
interface StorageLike {
|
|
@@ -50,7 +55,13 @@ function paramValue(arg: unknown, key: string): string {
|
|
|
50
55
|
}
|
|
51
56
|
|
|
52
57
|
function build(pendingAccent: string, brandAccent: string): State {
|
|
58
|
+
const flags: Record<string, boolean> = {};
|
|
59
|
+
for (const id of ACCENT_IDS) {
|
|
60
|
+
flags[`selected_${id}`] = id === pendingAccent;
|
|
61
|
+
flags[`notSelected_${id}`] = id !== pendingAccent;
|
|
62
|
+
}
|
|
53
63
|
return {
|
|
64
|
+
...flags,
|
|
54
65
|
pendingAccent,
|
|
55
66
|
brandAccent,
|
|
56
67
|
accentHex_brand: brandAccent || ACCENT_META.amber.hex,
|
|
@@ -85,7 +96,7 @@ const svc = defineService<State, {
|
|
|
85
96
|
selectAccent: (state, arg) => {
|
|
86
97
|
const id = paramValue(arg, "id");
|
|
87
98
|
if (!isAccentId(id)) return state;
|
|
88
|
-
return
|
|
99
|
+
return build(id, state.brandAccent);
|
|
89
100
|
},
|
|
90
101
|
// Apply: persist the accent; the home worker re-reads it on launch.
|
|
91
102
|
apply: (state) => {
|
|
@@ -5,11 +5,12 @@
|
|
|
5
5
|
import { defineService } from "@himalaya/state";
|
|
6
6
|
import { dispatch } from "@himalaya/dispatch";
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
/** `selected` drives the row's radio; `subtitle` stays for older descriptors. */
|
|
9
|
+
interface Row { id: string; name: string; subtitle: string; selected: boolean }
|
|
9
10
|
interface S { status: "ready"; options: Row[] }
|
|
10
11
|
|
|
11
12
|
/** Locales with catalogs (`tools/l10n/catalog.<tag>.json`) + LocaleStore support. */
|
|
12
|
-
const LOCALE_OPTIONS: Omit<Row, "subtitle">[] = [
|
|
13
|
+
const LOCALE_OPTIONS: Omit<Row, "subtitle" | "selected">[] = [
|
|
13
14
|
{ id: "en", name: "English" },
|
|
14
15
|
{ id: "es", name: "Español" },
|
|
15
16
|
{ id: "he", name: "עברית" },
|
|
@@ -19,6 +20,7 @@ function withSelected(selected: string): Row[] {
|
|
|
19
20
|
return LOCALE_OPTIONS.map((o) => ({
|
|
20
21
|
...o,
|
|
21
22
|
subtitle: o.id === selected ? "Selected" : "",
|
|
23
|
+
selected: o.id === selected,
|
|
22
24
|
}));
|
|
23
25
|
}
|
|
24
26
|
|
|
@@ -37,7 +37,7 @@ export default defineApp({
|
|
|
37
37
|
actions: "http://localhost:8190/v1/actions",
|
|
38
38
|
sync: "http://localhost:8190/v1/sync",
|
|
39
39
|
},
|
|
40
|
-
capabilities: ["live_activity","push","share","secure_storage","open_url","local_database","clipboard","ui"],
|
|
40
|
+
capabilities: ["live_activity","push","share","secure_storage","open_url","local_database","clipboard","ui","camera","presigned_upload"],
|
|
41
41
|
designTokensPath: "./tokens.json",
|
|
42
42
|
navigation: {
|
|
43
43
|
"navKind": "responsive",
|
|
@@ -50090,7 +50090,7 @@ const SCREENS = runtimeSetting({
|
|
|
50090
50090
|
"itemsPath": "$service:himiOwnerLiteManage.recents",
|
|
50091
50091
|
"items": [
|
|
50092
50092
|
{
|
|
50093
|
-
"id": "",
|
|
50093
|
+
"id": "himi_owner_lite.manage.recent.$item.id",
|
|
50094
50094
|
"body": {
|
|
50095
50095
|
"package": "himalaya",
|
|
50096
50096
|
"type": "VStack",
|
|
@@ -50235,7 +50235,7 @@ const SCREENS = runtimeSetting({
|
|
|
50235
50235
|
"spacing": 14,
|
|
50236
50236
|
"children": [
|
|
50237
50237
|
{
|
|
50238
|
-
"id": "",
|
|
50238
|
+
"id": "himi_owner_lite.manage.recent.create.$item.id",
|
|
50239
50239
|
"body": {
|
|
50240
50240
|
"package": "himalaya",
|
|
50241
50241
|
"type": "Text",
|
|
@@ -50260,7 +50260,7 @@ const SCREENS = runtimeSetting({
|
|
|
50260
50260
|
}
|
|
50261
50261
|
},
|
|
50262
50262
|
{
|
|
50263
|
-
"id": "",
|
|
50263
|
+
"id": "himi_owner_lite.manage.recent.handoff.$item.id",
|
|
50264
50264
|
"body": {
|
|
50265
50265
|
"package": "himalaya",
|
|
50266
50266
|
"type": "Text",
|
|
@@ -50396,7 +50396,7 @@ const SCREENS = runtimeSetting({
|
|
|
50396
50396
|
"itemsPath": "$item.areas",
|
|
50397
50397
|
"items": [
|
|
50398
50398
|
{
|
|
50399
|
-
"id": "",
|
|
50399
|
+
"id": "himi_owner_lite.manage.area.$item.id",
|
|
50400
50400
|
"body": {
|
|
50401
50401
|
"package": "himalaya",
|
|
50402
50402
|
"type": "VStack",
|
|
@@ -50541,7 +50541,7 @@ const SCREENS = runtimeSetting({
|
|
|
50541
50541
|
"spacing": 14,
|
|
50542
50542
|
"children": [
|
|
50543
50543
|
{
|
|
50544
|
-
"id": "",
|
|
50544
|
+
"id": "himi_owner_lite.manage.area.create.$item.id",
|
|
50545
50545
|
"body": {
|
|
50546
50546
|
"package": "himalaya",
|
|
50547
50547
|
"type": "Text",
|
|
@@ -50566,7 +50566,7 @@ const SCREENS = runtimeSetting({
|
|
|
50566
50566
|
}
|
|
50567
50567
|
},
|
|
50568
50568
|
{
|
|
50569
|
-
"id": "",
|
|
50569
|
+
"id": "himi_owner_lite.manage.area.handoff.$item.id",
|
|
50570
50570
|
"body": {
|
|
50571
50571
|
"package": "himalaya",
|
|
50572
50572
|
"type": "Text",
|
|
@@ -51346,7 +51346,7 @@ const SCREENS = runtimeSetting({
|
|
|
51346
51346
|
"props": {
|
|
51347
51347
|
"items": [
|
|
51348
51348
|
{
|
|
51349
|
-
"id": "",
|
|
51349
|
+
"id": "ol_drawer_nav.$item.id",
|
|
51350
51350
|
"body": {
|
|
51351
51351
|
"package": "himalaya",
|
|
51352
51352
|
"type": "ListItem",
|
|
@@ -51398,7 +51398,7 @@ const SCREENS = runtimeSetting({
|
|
|
51398
51398
|
"props": {
|
|
51399
51399
|
"items": [
|
|
51400
51400
|
{
|
|
51401
|
-
"id": "",
|
|
51401
|
+
"id": "ol_drawer_attention.$item.id",
|
|
51402
51402
|
"body": {
|
|
51403
51403
|
"package": "himalaya",
|
|
51404
51404
|
"type": "ListItem",
|
|
@@ -54959,6 +54959,45 @@ const SCREENS = runtimeSetting({
|
|
|
54959
54959
|
}
|
|
54960
54960
|
}
|
|
54961
54961
|
},
|
|
54962
|
+
{
|
|
54963
|
+
"id": "himi_owner_lite_aria.msg_attach_$item.id",
|
|
54964
|
+
"body": {
|
|
54965
|
+
"package": "himalaya",
|
|
54966
|
+
"type": "HStack",
|
|
54967
|
+
"props": {
|
|
54968
|
+
"spacing": 0,
|
|
54969
|
+
"children": [
|
|
54970
|
+
{
|
|
54971
|
+
"id": "",
|
|
54972
|
+
"body": {
|
|
54973
|
+
"package": "himalaya",
|
|
54974
|
+
"type": "Spacer",
|
|
54975
|
+
"props": {}
|
|
54976
|
+
},
|
|
54977
|
+
"modifiers": {
|
|
54978
|
+
"hiddenPath": "$item.notUser"
|
|
54979
|
+
}
|
|
54980
|
+
},
|
|
54981
|
+
{
|
|
54982
|
+
"id": "",
|
|
54983
|
+
"body": {
|
|
54984
|
+
"package": "himalaya",
|
|
54985
|
+
"type": "Text",
|
|
54986
|
+
"props": {
|
|
54987
|
+
"text": "$item.attachText",
|
|
54988
|
+
"style": "footnote",
|
|
54989
|
+
"color": "textSecondary",
|
|
54990
|
+
"maxLines": 3
|
|
54991
|
+
}
|
|
54992
|
+
}
|
|
54993
|
+
}
|
|
54994
|
+
]
|
|
54995
|
+
}
|
|
54996
|
+
},
|
|
54997
|
+
"modifiers": {
|
|
54998
|
+
"hiddenPath": "$item.attachHidden"
|
|
54999
|
+
}
|
|
55000
|
+
},
|
|
54962
55001
|
{
|
|
54963
55002
|
"id": "himi_owner_lite_aria.msg_$item.id.link1",
|
|
54964
55003
|
"body": {
|
|
@@ -58539,6 +58578,203 @@ const SCREENS = runtimeSetting({
|
|
|
58539
58578
|
}
|
|
58540
58579
|
}
|
|
58541
58580
|
},
|
|
58581
|
+
{
|
|
58582
|
+
"id": "himi_owner_lite_aria.attachments.bound",
|
|
58583
|
+
"body": {
|
|
58584
|
+
"package": "himalaya",
|
|
58585
|
+
"type": "LazyList",
|
|
58586
|
+
"props": {
|
|
58587
|
+
"itemsPath": "$service:himiOwnerLiteAria.attachments",
|
|
58588
|
+
"horizontal": true,
|
|
58589
|
+
"spacing": 8,
|
|
58590
|
+
"items": [
|
|
58591
|
+
{
|
|
58592
|
+
"id": "himi_owner_lite_aria.attachment_$item.id",
|
|
58593
|
+
"body": {
|
|
58594
|
+
"package": "himalaya",
|
|
58595
|
+
"type": "VStack",
|
|
58596
|
+
"props": {
|
|
58597
|
+
"spacing": 4,
|
|
58598
|
+
"children": [
|
|
58599
|
+
{
|
|
58600
|
+
"id": "himi_owner_lite_aria.attachment_thumb_$item.id",
|
|
58601
|
+
"body": {
|
|
58602
|
+
"package": "himalaya",
|
|
58603
|
+
"type": "Image",
|
|
58604
|
+
"props": {
|
|
58605
|
+
"url": "$item.thumbUrl",
|
|
58606
|
+
"width": 72,
|
|
58607
|
+
"height": 72,
|
|
58608
|
+
"contentMode": "fill",
|
|
58609
|
+
"shape": "rounded",
|
|
58610
|
+
"contentDescription": "$item.name"
|
|
58611
|
+
}
|
|
58612
|
+
},
|
|
58613
|
+
"modifiers": {
|
|
58614
|
+
"hiddenPath": "$item.thumbHidden"
|
|
58615
|
+
}
|
|
58616
|
+
},
|
|
58617
|
+
{
|
|
58618
|
+
"id": "",
|
|
58619
|
+
"body": {
|
|
58620
|
+
"package": "himalaya",
|
|
58621
|
+
"type": "Text",
|
|
58622
|
+
"props": {
|
|
58623
|
+
"text": "$item.statusText",
|
|
58624
|
+
"style": "caption",
|
|
58625
|
+
"color": "textSecondary",
|
|
58626
|
+
"maxLines": 2
|
|
58627
|
+
}
|
|
58628
|
+
},
|
|
58629
|
+
"modifiers": {
|
|
58630
|
+
"hiddenPath": "$item.statusHidden"
|
|
58631
|
+
}
|
|
58632
|
+
},
|
|
58633
|
+
{
|
|
58634
|
+
"id": "",
|
|
58635
|
+
"body": {
|
|
58636
|
+
"package": "himalaya",
|
|
58637
|
+
"type": "HStack",
|
|
58638
|
+
"props": {
|
|
58639
|
+
"spacing": 8,
|
|
58640
|
+
"children": [
|
|
58641
|
+
{
|
|
58642
|
+
"id": "himi_owner_lite_aria.attachment_retry_$item.id",
|
|
58643
|
+
"body": {
|
|
58644
|
+
"package": "himalaya",
|
|
58645
|
+
"type": "Text",
|
|
58646
|
+
"props": {
|
|
58647
|
+
"text": "Retry",
|
|
58648
|
+
"style": "caption",
|
|
58649
|
+
"color": "accentPrimary",
|
|
58650
|
+
"maxLines": 1
|
|
58651
|
+
}
|
|
58652
|
+
},
|
|
58653
|
+
"modifiers": {
|
|
58654
|
+
"onTap": {
|
|
58655
|
+
"actionId": "tier5.himiOwnerLiteAria.retryAttachment",
|
|
58656
|
+
"params": {
|
|
58657
|
+
"id": "$item.id"
|
|
58658
|
+
}
|
|
58659
|
+
},
|
|
58660
|
+
"hiddenPath": "$item.retryHidden"
|
|
58661
|
+
}
|
|
58662
|
+
},
|
|
58663
|
+
{
|
|
58664
|
+
"id": "himi_owner_lite_aria.attachment_remove_$item.id",
|
|
58665
|
+
"body": {
|
|
58666
|
+
"package": "himalaya",
|
|
58667
|
+
"type": "Icon",
|
|
58668
|
+
"props": {
|
|
58669
|
+
"name": "close",
|
|
58670
|
+
"size": 14,
|
|
58671
|
+
"tint": "textSecondary"
|
|
58672
|
+
}
|
|
58673
|
+
},
|
|
58674
|
+
"modifiers": {
|
|
58675
|
+
"onTap": {
|
|
58676
|
+
"actionId": "tier5.himiOwnerLiteAria.removeAttachment",
|
|
58677
|
+
"params": {
|
|
58678
|
+
"id": "$item.id"
|
|
58679
|
+
}
|
|
58680
|
+
},
|
|
58681
|
+
"accessibilityLabel": "Remove photo"
|
|
58682
|
+
}
|
|
58683
|
+
}
|
|
58684
|
+
]
|
|
58685
|
+
}
|
|
58686
|
+
}
|
|
58687
|
+
}
|
|
58688
|
+
]
|
|
58689
|
+
}
|
|
58690
|
+
},
|
|
58691
|
+
"modifiers": {
|
|
58692
|
+
"width": 72
|
|
58693
|
+
}
|
|
58694
|
+
}
|
|
58695
|
+
]
|
|
58696
|
+
}
|
|
58697
|
+
},
|
|
58698
|
+
"modifiers": {
|
|
58699
|
+
"hiddenPath": "$service:himiOwnerLiteAria.attachmentsHidden",
|
|
58700
|
+
"padding": {
|
|
58701
|
+
"leading": 0,
|
|
58702
|
+
"trailing": 0,
|
|
58703
|
+
"top": 8,
|
|
58704
|
+
"bottom": 0
|
|
58705
|
+
}
|
|
58706
|
+
}
|
|
58707
|
+
},
|
|
58708
|
+
{
|
|
58709
|
+
"id": "",
|
|
58710
|
+
"body": {
|
|
58711
|
+
"package": "himalaya",
|
|
58712
|
+
"type": "HStack",
|
|
58713
|
+
"props": {
|
|
58714
|
+
"spacing": 16,
|
|
58715
|
+
"children": [
|
|
58716
|
+
{
|
|
58717
|
+
"id": "himi_owner_lite_aria.attach.library",
|
|
58718
|
+
"body": {
|
|
58719
|
+
"package": "himalaya",
|
|
58720
|
+
"type": "Icon",
|
|
58721
|
+
"props": {
|
|
58722
|
+
"name": "image",
|
|
58723
|
+
"size": 22,
|
|
58724
|
+
"tint": "accentPrimary"
|
|
58725
|
+
}
|
|
58726
|
+
},
|
|
58727
|
+
"modifiers": {
|
|
58728
|
+
"onTap": {
|
|
58729
|
+
"actionId": "tier5.himiOwnerLiteAria.attach",
|
|
58730
|
+
"params": {
|
|
58731
|
+
"source": "library"
|
|
58732
|
+
}
|
|
58733
|
+
},
|
|
58734
|
+
"accessibilityLabel": "Add a photo"
|
|
58735
|
+
}
|
|
58736
|
+
},
|
|
58737
|
+
{
|
|
58738
|
+
"id": "himi_owner_lite_aria.attach.camera",
|
|
58739
|
+
"body": {
|
|
58740
|
+
"package": "himalaya",
|
|
58741
|
+
"type": "Icon",
|
|
58742
|
+
"props": {
|
|
58743
|
+
"name": "camera",
|
|
58744
|
+
"size": 22,
|
|
58745
|
+
"tint": "accentPrimary"
|
|
58746
|
+
}
|
|
58747
|
+
},
|
|
58748
|
+
"modifiers": {
|
|
58749
|
+
"onTap": {
|
|
58750
|
+
"actionId": "tier5.himiOwnerLiteAria.attach",
|
|
58751
|
+
"params": {
|
|
58752
|
+
"source": "camera"
|
|
58753
|
+
}
|
|
58754
|
+
},
|
|
58755
|
+
"accessibilityLabel": "Take a photo"
|
|
58756
|
+
}
|
|
58757
|
+
},
|
|
58758
|
+
{
|
|
58759
|
+
"id": "",
|
|
58760
|
+
"body": {
|
|
58761
|
+
"package": "himalaya",
|
|
58762
|
+
"type": "Spacer",
|
|
58763
|
+
"props": {}
|
|
58764
|
+
}
|
|
58765
|
+
}
|
|
58766
|
+
]
|
|
58767
|
+
}
|
|
58768
|
+
},
|
|
58769
|
+
"modifiers": {
|
|
58770
|
+
"padding": {
|
|
58771
|
+
"leading": 0,
|
|
58772
|
+
"trailing": 0,
|
|
58773
|
+
"top": 8,
|
|
58774
|
+
"bottom": 0
|
|
58775
|
+
}
|
|
58776
|
+
}
|
|
58777
|
+
},
|
|
58542
58778
|
{
|
|
58543
58779
|
"id": "form_aria",
|
|
58544
58780
|
"body": {
|
|
@@ -58624,7 +58860,9 @@ const SCREENS = runtimeSetting({
|
|
|
58624
58860
|
"wix_api",
|
|
58625
58861
|
"open_url",
|
|
58626
58862
|
"clipboard",
|
|
58627
|
-
"ui"
|
|
58863
|
+
"ui",
|
|
58864
|
+
"camera",
|
|
58865
|
+
"presigned_upload"
|
|
58628
58866
|
],
|
|
58629
58867
|
"minBinaryVersion": "0.1.0",
|
|
58630
58868
|
"bundleVersion": "0.0.1"
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
// Photo attachments for the Aria composer — the pure half.
|
|
2
|
+
//
|
|
3
|
+
// Everything here is a decision that can be made without touching the device
|
|
4
|
+
// or the network: which files may be attached, how many, how large, what a chip
|
|
5
|
+
// in the composer says in each of its three states, and how a picked image is
|
|
6
|
+
// turned into the bytes an upload sends. The half that DOES touch the world —
|
|
7
|
+
// minting the upload, sending the bytes, picking — lives in `aria-chat.ts`
|
|
8
|
+
// (the mint, through `@himalaya/wix-genie-chat`) and in each app's adapter (the
|
|
9
|
+
// picker and the byte transfer, which are device capabilities the adapter's
|
|
10
|
+
// screen has to declare).
|
|
11
|
+
//
|
|
12
|
+
// This file is copied verbatim into every generated starter app, so it explains
|
|
13
|
+
// itself without pointing at anything only this repo has.
|
|
14
|
+
|
|
15
|
+
/** Image types the composer accepts. The first-party clients' own allowlist
|
|
16
|
+
* for images: png, jpeg (and the non-standard `image/jpg` some pickers still
|
|
17
|
+
* report), webp, gif and heic. Anything else is REFUSED with a line saying so,
|
|
18
|
+
* never silently dropped — the native Aria app drops unsupported files without a
|
|
19
|
+
* word, and an owner who picked something and sees nothing happen assumes the
|
|
20
|
+
* button is broken. */
|
|
21
|
+
export const ARIA_IMAGE_TYPES: readonly string[] = [
|
|
22
|
+
"image/png",
|
|
23
|
+
"image/jpeg",
|
|
24
|
+
"image/jpg",
|
|
25
|
+
"image/webp",
|
|
26
|
+
"image/gif",
|
|
27
|
+
"image/heic",
|
|
28
|
+
];
|
|
29
|
+
|
|
30
|
+
/** At most this many attachments ride one message. The native Aria app caps at
|
|
31
|
+
* 10; nothing on the wire says otherwise. */
|
|
32
|
+
export const ARIA_MAX_ATTACHMENTS = 10;
|
|
33
|
+
|
|
34
|
+
/** The largest image the composer will try to send, in bytes.
|
|
35
|
+
*
|
|
36
|
+
* Not a product choice: it is the ceiling of the transfer this slice uses. A
|
|
37
|
+
* picked photo crosses the worker bridge as a base64 string and is sent inline,
|
|
38
|
+
* and the inline upload refuses anything over 8 MiB (the `MAX_INLINE_BASE64_BYTES`
|
|
39
|
+
* bound of the pre-signed upload capability, which it enforces on every arm).
|
|
40
|
+
* Checking it HERE is what turns that refusal into a sentence the owner can act
|
|
41
|
+
* on, instead of a chip that fails for no stated reason. */
|
|
42
|
+
export const ARIA_MAX_IMAGE_BYTES = 8 * 1024 * 1024;
|
|
43
|
+
|
|
44
|
+
/** A chip in the composer. Every field is always present — a `$item.` path that
|
|
45
|
+
* is missing on some rows does not substitute — and each `…Hidden` flag
|
|
46
|
+
* collapses the part it names. */
|
|
47
|
+
export interface AriaAttachmentChip {
|
|
48
|
+
/** Minted by the worker, never derived from the file. The native Aria app keyed
|
|
49
|
+
* concurrent uploads by file NAME and collided on the second `IMG_0001.jpg`. */
|
|
50
|
+
id: string;
|
|
51
|
+
name: string;
|
|
52
|
+
mimeType: string;
|
|
53
|
+
state: "uploading" | "ready" | "failed";
|
|
54
|
+
/** The chip's thumbnail as a `data:` URI, set only when the picked image is
|
|
55
|
+
* small; "" otherwise, which collapses the preview. The full bytes an upload
|
|
56
|
+
* and a retry send are held by the worker, never in the chip, because the chip
|
|
57
|
+
* rides the service state and a large photo there would exceed the web
|
|
58
|
+
* runtime's frame limit. */
|
|
59
|
+
thumbUrl: string;
|
|
60
|
+
thumbHidden: boolean;
|
|
61
|
+
/** "Uploading…" / "Couldn't upload" / "" — collapses when empty. */
|
|
62
|
+
statusText: string;
|
|
63
|
+
statusHidden: boolean;
|
|
64
|
+
/** The retry control shows ONLY on a failed chip. */
|
|
65
|
+
retryHidden: boolean;
|
|
66
|
+
/** `genie-upload://<id>` once the bytes have landed; "" until then. The send
|
|
67
|
+
* carries a chip only when this is set. */
|
|
68
|
+
ref: string;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/** What an upload reports back, delivered as a fresh action so it lands on the
|
|
72
|
+
* CURRENT state rather than on the snapshot the upload started from. */
|
|
73
|
+
export interface AriaAttachmentOutcome {
|
|
74
|
+
id: string;
|
|
75
|
+
ok: boolean;
|
|
76
|
+
/** Set when `ok`. */
|
|
77
|
+
ref?: string;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export interface ParsedDataUri { mimeType: string; base64: string; bytes: number }
|
|
81
|
+
|
|
82
|
+
/** `data:<mime>;base64,<payload>` → its parts, or null for anything else.
|
|
83
|
+
*
|
|
84
|
+
* Only the base64 form: every picker this composer is wired to returns it, and
|
|
85
|
+
* a percent-encoded `data:` URI would need decoding the bridge cannot do. The
|
|
86
|
+
* byte count is computed from the payload length, so a multi-megabyte photo is
|
|
87
|
+
* sized without being decoded. */
|
|
88
|
+
export function parseDataUri(uri: string): ParsedDataUri | null {
|
|
89
|
+
const m = /^data:([^;,]*)((?:;[^;,]*)*?);base64,/i.exec(uri ?? "");
|
|
90
|
+
if (!m) return null;
|
|
91
|
+
const base64 = uri.slice(m[0].length).replace(/\s+/g, "");
|
|
92
|
+
const pad = base64.endsWith("==") ? 2 : base64.endsWith("=") ? 1 : 0;
|
|
93
|
+
const bytes = Math.max(0, Math.floor((base64.length * 3) / 4) - pad);
|
|
94
|
+
return { mimeType: (m[1] || "").trim().toLowerCase(), base64, bytes };
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/** Normalize a MIME type a picker reported.
|
|
98
|
+
*
|
|
99
|
+
* Some pickers hand back a platform type identifier where a MIME type belongs
|
|
100
|
+
* (`public.jpeg`, `public.heic`), and the service validates the field as a MIME
|
|
101
|
+
* type. Mapped for the image identifiers this composer accepts; anything else
|
|
102
|
+
* is returned lowercased and left for the allowlist to judge. */
|
|
103
|
+
export function normalizeMime(mime: string): string {
|
|
104
|
+
const v = (mime ?? "").trim().toLowerCase();
|
|
105
|
+
switch (v) {
|
|
106
|
+
case "public.jpeg": return "image/jpeg";
|
|
107
|
+
case "public.png": return "image/png";
|
|
108
|
+
case "public.heic": return "image/heic";
|
|
109
|
+
case "com.compuserve.gif": return "image/gif";
|
|
110
|
+
case "org.webmproject.webp": return "image/webp";
|
|
111
|
+
case "image/jpg": return "image/jpeg";
|
|
112
|
+
default: return v;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/** A file name for an image the picker did not name, by type. The service
|
|
117
|
+
* requires one (1–255 characters), and it is what the transcript shows. */
|
|
118
|
+
export function imageFileName(mimeType: string, n: number, given?: string): string {
|
|
119
|
+
const name = (given ?? "").trim();
|
|
120
|
+
if (name) return name.slice(0, 255);
|
|
121
|
+
const ext = mimeType === "image/png" ? "png"
|
|
122
|
+
: mimeType === "image/webp" ? "webp"
|
|
123
|
+
: mimeType === "image/gif" ? "gif"
|
|
124
|
+
: mimeType === "image/heic" ? "heic"
|
|
125
|
+
: "jpg";
|
|
126
|
+
return `photo-${n}.${ext}`;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/** Why a picked file cannot be attached, or "" when it can. */
|
|
130
|
+
export type AttachRefusal = "" | "type" | "size" | "count";
|
|
131
|
+
|
|
132
|
+
export function refusalFor(parsed: ParsedDataUri | null, mimeType: string, attached: number): AttachRefusal {
|
|
133
|
+
if (attached >= ARIA_MAX_ATTACHMENTS) return "count";
|
|
134
|
+
if (!parsed || !ARIA_IMAGE_TYPES.includes(mimeType)) return "type";
|
|
135
|
+
if (parsed.bytes > ARIA_MAX_IMAGE_BYTES) return "size";
|
|
136
|
+
return "";
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/** A chip in a given state. One constructor so the flags can never disagree
|
|
140
|
+
* with the state they describe — a failed chip without its retry control is
|
|
141
|
+
* the shape of bug this rules out. */
|
|
142
|
+
export function chipIn(
|
|
143
|
+
base: Pick<AriaAttachmentChip, "id" | "name" | "mimeType" | "thumbUrl">,
|
|
144
|
+
state: AriaAttachmentChip["state"],
|
|
145
|
+
labels: { uploading: string; failed: string },
|
|
146
|
+
ref = "",
|
|
147
|
+
): AriaAttachmentChip {
|
|
148
|
+
const statusText = state === "uploading" ? labels.uploading : state === "failed" ? labels.failed : "";
|
|
149
|
+
return {
|
|
150
|
+
...base,
|
|
151
|
+
state,
|
|
152
|
+
thumbHidden: !base.thumbUrl,
|
|
153
|
+
statusText,
|
|
154
|
+
statusHidden: !statusText,
|
|
155
|
+
retryHidden: state !== "failed",
|
|
156
|
+
ref: state === "ready" ? ref : "",
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/** Why Send is refused while attachments are pending, or "" when it is not.
|
|
161
|
+
*
|
|
162
|
+
* An upload still running would be dropped from the message, and a failed one
|
|
163
|
+
* would be sent as if the owner had never picked it — in both cases the
|
|
164
|
+
* assistant answers about a photo it never received. So the send waits, and
|
|
165
|
+
* says what it is waiting for. */
|
|
166
|
+
export function sendBlocker(chips: readonly AriaAttachmentChip[]): "" | "uploading" | "failed" {
|
|
167
|
+
if (chips.some((c) => c.state === "uploading")) return "uploading";
|
|
168
|
+
if (chips.some((c) => c.state === "failed")) return "failed";
|
|
169
|
+
return "";
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/** The one line a bubble shows for its attachments: a paperclip and the file
|
|
173
|
+
* names. Text, not thumbnails, and not by choice: a `genie-upload://`
|
|
174
|
+
* reference has no published download url, so a sent photo cannot be shown
|
|
175
|
+
* again from the server's copy — and a resumed conversation has nothing else. */
|
|
176
|
+
export function attachmentLine(names: readonly string[]): string {
|
|
177
|
+
const shown = names.map((n) => n.trim()).filter(Boolean);
|
|
178
|
+
return shown.length ? `📎 ${shown.join(", ")}` : "";
|
|
179
|
+
}
|