pi-roundtable-web 0.26.2 → 0.26.3
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/CHANGELOG.md +13 -0
- package/README.md +16 -1
- package/dist/chunk-account-hck7mhf8.js +1 -0
- package/dist/{chunk-action-menu-ec9jqtxq.js → chunk-action-menu-beqh40k6.js} +1 -1
- package/dist/chunk-agent-znnth24t.js +1 -0
- package/dist/chunk-arranged-rooms-wfakrddk.js +1 -0
- package/dist/chunk-bulk-actions-c4tkvk9g.js +1 -0
- package/dist/chunk-character-creator-qwcsdytw.js +1 -0
- package/dist/{chunk-codeeditor-jm2sm333.js → chunk-codeeditor-6xavqntt.js} +2 -2
- package/dist/chunk-confirm-z95j9jt3.js +1 -0
- package/dist/{chunk-connectors-mhnw6d79.js → chunk-connectors-7xqsg5q5.js} +1 -1
- package/dist/{chunk-conversations-yjyq4g1y.js → chunk-conversations-zc4mv6vj.js} +1 -1
- package/dist/{chunk-drag-nyq52ck7.js → chunk-drag-0mefcvp3.js} +1 -1
- package/dist/{chunk-entry-red1597w.js → chunk-entry-hrt97qed.js} +1 -1
- package/dist/chunk-folder-list-nemtqbnc.js +1 -0
- package/dist/chunk-folds-xpg9qcwf.js +1 -0
- package/dist/chunk-gate-86r8a2vf.js +1 -0
- package/dist/chunk-group-scene-g24kxz6f.js +1 -0
- package/dist/chunk-group-table-851jm8ef.js +1 -0
- package/dist/chunk-host-icons-23zhqpmc.js +1 -0
- package/dist/chunk-host-picture-8tnh2wam.js +1 -0
- package/dist/chunk-host-state-j41sp065.js +1 -0
- package/dist/chunk-host-ui-cje7a9t9.js +1 -0
- package/dist/chunk-index-1fn8q4ps.js +2 -0
- package/dist/{chunk-index-kfv996qe.js → chunk-index-30vw4nhh.js} +35 -3
- package/dist/{chunk-index-tmx30r1w.js → chunk-index-3aa5czxj.js} +2 -2
- package/dist/chunk-index-3k7sdph2.js +1 -0
- package/dist/{chunk-index-7bbqtdce.js → chunk-index-3wbyq10m.js} +2 -2
- package/dist/{chunk-index-9nents16.js → chunk-index-47yspxa4.js} +2 -2
- package/dist/chunk-index-4s1qj9we.js +2 -0
- package/dist/chunk-index-5fz5e1ct.js +2 -0
- package/dist/{chunk-index-kw85ajap.js → chunk-index-67p2sc14.js} +3 -3
- package/dist/{chunk-index-0xj30mzw.js → chunk-index-6c8mewwy.js} +12 -12
- package/dist/{chunk-index-934zgd18.js → chunk-index-84wbc80d.js} +2 -2
- package/dist/{chunk-index-y00wke93.js → chunk-index-8eexybcx.js} +2 -2
- package/dist/{chunk-index-1f0j335v.js → chunk-index-agrvqf5b.js} +2 -2
- package/dist/chunk-index-azrnzgev.js +2 -0
- package/dist/chunk-index-c2ag3qw2.js +2 -0
- package/dist/chunk-index-e90kztkx.js +4 -0
- package/dist/chunk-index-efgm0066.js +2 -0
- package/dist/{chunk-index-b7jjca66.js → chunk-index-eh0wb6g0.js} +2 -2
- package/dist/{chunk-index-yrhbhmxz.js → chunk-index-eyc2rkq5.js} +2 -2
- package/dist/{chunk-index-datrrs6b.js → chunk-index-fe0m5mht.js} +2 -2
- package/dist/{chunk-index-f3b5nch2.js → chunk-index-gt42wjby.js} +3 -3
- package/dist/{chunk-index-6tpr6r6d.js → chunk-index-hc0dgmrs.js} +2 -2
- package/dist/{chunk-index-0n6ja7my.js → chunk-index-hczrjnky.js} +1 -1
- package/dist/chunk-index-hrtyanda.js +2 -0
- package/dist/chunk-index-j479p62w.js +2 -0
- package/dist/{chunk-index-cmxs5y22.js → chunk-index-jq970hsd.js} +3 -3
- package/dist/chunk-index-kankja6p.js +50 -0
- package/dist/chunk-index-kb44jp50.js +2 -0
- package/dist/{chunk-index-029209sy.js → chunk-index-m65cv329.js} +2 -2
- package/dist/chunk-index-mnwdbb4n.js +2 -0
- package/dist/chunk-index-n6zrc05a.js +2 -0
- package/dist/chunk-index-n93wqszt.js +8 -0
- package/dist/{chunk-index-43k1rjmx.js → chunk-index-nrexxkar.js} +2 -2
- package/dist/chunk-index-pgxgq61x.js +2 -0
- package/dist/chunk-index-q5vzjqr5.js +2 -0
- package/dist/chunk-index-qqwk157d.js +2 -0
- package/dist/{chunk-index-ewj52be9.js → chunk-index-r1v895tj.js} +2 -2
- package/dist/chunk-index-r3tqhew8.js +2 -0
- package/dist/chunk-index-raf772z6.js +2 -0
- package/dist/{chunk-index-smw1n2pt.js → chunk-index-rcxz5w5d.js} +5 -5
- package/dist/chunk-index-rg9vh59e.js +1 -0
- package/dist/chunk-index-sxq69p1f.js +2 -0
- package/dist/chunk-index-taq2psr6.js +2 -0
- package/dist/{chunk-index-frwa2fmc.js → chunk-index-tsxsy4qs.js} +2 -2
- package/dist/chunk-index-wc83vb0a.js +2 -0
- package/dist/chunk-index-xbs8q4kn.js +2 -0
- package/dist/chunk-index-xxbveevc.js +2 -0
- package/dist/chunk-index-zx6yka30.js +2 -0
- package/dist/chunk-lang-css-yrc25qk9.js +1 -0
- package/dist/{chunk-lang-dockerfile-46rk929v.js → chunk-lang-dockerfile-tjxsnhr9.js} +1 -1
- package/dist/{chunk-lang-go-qb0qdpg7.js → chunk-lang-go-drmfa25k.js} +3 -3
- package/dist/chunk-lang-html-rwe8epvf.js +1 -0
- package/dist/chunk-lang-javascript-d6x6qjtg.js +1 -0
- package/dist/{chunk-lang-json-1q4fp694.js → chunk-lang-json-790swysy.js} +1 -1
- package/dist/{chunk-lang-markdown-5w7t28wa.js → chunk-lang-markdown-483dkxcq.js} +5 -5
- package/dist/{chunk-lang-python-3dq0p4rf.js → chunk-lang-python-v9s40bzj.js} +2 -2
- package/dist/{chunk-lang-rust-70pa0agr.js → chunk-lang-rust-z4gry1bf.js} +1 -1
- package/dist/{chunk-lang-shell-4pxt7hf4.js → chunk-lang-shell-egsvk8rj.js} +1 -1
- package/dist/{chunk-lang-sql-kgcbh2a9.js → chunk-lang-sql-75j3denr.js} +2 -2
- package/dist/{chunk-lang-toml-99t95pab.js → chunk-lang-toml-7dbjvhex.js} +1 -1
- package/dist/chunk-lang-typescript-1rv9vdcz.js +1 -0
- package/dist/{chunk-lang-xml-mnbv9yfa.js → chunk-lang-xml-jg1sv4h2.js} +1 -1
- package/dist/{chunk-lang-yaml-2by9g1dy.js → chunk-lang-yaml-g3v7s5je.js} +1 -1
- package/dist/chunk-layout-actions-6assr93n.js +1 -0
- package/dist/chunk-menu-items-9szcza00.js +2 -0
- package/dist/chunk-mode-toggle-bzbq7ycq.js +1 -0
- package/dist/{chunk-note-row-72n6cqyk.js → chunk-note-row-g20h11pm.js} +2 -2
- package/dist/chunk-notes-gc8bssxn.js +1 -0
- package/dist/chunk-notice-bell-jehad6sx.js +1 -0
- package/dist/{chunk-notices-evny44be.js → chunk-notices-prqkv7ge.js} +1 -1
- package/dist/chunk-onboarding-mdtc2mb7.js +1 -0
- package/dist/{chunk-overview-42h45ehd.js → chunk-overview-2j1s6kqg.js} +1 -1
- package/dist/chunk-palette-4qt6ewem.js +1 -0
- package/dist/chunk-placement-items-2eect825.js +1 -0
- package/dist/{chunk-profile-bqcgkgk4.js → chunk-profile-pfzyc04p.js} +1 -1
- package/dist/chunk-prompt-history-2bcp2rky.js +1 -0
- package/dist/chunk-prompts-052mb05y.js +1 -0
- package/dist/chunk-room-confirms-asvmjh5s.js +1 -0
- package/dist/{chunk-room-menu-7s0feajw.js → chunk-room-menu-dm2r2hk6.js} +1 -1
- package/dist/chunk-rooms-menu-button-32hemzxc.js +1 -0
- package/dist/{chunk-schedules-zba7krac.js → chunk-schedules-64h9gfwn.js} +1 -1
- package/dist/{chunk-seat-menu-ca5p4e9q.js → chunk-seat-menu-vrpc40v9.js} +1 -1
- package/dist/chunk-sheet-hosts-jaqx490x.js +1 -0
- package/dist/chunk-shortcut-help-bdbkdcs9.js +26 -0
- package/dist/chunk-shortcuts-qft33r8t.js +1 -0
- package/dist/{chunk-skill-editor-n0y9pd90.js → chunk-skill-editor-z3dx2895.js} +2 -2
- package/dist/{chunk-skills-ea4vb2s4.js → chunk-skills-4jfcv39n.js} +1 -1
- package/dist/chunk-switcher-list-xysjd4tw.js +1 -0
- package/dist/{chunk-tab-dot-4tkpxqeh.js → chunk-tab-dot-1p68ybf8.js} +1 -1
- package/dist/chunk-table-0v4q4dx3.js +1 -0
- package/dist/{chunk-table-seats-qeytqe0m.js → chunk-table-seats-f683hx8k.js} +1 -1
- package/dist/{chunk-table2d-18y029k9.js → chunk-table2d-1a6atjhj.js} +1 -1
- package/dist/{chunk-table3d-q2s31ae0.js → chunk-table3d-k0ffeffj.js} +23 -23
- package/dist/chunk-thread-actions-4rpfg4fq.js +1 -0
- package/dist/chunk-thread-cards-t794fp4d.js +1 -0
- package/dist/chunk-thread-list-1pcygpka.js +1 -0
- package/dist/chunk-transcript-km4e3aey.js +1 -0
- package/dist/chunk-where-phjwqggy.js +1 -0
- package/dist/{chunk-workspace-h0p32ygy.js → chunk-workspace-d064v56e.js} +2 -2
- package/dist/chunk-zh-tw-qf18hcxc.js +1 -0
- package/dist/index.html +1 -1
- package/dist/sw.js +1 -1
- package/package.json +2 -2
- package/src/api-types.ts +22 -0
- package/src/app/routes.ts +105 -2
- package/src/app/threads.ts +11 -0
- package/src/host/host-app.ts +15 -1
- package/src/host/read-all.ts +80 -0
- package/src/host/reads.ts +67 -0
- package/src/i18n/zh-tw.ts +18 -4
- package/dist/chunk-account-nhpd9j90.js +0 -1
- package/dist/chunk-agent-d1xfrawq.js +0 -1
- package/dist/chunk-arranged-rooms-bga8yk2v.js +0 -1
- package/dist/chunk-character-creator-k67f77w5.js +0 -1
- package/dist/chunk-confirm-wc5xraev.js +0 -1
- package/dist/chunk-folder-list-x56y26yq.js +0 -1
- package/dist/chunk-folds-3p7s2nvx.js +0 -1
- package/dist/chunk-gate-h41bv4y9.js +0 -1
- package/dist/chunk-group-scene-7eb6jyev.js +0 -1
- package/dist/chunk-group-table-rca48kt0.js +0 -1
- package/dist/chunk-host-icons-x318gjqp.js +0 -1
- package/dist/chunk-host-picture-xswcakgy.js +0 -1
- package/dist/chunk-host-state-bpahvk54.js +0 -1
- package/dist/chunk-host-ui-tsbwwk38.js +0 -1
- package/dist/chunk-index-066vzexw.js +0 -2
- package/dist/chunk-index-0h4h76kw.js +0 -2
- package/dist/chunk-index-2f5nfekb.js +0 -8
- package/dist/chunk-index-31ays46f.js +0 -2
- package/dist/chunk-index-4gk88a0x.js +0 -4
- package/dist/chunk-index-4mf29sbx.js +0 -2
- package/dist/chunk-index-51n20yhb.js +0 -2
- package/dist/chunk-index-84v7j6vh.js +0 -50
- package/dist/chunk-index-8f9jer8r.js +0 -2
- package/dist/chunk-index-91z3g774.js +0 -1
- package/dist/chunk-index-9w0sar6s.js +0 -2
- package/dist/chunk-index-a768zmp6.js +0 -2
- package/dist/chunk-index-c5x70d9g.js +0 -2
- package/dist/chunk-index-cwc1vvpw.js +0 -2
- package/dist/chunk-index-d85x96q0.js +0 -2
- package/dist/chunk-index-dep2e3f3.js +0 -2
- package/dist/chunk-index-dtste2ed.js +0 -2
- package/dist/chunk-index-grkczq2c.js +0 -2
- package/dist/chunk-index-gzvkpe3e.js +0 -2
- package/dist/chunk-index-satam151.js +0 -2
- package/dist/chunk-index-th43f690.js +0 -2
- package/dist/chunk-index-ths2hxpe.js +0 -1
- package/dist/chunk-index-y4sqmenv.js +0 -2
- package/dist/chunk-index-zd76pr2k.js +0 -2
- package/dist/chunk-lang-css-fa7c0zfj.js +0 -1
- package/dist/chunk-lang-html-47mf2y0v.js +0 -1
- package/dist/chunk-lang-javascript-d32qrvxz.js +0 -1
- package/dist/chunk-lang-typescript-4k1d8z7s.js +0 -1
- package/dist/chunk-layout-actions-cgghzj1w.js +0 -1
- package/dist/chunk-menu-items-24cfwawa.js +0 -2
- package/dist/chunk-mode-toggle-v4baz3r1.js +0 -1
- package/dist/chunk-notes-83s3tsey.js +0 -1
- package/dist/chunk-notice-bell-a4ty5h1p.js +0 -1
- package/dist/chunk-onboarding-q1avjbrx.js +0 -1
- package/dist/chunk-palette-e44qepmh.js +0 -1
- package/dist/chunk-placement-items-v466t0sv.js +0 -1
- package/dist/chunk-prompt-history-hgbtcn4b.js +0 -1
- package/dist/chunk-prompts-czs8y6r1.js +0 -1
- package/dist/chunk-room-confirms-h8cdj3ng.js +0 -1
- package/dist/chunk-rooms-menu-button-gawqvpsr.js +0 -1
- package/dist/chunk-sheet-hosts-ssbz6hf2.js +0 -1
- package/dist/chunk-switcher-list-pj5csqr9.js +0 -1
- package/dist/chunk-table-j8nmtdnn.js +0 -1
- package/dist/chunk-thread-actions-w3eadnh7.js +0 -1
- package/dist/chunk-thread-cards-fbpky3c9.js +0 -1
- package/dist/chunk-thread-list-pghe84be.js +0 -1
- package/dist/chunk-transcript-eqzxgqys.js +0 -1
- package/dist/chunk-where-ygyr4jdj.js +0 -1
- package/dist/chunk-zh-tw-k6xx1hp2.js +0 -1
package/src/app/routes.ts
CHANGED
|
@@ -11,7 +11,7 @@ import type {
|
|
|
11
11
|
SkillRegistry,
|
|
12
12
|
Speaker,
|
|
13
13
|
} from "pi-roundtable";
|
|
14
|
-
import { PluginError } from "pi-roundtable";
|
|
14
|
+
import { channelKey, PluginError } from "pi-roundtable";
|
|
15
15
|
import { CharacterError } from "pi-roundtable/characters";
|
|
16
16
|
import { AgentError } from "pi-roundtable/kit";
|
|
17
17
|
import type {
|
|
@@ -19,6 +19,8 @@ import type {
|
|
|
19
19
|
CharacterRefusal,
|
|
20
20
|
MessagesView,
|
|
21
21
|
ModelsView,
|
|
22
|
+
ReadAllUndone,
|
|
23
|
+
ReadAllView,
|
|
22
24
|
RoomOneView,
|
|
23
25
|
RoomsView,
|
|
24
26
|
SchedulesView,
|
|
@@ -26,6 +28,7 @@ import type {
|
|
|
26
28
|
SessionView,
|
|
27
29
|
SkillView,
|
|
28
30
|
ThreadsDismissed,
|
|
31
|
+
ThreadsDismissedAll,
|
|
29
32
|
ThreadsRestored,
|
|
30
33
|
WorkspaceConflict,
|
|
31
34
|
WorkspaceNew,
|
|
@@ -38,6 +41,7 @@ import type { Authenticated } from "../auth/authenticator.ts";
|
|
|
38
41
|
import { type ConsolePresentation, message } from "../features.ts";
|
|
39
42
|
import type { Gate } from "../gate.ts";
|
|
40
43
|
import type { HostApp } from "../host/host-app.ts";
|
|
44
|
+
import { MAX_READ_ALL } from "../host/read-all.ts";
|
|
41
45
|
import type { RoomReads } from "../host/reads.ts";
|
|
42
46
|
import { readsOf, withExpiredFiles } from "../host/room-views.ts";
|
|
43
47
|
import { json } from "../http.ts";
|
|
@@ -66,6 +70,8 @@ import {
|
|
|
66
70
|
|
|
67
71
|
/** The most threads one request puts back on the room list: more than the list ever shows. */
|
|
68
72
|
const MAX_RESTORED = 100;
|
|
73
|
+
/** The most rooms one bulk request names. */
|
|
74
|
+
const MAX_BULK_ROOMS = MAX_READ_ALL;
|
|
69
75
|
|
|
70
76
|
export interface AppApiOptions {
|
|
71
77
|
/** The host's wording: a refusal reaches a client of the API in this locale when the catalog has it. */
|
|
@@ -87,6 +93,7 @@ export interface AppApiOptions {
|
|
|
87
93
|
| "removeUnder"
|
|
88
94
|
| "dismiss"
|
|
89
95
|
| "dismissFinished"
|
|
96
|
+
| "dismissFinishedUnder"
|
|
90
97
|
| "restore"
|
|
91
98
|
| "restoreFinished"
|
|
92
99
|
>;
|
|
@@ -132,7 +139,7 @@ export interface AppApiOptions {
|
|
|
132
139
|
/** The read cursors, for each room's unread count and who has read what. */
|
|
133
140
|
reads?: Pick<RoomReads, "unread" | "cursorOf" | "marks">;
|
|
134
141
|
/** Who may be served a file bound to a host room or a page. */
|
|
135
|
-
host?: Pick<HostApp, "mayRead">;
|
|
142
|
+
host?: Pick<HostApp, "mayRead" | "readAll" | "unreadAll">;
|
|
136
143
|
/** The name the app shows for a person. */
|
|
137
144
|
nameOf?(principalId: string): Promise<string>;
|
|
138
145
|
/** Present when the workspace pane is served. */
|
|
@@ -158,6 +165,22 @@ export interface AppApiOptions {
|
|
|
158
165
|
logger: Logger;
|
|
159
166
|
}
|
|
160
167
|
|
|
168
|
+
/** A cursor move as the page sends it back to undo a marking. */
|
|
169
|
+
const isReadMove = (
|
|
170
|
+
value: unknown,
|
|
171
|
+
): value is { room: string; from: number; to: number } => {
|
|
172
|
+
if (typeof value !== "object" || value === null) return false;
|
|
173
|
+
const { room, from, to } = value as Record<string, unknown>;
|
|
174
|
+
return (
|
|
175
|
+
typeof room === "string" &&
|
|
176
|
+
room.length <= 300 &&
|
|
177
|
+
Number.isSafeInteger(from) &&
|
|
178
|
+
(from as number) >= 0 &&
|
|
179
|
+
Number.isSafeInteger(to) &&
|
|
180
|
+
(to as number) >= 0
|
|
181
|
+
);
|
|
182
|
+
};
|
|
183
|
+
|
|
161
184
|
/** A refusal of the workspace pane as the HTTP error the owner reads. */
|
|
162
185
|
function refusalOf(refusal: WorkspaceRefusal): HttpError {
|
|
163
186
|
const { status } = refusal;
|
|
@@ -508,6 +531,11 @@ export class AppApi {
|
|
|
508
531
|
...(await this.#layout.view()),
|
|
509
532
|
} satisfies RoomsView);
|
|
510
533
|
}
|
|
534
|
+
// No room key is a bare word: the bulk calls take that place.
|
|
535
|
+
if (key === "read-all" && !action && method === "POST")
|
|
536
|
+
return this.#readAll(request, admission);
|
|
537
|
+
if (key === "dismiss-finished-threads" && !action && method === "POST")
|
|
538
|
+
return this.#dismissAllFinished(request, admission);
|
|
511
539
|
const room = await rooms.resolve(key);
|
|
512
540
|
if (!room) throw notFound();
|
|
513
541
|
if (!action && method === "GET") {
|
|
@@ -605,6 +633,81 @@ export class AppApi {
|
|
|
605
633
|
throw new HttpError(404, "There is no such API.");
|
|
606
634
|
}
|
|
607
635
|
|
|
636
|
+
/**
|
|
637
|
+
* Reads the person's rooms up to their newest message in one call: the named ones, or every room
|
|
638
|
+
* the list shows. A room they may not read is passed over as if it were not named. With `restore`
|
|
639
|
+
* instead, the cursors a call moved go back, where the person has not read on since.
|
|
640
|
+
*/
|
|
641
|
+
async #readAll(
|
|
642
|
+
request: Request,
|
|
643
|
+
admission: Authenticated,
|
|
644
|
+
): Promise<Response> {
|
|
645
|
+
const { host } = this.#options;
|
|
646
|
+
if (!host) throw new HttpError(404, "There is no such API.");
|
|
647
|
+
const viewer = viewerOf(admission.visitor);
|
|
648
|
+
const body = await bodyOf(request);
|
|
649
|
+
if (body.restore !== undefined) {
|
|
650
|
+
const { restore } = body;
|
|
651
|
+
if (
|
|
652
|
+
!Array.isArray(restore) ||
|
|
653
|
+
restore.length > MAX_BULK_ROOMS ||
|
|
654
|
+
!restore.every(isReadMove)
|
|
655
|
+
)
|
|
656
|
+
throw bad("restore must be a list of at most 500 moves.");
|
|
657
|
+
const restored = await host.unreadAll(viewer, restore);
|
|
658
|
+
if (restored.length) this.#options.changed();
|
|
659
|
+
return json({ restored } satisfies ReadAllUndone);
|
|
660
|
+
}
|
|
661
|
+
const named = await this.#named(body.rooms);
|
|
662
|
+
const keys =
|
|
663
|
+
named ?? (await this.#options.rooms.list()).map((one) => one.key);
|
|
664
|
+
const moved = await host.readAll(viewer, keys);
|
|
665
|
+
if (moved.length) this.#options.changed();
|
|
666
|
+
return json({
|
|
667
|
+
moved: moved.map(({ room, from, to }) => ({ room, from, to })),
|
|
668
|
+
} satisfies ReadAllView);
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
/** Takes every finished thread under the named rooms, or under every room the list shows, off the list. */
|
|
672
|
+
async #dismissAllFinished(
|
|
673
|
+
request: Request,
|
|
674
|
+
admission: Authenticated,
|
|
675
|
+
): Promise<Response> {
|
|
676
|
+
await this.#owner(admission);
|
|
677
|
+
const { rooms, threads, surface } = this.#options;
|
|
678
|
+
const named = await this.#named((await bodyOf(request)).rooms);
|
|
679
|
+
const listed = named ?? (await rooms.list()).map((one) => one.key);
|
|
680
|
+
const parents: string[] = [];
|
|
681
|
+
for (const key of new Set(listed)) {
|
|
682
|
+
const one = await rooms.resolve(key);
|
|
683
|
+
if (one && one.kind !== "thread") parents.push(one.key);
|
|
684
|
+
}
|
|
685
|
+
const dismissed = await threads.dismissFinishedUnder(parents);
|
|
686
|
+
const byParent: Record<string, string[]> = {};
|
|
687
|
+
for (const { id, parent } of dismissed)
|
|
688
|
+
byParent[parent] = [
|
|
689
|
+
...(byParent[parent] ?? []),
|
|
690
|
+
channelKey(surface.surface, id),
|
|
691
|
+
];
|
|
692
|
+
if (dismissed.length) this.#options.changed();
|
|
693
|
+
return json({
|
|
694
|
+
dismissed: dismissed.length,
|
|
695
|
+
threads: byParent,
|
|
696
|
+
} satisfies ThreadsDismissedAll);
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
/** The room keys a bulk body names; undefined when it names none, meaning every room. */
|
|
700
|
+
async #named(value: unknown): Promise<string[] | undefined> {
|
|
701
|
+
if (value === undefined) return undefined;
|
|
702
|
+
if (
|
|
703
|
+
!Array.isArray(value) ||
|
|
704
|
+
value.length > MAX_BULK_ROOMS ||
|
|
705
|
+
!value.every((one) => typeof one === "string" && one.length <= 300)
|
|
706
|
+
)
|
|
707
|
+
throw bad("rooms must be a list of at most 500 keys.");
|
|
708
|
+
return value;
|
|
709
|
+
}
|
|
710
|
+
|
|
608
711
|
/** Takes one finished thread off the room list for every owner; an open one is refused. */
|
|
609
712
|
async #dismiss(
|
|
610
713
|
room: ResolvedRoom,
|
package/src/app/threads.ts
CHANGED
|
@@ -105,6 +105,17 @@ export class WebThreads {
|
|
|
105
105
|
return rows.length;
|
|
106
106
|
}
|
|
107
107
|
|
|
108
|
+
/** Dismisses every finished thread under any of `parents` that is still listed; the threads dismissed, with their parents. */
|
|
109
|
+
async dismissFinishedUnder(
|
|
110
|
+
parents: readonly string[],
|
|
111
|
+
): Promise<{ id: string; parent: string }[]> {
|
|
112
|
+
if (parents.length === 0) return [];
|
|
113
|
+
return this.#sql`
|
|
114
|
+
UPDATE web_threads SET dismissed_at = now()
|
|
115
|
+
WHERE parent IN ${this.#sql([...parents])} AND NOT open AND dismissed_at IS NULL
|
|
116
|
+
RETURNING id, parent`;
|
|
117
|
+
}
|
|
118
|
+
|
|
108
119
|
/** Puts a dismissed thread back on the room list; asking again changes nothing. */
|
|
109
120
|
async restore(id: string): Promise<"restored" | "missing"> {
|
|
110
121
|
const rows: unknown[] = await this.#sql`
|
package/src/host/host-app.ts
CHANGED
|
@@ -24,7 +24,8 @@ import { installFrames } from "./frames.ts";
|
|
|
24
24
|
import type { HostContext } from "./host-context.ts";
|
|
25
25
|
import { hostArea, pagesArea } from "./host-routes.ts";
|
|
26
26
|
import { HostPagesService, PAGE_BINDING } from "./pages.ts";
|
|
27
|
-
import
|
|
27
|
+
import { readAll, unreadAll } from "./read-all.ts";
|
|
28
|
+
import type { MovedMark, RoomReads } from "./reads.ts";
|
|
28
29
|
import { type HostSweep, sweepHostKinds } from "./retention.ts";
|
|
29
30
|
import { HostRoomsService, ListedKinds } from "./rooms-service.ts";
|
|
30
31
|
|
|
@@ -171,6 +172,19 @@ export class HostApp {
|
|
|
171
172
|
return this.access.read(viewer, binding as ChannelKey);
|
|
172
173
|
}
|
|
173
174
|
|
|
175
|
+
/** Reads the named rooms the viewer may read up to their newest message; the cursors that moved. */
|
|
176
|
+
readAll(viewer: Viewer, rooms: readonly string[]): Promise<MovedMark[]> {
|
|
177
|
+
return readAll(this.#context, viewer, rooms);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/** Puts back cursors that `readAll` moved, where the viewer has not read on since; the rooms put back. */
|
|
181
|
+
unreadAll(
|
|
182
|
+
viewer: Viewer,
|
|
183
|
+
moves: readonly { room: string; from: number; to: number }[],
|
|
184
|
+
): Promise<string[]> {
|
|
185
|
+
return unreadAll(this.#context, viewer, moves);
|
|
186
|
+
}
|
|
187
|
+
|
|
174
188
|
/** Applies the kinds' retention; the counts of what it removed. */
|
|
175
189
|
sweep(): Promise<HostSweep> {
|
|
176
190
|
return sweepHostKinds(this.#context);
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import type { Viewer } from "../web-app.ts";
|
|
2
|
+
import { hostRoomOf, readableAudience } from "./frames.ts";
|
|
3
|
+
import type { HostContext } from "./host-context.ts";
|
|
4
|
+
import type { MovedMark } from "./reads.ts";
|
|
5
|
+
|
|
6
|
+
/** The most rooms one bulk read, or one undo of it, names. */
|
|
7
|
+
export const MAX_READ_ALL = 500;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Reads every one of `rooms` the viewer may read now up to its newest message, and tells the
|
|
11
|
+
* others: each room's readers see the new mark (as for a single `read` frame), and the viewer's own
|
|
12
|
+
* pages, wherever they follow the room or not, hear of it too. A room the viewer may not read, or
|
|
13
|
+
* that is none, is skipped as if it were not named. Gives the cursors that moved.
|
|
14
|
+
*/
|
|
15
|
+
export async function readAll(
|
|
16
|
+
ctx: HostContext,
|
|
17
|
+
viewer: Viewer,
|
|
18
|
+
rooms: readonly string[],
|
|
19
|
+
): Promise<MovedMark[]> {
|
|
20
|
+
const audiences = new Map<
|
|
21
|
+
string,
|
|
22
|
+
Awaited<ReturnType<typeof readableAudience>>
|
|
23
|
+
>();
|
|
24
|
+
await Promise.all(
|
|
25
|
+
[...new Set(rooms)].map(async (room) => {
|
|
26
|
+
audiences.set(room, await readableAudience(ctx, viewer, room));
|
|
27
|
+
}),
|
|
28
|
+
);
|
|
29
|
+
const allowed = [...audiences].flatMap(([room, audience]) =>
|
|
30
|
+
audience ? [room] : [],
|
|
31
|
+
);
|
|
32
|
+
const moved = await ctx.reads.advanceAll(viewer.principalId, allowed);
|
|
33
|
+
for (const mark of moved) {
|
|
34
|
+
const audience = audiences.get(mark.room);
|
|
35
|
+
if (!audience) continue;
|
|
36
|
+
const frame = {
|
|
37
|
+
type: "read",
|
|
38
|
+
room: mark.room,
|
|
39
|
+
principal: viewer.principalId,
|
|
40
|
+
name: viewer.name,
|
|
41
|
+
upTo: mark.to,
|
|
42
|
+
at: mark.at,
|
|
43
|
+
} as const;
|
|
44
|
+
ctx.sockets.deliver(frame, audience);
|
|
45
|
+
// A host room reaches only the pages that follow it; the viewer's other pages show its count in a list.
|
|
46
|
+
if ("room" in audience)
|
|
47
|
+
ctx.sockets.deliver(frame, { principal: viewer.principalId });
|
|
48
|
+
}
|
|
49
|
+
return moved;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Puts back cursors that `readAll` moved, for the rooms the viewer may still read and whose cursor
|
|
54
|
+
* is still where it left it. The viewer's pages read their lists again to find the counts back.
|
|
55
|
+
* Gives the rooms put back.
|
|
56
|
+
*/
|
|
57
|
+
export async function unreadAll(
|
|
58
|
+
ctx: HostContext,
|
|
59
|
+
viewer: Viewer,
|
|
60
|
+
moves: readonly { room: string; from: number; to: number }[],
|
|
61
|
+
): Promise<string[]> {
|
|
62
|
+
const allowed: { room: string; from: number; to: number }[] = [];
|
|
63
|
+
await Promise.all(
|
|
64
|
+
moves.map(async (move) => {
|
|
65
|
+
if (await readableAudience(ctx, viewer, move.room)) allowed.push(move);
|
|
66
|
+
}),
|
|
67
|
+
);
|
|
68
|
+
const restored = await ctx.reads.rewind(viewer.principalId, allowed);
|
|
69
|
+
const kinds = new Set<string>();
|
|
70
|
+
for (const room of restored) {
|
|
71
|
+
const kind = hostRoomOf(ctx, room)?.kind.kind;
|
|
72
|
+
if (kind) kinds.add(kind);
|
|
73
|
+
}
|
|
74
|
+
for (const kind of kinds)
|
|
75
|
+
ctx.sockets.deliver(
|
|
76
|
+
{ type: "list_changed", kind },
|
|
77
|
+
{ principal: viewer.principalId },
|
|
78
|
+
);
|
|
79
|
+
return restored;
|
|
80
|
+
}
|
package/src/host/reads.ts
CHANGED
|
@@ -10,6 +10,15 @@ export interface ReadMark {
|
|
|
10
10
|
at: string;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
+
/** A cursor a bulk read moved: where it was (0 when the person never read the room) and where it is now. */
|
|
14
|
+
export interface MovedMark {
|
|
15
|
+
room: string;
|
|
16
|
+
from: number;
|
|
17
|
+
to: number;
|
|
18
|
+
/** ISO time. */
|
|
19
|
+
at: string;
|
|
20
|
+
}
|
|
21
|
+
|
|
13
22
|
interface MarkRow {
|
|
14
23
|
principal_id: string;
|
|
15
24
|
last_read_id: string | number | bigint;
|
|
@@ -64,6 +73,64 @@ export class RoomReads {
|
|
|
64
73
|
return row && markOf(row);
|
|
65
74
|
}
|
|
66
75
|
|
|
76
|
+
/**
|
|
77
|
+
* Moves the person's cursor in each of `rooms` up to the room's newest message. Rooms with
|
|
78
|
+
* nothing past the cursor, and rooms with no messages, are left out of the answer, which gives
|
|
79
|
+
* for every room moved where its cursor was and where it is.
|
|
80
|
+
*/
|
|
81
|
+
async advanceAll(
|
|
82
|
+
principalId: string,
|
|
83
|
+
rooms: readonly string[],
|
|
84
|
+
): Promise<MovedMark[]> {
|
|
85
|
+
if (rooms.length === 0) return [];
|
|
86
|
+
const rows: {
|
|
87
|
+
room: string;
|
|
88
|
+
last_read_id: string | number | bigint;
|
|
89
|
+
was: string | number | bigint | null;
|
|
90
|
+
read_at: Date;
|
|
91
|
+
}[] = await this.#sql`
|
|
92
|
+
WITH before AS (
|
|
93
|
+
SELECT room, last_read_id FROM web_room_reads
|
|
94
|
+
WHERE principal_id = ${principalId} AND room IN ${this.#sql(rooms)}
|
|
95
|
+
), newest AS (
|
|
96
|
+
SELECT room, max(id) AS id FROM web_room_messages
|
|
97
|
+
WHERE room IN ${this.#sql(rooms)} GROUP BY room
|
|
98
|
+
)
|
|
99
|
+
INSERT INTO web_room_reads (room, principal_id, last_read_id)
|
|
100
|
+
SELECT room, ${principalId}, id FROM newest
|
|
101
|
+
ON CONFLICT (room, principal_id) DO UPDATE
|
|
102
|
+
SET last_read_id = EXCLUDED.last_read_id, read_at = now()
|
|
103
|
+
WHERE web_room_reads.last_read_id < EXCLUDED.last_read_id
|
|
104
|
+
RETURNING room, last_read_id, read_at,
|
|
105
|
+
(SELECT b.last_read_id FROM before b WHERE b.room = web_room_reads.room) AS was`;
|
|
106
|
+
return rows.map((row) => ({
|
|
107
|
+
room: row.room,
|
|
108
|
+
from: Number(row.was ?? 0),
|
|
109
|
+
to: Number(row.last_read_id),
|
|
110
|
+
at: row.read_at.toISOString(),
|
|
111
|
+
}));
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Puts back cursors that `advanceAll` moved: each room's goes from `to` back to `from`, unless
|
|
116
|
+
* the person read on since (their cursor is no longer at `to`). Gives the rooms put back.
|
|
117
|
+
*/
|
|
118
|
+
async rewind(
|
|
119
|
+
principalId: string,
|
|
120
|
+
moves: readonly { room: string; from: number; to: number }[],
|
|
121
|
+
): Promise<string[]> {
|
|
122
|
+
if (moves.length === 0) return [];
|
|
123
|
+
const rows: { room: string }[] = await this.#sql`
|
|
124
|
+
UPDATE web_room_reads r SET last_read_id = v.was, read_at = now()
|
|
125
|
+
FROM jsonb_to_recordset(${JSON.stringify(
|
|
126
|
+
moves.map((move) => ({ room: move.room, was: move.from, at: move.to })),
|
|
127
|
+
)}::text::jsonb) AS v(room text, was bigint, at bigint)
|
|
128
|
+
WHERE r.principal_id = ${principalId} AND r.room = v.room AND r.last_read_id = v.at
|
|
129
|
+
AND v.was < v.at
|
|
130
|
+
RETURNING r.room`;
|
|
131
|
+
return rows.map((row) => row.room);
|
|
132
|
+
}
|
|
133
|
+
|
|
67
134
|
/** The person's cursor in the room, or undefined when they never read it. */
|
|
68
135
|
async cursorOf(
|
|
69
136
|
room: string,
|
package/src/i18n/zh-tw.ts
CHANGED
|
@@ -570,6 +570,16 @@ export const ZH_TW: Readonly<Record<string, string>> = {
|
|
|
570
570
|
"Dispatch threads": "派工討論串",
|
|
571
571
|
"Find a room": "尋找聊天室",
|
|
572
572
|
"Switch rooms": "切換聊天室",
|
|
573
|
+
"Keyboard shortcuts": "鍵盤快速鍵",
|
|
574
|
+
"Previous room": "上一個聊天室",
|
|
575
|
+
"Next room": "下一個聊天室",
|
|
576
|
+
"Previous room with unread messages": "上一個有未讀訊息的聊天室",
|
|
577
|
+
"Next room with unread messages": "下一個有未讀訊息的聊天室",
|
|
578
|
+
"Close the open menu or sheet, or leave the message box":
|
|
579
|
+
"關閉開啟的選單或面板;都沒有時離開訊息輸入框",
|
|
580
|
+
"Show these shortcuts": "顯示這份快速鍵清單",
|
|
581
|
+
"In a message box the arrow shortcuts switch rooms only when it is empty or the caret is at its very start (up) or very end (down).":
|
|
582
|
+
"在訊息輸入框裡,方向鍵快速鍵只在框內沒有文字,或游標在最開頭(上)、最結尾(下)時才會切換聊天室。",
|
|
573
583
|
Group: "群組",
|
|
574
584
|
Groups: "群組",
|
|
575
585
|
Home: "首頁",
|
|
@@ -592,13 +602,17 @@ export const ZH_TW: Readonly<Record<string, string>> = {
|
|
|
592
602
|
"Cleared “{name}”": "已清除「{name}」",
|
|
593
603
|
"Cleared {count} finished thread": "已清除 {count} 個已完成的討論串",
|
|
594
604
|
"Cleared {count} finished threads": "已清除 {count} 個已完成的討論串",
|
|
595
|
-
"Clear {count} finished thread?": "清除 {count} 個已完成的討論串?",
|
|
596
|
-
"Clear {count} finished threads?": "清除 {count} 個已完成的討論串?",
|
|
597
|
-
"They leave the list for every owner. Each one stays readable by its address, and Undo brings them back.":
|
|
598
|
-
"這些討論串會從所有擁有者的列表中消失,仍可用網址讀取,按「復原」就會回來。",
|
|
599
605
|
"The thread is still open.": "這個討論串還在進行中。",
|
|
600
606
|
"threads must be a list of at most 100 keys.":
|
|
601
607
|
"threads 必須是最多 100 個鍵的清單。",
|
|
608
|
+
"rooms must be a list of at most 500 keys.":
|
|
609
|
+
"rooms 必須是最多 500 個鍵的清單。",
|
|
610
|
+
"restore must be a list of at most 500 moves.":
|
|
611
|
+
"restore 必須是最多 500 筆移動紀錄的清單。",
|
|
612
|
+
"Mark all as read": "全部標為已讀",
|
|
613
|
+
"Marked {count} room as read": "已將 {count} 個聊天室標為已讀",
|
|
614
|
+
"Marked {count} rooms as read": "已將 {count} 個聊天室標為已讀",
|
|
615
|
+
"Clear all finished threads": "清除所有已結束的討論串",
|
|
602
616
|
|
|
603
617
|
// 排程
|
|
604
618
|
"{days} at {time}": "每{days} {time}",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{f,Q,w,e,S}from"./chunk-index-84v7j6vh.js";var a={profile:w(()=>(f("bqcgkgk4"),import("./chunk-profile-bqcgkgk4.js")).then((o)=>({default:o.ProfilePage}))),notices:w(()=>(f("evny44be"),import("./chunk-notices-evny44be.js")).then((o)=>({default:o.NoticesPage}))),onboarding:w(()=>(f("q1avjbrx"),import("./chunk-onboarding-q1avjbrx.js")).then((o)=>({default:o.OnboardingPage})))};function n({pane:o}){let t=a[o];return t?e(Q,{fallback:e(S,{}),children:e(t,{})}):null}export{n as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{o,e,K,u,S,et}from"./chunk-index-84v7j6vh.js";function c({name:r}){let m=u((i)=>i.listed),t=u((i)=>Object.values(i.rooms).find((n)=>n.view?.kind==="agent"&&n.view.name===r)?.view?.key,r);return o(()=>{if(t)K("room",t,{replace:!0}),et(r);else if(m)K("rooms",void 0,{replace:!0})},[t,m,r]),e("div",{className:"page",children:e(S,{})})}export{c as AgentPage};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{f,Q,w,J,N,a,t,g,e,n,s,Ve,u,k,_,fe,Zt,hn,te,Ii,ai,vr,Wt,li,xr}from"./chunk-index-84v7j6vh.js";import{Ce}from"./chunk-index-51n20yhb.js";import{jn}from"./chunk-index-gzvkpe3e.js";import{Fn}from"./chunk-index-066vzexw.js";import{Yn,Hn}from"./chunk-index-f3b5nch2.js";import{Dt}from"./chunk-index-a768zmp6.js";import{At}from"./chunk-index-43k1rjmx.js";Yn();var M=w(()=>(f("x56y26yq"),import("./chunk-folder-list-x56y26yq.js")).then((o)=>({default:o.FolderList}))),O=J(function(l){let{view:r}=l,p=Dt(()=>Zt(r.key),r.home?void 0:Hn(r.key));return e(vr,{...l,press:p,item:{...r.home?{}:{"data-drop-item":"","data-key":r.key},...l.arranging?{"data-arranging":""}:{}},after:l.arranging?e("button",{type:"button",className:"icon-button row-more","aria-haspopup":"menu","aria-label":t("Room menu"),onClick:(d)=>{let c=d.currentTarget;Zt(r.key).then((i)=>{if(!i)return;let y=c.getBoundingClientRect();fe({...i,at:{x:y.left,y:y.bottom},via:"key",source:c})},()=>{return})},children:e(s,{name:"more",size:18})}):null})});function P(o){let{now:l}=te(),{timeZone:r}=_(),p=Wt(o.rooms);return e("ul",{className:"room-list",children:p.map(({key:d,...c})=>{let i=o.threads[d];return e(O,{...c,active:d===o.active,now:l,timeZone:r,arranging:o.arranging,...i?{threads:e(li,{open:i.open,closed:i.closed,active:o.active,parent:d})}:{}},d)})})}function v(o){let r=Wt(o.rooms).length===0;if(r&&o.zone?.kind!=="pinned")return null;return n("section",{className:"stack",...r?{"data-empty":""}:{},...o.zone?{"data-drop-zone":o.zone.kind,"data-zone-id":o.zone.id}:{},children:[e("h2",{className:"section-title",children:o.title}),r?null:e(P,{rooms:o.rooms,threads:o.threads,active:o.active,arranging:o.arranging})]})}function re(o){let l=Boolean(_().kinds?.length),r=u((m)=>JSON.stringify({listed:m.listed,...At(m,(F)=>Ve(m,F))})),p=jn(),d=a(r);if(!p)d.current=r;let c=d.current,{listed:i,...y}=N(()=>JSON.parse(c),[c]),{home:S,pinned:A,folders:R,restAgents:T,restGroups:D,rest:C,threads:L,orphans:h}=y,z=Ii(),K=S.length+A.length+C.length===0&&R.every((m)=>m.rooms.length===0)&&h.open.length+h.closed.length===0,b={threads:L,active:o.active,arranging:z};return n("div",{className:"page","data-column":o.active?"":void 0,"data-drop-root":"",children:[n("header",{className:"page-head",children:[e("h1",{children:t("Rooms")}),n("div",{className:"actions",children:[n("button",{type:"button",className:"header-button search-button",onClick:o.onSearch,children:[e(s,{name:"search",size:16}),e("span",{children:t("Find a room")}),e("kbd",{children:"⌘K"})]}),i?e("button",{type:"button",className:"header-button icon-button","aria-haspopup":"menu","aria-label":t("Folders and order"),onClick:(m)=>Fn(m.currentTarget),children:e(s,{name:"more",size:18})}):null,e("button",{type:"button",className:"header-button icon-button","aria-label":t("Add"),"aria-haspopup":"menu",onClick:(m)=>hn(m.currentTarget),children:e(s,{name:"plus"})})]})]}),z?n("div",{className:"arrange-bar",children:[n("button",{type:"button",className:"secondary",onClick:()=>Ce({kind:"new"}),children:[e(s,{name:"plus",size:16}),e("span",{children:t("Add a folder")})]}),e("button",{type:"button",onClick:()=>ai(!1),children:t("Done")})]}):null,i&&K&&!l?e(k,{children:t("No rooms yet. Rooms appear when the team has a knight.")}):null,!i?n("div",{className:"stack","aria-busy":"true",children:[e("div",{className:"skeleton"}),e("div",{className:"skeleton"}),e("div",{className:"skeleton"})]}):null,e(v,{title:t("Home"),rooms:S,...b}),e(v,{title:t("Pinned"),rooms:A,zone:{kind:"pinned",id:"pinned"},...b}),R.length>0?e("div",{className:"stack folder-list","data-folder-list":"",children:e(Q,{fallback:e("div",{className:"skeleton","aria-busy":"true"}),children:e(M,{folders:R,active:o.active,listed:i,rooms:(m)=>e(P,{rooms:m,threads:L,active:o.active,arranging:z})})})}):null,R.length>0?e(v,{title:t("Ungrouped"),rooms:C,zone:{kind:"rest",id:"rest"},...b}):n(g,{children:[e(v,{title:t("Knights"),rooms:T,zone:{kind:"rest",id:"rest-agents"},...b}),e(v,{title:t("Groups"),rooms:D,zone:{kind:"rest",id:"rest-groups"},...b})]}),h.open.length+h.closed.length>0?n("section",{className:"stack",children:[e("h2",{className:"section-title",children:t("Dispatch threads")}),e(li,{open:h.open,closed:h.closed,active:o.active})]}):null,e(xr,{active:o.active})]})}export{re as ArrangedRoomsPage};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{Be,Yt,F,ci,On}from"./chunk-index-yrhbhmxz.js";import{J,fr,o,A,N,a,r,t,c,g,e,n,ni,le,O,d,p,pn,he,Ze,Me}from"./chunk-index-84v7j6vh.js";import{j}from"./chunk-index-7bbqtdce.js";import{D}from"./chunk-index-9nents16.js";var ue={"hat.none":"No hat","hat.goggcap":"Leather cap","hat.tallcap":"Burgundian felt cap","hat.softcap":"Soft cap","hat.hardhat":"Iron skullcap","hat.fcap":"Hunter's cap","hat.winghelm":"Winged helm","hat.helm":"Helm","hat.mortar":"Biretta","hat.beret":"Chaperon","hat.goggles":"Pointed cap","hat.tricorn":"Pilgrim hat","hat.sailor":"Straw hat","hat.kettle":"Kettle hat","hat.cavalier":"Feathered hat","hat.toque":"Linen cook's cap","hair.none":"No hair","beard.none":"No beard","accessory.none":"No accessory","prop.beads":"Prayer beads","prop.marotte":"Marotte","prop.map":"Chart","prop.flask":"Alchemist's phial","prop.telescope":"Astrolabe","prop.wrench":"Dividers","outfit.surplice":"Surplice","outfit.overalls":"Work jerkin","outfit.armor":"Mail hauberk","outfit.apron":"Smith's apron","outfit.chef":"Cook's tunic","outfit.coat":"Doublet","outfit.vest":"Pourpoint","outfit.sailor":"Mariner's tunic","hair.bob":"Bob","hair.bun":"Bun","hair.ponytail":"Ponytail"},Y=(i)=>i.charAt(0).toUpperCase()+i.slice(1);function S(i,l){let m=`character.${i}.${l}`,h=t(m);if(h!==m)return h;if(i==="class")return F.classes[l]?.label??Y(l);return ue[`${i}.${l}`]??Y(l)}function Z(i){let l=`character.jobs.${i}`,m=t(l);return m!==l?m:F.classes[i]?.jobs??""}var z=[{field:"hat",title:c("Hat"),ids:F.hats},{field:"outfit",title:c("Outfit"),ids:F.outfits},{field:"prop",title:c("Prop"),ids:F.props},{field:"hair",title:c("Hair"),ids:F.hair},{field:"beard",title:c("Beard"),ids:["none",...F.beards]},{field:"accessory",title:c("Accessory"),ids:["none",...F.accessories]}],fe=new Set(["class","colors","palette","build","skin","hairColor",...z.map((i)=>i.field)]),re=Object.keys(F.palettes),ee={idle:c("Idle"),thinking:c("Thinking"),working:c("Working"),waiting:c("Waiting for you"),done:c("Done"),error:c("Error"),sleepy:c("Sleepy")},me={slim:c("Slim"),regular:c("Regular"),stout:c("Stout")};function W(i){return{class:i.class,outfit:i.outfit,hat:i.hat,prop:i.prop,hair:i.hair,beard:i.beard,accessory:i.accessory,build:i.build,skin:i.skin,hairColor:i.hairColor,colors:{...i.colors}}}var te=(i)=>JSON.stringify(W(i)),k=(i)=>i[Math.floor(Math.random()*i.length)];function be(){return{class:k(Be),outfit:k(F.outfits),hat:k(F.hats),prop:k(F.props),hair:k(F.hair),beard:k(["none",...F.beards]),accessory:k(["none",...F.accessories]),build:k(["slim","regular","stout"]),skin:k([0,1,2,3,4,5]),hairColor:k(F.hairColors),palette:k(re)}}var ie=J(function(l){return n("button",{type:"button",className:"creator-tile","aria-pressed":l.pressed,title:l.hint?`${l.label} — ${l.hint}`:l.label,onClick:l.onPick,...l.data,children:[e(he,{spec:l.spec,size:l.size,live:!1}),e("span",{children:l.label})]})});function ge(i,l,m){let h=JSON.stringify({...i,[l]:0});return N(()=>m.map((u)=>({...i,[l]:u})),[h,l,m])}function pe(){let i=a(null),[l,m]=r();return o(()=>{let h=i.current;if(!h)return;let u=()=>{let v=h.scrollLeft>1,L=h.scrollLeft+h.clientWidth<h.scrollWidth-1;m(v&&L?"both":L?"end":v?"start":void 0)};u(),h.addEventListener("scroll",u,{passive:!0});let b=typeof ResizeObserver>"u"?void 0:new ResizeObserver(u);return b?.observe(h),()=>{h.removeEventListener("scroll",u),b?.disconnect()}},[]),[i,l]}function ye(i){let{part:l}=i,m=ge(i.shown,l.field,l.ids),[h,u]=pe();return e("div",{className:"creator-strip",ref:h,"data-more":u,children:l.ids.map((b,v)=>e(ie,{data:{[`data-${l.field}`]:b},spec:m[v],size:44,label:S(l.field,b),pressed:i.draft[l.field]===b,onPick:()=>i.onPick(b)},b))})}function M(i){return e("button",{type:"button",className:"creator-swatch","aria-pressed":i.pressed,"aria-label":i.label,title:i.label,style:{background:i.background},onClick:i.onPick,...i.data})}function P(i){return n("div",{className:"creator-field","data-field":i.field,children:[i.title?e("h3",{children:i.title}):null,i.children,i.error?e("p",{className:"field-error",role:"alert",children:i.error}):null]})}function Oe(i){let[l,m]=r(i.character),h=fr(l),[u,b]=r({}),[v,L]=r(!1),[R,ne]=r("idle"),[U,T]=r(),[I,_]=r(),G=Me("(max-width: 719px)"),V=a(null),B=A(),oe=Ze(l),se=pn(),w=te(l)!==te(i.character);o(()=>m(i.character),[i.character]),o(()=>{if(!w||i.onPick)return;let s=(y)=>y.preventDefault(),f=(y)=>{if(y.button!==0||y.metaKey||y.ctrlKey||y.shiftKey||y.altKey)return;let E=y.target instanceof Element?y.target.closest("a"):null;if(!E||E.target||E.hasAttribute("download"))return;if(V.current?.contains(E))return;y.preventDefault(),y.stopPropagation(),T({kind:"link",anchor:E})},K=ni((y)=>T({kind:"navigate",proceed:y}));return window.addEventListener("beforeunload",s),document.addEventListener("click",f,!0),()=>{K(),window.removeEventListener("beforeunload",s),document.removeEventListener("click",f,!0)}},[w,i.onPick]);let C=(s)=>{b({}),m((f)=>ci(s,f))},ce=async()=>{if(i.onPick){i.onPick(W(l),l);return}L(!0),b({});try{let s=await O.setCharacter(i.name,W(l));i.onSaved?.(s),p(t("Saved."))}catch(s){let f=s instanceof le&&s.field?s.field.split(".")[0]:void 0,K=f&&fe.has(f)?f:"*";b({[K]:d(s)})}finally{L(!1)}},de=async()=>{let s=U;if(m(i.character),b({}),s?.kind==="link")setTimeout(()=>s.anchor.click(),0);else if(s?.kind==="navigate")s.proceed()},q=e(P,{field:"class",title:t("Class"),error:u.class,children:e("div",{className:"creator-grid",children:Be.map((s)=>e(ke,{id:s,base:h,pressed:l.class===s,onPick:()=>C({class:s,colors:l.colors})},s))})}),x=n(P,{field:"colors",title:t("Colors"),error:u.colors??u.palette,children:[n("fieldset",{className:"creator-swatches",children:[e("legend",{className:"visually-hidden",children:t("Palette")}),re.map((s)=>{let f=F.palettes[s];return e(M,{data:{"data-palette":s},label:S("palette",s),pressed:l.palette===s,background:`linear-gradient(135deg, ${f.primary} 52%, ${f.trim} 52%)`,onPick:()=>C({palette:s})},s)})]}),e("div",{className:"creator-custom",children:["primary","secondary","trim"].map((s)=>n("label",{children:[e("span",{children:s==="primary"?t("Primary (the accent)"):s==="secondary"?t("Secondary"):t("Trim")}),e("input",{type:"color",value:l.colors[s],onChange:(f)=>C({colors:{[s]:f.target.value}})})]},s))})]}),Q=z.map((s)=>e(P,{field:s.field,title:t(s.title),error:u[s.field],children:e(ye,{part:s,draft:l,shown:h,onPick:(f)=>C({[s.field]:f})})},s.field)),X=n(g,{children:[e(P,{field:"build",title:t("Build"),error:u.build,children:n("fieldset",{className:"segmented",children:[e("legend",{className:"visually-hidden",children:t("Build")}),["slim","regular","stout"].map((s)=>n("label",{"data-checked":l.build===s,children:[e("input",{type:"radio",name:`${B}-build`,checked:l.build===s,onChange:()=>C({build:s})}),ae(s)]},s))]})}),e(P,{field:"skin",title:t("Skin tone"),error:u.skin,children:n("fieldset",{className:"creator-swatches",children:[e("legend",{className:"visually-hidden",children:t("Skin tone")}),(se??F.skins).map((s,f)=>e(M,{data:{"data-skin":String(f)},label:t("Skin tone {n}",{n:f+1}),pressed:l.skin===f,background:s,onPick:()=>C({skin:f})},f))]})}),e(P,{field:"hairColor",title:t("Hair color"),error:u.hairColor,children:n("fieldset",{className:"creator-swatches",children:[e("legend",{className:"visually-hidden",children:t("Hair color")}),F.hairColors.map((s,f)=>e(M,{data:{"data-hair-color":s},label:t("Hair color {n}",{n:f+1}),pressed:l.hairColor===s,background:s,onPick:()=>C({hairColor:s})},s)),e("input",{type:"color","aria-label":t("Hair color"),value:l.hairColor,onChange:(s)=>C({hairColor:s.target.value})})]})})]}),H=[{id:"class",title:t("Class"),summary:S("class",l.class),error:u.class,node:q},{id:"colors",title:t("Colors"),summary:l.palette?S("palette",l.palette):l.colors.primary,error:u.colors??u.palette,node:x},...z.map((s,f)=>({id:s.field,title:t(s.title),summary:S(s.field,l[s.field]),error:u[s.field],node:Q[f]})),{id:"body",title:t("Body"),summary:ae(l.build),error:u.build??u.skin??u.hairColor,node:X}];return n("form",{ref:V,className:"creator",style:oe,"aria-labelledby":B,onSubmit:(s)=>{if(s.preventDefault(),(w||i.onPick)&&!v)ce()},children:[e("h2",{id:B,className:"visually-hidden",children:t("Character of {name}",{name:i.displayName})}),n("div",{className:"creator-preview",children:[e(he,{spec:l,name:i.name,state:R,size:176,label:t("{name}, {state}",{name:i.displayName,state:t(ee[R])})}),e("button",{type:"button",className:"secondary","data-action":"cycle",onClick:()=>ne((s)=>Yt[(Yt.indexOf(s)+1)%Yt.length]??"idle"),children:t("Preview states")}),e("span",{className:"meta","aria-live":"polite",children:t(ee[R])})]}),n("div",{className:"creator-body",children:[u["*"]?e("p",{className:"field-error",role:"alert","data-field":"*",children:u["*"]}):null,G?e("ul",{className:"creator-sections",children:H.map((s)=>e("li",{children:n("button",{type:"button",className:"creator-section secondary",onClick:()=>_(s.id),children:[e("strong",{children:s.title}),e("span",{className:"meta",children:s.summary}),s.error?e("span",{className:"field-error",role:"alert",children:s.error}):null]})},s.id))}):n(g,{children:[q,x,Q,X]}),n("div",{className:"actions creator-actions",children:[e("button",{type:"button",className:"secondary","data-action":"suggest",onClick:()=>{b({}),m(On({name:i.name,displayName:i.displayName,prompt:i.prompt}))},children:t("Suggest from role")}),e("button",{type:"button",className:"secondary","data-action":"randomize",onClick:()=>C(be()),children:t("Randomize")}),e("button",{type:"button",className:"secondary","data-action":"cancel",onClick:()=>{if(i.onCancel)i.onCancel();else if(w)T({kind:"cancel"})},children:t("Cancel")}),e("button",{type:"submit","data-action":"save",disabled:!w&&!i.onPick||v,children:v?t("Saving…"):i.onPick?t("Use this look"):t("Save")})]})]}),e(D,{open:G&&I!==void 0,title:H.find((s)=>s.id===I)?.title??"",onClose:()=>_(void 0),children:e("div",{className:"stack",children:H.find((s)=>s.id===I)?.node})}),e(j,{open:U!==void 0,title:t("Discard your changes?"),confirmLabel:t("Discard"),cancelLabel:t("Keep editing"),tone:"danger",onClose:()=>T(void 0),onConfirm:de,children:e("p",{children:t("The new look for {name} has not been saved.",{name:i.displayName})})})]})}var ae=(i)=>t(me[i]);function ke(i){let l=i.base.colors,m=N(()=>ci({class:i.id,colors:l}),[i.id,l]);return e(ie,{data:{"data-class":i.id},spec:m,size:56,label:S("class",i.id),hint:Z(i.id),pressed:i.pressed,onPick:i.onPick})}export{Oe as CharacterCreator};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{j}from"./chunk-index-7bbqtdce.js";import"./chunk-index-9nents16.js";export{j as Confirm};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{f,o,A,t,ne,g,e,n,s,mt,u,fe,We,$n,Nn}from"./chunk-index-84v7j6vh.js";import{Ji,er,tr,nr}from"./chunk-index-ths2hxpe.js";import{Dt}from"./chunk-index-a768zmp6.js";import{di}from"./chunk-index-43k1rjmx.js";var v=()=>(f("cgghzj1w"),import("./chunk-layout-actions-cgghzj1w.js")),k=(a)=>(f("v466t0sv"),import("./chunk-placement-items-v466t0sv.js")).then((r)=>r.folderMenu(a)),F=(a)=>({mode:"folder",key:a,item:(r)=>r.closest("[data-folder-block]"),root:(r)=>r.closest("[data-folder-block]")?.parentElement??null,onDrop:(r)=>{if(r.type==="folder")v().then((i)=>i.placeFolderBefore(a,r.before))},open:tr});function b(a){let{id:r,name:i}=a,d=Ji().has(r),l=a.holdsActive||!d,m=A(),h=Dt(()=>k(r),F(r)),N=(c)=>{k(r).then((p)=>{if(!p)return;let y=c.getBoundingClientRect();fe({...p,at:{x:y.left,y:y.bottom},via:"key",source:c})},()=>{return})};return n("section",{className:"folder","aria-label":i,"data-folder-block":"","data-key":r,"data-drop-zone":"folder","data-zone-id":r,"data-folder":r,"data-collapsed":l?void 0:"",children:[n("header",{className:"folder-head","data-folder-head":"",...h,children:[n("button",{type:"button",className:"folder-toggle","aria-expanded":l,"aria-controls":m,"aria-label":l?t("Collapse {name}",{name:i}):t("Expand {name}",{name:i}),onClick:()=>er(r),children:[e(s,{name:"chevron",size:16,className:"folder-chevron","data-open":l||void 0}),e("strong",{children:i}),e("span",{className:"meta",children:ne(a.count,"{count} room","{count} rooms")}),l?null:a.stack]}),a.muted==="none"?null:e(s,{name:"bell-off",size:14,className:"muted-mark","data-partial":a.muted==="some"||void 0,role:"img","aria-hidden":!1,"aria-label":a.muted==="all"?t("Notifications are off"):t("Some notifications are off")}),l?null:a.summary,e("button",{type:"button",className:"icon-button folder-more","aria-haspopup":"menu","aria-label":t("Folder menu"),onClick:(c)=>N(c.currentTarget),children:e(s,{name:"more",size:18})})]}),e("div",{id:m,className:"folder-body",hidden:!l,children:l?a.count===0?e("p",{className:"meta folder-empty",children:t("No rooms in this folder yet.")}):a.children:null})]})}var R=4;function S(a){let r=a.rooms.slice(0,R),i=u((l)=>r.map((m)=>l.rooms[m]?.view),r.join(",")),d=a.rooms.length-r.length;return n("span",{className:"folder-stack","aria-hidden":"true",children:[i.map((l)=>l?e("span",{className:"folder-stack-item",children:e(We,{view:l,size:28})},l.key):null),d>0?n("span",{className:"folder-stack-more",children:["+",d]}):null]})}function M(a){let r=u((i)=>({waiting:a.rooms.reduce((d,l)=>d+mt(i,l),0),typing:a.rooms.some((d)=>i.rooms[d]?.typing)}),a.rooms.join(","));return n(g,{children:[r.typing?e($n,{}):null,r.waiting?e(Nn,{count:r.waiting}):null]})}function w(a){return u((r)=>di(a,(i)=>r.rooms[i]?.view?.muted===!0),a.join(","))}function Q(a){let r=a.folders.map((i)=>i.id).join(",");return o(()=>{if(a.listed)nr(r?r.split(","):[])},[a.listed,r]),e(g,{children:a.folders.map((i)=>e(C,{folder:i,...a},i.id))})}function C(a){let{folder:r}=a,i=w(r.rooms);return e(b,{id:r.id,name:r.name,count:r.rooms.length,holdsActive:a.active!==void 0&&r.rooms.includes(a.active),muted:i,summary:e(M,{rooms:r.rooms}),stack:e(S,{rooms:r.rooms}),children:a.rooms(r.rooms)})}export{Q as FolderList};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{Ji,er,tr,nr}from"./chunk-index-ths2hxpe.js";export{tr as expandFolder,nr as pruneCollapsed,er as toggleCollapsed,Ji as useCollapsed};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{t,e,n,s,x}from"./chunk-index-84v7j6vh.js";import{Sn,Kt}from"./chunk-index-y00wke93.js";function l({steps:p}){return n("div",{className:"page",children:[e("header",{className:"page-head",children:e("h1",{children:t("Finish setting up")})}),e("p",{className:"meta",children:t("These steps come first. The rest of the app opens when they are done.")}),e("ul",{className:"menu",children:p.map((a)=>e("li",{children:n("a",{className:"menu-item menu-link",href:x(a.open.page),children:[n("span",{className:"menu-text",children:[e("strong",{children:Sn(a)}),Kt(a)?e("span",{className:"meta",children:Kt(a)}):null]}),e(s,{name:"chevron",size:16})]})},a.id))})]})}export{l as GatePage};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{r,e,n}from"./chunk-index-84v7j6vh.js";import"./chunk-index-934zgd18.js";import"./chunk-index-8f9jer8r.js";import"./chunk-index-dtste2ed.js";import{Bt}from"./chunk-index-2f5nfekb.js";import{Jr,es,ji,Gn}from"./chunk-index-y4sqmenv.js";import"./chunk-index-9nents16.js";function b(i){let{roomKey:o,members:m}=i,{line:s}=ji(o),[l,a]=r(),u=es(Jr(s,m),s?.id,l),t=(f)=>a({lineId:s?.id,member:f});return n("div",{className:"table-frame room-scene","data-focused":"",children:[e(Bt,{members:m,groupRoom:o,variant:"full",focus:u,onFocus:t,onSeat:t}),e(Gn,{roomKey:o,open:!0,streams:!1})]})}export{b as GroupScene};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{hr,t,g,e,n,s,u,Je}from"./chunk-index-84v7j6vh.js";import"./chunk-index-934zgd18.js";import"./chunk-index-8f9jer8r.js";import"./chunk-index-dtste2ed.js";import{Bt}from"./chunk-index-2f5nfekb.js";var c=(o,a)=>a?hr(o,a):o;function T(o){let a=u((m)=>m.rooms[o.roomKey]?.view),r=Je();if(!a||a.kind!=="group")return null;let l=a.members??[];return n(g,{children:[n("button",{type:"button",className:"icon-button group-table-button","aria-label":t("Table"),"aria-pressed":o.scene,onClick:()=>o.onScene(!o.scene),children:[e(s,{name:"table"}),e("span",{className:"group-table-label",children:t("Table")})]}),r==="camelot"&&!o.scene?c(e("div",{className:"group-strip",children:e(Bt,{members:l,groupRoom:o.roomKey,variant:"compact"})}),o.slot):null]})}export{T as GroupTable};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import"./chunk-index-0n6ja7my.js";
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{it}from"./chunk-index-kfv996qe.js";export{it as HostPicture};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{Sr,Ee,wr,kr,_r,Di,Ui,Tr,no}from"./chunk-index-dtste2ed.js";export{Tr as keepCards,Ui as keepReads,_r as noCards,kr as noReads,no as onFrame,Di as seedUnread,Sr as subscribeHost,wr as totalUnread,Ee as useHost};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{J,z,o,A,Fe,N,a,r,t,ne,g,e,n,s,x,ii,b,u,le,d,p,S,m,k,P,Ft,Mn,Rt,_,mr,Pe,Gt,Qi,ln,cn,Ct,te,mn,Me,yr,Re}from"./chunk-index-84v7j6vh.js";import{Pn}from"./chunk-index-934zgd18.js";import{ki,vs,Ue,_i}from"./chunk-index-8f9jer8r.js";import{j}from"./chunk-index-7bbqtdce.js";import{Ee,kr,_r,Di,Ui,Tr}from"./chunk-index-dtste2ed.js";import{nt,it}from"./chunk-index-kfv996qe.js";import{Ki}from"./chunk-index-kw85ajap.js";import"./chunk-index-0n6ja7my.js";import{De}from"./chunk-index-cmxs5y22.js";import{de}from"./chunk-index-grkczq2c.js";import"./chunk-index-9nents16.js";function Ze(l){let i={};for(let c of l)if(c.type==="multiselect")i[c.name]=[...Ae(c.initial)];else i[c.name]=Ae(c.initial)[0]??"";return i}var Ae=(l)=>l===void 0?[]:typeof l==="string"?[l]:[...l];function Qe(l,i){let c={};for(let f of l){let v=i[f.name];if(v===void 0||v===""||v.length===0)continue;c[f.name]=v}return c}function Ye(l){let{field:i,value:c}=l,[f,v]=r(""),H=i.search?i.options.filter((h)=>h.label.toLowerCase().includes(f.trim().toLowerCase())):i.options,w=i.search?e("input",{type:"search",value:f,placeholder:t("Search…"),"aria-label":t("Search {name}",{name:i.label}),onChange:(h)=>v(h.target.value)}):null;if(i.type==="select")return n(g,{children:[w,n(De,{id:l.id,value:String(c),required:i.required===!0,"aria-describedby":l.described,...i.search?{size:6}:{},onChange:(h)=>l.onChange(h.target.value),children:[i.required?null:e("option",{value:"",children:t("None")}),H.map((h)=>e("option",{value:h.value,children:h.label},h.value))]})]});let y=new Set(Array.isArray(c)?c:[]);return n(g,{children:[w,e("fieldset",{"aria-describedby":l.described,children:H.map((h)=>n("label",{children:[e("input",{type:"checkbox",checked:y.has(h.value),onChange:(E)=>{let C=new Set(y);if(E.target.checked)C.add(h.value);else C.delete(h.value);l.onChange(i.options.filter((M)=>C.has(M.value)).map((M)=>M.value))}}),h.label]},h.value))})]})}function Xe(l){let{field:i,value:c}=l,f=A(),v="hint"in i?i.hint:void 0,H=l.error||v?`${f}-note`:void 0,w;if("options"in i)w=e(Ye,{field:i,id:f,value:c,described:H,onChange:l.onChange});else if(i.type==="textarea")w=e("textarea",{id:f,rows:5,value:String(c),maxLength:i.max??8000,required:i.required===!0,"aria-describedby":H,onChange:(y)=>l.onChange(y.target.value)});else w=e("input",{id:f,type:i.type==="url"?"url":"text",value:String(c),maxLength:i.max??500,required:i.required===!0,"aria-describedby":H,onChange:(y)=>l.onChange(y.target.value)});return n("div",{className:"host-field",children:[i.type==="multiselect"?e("span",{className:"field-label",children:i.label}):e("label",{htmlFor:f,children:i.label}),w,l.error||v?e("span",{id:`${f}-note`,className:l.error?"field-error":"hint",role:l.error?"alert":void 0,children:l.error??v}):null]})}function ie(l){let{spec:i}=l,[c,f]=r(()=>Ze(i.fields)),[v,H]=r(!1),[w,y]=r();return n("form",{className:"host-form",onSubmit:async(E)=>{if(E.preventDefault(),v)return;H(!0),y(void 0);try{y(await l.onSubmit(Qe(i.fields,c)))}catch(C){y({error:d(C)})}finally{H(!1)}},children:[i.fields.map((E)=>e(Xe,{field:E,value:c[E.name]??"",error:w?.field===E.name?w.error:void 0,onChange:(C)=>f((M)=>({...M,[E.name]:C}))},E.name)),w&&!i.fields.some((E)=>E.name===w.field)?e(m,{message:w.error}):null,n("div",{className:"actions",children:[l.onCancel?e("button",{type:"button",className:"secondary",disabled:v,onClick:l.onCancel,children:t("Cancel")}):null,e("button",{type:"submit",disabled:v,children:i.submit})]})]})}function Je(l){if(!l.ok)return{error:ki(l.error),...l.field?{field:l.field}:{}};if(l.notice)p(l.notice);if(l.open)_i(l.open);return}function Q(l){let[i,c]=r(),[f,v]=r(!1),H=async(y,h)=>Je(await l.run(y,h)),w=async(y)=>{if(y.form||y.confirm){c(y);return}v(!0);try{let h=await H(y,{});if(h)p(h.error,"danger")}catch(h){p(d(h),"danger")}finally{v(!1)}};if(l.actions.length===0)return null;return n("div",{className:l.className??"host-actions",children:[l.actions.map((y)=>e("button",{type:"button",className:y.style==="danger"?"danger":y.style==="secondary"?"secondary":"",disabled:f,onClick:()=>w(y),children:y.label},y.id)),i?.form?e(de,{open:!0,title:i.form.title,onClose:()=>c(void 0),children:e(ie,{spec:i.form,onCancel:()=>c(void 0),onSubmit:async(y)=>{let h=await H(i,y);if(!h)c(void 0);return h}})}):i?e(j,{open:!0,title:i.label,confirmLabel:i.label,tone:i.style==="danger"?"danger":"primary",onConfirm:async()=>{let y=await H(i,{});if(y)throw Error(y.error)},onClose:()=>c(void 0),children:e("p",{children:i.confirm})}):null]})}var Ce=/^file:([A-Za-z0-9_-]{1,64})$/;function Se(l){let i=URL.parse(l,document.baseURI);return i!==null&&i.origin===window.location.origin}function Ke({id:l,alt:i}){return e("img",{className:"file-image",src:`api/files/${encodeURIComponent(l)}`,alt:i,loading:"lazy",decoding:"async",onError:(c)=>{let f=document.createElement("span");f.textContent=i||t("Image"),c.currentTarget.replaceWith(f)}})}var W=J(function({source:i}){return e("div",{className:"prose",children:e(Ft,{remarkPlugins:[Rt],urlTransform:(c)=>Ce.test(c)?c:Mn(c),components:{a:({href:c,children:f})=>c&&/^https?:\/\//.test(c)&&!Se(c)?e("a",{href:c,target:"_blank",rel:"noreferrer noopener",children:f}):c&&Se(c)?e("a",{href:c,children:f}):e("span",{children:f}),img:({src:c,alt:f})=>{let v=typeof c==="string"?Ce.exec(c):null;return v?.[1]?e(Ke,{id:v[1],alt:f??""}):e("span",{children:f})},pre:mr,table:({children:c})=>e("div",{className:"table-wrap",children:e("table",{children:c})})},children:i})})});function je(l){switch(l??"open"){case"working":return t("Working…");case"done":return t("Done");case"superseded":return t("Replaced");case"expired":return t("Expired");default:return""}}var he=(l)=>(l.state??"open")==="open";function ee(l){let{card:i}=l,c=je(i.state);return n("article",{className:"host-card","data-tone":i.tone??"note","data-state":i.state??"open",children:[n("header",{children:[e("h3",{children:i.title}),c?e(P,{tone:i.state==="working"?"busy":"plain",children:c}):null]}),i.body?e(W,{source:i.body}):null,i.links?.length?e("div",{className:"host-card-links",children:i.links.map((f)=>e("a",{href:f.url,...f.url.startsWith("/")?{}:{target:"_blank",rel:"noreferrer noopener"},children:f.label},`${f.url}`))}):null,he(i)&&i.buttons?.length?e(Q,{actions:i.buttons,run:l.run}):null]})}nt();function et(){let[l,i]=r(()=>Pn().toString());return o(()=>{let c=()=>i(Pn().toString());return window.addEventListener("popstate",c),window.addEventListener("hashchange",c),()=>{window.removeEventListener("popstate",c),window.removeEventListener("hashchange",c)}},[]),l}function tt(l){if(!l.ok)return{error:ki(l.error),...l.field?{field:l.field}:{}};if(l.notice)p(l.notice);if(l.open)_i(l.open);return}function rt(l){let{section:i}=l;switch(i.kind){case"markdown":return e(W,{source:i.text});case"card":return e(ee,{card:i.card,run:l.run});case"form":return n("section",{className:"stack",children:[e("h2",{className:"section-title",children:i.form.title}),e(ie,{spec:i.form,onSubmit:(c)=>l.submit(i.action,c)})]});case"list":return n("section",{className:"stack",children:[i.title?e("h2",{className:"section-title",children:i.title}):null,i.rows.length===0?e(k,{children:t("Nothing here.")}):null,e("ul",{className:"host-list",children:st(i.rows).map(([c,f])=>n("li",{children:[f.attention?e("span",{className:"attention-dot",role:"img","aria-label":t("Needs attention")}):null,n("div",{className:"host-list-main",children:[f.open?e("a",{href:f.open,...f.open.startsWith("/")?{}:{target:"_blank",rel:"noreferrer noopener"},children:f.title}):e("strong",{children:f.title}),f.subtitle?e("span",{children:f.subtitle}):null]}),f.actions?.length?e(Q,{actions:f.actions,run:l.run}):null]},c))})]})}}function ot({routeKey:l}){let i=l??"",c=et(),f=Ee((C)=>C.pages[i]??0),[v,H]=r(0),[w,y]=r({});o(()=>{let C=!0;return Ue.page(i,Object.fromEntries(new URLSearchParams(c))).then((M)=>C&&y({page:M}),(M)=>{if(!C)return;let L=M instanceof le&&M.status===404;y((T)=>({...L||!T.page?{}:{page:T.page},error:d(M),gone:L}))}),()=>{C=!1}},[i,c,f,v]);let h=async(C,M)=>{let L=await Ue.pageAct(i,{action:C,input:M}),T=tt(L);if(!T)H((O)=>O+1);return T},E=async(C,M)=>{let L=await Ue.pageAct(i,{action:C.id,input:M});if(L.ok)H((T)=>T+1);return L};if(w.gone)return e("div",{className:"page",children:e(k,{children:t("This page is not available.")})});if(!w.page)return e("div",{className:"page",children:w.error?e(m,{message:w.error}):e(S,{})});return n("div",{className:"page",children:[e("header",{className:"page-head",children:e("h1",{children:w.page.title})}),w.error?e(m,{message:w.error}):null,w.page.sections.map((C,M)=>e(rt,{section:C,run:E,submit:h},M))]})}function st(l){let i=new Map;return l.map((c)=>{let f=i.get(c.title)??0;return i.set(c.title,f+1),[`${c.title}:${f}`,c]})}var at=/https?:\/\/[^\s<>"']+/g,lt=/[.,;:!?)\]}\u3001\u3002\uff0c\uff1b\uff1a\uff01\uff1f\uff09\u300d\u300f]+$/;function ct(l){let i=l.replace(lt,""),c=URL.parse(i);return c&&(c.protocol==="https:"||c.protocol==="http:")?i:""}function Le({text:l}){let i=[],c=0;for(let f of l.matchAll(at)){let v=ct(f[0]);if(v==="")continue;let H=f.index;if(H>c)i.push(l.slice(c,H));i.push(e("a",{href:v,target:"_blank",rel:"noreferrer noopener",children:v},`${H}`)),c=H+v.length}if(c<l.length)i.push(l.slice(c));return e("span",{className:"plain",children:i})}var Te=J(function(i){let{message:c}=i,f=c.authorKind??"external";if(f==="notice")return n("li",{className:"host-notice","data-mid":c.id,"data-highlight":i.highlighted||void 0,"data-enter":i.enter||void 0,children:[e(s,{name:"bell",size:14}),e(W,{source:c.text}),e("time",{dateTime:c.at,children:Gt(c.at,i.timeZone)})]});let v=f==="member"&&c.principalId!==void 0&&c.principalId===i.me;return n("li",{className:"message","data-mid":c.id,"data-author":f,"data-mine":v||void 0,"data-header":i.header||void 0,"data-enter":i.enter||void 0,"data-highlight":i.highlighted||void 0,children:[v?null:e("span",{className:"message-avatar",children:i.header?e(it,{picture:c.picture,name:c.author}):null}),n("div",{className:"message-main",children:[i.header?n("div",{className:"message-meta",children:[e("strong",{children:c.author}),c.authorLabel?e("span",{className:"label-chip",children:c.authorLabel}):null,e("time",{dateTime:c.at,children:Gt(c.at,i.timeZone)})]}):null,n("div",{className:"bubble",children:[c.text?f==="assistant"?e(W,{source:c.text}):e(Le,{text:c.text}):null,e(Ct,{files:c.files}),c.expiredFiles?e("p",{className:"message-expired",children:ne(c.expiredFiles,"{count} file was removed","{count} files were removed")}):null]}),c.edited?e("span",{className:"message-edited",children:t("edited")}):null]})]})});nt();var dt=3;function ut({marks:l}){let[i,c]=r(!1);return n("li",{className:"seen",children:[n("button",{type:"button",className:"seen-toggle","aria-expanded":i,onClick:()=>c((f)=>!f),children:[l.slice(0,dt).map((f)=>e(it,{picture:{principal:f.principal},name:f.name,size:16},f.principal)),e("span",{children:t("Seen by {count}",{count:l.length})})]}),i?e("span",{className:"seen-names",children:l.map((f)=>f.name).join(t(", "))}):null]})}function mt(l,i){let c=Re(),f=u((v)=>v.connects);o(()=>{let v=i.current;if(!v)return;let H=0,w=0,y,h,E=()=>{if(h=void 0,document.visibilityState!=="visible")return;let L=v.getBoundingClientRect(),T=0;for(let B of v.querySelectorAll("[data-mid]")){let D=B.getBoundingClientRect();if(D.bottom>L.top&&D.top<L.bottom-4)T=Math.max(T,Number(B.dataset.mid))}if(T<=H)return;let O=w+1000-Date.now();if(O>0){clearTimeout(y),y=setTimeout(C,O);return}if(c.send({type:"read",room:l,upTo:T}))H=T,w=Date.now()},C=()=>{if(h===void 0)h=requestAnimationFrame(E)};v.addEventListener("scroll",C,{passive:!0}),document.addEventListener("visibilitychange",C),window.addEventListener("resize",C);let M=new MutationObserver(C);return M.observe(v,{childList:!0,subtree:!0}),C(),()=>{if(v.removeEventListener("scroll",C),document.removeEventListener("visibilitychange",C),window.removeEventListener("resize",C),M.disconnect(),clearTimeout(y),h!==void 0)cancelAnimationFrame(h)}},[c,l,i,f])}function ae(l){let{roomKey:i}=l;mt(i,l.scroller);let c=u((h)=>h.principal?.id),f=u((h)=>h.rooms[i]?.messages),v=Ee((h)=>h.reads[i]??kr),H=Ee((h)=>h.cursor[i]),w=a(void 0);if(w.current===void 0&&H!==void 0)w.current=H;let y=N(()=>{let E=(f??[]).filter((L)=>L.kind!=="system"),C=w.current===void 0?void 0:E.find((L)=>L.id>(w.current??0)&&(L.principalId===void 0||L.principalId!==c))?.id,M=new Map;for(let L of v){if(L.principal===c)continue;let T=E.findLast((O)=>O.id<=L.upTo);if(T)M.set(T.id,[...M.get(T.id)??[],L])}return{before:(L)=>L.id===C?e("li",{className:"new-divider",children:e("span",{children:t("New messages")})}):null,after:(L)=>{let T=M.get(L.id);return T?e(ut,{marks:T}):null},...l.host?{message:(L,T)=>L.kind==="system"&&L.authorKind===void 0?void 0:e(Te,{message:L,header:T.header,enter:T.enter,timeZone:T.timeZone,me:c,highlighted:l.highlight===L.id})}:{}}},[f,v,c,l.host,l.highlight]);return e(mn,{roomKey:i,enterAfter:l.enterAfter,quotable:l.quotable,decor:y})}nt();var ft=20,pt=2600,xe;function gt(l,i,c){let f=u((y)=>y.connects),v=Ee((y)=>y.rooms[l]??0),[H,w]=r({view:void 0,error:void 0,gone:!1});return o(()=>{let y=!0;return Ue.open(i,c).then((h)=>{if(!y)return;b.dispatch({type:"history_loaded",room:l,messages:h.messages,more:h.more,older:!1}),Ui(l,h.reads,h.cursor),Tr(l,h.cards),w({view:h,error:void 0,gone:!1})},(h)=>{if(!y)return;let E=h instanceof le&&h.status===404;w((C)=>({view:E?void 0:C.view,error:d(h),gone:E}))}),()=>{y=!1}},[l,i,c,f,v]),H}function ht(l){let{header:i}=l;return n(g,{children:[i.banner?e("p",{className:"host-banner","data-tone":i.banner.tone,role:"status",children:i.banner.text}):null,i.fields.length?e("dl",{className:"host-head-fields",children:i.fields.map((c)=>n("div",{children:[e("dt",{children:c.label}),e("dd",{children:c.link?e("a",{href:c.link,...c.link.startsWith("/")?{}:{target:"_blank",rel:"noreferrer noopener"},children:c.value}):c.value})]},`${c.label}:${c.value}`))}):null,e(Q,{className:"host-actions bar",actions:i.actions,run:l.run})]})}function bt(l){let i=Ee((E)=>E.cards[l.room]??_r),c=Me("(min-width: 720px) and (min-height: 760px)"),[f,v]=r();if(i.length===0)return null;let H=i.filter((E)=>he(E)||E.state==="working"),w=i.filter((E)=>!H.includes(E)),y=f??(c&&H.length>0),h=H[0];return n("div",{className:"host-cards","data-open":y||void 0,children:[n("button",{type:"button",className:"host-cards-toggle","aria-expanded":y,onClick:()=>v(!y),children:[e(s,{name:"chevron",size:14}),h?n("span",{children:[e("strong",{children:ne(H.length,"{count} card waiting","{count} cards waiting")}),`: ${h.title}`]}):e("span",{children:t("Earlier cards ({count})",{count:w.length})})]}),y?n("div",{className:"host-cards-body",children:[H.map((E)=>e(ee,{card:E,run:l.run(E.id)},E.id)),w.length?n("details",{className:"host-cards-older",children:[e("summary",{children:t("Earlier cards ({count})",{count:w.length})}),w.map((E)=>e(ee,{card:E,run:l.run(E.id)},E.id))]}):null]}):null]})}function yt({roomKey:l}){let i=Re(),c=vs(l),f=c?.kind??"",v=c?.id??"",{view:H,error:w,gone:y}=gt(l,f,v),h=u((R)=>R.rooms[l]),E=u((R)=>R.limits),C=u((R)=>R.connects),M=u((R)=>R.connection==="open"),L=a(null),T=a(null),{away:O,onScroll:B,onGrow:D,toEnd:Z}=yr(L),[re,F]=r(!1),[I,Y]=r(),[ue,Oe]=r(xe),[qe,_e]=r(!1),[ze,ye]=r(),me=a(void 0),X=a(void 0),q=H!==void 0;if(o(()=>{if(!c||y||!q)return;return i.send({type:"subscribe",room:l}),i.focus(l),()=>{i.focus(void 0),i.send({type:"unsubscribe",room:l})}},[i,l,C,y,q]),q&&me.current===void 0)me.current=h?.messages.at(-1)?.id??0;Fe(()=>{if(q)Z(!1)},[q]),Fe(()=>{let R=L.current;if(R&&X.current!==void 0)R.scrollTop+=R.scrollHeight-X.current,X.current=void 0},[h?.messages[0]?.id]),o(()=>{let R=T.current;if(!R||typeof ResizeObserver>"u")return;let V=new ResizeObserver(D);return V.observe(R),()=>V.disconnect()},[D]);let fe=z(async()=>{let R=b.getState().rooms[l]?.messages[0];if(!R)return!1;let V=await Ue.older(f,v,R.id,ii);return b.dispatch({type:"history_loaded",room:l,messages:V.messages,more:V.more,older:!0}),Ui(l,V.reads,void 0),V.more},[l,f,v]),oe=a(void 0);o(()=>{let R=()=>{let V=Number(Pn().get("message"));oe.current=Number.isSafeInteger(V)&&V>0?V:void 0};return R(),window.addEventListener("popstate",R),()=>window.removeEventListener("popstate",R)},[]);let pe=h?.messages[0]?.id,ve=h?.more===!0;o(()=>{let R=oe.current,V=L.current;if(!q||R===void 0||!V)return;let U=V.querySelector(`[data-mid="${R}"]`);if(U){oe.current=void 0,U.scrollIntoView({block:"center"}),ye(R),requestAnimationFrame(()=>V.dispatchEvent(new Event("scroll"))),setTimeout(()=>ye(void 0),pt);return}if(pe!==void 0&&R<pe&&ve){let K=0;(async()=>{if(K+=1,!await fe().catch(()=>!1)||K>=ft)oe.current=void 0})()}},[q,pe,ve,h?.messages.length,fe]);let we=(R,V={},U)=>Ue.act(f,v,{action:R.id,...U===void 0?{}:{card:U},input:V}),$e=(R,V)=>we(R,V),Be=(R)=>(V,U)=>we(V,U,R);if(y||!q&&!w&&!c)return e("section",{className:"room",children:n("div",{className:"page",children:[e(k,{children:t("This room is not available.")}),e("a",{className:"back",href:x("rooms"),children:t("Back to rooms")})]})});let G=H?.access.send??[],ge=G.length>1,ke=ge&&qe,Ne=ue&&G.includes(ue)?ue:G.includes("turn")?"turn":G[0],He=ke||Ne==="turn",Ge=He?H?.wording?.turn?.placeholder??t("Ask AI…"):H?.wording?.note?.placeholder??t("Write an internal note…"),se=H?.header.title??l,We=h?.messages??[];return n("section",{className:"room",onDragOver:(R)=>{if(G.length&&R.dataTransfer.types.includes("Files"))R.preventDefault()},onDrop:(R)=>{if(!G.length||!R.dataTransfer.files.length)return;R.preventDefault(),Y([...R.dataTransfer.files])},children:[n("header",{className:"room-head",children:[e("a",{className:"icon-button room-back",href:x("rooms"),"aria-label":t("Back to rooms"),children:e(s,{name:"back"})}),e(it,{name:se,size:40}),n("div",{className:"room-title",children:[e("h1",{children:se}),e("span",{className:"room-status","data-working":h?.typing||void 0,children:h?.typing?t("Working…"):t("Host room")})]})]}),!M?n("div",{className:"offline-banner",role:"status",children:[e("span",{className:"spinner","aria-hidden":"true"}),t("Reconnecting… messages wait here until it is back.")]}):null,H?e(ht,{header:H.header,run:$e}):null,e("div",{className:"room-scroll",ref:L,onScroll:B,children:n("div",{className:"room-content",ref:T,children:[w?e(m,{message:w}):null,!q&&!w?e(S,{}):null,h?.more?e("button",{type:"button",className:"secondary older",disabled:re,onClick:async()=>{F(!0),X.current=L.current?.scrollHeight;try{await fe()}catch(R){X.current=void 0,p(d(R),"danger")}finally{F(!1)}},children:re?t("Loading…"):t("Load earlier messages")}):null,q&&We.length===0?e(k,{children:t("No messages yet.")}):null,e(ae,{roomKey:l,enterAfter:me.current,quotable:!1,scroller:L,host:!0,highlight:ze}),h?.typing?e(cn,{name:se,progress:h.progress}):null]})}),O?n("button",{type:"button",className:"to-end",onClick:()=>Z(!0),children:[e(s,{name:"send",size:16,style:{transform:"rotate(180deg)"}}),t("Latest")]}):null,H?e(bt,{room:l,run:Be}):null,H&&G.length===0?e("p",{className:"room-note",children:t("You can read this room but not write in it.")}):null,H&&G.length>0?e(g,{children:e(ln,{draftKey:l,name:se,placeholder:Ge,onAddressed:_e,...ge?{above:e(Ki,{on:He,label:H?.wording?.turn?.label??t("@AI"),...ke?{locked:t("The message starts with @AI, so the knight answers.")}:{},onChange:(R)=>{let V=R?"turn":"note";xe=V,Oe(V)}})}:{},limits:E,stoppable:Boolean(h?.stoppable),onSend:(R,V,U)=>{if(ge&&U){let K=Qi(R);i.say(l,K===""&&V.length===0?R:K,V,"turn")}else i.say(l,R,V,Ne);Z(!0)},onStop:()=>i.send({type:"stop",room:l}),...I?{incoming:I,onIncomingTaken:()=>Y(void 0)}:{}},l)}):null]})}nt();function ce({room:l}){let i=Ee((c)=>c.unread[l]??0);if(i<=0)return null;return e("span",{className:"unread-mark",role:"img","aria-label":ne(i,"{count} unread message","{count} unread messages"),children:i>99?"99+":i})}nt();var vt=6,wt=250;function be(l){let{kind:i}=l,{timeZone:c}=_(),{now:f}=te(),v=u((F)=>F.connects),H=Ee((F)=>F.lists[i]??0),[w,y]=r(""),[h,E]=r(""),[C,M]=r(),[L,T]=r(),[O,B]=r(),[D,Z]=r(!1);o(()=>{let F=setTimeout(()=>E(w.trim()),wt);return()=>clearTimeout(F)},[w]),o(()=>{let F=!0;return Ue.list(i,h||void 0).then((I)=>{if(!F)return;Di(Object.fromEntries(I.rooms.map((Y)=>[Y.key,Y.unread??0]))),M(I.rooms),T(I.cursor),B(void 0)},(I)=>F&&B(d(I))),()=>{F=!1}},[i,h,v,H]);let re=async()=>{if(!L||D)return;Z(!0);try{let F=await Ue.list(i,h||void 0,L);Di(Object.fromEntries(F.rooms.map((I)=>[I.key,I.unread??0]))),M((I)=>[...I??[],...F.rooms]),T(F.cursor)}catch(F){B(d(F))}finally{Z(!1)}};return n("section",{className:"stack",children:[n("h2",{className:"section-title",children:[l.icon?e(s,{name:l.icon,size:14,className:"section-icon"}):null,l.label]}),C&&(C.length>=vt||h||w)?e("input",{type:"search",className:"kind-filter",value:w,placeholder:t("Search {name}",{name:l.label}),"aria-label":t("Search {name}",{name:l.label}),onChange:(F)=>y(F.target.value)}):null,O?e(m,{message:O}):null,!C&&!O?n("div",{className:"stack","aria-busy":"true",children:[e("div",{className:"skeleton"}),e("div",{className:"skeleton"})]}):null,C&&C.length===0?e(k,{children:h?t("Nothing matches."):t("No rooms yet.")}):null,C&&C.length>0?e("ul",{className:"room-list",children:C.map((F)=>e("li",{children:n("a",{className:"room-row",href:x("room",F.key),"aria-current":F.key===l.active?"page":void 0,children:[n("span",{className:"kind-row-picture",children:[e(it,{picture:F.picture,name:F.title,size:44}),F.attention?e("span",{className:"attention-dot",role:"img","aria-label":t("Needs attention")}):null]}),n("span",{className:"room-row-main",children:[n("span",{className:"room-row-top",children:[e("strong",{children:F.title}),e(ce,{room:F.key}),e("span",{className:"room-row-time",children:F.lastAt?Pe(F.lastAt,f,c):""})]}),e("span",{className:"room-row-preview",children:e("span",{children:F.subtitle??""})})]}),e(s,{name:"chevron",size:16,className:"room-row-chevron"})]})},F.key))}):null,L?e("button",{type:"button",className:"secondary",disabled:D,onClick:re,children:D?t("Loading…"):t("Show more")}):null]})}function Ve(l){return l.kinds.map((i)=>e(be,{kind:i.kind,label:i.label,...i.icon?{icon:i.icon}:{},active:l.active},i.kind))}function Ie(){let l=(_().pages??[]).filter((i)=>i.place==="settings");if(l.length===0)return null;return n("section",{className:"card stack",children:[e("h2",{children:t("More settings")}),l.map((i)=>n("a",{className:"menu-item menu-link",href:x("p",i.id),children:[e("span",{className:"menu-text",children:e("strong",{children:i.label})}),e(s,{name:"chevron",size:16})]},i.id))]})}export{Ve as HostKinds,ot as HostPage,yt as HostRoomPage,Ie as HostSettingsPages,ae as ReadLog,ce as UnreadMark};
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{Ce}from"./chunk-index-51n20yhb.js";import{t,fe,$s,ai}from"./chunk-index-84v7j6vh.js";function Fn(e){let n=e.getBoundingClientRect(),o=$s();fe({title:t("Rooms"),items:[{id:"new-folder",label:t("Add a folder"),icon:"plus",run:()=>Ce({kind:"new"})},{id:"arrange",label:o?t("Done"):t("Arrange"),icon:o?"check":"list",run:()=>ai(!o)}],at:{x:n.left,y:n.bottom},via:"key",source:e})}
|
|
2
|
-
export{Fn};
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import{f,be,o,N,a,r,t,c,e,Se,K,u,B,sn,Qn,Ge,Je,Rn,pn,gt,Es,Me,qe,Re}from"./chunk-index-84v7j6vh.js";import{Ue}from"./chunk-index-8f9jer8r.js";import{Ee}from"./chunk-index-dtste2ed.js";var we=12,xe={views:[],attention:{},loaded:!1},de=xe,{emit:Te,use:ke}=B(),_n=()=>ke(()=>de);function Tn(){let n=be(Ge)?.tier;return n!==void 0&&n!=="owner"}function Si(){let n=be(Ge);return Tn()||(n?.kinds?.length??0)>0}function He(n,l){return{key:n.key,kind:"agent",name:`${l}.${n.id}`,displayName:n.title,home:!1,readOnly:!1,mode:{yolo:!1,longRunning:!1},typing:!1,stoppable:!1}}var Ae=(n)=>n.attention===!0,Le=(n,l)=>(l.lastAt??"").localeCompare(n.lastAt??"");async function Ce(n){let l=await Promise.allSettled(n.map((s)=>Ue.list(s))),d=[];l.forEach((s,p)=>{let i=n[p];if(s.status!=="fulfilled"||i===void 0)return;for(let y of s.value.rooms)d.push({room:y,kind:i})}),d.sort((s,p)=>Le(s.room,p.room));let m={};for(let{room:s}of d)if(Ae(s))m[s.key]=!0;return{views:d.map(({room:s,kind:p})=>He(s,p)),attention:m,loaded:!0}}function bs(n){let l=Re(),d=u((v)=>v.connects),m=Ee((v)=>v.lists),s=a(0),p=a(0),i=n.join(`
|
|
2
|
-
`),{views:y}=_n();o(()=>{s.current+=1;let v=s.current,R=!0;return Ce(i===""?[]:i.split(`
|
|
3
|
-
`)).then((h)=>{if(!R||v<p.current)return;p.current=v,de=h,Te()}),()=>{R=!1}},[i,d,m]);let S=y.slice(0,we).map((v)=>v.key).join(`
|
|
4
|
-
`);o(()=>{let v=S===""?[]:S.split(`
|
|
5
|
-
`);for(let R of v)l.send({type:"subscribe",room:R});return()=>{for(let R of v)l.send({type:"unsubscribe",room:R})}},[l,S,d])}var Ne=380,Oe="cubic-bezier(0.7, 0, 0.84, 0)",Ve=2.4,le=0.35,$e=260,_e="cubic-bezier(0.2, 0.8, 0.2, 1)",De=1.06,Ie=700,x;function fe(n){if(x?.host===n&&x.phase==="diving")x.abort()}var Pe=(n)=>{if(!n||typeof n.animate!=="function")return;n.animate([{transform:`scale(${De})`,opacity:le},{transform:"scale(1)",opacity:1}],{duration:$e,easing:_e})};function me(n,l,d,m){if(x)return;let s=n.closest("main.route")??n;if(Se()||typeof s.animate!=="function"){d();return}m?.();let p=s.getBoundingClientRect(),i=`${l.x-p.left}px ${l.y-p.top}px`,y={overflow:s.style.overflow,events:s.style.pointerEvents};s.style.overflow="hidden",s.style.pointerEvents="none";let S=s.animate([{transformOrigin:i,transform:"scale(1)",opacity:1},{transformOrigin:i,transform:`scale(${Ve})`,opacity:le}],{duration:Ne,easing:Oe,fill:"forwards"}),v=document.documentElement,R,h,T=()=>{s.style.overflow=y.overflow,s.style.pointerEvents=y.events,S.cancel()},D=()=>{window.removeEventListener("popstate",H),window.removeEventListener("hashchange",H)},k={host:n,phase:"diving",abort:H};function H(){if(x!==k||k.phase!=="diving")return;D(),T(),x=void 0}let A=(O)=>{if(x!==k)return;if(h?.disconnect(),clearTimeout(R),v.removeAttribute("data-dive"),T(),x=void 0,O)Pe(document.querySelector("main.route"))};x=k,window.addEventListener("popstate",H),window.addEventListener("hashchange",H),S.finished.then(()=>{if(x!==k||k.phase!=="diving")return;if(k.phase="committing",D(),v.setAttribute("data-dive",""),d(),!n.isConnected){A(!0);return}h=new MutationObserver(()=>{if(!n.isConnected)A(!0)}),h.observe(s.parentElement??document.body,{childList:!0,subtree:!0}),R=setTimeout(()=>A(!n.isConnected),Ie)},()=>{return})}var pe=(n)=>n.filter((l)=>l.muted!==!0),Be=(n)=>n==="sleepy"?"idle":n;function ge(n,l){let d={};for(let[m,s]of Object.entries(n))d[m]=Be(s);for(let m of l){let s=m.agent;if(!m.typing||s===void 0||!(s in d))continue;let p=d[s];if(p==="waiting"||p==="error")continue;d[s]="speaking"}return d}function Z(n,l){if(n==="speaking")return"happy";return(l?.STATE_EXPRESSION??Fe)[n]}var Fe={idle:"neutral",thinking:"thinking",working:"determined",waiting:"curious",done:"proud",error:"apologetic",sleepy:"sleepy"};function ee(n,l){return`s${n}${l.toLowerCase().replace(/[^a-z0-9]/g,"")}`.slice(0,16)}var je={x:-7,y:-3,w:114,h:100},P=256;function te(n,l,d,m,s,p){let i=n.composeSvg(l,{bare:!0,look:d,expr:Z(m,n),state:"idle",still:!0,size:P,uid:s,skins:p}),{x:y,y:S,w:v,h:R}=je;return i.replace('viewBox="0 0 100 100"',`viewBox="${y} ${S} ${v} ${R}"`).replace(`width="${P}" height="${P}"`,`width="${P}" height="${Math.round(P*R/v)}"`)}function ye(n){let l=n.delayMs??300,d=n.timers??{set:(i,y)=>setTimeout(i,y),clear:(i)=>clearTimeout(i)},m=new Map,s=new Map,p=(i)=>{let y=s.get(i);if(y===void 0)return;d.clear(y),s.delete(i)};return{seed(i,y){p(i),m.set(i,Z(y))},update(i,y){let S=Z(y);if(!m.has(i)){m.set(i,S);return}if(p(i),m.get(i)===S)return;s.set(i,d.set(()=>{s.delete(i),m.set(i,S),n.setAvatar(i,y)},l))},forget(i){p(i),m.delete(i)},dispose(){for(let i of[...s.keys()])p(i);m.clear()}}}var ze={idle:c("idle"),thinking:c("thinking"),working:c("working"),waiting:c("waiting"),speaking:c("speaking"),done:c("done"),error:c("error")},Ke=()=>({table:t("Round table"),seat:(n,l)=>t("{name} ({state})",{name:n,state:t(ze[l])})}),Xe=()=>{qe().catch(()=>{return})},We=10;function wi(n,l={}){let d=l.all===!0,m=Tn(),{views:s}=_n(),p=Si(),i=u((y)=>{let S=y.order.map((h)=>y.rooms[h]?.view).filter((h)=>h!==void 0&&h.kind==="agent"),v=n?n.map((h)=>S.find((T)=>T.name===h)).filter((h)=>h!==void 0):S;return[...n||d?v:pe(v)].sort((h,T)=>Number(T.home)-Number(h.home))},`${d}
|
|
6
|
-
${n?.join(`
|
|
7
|
-
`)??""}`);if(m)return s;return p&&!n&&!d?[...i,...s]:i}var Jn=()=>wi(void 0,{all:!0});function Ye(n){return u((l)=>Object.values(l.rooms).filter((d)=>n?d.key===n:d.view?.kind==="group").map((d)=>({typing:d.typing,...d.agent===void 0?{}:{agent:d.agent}})),n??"")}function Bt(n){let{variant:l="full",onHandle:d}=n,m=Qn(),s=Je(),p=Rn(),i=pn(),y=gt(),S=wi(n.members),v=Es(S.map((g)=>g.key)),R=Ye(n.groupRoom),h=_n().attention,T=Tn(),D=a(T);D.current=T;let k=Me("(orientation: portrait)"),H=l==="full"&&(n.list===!0||k&&S.length>We),A=N(()=>ge(Object.fromEntries(S.map((g)=>{let w=v[g.key]??"idle";return[g.name,h[g.key]&&(w==="idle"||w==="sleepy")?"waiting":w]})),R),[S,v,R,h]),O=a(A);O.current=A;let L=N(()=>{if(!m)return[];return S.map((g,w)=>{let b=y[g.name]??g.character??sn(m,g);return{id:g.name,name:g.displayName,color:m.accentOf(b,p.look),avatarSvg:te(m,b,p.look,O.current[g.name]??"idle",ee(w,g.name),i)}})},[m,S,y,p.look,i]),X=a(L);X.current=L;let G=a(S);G.current=S;let U=a({look:s,scheme:p.scheme});U.current={look:s,scheme:p.scheme};let W=a(null),V=a(void 0),[F,ve]=r(0),j=a(void 0),ne=a(()=>{return});ne.current=(g)=>{let w=S.find((b)=>b.name===g);if(!m||!w)return;return y[g]??w.character??sn(m,w)};let oe=a(p);oe.current=p;let re=a(i);re.current=i;let se=a(m);se.current=m;let Y=a(d);Y.current=d;let M=a(n);M.current=n;let ie=m!==void 0&&L.length>0;o(()=>{let g=W.current;if(!ie||!g)return;let w=!0,b,Q=ye({setAvatar:(_,q)=>{let C=ne.current(_),E=se.current,I=G.current.findIndex((z)=>z.name===_);if(!C||!E||I<0)return;b?.setAvatar(_,te(E,C,oe.current.look,q,ee(I,_),re.current))}});return j.current=Q,(async()=>{let{mountRoundTable:_}=await (f("red1597w"),import("./chunk-entry-red1597w.js")),q=X.current.map((E)=>({...E,state:O.current[E.id]??"idle"})),C=await _(g,{theme:U.current.look,scheme:U.current.scheme,seats:q,onSeatClick:({id:E,at:I})=>{let z=M.current.onSeat;if(z){z(E);return}let ae=G.current.find((he)=>he.name===E);if(!ae)return;let ce=()=>K("room",ae.key),ue=W.current;if(I&&ue)me(ue,I,ce,D.current?Xe:void 0);else ce()},...M.current.onSeatMenu?{onSeatMenu:(E)=>M.current.onSeatMenu?.(E)}:{},ownerName:M.current.ownerName??t("You"),focus:M.current.focus??null,onFocus:(E)=>M.current.onFocus?.(E),onMore:()=>M.current.onMore?.(),reducedMotion:"auto",lowPower:"auto",variant:l,listBelow:H,labels:Ke()});if(!w){C.dispose();return}b=C,V.current=C;for(let E of q)Q.seed(E.id,E.state??"idle");Y.current?.(C),ve((E)=>E+1)})(),()=>{w=!1,fe(g),Q.dispose(),j.current=void 0,V.current=void 0,Y.current?.(void 0),b?.dispose()}},[ie,l,H]);let J=n.focus??null;if(o(()=>{let g=V.current;if(g&&g.focused()!==J)g.focus(J)},[J,F]),o(()=>{let g=V.current;if(!g||L.length===0)return;let w=O.current;g.setSeats(L.map((b)=>({...b,state:w[b.id]??"idle"})));for(let b of L)j.current?.seed(b.id,w[b.id]??"idle")},[L,F]),o(()=>{let g=V.current;if(g)g.setTheme(s,p.scheme)},[s,p.scheme,F]),o(()=>{let g=V.current;if(!g)return;for(let w of X.current){let b=A[w.id]??"idle";g.setState(w.id,b),j.current?.update(w.id,b)}},[A,F]),S.length===0)return e("p",{className:"table-empty",children:t("No knights are seated yet.")});return e("section",{className:"table-host",ref:W,"aria-label":t("Round table")})}
|
|
8
|
-
export{_n,Tn,Si,bs,wi,Jn,Bt};
|