pi-roundtable-web 0.26.2 → 0.27.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/CHANGELOG.md +42 -0
- package/README.md +34 -12
- package/dist/chunk-account-1ecx5kt7.js +1 -0
- package/dist/chunk-action-menu-zh2n0ahf.js +1 -0
- package/dist/chunk-agent-ynm2tcbx.js +1 -0
- package/dist/chunk-arranged-rooms-qnz8vese.js +1 -0
- package/dist/chunk-bulk-actions-pr0mw0kc.js +1 -0
- package/dist/chunk-character-creator-caj4pmg4.js +1 -0
- package/dist/{chunk-codeeditor-jm2sm333.js → chunk-codeeditor-dga6s78p.js} +2 -2
- package/dist/chunk-confirm-g76v5d9r.js +1 -0
- package/dist/{chunk-connectors-mhnw6d79.js → chunk-connectors-j79ze3j1.js} +1 -1
- package/dist/{chunk-conversations-yjyq4g1y.js → chunk-conversations-2farn72g.js} +1 -1
- package/dist/chunk-council-sheet-s9sz1bzf.js +2 -0
- package/dist/{chunk-drag-nyq52ck7.js → chunk-drag-45e8222r.js} +1 -1
- package/dist/chunk-entry-q11n47h9.js +1 -0
- package/dist/chunk-folder-list-4gcj7g7h.js +1 -0
- package/dist/chunk-folds-ten4ykfw.js +1 -0
- package/dist/chunk-gate-kcv1a4t0.js +1 -0
- package/dist/chunk-group-scene-12ghcvzd.js +1 -0
- package/dist/chunk-group-table-t458kdgn.js +1 -0
- package/dist/chunk-host-icons-h1k9k96a.js +1 -0
- package/dist/chunk-host-picture-3p0wzn3v.js +1 -0
- package/dist/chunk-host-state-7mdve7cb.js +1 -0
- package/dist/chunk-host-ui-bdgwa6sf.js +1 -0
- package/dist/chunk-index-02vfshtt.js +2 -0
- package/dist/{chunk-index-31ays46f.js → chunk-index-0a81da8z.js} +2 -2
- package/dist/{chunk-index-y00wke93.js → chunk-index-0w4bfjb5.js} +2 -2
- package/dist/chunk-index-12zyshae.js +2 -0
- package/dist/chunk-index-18pgxxw3.js +2 -0
- package/dist/chunk-index-2e4am3hw.js +50 -0
- package/dist/{chunk-index-1f0j335v.js → chunk-index-2fdns8tn.js} +2 -2
- package/dist/{chunk-index-934zgd18.js → chunk-index-2t30xwed.js} +2 -2
- package/dist/{chunk-index-cmxs5y22.js → chunk-index-31x6krbs.js} +3 -3
- package/dist/{chunk-index-b7jjca66.js → chunk-index-3d8s3565.js} +2 -2
- package/dist/chunk-index-5bfqek1d.js +2 -0
- package/dist/chunk-index-64rsz6pf.js +2 -0
- package/dist/chunk-index-6bkcq9ka.js +2 -0
- package/dist/{chunk-index-9nents16.js → chunk-index-8d81qy69.js} +2 -2
- package/dist/chunk-index-92zgb7my.js +2 -0
- package/dist/chunk-index-aamhjg5n.js +2 -0
- package/dist/{chunk-index-ewj52be9.js → chunk-index-ac1ktr56.js} +2 -2
- package/dist/{chunk-index-6tpr6r6d.js → chunk-index-ak6ecqy3.js} +2 -2
- package/dist/{chunk-index-yrhbhmxz.js → chunk-index-b73y2gc0.js} +2 -2
- package/dist/chunk-index-b8cpvr7y.js +2 -0
- package/dist/{chunk-index-tmx30r1w.js → chunk-index-bhqczxr3.js} +2 -2
- package/dist/{chunk-index-0xj30mzw.js → chunk-index-cbqhzf40.js} +12 -12
- package/dist/chunk-index-cdctnw71.js +2 -0
- package/dist/chunk-index-dj0tbfyb.js +2 -0
- package/dist/chunk-index-dnjftvtq.js +2 -0
- package/dist/chunk-index-e2dqjde8.js +1 -0
- package/dist/{chunk-index-frwa2fmc.js → chunk-index-ebg48jgy.js} +2 -2
- package/dist/{chunk-index-smw1n2pt.js → chunk-index-ek5mek4j.js} +5 -5
- package/dist/chunk-index-f6q0stqx.js +2 -0
- package/dist/{chunk-index-kw85ajap.js → chunk-index-ffbrm6tr.js} +3 -3
- package/dist/chunk-index-g1awv7rk.js +2 -0
- package/dist/chunk-index-g3wrs02w.js +1 -0
- package/dist/chunk-index-j0m16cj1.js +2 -0
- package/dist/chunk-index-j4kk1m59.js +2 -0
- package/dist/chunk-index-j4x9dq30.css +1 -0
- package/dist/{chunk-index-7bbqtdce.js → chunk-index-jgzygbt8.js} +2 -2
- package/dist/chunk-index-kb3w11mn.js +7 -0
- package/dist/chunk-index-kbrg32sx.js +2 -0
- package/dist/chunk-index-msqhgvfx.js +2 -0
- package/dist/chunk-index-pefwfm26.js +2 -0
- package/dist/chunk-index-pyfx77cj.js +2 -0
- package/dist/{chunk-index-kfv996qe.js → chunk-index-q7g62sgm.js} +35 -3
- package/dist/chunk-index-qfgkfq86.js +2 -0
- package/dist/chunk-index-rh0x9rzf.js +2 -0
- package/dist/{chunk-index-029209sy.js → chunk-index-sm7m4fej.js} +2 -2
- package/dist/chunk-index-sv9qpmhv.js +1 -0
- package/dist/chunk-index-t998yg8y.js +2 -0
- package/dist/chunk-index-tk4se135.js +4 -0
- package/dist/chunk-index-v6smgw77.js +2 -0
- package/dist/chunk-index-w42rcbx1.js +2 -0
- package/dist/chunk-index-x4enmj72.js +2 -0
- package/dist/chunk-index-xq84gg8w.js +2 -0
- package/dist/{chunk-index-f3b5nch2.js → chunk-index-xxeb2xp0.js} +3 -3
- package/dist/{chunk-index-0n6ja7my.js → chunk-index-zyvwhxga.js} +1 -1
- package/dist/chunk-lang-css-y9133ktr.js +1 -0
- package/dist/{chunk-lang-dockerfile-46rk929v.js → chunk-lang-dockerfile-cnwqn660.js} +1 -1
- package/dist/{chunk-lang-go-qb0qdpg7.js → chunk-lang-go-yy6kgsxv.js} +3 -3
- package/dist/chunk-lang-html-r2xmryek.js +1 -0
- package/dist/chunk-lang-javascript-1r6wd177.js +1 -0
- package/dist/{chunk-lang-json-1q4fp694.js → chunk-lang-json-dx56g11y.js} +1 -1
- package/dist/{chunk-lang-markdown-5w7t28wa.js → chunk-lang-markdown-fpcf2dfq.js} +5 -5
- package/dist/{chunk-lang-python-3dq0p4rf.js → chunk-lang-python-zzp95955.js} +2 -2
- package/dist/{chunk-lang-rust-70pa0agr.js → chunk-lang-rust-214fh7sp.js} +1 -1
- package/dist/{chunk-lang-shell-4pxt7hf4.js → chunk-lang-shell-1rpgtepw.js} +1 -1
- package/dist/{chunk-lang-sql-kgcbh2a9.js → chunk-lang-sql-vvp46hpj.js} +2 -2
- package/dist/{chunk-lang-toml-99t95pab.js → chunk-lang-toml-tbj7467c.js} +1 -1
- package/dist/chunk-lang-typescript-y5w4tt4g.js +1 -0
- package/dist/{chunk-lang-xml-mnbv9yfa.js → chunk-lang-xml-tbcqmedk.js} +1 -1
- package/dist/{chunk-lang-yaml-2by9g1dy.js → chunk-lang-yaml-jh56t3sv.js} +1 -1
- package/dist/chunk-layout-actions-y73mpsh1.js +1 -0
- package/dist/chunk-menu-items-bza16bw6.js +2 -0
- package/dist/chunk-mode-toggle-nj9gnt3b.js +1 -0
- package/dist/chunk-note-row-6fmhrdng.js +75 -0
- package/dist/chunk-notes-wv0e6ssf.js +1 -0
- package/dist/chunk-notice-bell-9z27epd2.js +1 -0
- package/dist/{chunk-notices-evny44be.js → chunk-notices-fte9f196.js} +1 -1
- package/dist/chunk-onboarding-c5twahc3.js +1 -0
- package/dist/{chunk-overview-42h45ehd.js → chunk-overview-k4ccprax.js} +1 -1
- package/dist/chunk-palette-9rbp2fab.js +1 -0
- package/dist/chunk-placement-items-me598wsb.js +1 -0
- package/dist/{chunk-profile-bqcgkgk4.js → chunk-profile-s7r7fcvz.js} +1 -1
- package/dist/chunk-prompt-history-hf296e7v.js +1 -0
- package/dist/chunk-prompts-c8s0nhkm.js +1 -0
- package/dist/chunk-room-confirms-ga2sbvhc.js +1 -0
- package/dist/chunk-room-menu-7h4jym2b.js +1 -0
- package/dist/chunk-rooms-menu-button-pgtaanb6.js +1 -0
- package/dist/chunk-schedules-mbnwcxpc.js +1 -0
- package/dist/{chunk-seat-menu-ca5p4e9q.js → chunk-seat-menu-r0k0eawr.js} +1 -1
- package/dist/chunk-sheet-hosts-a5dfevy9.js +1 -0
- package/dist/chunk-shortcut-help-a6pkjcq7.js +26 -0
- package/dist/chunk-shortcuts-cgt87jkz.js +1 -0
- package/dist/chunk-skill-editor-67yk4x7t.js +8 -0
- package/dist/chunk-skills-rewemey4.js +1 -0
- package/dist/chunk-switcher-list-t8rbay2y.js +1 -0
- package/dist/{chunk-tab-dot-4tkpxqeh.js → chunk-tab-dot-vr11dfrw.js} +1 -1
- package/dist/chunk-table-52nh0azk.js +1 -0
- package/dist/chunk-table2d-g57vr6h0.js +1 -0
- package/dist/chunk-table3d-rp0w6kt4.js +4220 -0
- package/dist/chunk-thread-actions-qcxt1y1g.js +1 -0
- package/dist/chunk-thread-cards-c2mrp2gj.js +1 -0
- package/dist/chunk-thread-list-0071q455.js +217 -0
- package/dist/chunk-transcript-789yqysq.js +1 -0
- package/dist/chunk-where-hmwmme9e.js +1 -0
- package/dist/{chunk-workspace-h0p32ygy.js → chunk-workspace-wr1qrtsh.js} +2 -2
- package/dist/chunk-zh-tw-z5p5mpph.js +1 -0
- package/dist/index.html +1 -1
- package/dist/sw.js +1 -1
- package/package.json +3 -3
- package/src/api-types.ts +73 -0
- package/src/app/app.ts +38 -4
- package/src/app/helper-routes.ts +106 -0
- package/src/app/rooms.ts +18 -3
- package/src/app/routes.ts +125 -2
- package/src/app/surface.ts +18 -1
- package/src/app/team-routes.ts +21 -1
- 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 +64 -13
- package/dist/chunk-account-nhpd9j90.js +0 -1
- package/dist/chunk-action-menu-ec9jqtxq.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-entry-red1597w.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-43k1rjmx.js +0 -2
- package/dist/chunk-index-4gk88a0x.js +0 -4
- package/dist/chunk-index-4jf4jvfd.css +0 -1
- 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-datrrs6b.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-note-row-72n6cqyk.js +0 -75
- 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-room-menu-7s0feajw.js +0 -1
- package/dist/chunk-rooms-menu-button-gawqvpsr.js +0 -1
- package/dist/chunk-schedules-zba7krac.js +0 -1
- package/dist/chunk-sheet-hosts-ssbz6hf2.js +0 -1
- package/dist/chunk-skill-editor-n0y9pd90.js +0 -8
- package/dist/chunk-skills-ea4vb2s4.js +0 -1
- package/dist/chunk-switcher-list-pj5csqr9.js +0 -1
- package/dist/chunk-table-j8nmtdnn.js +0 -1
- package/dist/chunk-table-seats-qeytqe0m.js +0 -1
- package/dist/chunk-table2d-18y029k9.js +0 -1
- package/dist/chunk-table3d-q2s31ae0.js +0 -4220
- 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/surface.ts
CHANGED
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
roomOf,
|
|
15
15
|
type TurnProgress,
|
|
16
16
|
} from "pi-roundtable";
|
|
17
|
-
import type { RoomFile, RoomMessage } from "../api-types.ts";
|
|
17
|
+
import type { RoomFile, RoomMessage, RoundView } from "../api-types.ts";
|
|
18
18
|
import type { OwnerDesk } from "./desk.ts";
|
|
19
19
|
import { type FileBinding, type FileDir, typeByName } from "./files.ts";
|
|
20
20
|
import type { NewRoomMessage, RoomLog } from "./room-log.ts";
|
|
@@ -115,6 +115,8 @@ export class AppSurface implements ChatSurface {
|
|
|
115
115
|
readonly threads: AppSurfaceThreads;
|
|
116
116
|
readonly #options: AppSurfaceOptions;
|
|
117
117
|
readonly #activity = new Map<ChannelKey, Activity>();
|
|
118
|
+
/** The round each group room runs now; an ended round is dropped, since the page keeps what it was told. */
|
|
119
|
+
readonly #rounds = new Map<ChannelKey, RoundView>();
|
|
118
120
|
/** When a page last sent a message to each room. */
|
|
119
121
|
readonly #askedAt = new Map<ChannelKey, number>();
|
|
120
122
|
/** The turns running in each room that a page's message started. */
|
|
@@ -196,6 +198,21 @@ export class AppSurface implements ChatSurface {
|
|
|
196
198
|
};
|
|
197
199
|
}
|
|
198
200
|
|
|
201
|
+
/** Where the group room's running round stands, for a page that opens mid-round. */
|
|
202
|
+
roundOf(room: ChannelKey): RoundView | undefined {
|
|
203
|
+
return this.#rounds.get(room);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/** Shows a group round's step to the sockets that may have the room. */
|
|
207
|
+
groupRound(channel: ChannelKey, round: RoundView): void {
|
|
208
|
+
if (round.state === "ended") this.#rounds.delete(channel);
|
|
209
|
+
else this.#rounds.set(channel, round);
|
|
210
|
+
this.#options.sockets.deliver(
|
|
211
|
+
{ type: "round", room: channel, round },
|
|
212
|
+
this.#options.audienceOf(channel),
|
|
213
|
+
);
|
|
214
|
+
}
|
|
215
|
+
|
|
199
216
|
/** The agents with a turn working in an app room now: a room's own agent, or a group's speaker. */
|
|
200
217
|
workingAgents(): Set<string> {
|
|
201
218
|
const names = new Set<string>();
|
package/src/app/team-routes.ts
CHANGED
|
@@ -133,7 +133,17 @@ export class TeamApi {
|
|
|
133
133
|
// The app's part runs inside the delete, after its checks and before the row goes: a
|
|
134
134
|
// cleanup that fails leaves the agent there to delete again.
|
|
135
135
|
const room = agentRoomKey(this.#options.surface, name);
|
|
136
|
-
await this.#options.team.remove(name, () =>
|
|
136
|
+
await this.#options.team.remove(name, async () => {
|
|
137
|
+
// Its archived temp knights go with it, and so does what the app kept of their rooms.
|
|
138
|
+
for (const helper of this.#options.directory
|
|
139
|
+
.agents()
|
|
140
|
+
.filter((one) => one.parent === name))
|
|
141
|
+
await this.#forget(
|
|
142
|
+
agentRoomKey(this.#options.surface, helper.name),
|
|
143
|
+
by,
|
|
144
|
+
);
|
|
145
|
+
await this.#forget(room, by);
|
|
146
|
+
});
|
|
137
147
|
this.#options.changed();
|
|
138
148
|
return json({ ok: true });
|
|
139
149
|
}
|
|
@@ -311,6 +321,15 @@ export class TeamApi {
|
|
|
311
321
|
avatar: rooms.avatarOf(agent),
|
|
312
322
|
character: characterOf(agent),
|
|
313
323
|
room: agentRoomKey(surface, agent.name),
|
|
324
|
+
...(agent.parent
|
|
325
|
+
? {
|
|
326
|
+
helper: {
|
|
327
|
+
parent: agentRoomKey(surface, agent.parent),
|
|
328
|
+
parentName:
|
|
329
|
+
directory.agent(agent.parent)?.displayName ?? agent.parent,
|
|
330
|
+
},
|
|
331
|
+
}
|
|
332
|
+
: {}),
|
|
314
333
|
};
|
|
315
334
|
}
|
|
316
335
|
|
|
@@ -412,6 +431,7 @@ export class TeamApi {
|
|
|
412
431
|
displayName: agent.displayName,
|
|
413
432
|
avatar: rooms.avatarOf(agent),
|
|
414
433
|
character: characterOf(agent),
|
|
434
|
+
...(agent.parent ? { parent: agent.parent } : {}),
|
|
415
435
|
}),
|
|
416
436
|
),
|
|
417
437
|
...directory
|
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
|
@@ -282,16 +282,38 @@ export const ZH_TW: Readonly<Record<string, string>> = {
|
|
|
282
282
|
"Reply to the knight that started this thread.": "回覆開啟這個討論串的騎士。",
|
|
283
283
|
"Yolo mode": "Yolo 模式",
|
|
284
284
|
"No knights are seated yet.": "圓桌上還沒有騎士入座。",
|
|
285
|
-
"Who's at the table": "誰上桌",
|
|
286
|
-
"Off the table": "離席中",
|
|
287
|
-
"Leave the table": "離席",
|
|
288
|
-
"{name} left the table": "{name}已離席",
|
|
289
285
|
"The table is empty": "圓桌空了",
|
|
290
286
|
"There are no rooms to seat yet.": "還沒有可以入座的聊天室。",
|
|
291
|
-
"
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
287
|
+
"All rooms": "所有聊天室",
|
|
288
|
+
"Council: {name} ▾": "評議會:{name} ▾",
|
|
289
|
+
Council: "評議會",
|
|
290
|
+
Councils: "評議會",
|
|
291
|
+
"{count} knights": "{count} 位騎士",
|
|
292
|
+
"Pick who sits": "選誰上桌",
|
|
293
|
+
"No council yet": "還沒有評議會",
|
|
294
|
+
"The council is empty": "評議會沒有人了",
|
|
295
|
+
"Every member of this council is gone. Edit who sits.":
|
|
296
|
+
"這個評議會的成員都不在了。請重新選誰上桌。",
|
|
297
|
+
"A council is a group of up to {max} knights who answer in turn. Pick who sits.":
|
|
298
|
+
"評議會是最多 {max} 位騎士組成的群組,他們輪流發言。請選誰上桌。",
|
|
299
|
+
"Edit this council": "編輯這個評議會",
|
|
300
|
+
"{count} of {max} picked": "已選 {count}/{max}",
|
|
301
|
+
"At most {max} knights": "最多 {max} 位",
|
|
302
|
+
"A council needs at least {min} knights.": "評議會至少要有 {min} 位騎士。",
|
|
303
|
+
"Council name": "評議會名稱",
|
|
304
|
+
"Save as a new council": "另存為新評議會",
|
|
305
|
+
"Make council": "建立評議會",
|
|
306
|
+
"Private chat": "私下對話",
|
|
307
|
+
"Remove from the council": "移出評議會",
|
|
308
|
+
"{name} left the council": "{name}已移出評議會",
|
|
309
|
+
"Speaking order": "發言順序",
|
|
310
|
+
"has spoken": "已發言",
|
|
311
|
+
"Reply {n} of {limit}": "第 {n}/{limit} 則",
|
|
312
|
+
"{count} of {limit} replies": "{count}/{limit} 則回覆",
|
|
313
|
+
"Limit reached": "已達上限",
|
|
314
|
+
"Round stopped": "本輪已停止",
|
|
315
|
+
"Stop the round": "停止本輪",
|
|
316
|
+
"Your message waits for the next round": "你的訊息排在下一輪",
|
|
295
317
|
|
|
296
318
|
// 通知
|
|
297
319
|
"A file is no longer available. Attach it again.":
|
|
@@ -542,7 +564,7 @@ export const ZH_TW: Readonly<Record<string, string>> = {
|
|
|
542
564
|
"Edit group": "編輯群組",
|
|
543
565
|
"Name, members and host": "名稱、成員與主持人",
|
|
544
566
|
Members: "成員",
|
|
545
|
-
"Pick 2 to
|
|
567
|
+
"Pick 2 to 8 knights. They take turns in the order picked.":
|
|
546
568
|
"選 2 到 6 位騎士。他們依選取的順序輪流發言。",
|
|
547
569
|
Host: "主持人",
|
|
548
570
|
"It stops answering. The history is kept and it can be restored.":
|
|
@@ -570,6 +592,16 @@ export const ZH_TW: Readonly<Record<string, string>> = {
|
|
|
570
592
|
"Dispatch threads": "派工討論串",
|
|
571
593
|
"Find a room": "尋找聊天室",
|
|
572
594
|
"Switch rooms": "切換聊天室",
|
|
595
|
+
"Keyboard shortcuts": "鍵盤快速鍵",
|
|
596
|
+
"Previous room": "上一個聊天室",
|
|
597
|
+
"Next room": "下一個聊天室",
|
|
598
|
+
"Previous room with unread messages": "上一個有未讀訊息的聊天室",
|
|
599
|
+
"Next room with unread messages": "下一個有未讀訊息的聊天室",
|
|
600
|
+
"Close the open menu or sheet, or leave the message box":
|
|
601
|
+
"關閉開啟的選單或面板;都沒有時離開訊息輸入框",
|
|
602
|
+
"Show these shortcuts": "顯示這份快速鍵清單",
|
|
603
|
+
"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).":
|
|
604
|
+
"在訊息輸入框裡,方向鍵快速鍵只在框內沒有文字,或游標在最開頭(上)、最結尾(下)時才會切換聊天室。",
|
|
573
605
|
Group: "群組",
|
|
574
606
|
Groups: "群組",
|
|
575
607
|
Home: "首頁",
|
|
@@ -588,17 +620,36 @@ export const ZH_TW: Readonly<Record<string, string>> = {
|
|
|
588
620
|
"Clear finished": "清除已完成",
|
|
589
621
|
Finished: "已完成",
|
|
590
622
|
"In progress": "進行中",
|
|
623
|
+
Ended: "已結束",
|
|
624
|
+
"Temp knight": "臨時騎士",
|
|
625
|
+
"{count} temp knight": "{count} 位臨時騎士",
|
|
626
|
+
"{count} temp knights": "{count} 位臨時騎士",
|
|
627
|
+
"Made by {name}": "隸屬 {name}",
|
|
628
|
+
"Temp knight of {name}": "{name} 的臨時騎士",
|
|
629
|
+
"Clear finished temp knights": "清除已結束的臨時騎士",
|
|
630
|
+
"Archived {count} temp knight": "已封存 {count} 位臨時騎士",
|
|
631
|
+
"Archived {count} temp knights": "已封存 {count} 位臨時騎士",
|
|
632
|
+
"Archive this temp knight": "封存這位臨時騎士",
|
|
633
|
+
"{name} archived {count} temp knight: {names}":
|
|
634
|
+
"{name}封存了 {count} 位臨時騎士:{names}",
|
|
635
|
+
"{name} archived {count} temp knights: {names}":
|
|
636
|
+
"{name}封存了 {count} 位臨時騎士:{names}",
|
|
591
637
|
"More actions for {name}": "{name} 的更多動作",
|
|
592
638
|
"Cleared “{name}”": "已清除「{name}」",
|
|
593
639
|
"Cleared {count} finished thread": "已清除 {count} 個已完成的討論串",
|
|
594
640
|
"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
641
|
"The thread is still open.": "這個討論串還在進行中。",
|
|
600
642
|
"threads must be a list of at most 100 keys.":
|
|
601
643
|
"threads 必須是最多 100 個鍵的清單。",
|
|
644
|
+
"Give names, the temp knights to restore.": "請提供要復原的臨時騎士名稱。",
|
|
645
|
+
"rooms must be a list of at most 500 keys.":
|
|
646
|
+
"rooms 必須是最多 500 個鍵的清單。",
|
|
647
|
+
"restore must be a list of at most 500 moves.":
|
|
648
|
+
"restore 必須是最多 500 筆移動紀錄的清單。",
|
|
649
|
+
"Mark all as read": "全部標為已讀",
|
|
650
|
+
"Marked {count} room as read": "已將 {count} 個聊天室標為已讀",
|
|
651
|
+
"Marked {count} rooms as read": "已將 {count} 個聊天室標為已讀",
|
|
652
|
+
"Clear all finished threads": "清除所有已結束的討論串",
|
|
602
653
|
|
|
603
654
|
// 排程
|
|
604
655
|
"{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,Fe,a,r,g,e,n,s,un,ks}from"./chunk-index-84v7j6vh.js";import{D}from"./chunk-index-9nents16.js";var L=()=>typeof matchMedia==="function"&&matchMedia("(max-width: 719px)").matches,k={rtMenu:!0},x=()=>Boolean(window.history.state?.rtMenu),w=8,M=(t)=>t?.isConnected?t:null;function y(t){return t.items.map((u)=>n("button",{type:"button",role:u.checked===void 0?"menuitem":"menuitemcheckbox",...u.checked===void 0?{}:{"aria-checked":u.checked},className:"menu-item menu-link","data-tone":u.tone,onClick:()=>t.onChoose(u),children:[u.icon?e("span",{className:"menu-icon","data-tone":u.tone,children:e(s,{name:u.icon,size:18})}):null,e("span",{className:"menu-text",children:e("strong",{children:u.label})}),u.checked?e(s,{name:"check",size:18,className:"menu-check"}):null]},u.id))}function H({menu:t}){let u=a(void 0);if(t)u.current=t;let c=u.current,m=a(!1),p=a(void 0),h=t?.serial;return o(()=>{if(h===void 0)return;return window.history.pushState(k,"",window.location.href),m.current=!0,()=>{if(m.current)m.current=!1,window.history.back()}},[h]),o(()=>{let f=()=>{if(!m.current||x())return;m.current=!1,un();let E=p.current;p.current=void 0,E?.()};return window.addEventListener("popstate",f),()=>window.removeEventListener("popstate",f)},[]),e(D,{open:t!==void 0,title:c?.title??"",onClose:un,restoreFocus:()=>M(c?.source??null),children:c?e("div",{className:"menu action-items",role:"menu","aria-label":c.title,children:e(y,{items:c.items,onChoose:(f)=>{if(!m.current){un(),f.run();return}p.current=f.run,window.history.back()}})}):null})}function T({menu:t}){let u=a(null),[c,m]=r(t.at),{source:p}=t,h=(i)=>{M(p)?.focus(),un(),i?.()},f=a(h);f.current=h,Fe(()=>{let i=u.current;if(!i)return;let d=i.getBoundingClientRect();m({x:Math.max(w,Math.min(t.at.x,window.innerWidth-d.width-w)),y:Math.max(w,Math.min(t.at.y,window.innerHeight-d.height-w))}),i.querySelector('[role^="menuitem"]')?.focus()},[t.serial]),o(()=>{let i=(l)=>{if(l.target instanceof Node&&u.current?.contains(l.target))return;un()},d=()=>un();return document.addEventListener("pointerdown",i,!0),document.addEventListener("wheel",i,{capture:!0,passive:!0}),document.addEventListener("touchmove",i,{capture:!0,passive:!0}),window.addEventListener("resize",d),()=>{document.removeEventListener("pointerdown",i,!0),document.removeEventListener("wheel",i,!0),document.removeEventListener("touchmove",i,!0),window.removeEventListener("resize",d)}},[]);let E=(i)=>{let d=[...u.current?.querySelectorAll('[role^="menuitem"]')??[]],l=d.indexOf(document.activeElement),v=(b)=>{i.preventDefault(),d[(b+d.length)%d.length]?.focus()};switch(i.key){case"Escape":i.preventDefault(),i.stopPropagation(),f.current();return;case"ArrowDown":return v(l+1);case"ArrowUp":return v(l<0?-1:l-1);case"Tab":return v(i.shiftKey?l<0?-1:l-1:l+1);case"Home":return v(0);case"End":return v(-1)}};return e("div",{ref:u,className:"action-popover",role:"menu","aria-label":t.title,tabIndex:-1,style:{left:`${c.x}px`,top:`${c.y}px`},onKeyDown:E,children:e(y,{items:t.items,onChoose:(i)=>h(i.run)})})}function O(){let t=ks(),u=a(void 0);if(t&&u.current?.serial!==t.serial)u.current={serial:t.serial,sheet:L()};let c=Boolean(t&&u.current?.sheet);return n(g,{children:[e(H,{menu:c?t:void 0}),t&&!c?e(T,{menu:t},t.serial):null]})}export{O as ActionMenuHost};
|
|
@@ -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{Mt,qt}from"./chunk-index-31ays46f.js";import{f}from"./chunk-index-84v7j6vh.js";function H(){try{let c=document.createElement("canvas");return!!(c.getContext("webgl2")||c.getContext("webgl"))}catch{return!1}}function x(c,n){return[c,n.includes("?")?n.slice(n.indexOf("?")):""].some((r)=>{let d=new URLSearchParams(r).get("nogl");return d!==null&&d!=="0"&&d!=="false"})}async function I(c,n,T){let r=n.variant==="compact",d=n.labels??qt,l=new Map,E=(e)=>{l.clear();for(let t of e)l.set(t.id,{...t})};E(n.seats);let m={t:n.theme,s:n.scheme},a=null,o=document.createElement("div");o.className="rt-table",o.dataset.variant=r?"compact":"full";let g=document.createElement("div");g.className="rt-table-stage",o.appendChild(g);let i=null,y=!1,A=()=>!r&&(Boolean(n.listBelow)||y);c.appendChild(o);let u=new Map,p=()=>{if(!A()){i?.remove(),i=null,u.clear(),delete o.dataset.list;return}if(!i)i=document.createElement("ul"),i.className="rt-table-list",i.setAttribute("aria-label",d.table),o.appendChild(i),o.dataset.list="";for(let e of[...u.keys()])if(!l.has(e))u.delete(e);for(let e of l.values()){let t=u.get(e.id);if(!t){t=document.createElement("button"),t.type="button",t.dataset.seat=e.id;let s=e.id;t.addEventListener("click",(S)=>{let b=l.get(s);if(b)n.onSeatClick({id:b.id,name:b.name,at:Mt(S,S.currentTarget)})}),u.set(e.id,t)}t.textContent=d.seat(e.name,e.state??"idle"),t.style.setProperty("--seat",e.color)}i.replaceChildren(...[...l.values()].map((e)=>{let t=document.createElement("li"),s=u.get(e.id);if(s)t.appendChild(s);return t}))};p();let w=(e)=>{y=!e,p(),n.onNames?.(e)},v=async()=>{let{createTable2D:e}=await (f("18y029k9"),import("./chunk-table2d-18y029k9.js"));a=e(g,{...n,theme:m.t,scheme:m.s,seats:[...l.values()]}),w(!0)},C=async()=>{let{createTable3D:e}=await (f("q2s31ae0"),import("./chunk-table3d-q2s31ae0.js"));a=e(g,{...n,theme:m.t,scheme:m.s,seats:[...l.values()],onNames:w},()=>{a?.dispose(),v()})};if(r||T==="svg"||T!=="webgl"&&(x(location.search,location.hash)||!H()))await v();else try{await C()}catch{await v()}let L,M=n.onSeatMenu;if(M&&!r){let{attachSeatMenu:e}=await (f("ca5p4e9q"),import("./chunk-seat-menu-ca5p4e9q.js"));L=e(o,(t,s,S)=>{let b=t instanceof Element?t.closest("[data-seat]")?.dataset.seat:void 0,h=l.get(b??a?.seatAt?.(s,S)??"");return h?{id:h.id,name:h.name}:void 0},M)}return{get kind(){return a.kind},setTheme(e,t){m={t:e,s:t},a.setTheme(e,t)},setSeats(e){E(e),p(),a.setSeats(e)},setState(e,t){let s=l.get(e);if(s)s.state=t;p(),a.setState(e,t)},setAvatar(e,t){let s=l.get(e);if(s)s.avatarSvg=t;return a.setAvatar(e,t)},setReducedMotion:(e)=>a.setReducedMotion(e),resetCamera:()=>a.resetCamera(),focus:(e,t)=>a.focus(e,t),focused:()=>a.focused(),seatAt:(e,t)=>a.seatAt?.(e,t)??null,getStats:()=>a.getStats(),dispose(){L?.(),a?.dispose(),o.remove()}}}export{I as mountRoundTable};
|
|
@@ -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};
|