@senguoyun/dsh-arkme 0.1.84 → 0.1.85

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.
Files changed (64) hide show
  1. package/docs/self-role-cross-client.md +60 -0
  2. package/lib/client.js +1397 -419
  3. package/lib/client.js.map +1 -1
  4. package/lib/harness-model-client.js +58 -0
  5. package/lib/harness-native-selection-client.js +58 -0
  6. package/lib/harness-sidebar-client.js +40 -0
  7. package/lib/index.js +135 -66
  8. package/lib/persistent-extension.js +1 -1
  9. package/lib/{persistent-runtime-CuKplHIv.js → persistent-runtime-adGFmkIa.js} +457 -93
  10. package/lib/sdk.js +40 -0
  11. package/lib/types/arkme-service.d.ts +2 -3
  12. package/lib/types/arkme-service.d.ts.map +1 -1
  13. package/lib/types/client/ArkmeCalendarSurface.d.ts.map +1 -1
  14. package/lib/types/client/ArkmeFileViewer.d.ts.map +1 -1
  15. package/lib/types/client/ArkmeLongArticleDialog.d.ts +0 -1
  16. package/lib/types/client/ArkmeLongArticleDialog.d.ts.map +1 -1
  17. package/lib/types/client/ArkmeLongArticleDraftDialog.d.ts +11 -0
  18. package/lib/types/client/ArkmeLongArticleDraftDialog.d.ts.map +1 -0
  19. package/lib/types/client/ArkmeMarkdownBody.d.ts +2 -1
  20. package/lib/types/client/ArkmeMarkdownBody.d.ts.map +1 -1
  21. package/lib/types/client/ArkmePersistentShell.d.ts.map +1 -1
  22. package/lib/types/client/ArkmeRecordingSurface.d.ts.map +1 -1
  23. package/lib/types/client/ArkmeSelfRoleMenu.d.ts +15 -0
  24. package/lib/types/client/ArkmeSelfRoleMenu.d.ts.map +1 -0
  25. package/lib/types/client/ArkmeSelfRolePicker.d.ts.map +1 -1
  26. package/lib/types/client/ArkmeVirtualWorkspace.d.ts.map +1 -1
  27. package/lib/types/client/locale.d.ts +1 -1
  28. package/lib/types/client/locale.d.ts.map +1 -1
  29. package/lib/types/client/locales/actions-en.d.ts.map +1 -1
  30. package/lib/types/client/locales/en.d.ts.map +1 -1
  31. package/lib/types/client/realtime-client-events.d.ts.map +1 -1
  32. package/lib/types/client/recordings/ArkmeRecordingTimeline.d.ts.map +1 -1
  33. package/lib/types/local-database.d.ts +8 -10
  34. package/lib/types/local-database.d.ts.map +1 -1
  35. package/lib/types/markdown.d.ts +1 -0
  36. package/lib/types/markdown.d.ts.map +1 -1
  37. package/lib/types/recording-presentation.d.ts.map +1 -1
  38. package/lib/types/sdk/index.d.ts +11 -0
  39. package/lib/types/sdk/index.d.ts.map +1 -1
  40. package/lib/types/self-role-avatar-store.d.ts +1 -6
  41. package/lib/types/self-role-avatar-store.d.ts.map +1 -1
  42. package/lib/types/self-role-contract.d.ts +13 -0
  43. package/lib/types/self-role-contract.d.ts.map +1 -0
  44. package/lib/types/self-role-sync-store.d.ts +44 -0
  45. package/lib/types/self-role-sync-store.d.ts.map +1 -0
  46. package/lib/types/services/chat-realtime-service.d.ts +1 -0
  47. package/lib/types/services/chat-realtime-service.d.ts.map +1 -1
  48. package/lib/types/services/chat-service.d.ts.map +1 -1
  49. package/lib/types/services/media-service.d.ts +15 -0
  50. package/lib/types/services/media-service.d.ts.map +1 -1
  51. package/lib/types/services/record-service.d.ts +3 -0
  52. package/lib/types/services/record-service.d.ts.map +1 -1
  53. package/lib/types/services/search-service.d.ts.map +1 -1
  54. package/lib/types/services/self-role-service.d.ts +29 -0
  55. package/lib/types/services/self-role-service.d.ts.map +1 -0
  56. package/lib/types/tools/business/index.d.ts.map +1 -1
  57. package/lib/types/tools/business/records/create.d.ts.map +1 -1
  58. package/lib/types/tools/business/records/self-roles.d.ts +2 -0
  59. package/lib/types/tools/business/records/self-roles.d.ts.map +1 -0
  60. package/lib/types/tools/ports/index.d.ts +2 -1
  61. package/lib/types/tools/ports/index.d.ts.map +1 -1
  62. package/lib/types/types.d.ts +27 -1
  63. package/lib/types/types.d.ts.map +1 -1
  64. package/package.json +5 -5
package/lib/client.js CHANGED
@@ -512,6 +512,46 @@ window.__ModuleLoader__.load({
512
512
  if (normalized === "") throw new TypeError("Arkme call reference must not be empty");
513
513
  return await this.call("calls.history.summary.retry", { callRef: normalized }, signal);
514
514
  }
515
+ async requireSelfRoles(signal) {
516
+ if ((await this.capabilities(signal)).features.selfRoles !== true) throw new Error("当前 Arkme Provider 不支持跨端角色,请升级");
517
+ }
518
+ async listSelfRoles(expectedUserId, signal) {
519
+ await this.requireSelfRoles(signal);
520
+ return await this.call("self-roles.list", { expectedUserId }, signal);
521
+ }
522
+ async createSelfRole(expectedUserId, name, avatarRef, signal) {
523
+ await this.requireSelfRoles(signal);
524
+ return await this.call("self-roles.create", {
525
+ expectedUserId,
526
+ name,
527
+ ...avatarRef === void 0 ? {} : { avatarRef }
528
+ }, signal);
529
+ }
530
+ async updateSelfRole(expectedUserId, roleId, name, avatarRef, signal) {
531
+ await this.requireSelfRoles(signal);
532
+ return await this.call("self-roles.update", {
533
+ expectedUserId,
534
+ roleId,
535
+ name,
536
+ ...avatarRef === void 0 ? {} : { avatarRef }
537
+ }, signal);
538
+ }
539
+ async deleteSelfRole(expectedUserId, roleId, signal) {
540
+ await this.requireSelfRoles(signal);
541
+ return await this.call("self-roles.delete", {
542
+ expectedUserId,
543
+ roleId
544
+ }, signal);
545
+ }
546
+ async bindSelfRole(expectedUserId, sourceRef, recordUid, roleId, signal) {
547
+ await this.requireSelfRoles(signal);
548
+ return await this.call("self-roles.bind", {
549
+ expectedUserId,
550
+ sourceRef,
551
+ recordUid,
552
+ roleId
553
+ }, signal);
554
+ }
515
555
  async profile(options = {}) {
516
556
  return await this.call(options.refresh === true ? "user.profile.refresh" : "user.profile", void 0, options.signal);
517
557
  }
@@ -32969,22 +33009,22 @@ window.__ModuleLoader__.load({
32969
33009
  }
32970
33010
  //#endregion
32971
33011
  //#region src/client/use-ask-dsh.ts
32972
- const sdk$1 = createArkmeSdk();
33012
+ const sdk$2 = createArkmeSdk();
32973
33013
  async function readAskDshOriginal(block, signal) {
32974
33014
  let fileRef = block.localFileRef;
32975
33015
  if (!fileRef) {
32976
33016
  if (!block.originalRef) throw new Error("原文件不可用");
32977
- let reception = await sdk$1.receiveFile(block.originalRef, true, signal);
33017
+ let reception = await sdk$2.receiveFile(block.originalRef, true, signal);
32978
33018
  while (reception.state !== "ready") {
32979
33019
  signal.throwIfAborted();
32980
33020
  if (reception.state === "failed") throw new Error(reception.error || "原文件下载失败");
32981
33021
  await abortableDelay(signal, 300);
32982
- reception = await sdk$1.receiveFile(block.originalRef, false, signal);
33022
+ reception = await sdk$2.receiveFile(block.originalRef, false, signal);
32983
33023
  }
32984
33024
  fileRef = reception.file?.fileRef;
32985
33025
  }
32986
33026
  if (!fileRef) throw new Error("原文件下载未完成");
32987
- const response = await fetch(sdk$1.localFileUrl(fileRef), { signal });
33027
+ const response = await fetch(sdk$2.localFileUrl(fileRef), { signal });
32988
33028
  if (!response.ok) throw new Error("读取原文件失败");
32989
33029
  const blob = await response.blob();
32990
33030
  if (block.size > 0 && blob.size !== block.size) throw new Error("原文件大小不匹配,请重新下载");
@@ -34516,6 +34556,24 @@ Arkme 用户|Arkme user
34516
34556
  正在读取录音|Loading recordings
34517
34557
  当前窗口说话人统计|Speaker statistics for this range
34518
34558
  当前窗口说话人图例|Speakers in this range
34559
+ 全天说话人统计|All-day speaker statistics
34560
+ 全天说话人图例|All-day speakers
34561
+ 关闭全天说话人统计|Close all-day speaker statistics
34562
+ 时间轴记录|Timeline entry
34563
+ 时间未标注|Time unavailable
34564
+ 场景类型|Scene
34565
+ 场景说明|Scene note
34566
+ 环境说明|Environment note
34567
+ 评价|Assessment
34568
+ 评价分数|Assessment score
34569
+ 事件标签|Event tags
34570
+ 时段总结|Period summary
34571
+ 参与者|Participants
34572
+ 说话人备注|Speaker note
34573
+ 待办|To-do
34574
+ 代表性原话|Representative quotes
34575
+ 对话摘要|Dialogue summaries
34576
+ 其他信息|Other information
34519
34577
  暂停播放|Pause
34520
34578
  转发录音片段|Forward recording segment
34521
34579
  转发对象|Forwarding destination
@@ -35115,6 +35173,15 @@ Bot 列表加载失败,点击重试|Could not load Bots. Click to retry
35115
35173
  //#endregion
35116
35174
  //#region src/client/locales/actions-en.ts
35117
35175
  const actionEnglish = {
35176
+ "发现未发布的草稿": "Unpublished draft found",
35177
+ "草稿预览": "Draft preview",
35178
+ "预览草稿": "Preview draft",
35179
+ "关闭草稿预览": "Close draft preview",
35180
+ "关闭草稿恢复弹窗": "Close draft recovery dialog",
35181
+ "保存时间:": "Saved at: ",
35182
+ "保存时间未知": "Save time unavailable",
35183
+ "编辑原文": "Edit original",
35184
+ "恢复草稿": "Restore draft",
35118
35185
  "群聊提及": "Group mention",
35119
35186
  "群内原消息的已读状态暂不可用": "Read status of the original group message is unavailable",
35120
35187
  "对方已阅读群内原消息": "They have read the original group message",
@@ -35161,6 +35228,10 @@ Bot 列表加载失败,点击重试|Could not load Bots. Click to retry
35161
35228
  "保留这篇长文的修改?": "Keep changes to this article?",
35162
35229
  "保存草稿后,可以下次继续编辑。": "Save a draft to continue editing later.",
35163
35230
  "保存并关闭": "Save and close",
35231
+ "是否暂存草稿": "Save a draft?",
35232
+ "保存草稿": "Save draft",
35233
+ "确认修改": "Confirm changes",
35234
+ "关闭草稿确认弹窗": "Close draft confirmation",
35164
35235
  "放弃修改": "Discard changes",
35165
35236
  "关闭用量与额度详情": "Close usage and limits details",
35166
35237
  "所属会话:": "Conversation: ",
@@ -35553,7 +35624,7 @@ AI 额度充值流程|AI point purchase
35553
35624
  };
35554
35625
  const getArkmeLocale = () => active;
35555
35626
  /** One language owner: the Harness preference. No second persisted preference,
35556
- * component remount, network translation, or access to user-authored content. */
35627
+ * component remount, network translation, theme mutation, or access to user-authored content. */
35557
35628
  function connectArkmeLocale(source) {
35558
35629
  const sync = () => {
35559
35630
  const next = source.getLocale().active === "en" ? "en" : "zh";
@@ -35662,7 +35733,7 @@ AI 额度充值流程|AI point purchase
35662
35733
  const n$14 = e$80;
35663
35734
  //#endregion
35664
35735
  //#region src/client/ArkmeRightPanelHeader.tsx
35665
- const styles$68 = {
35736
+ const styles$69 = {
35666
35737
  header: {
35667
35738
  flex: "none",
35668
35739
  display: "flex",
@@ -35713,7 +35784,7 @@ AI 额度充值流程|AI point purchase
35713
35784
  /** Shared geometry for right-side drawers; each panel retains its own navigation and body. */
35714
35785
  function ArkmeRightPanelHeader({ title, titleId, heading, subtitle, actions, onClose, closeLabel = "关闭详情", closeRef, closeDisabled = false, onBack, backLabel = "返回", backRef, backDisabled = false }) {
35715
35786
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("header", {
35716
- style: styles$68.header,
35787
+ style: styles$69.header,
35717
35788
  "data-arkme-right-panel-header": true,
35718
35789
  children: [
35719
35790
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("style", { children: `.arkme-right-panel-header-button:not([data-arkme-feedback]):not(:disabled):hover { background: ${arkmeTheme.hover} !important; }
@@ -35724,7 +35795,7 @@ AI 额度充值流程|AI point purchase
35724
35795
  ref: backRef,
35725
35796
  type: "button",
35726
35797
  className: "arkme-right-panel-header-button",
35727
- style: styles$68.button,
35798
+ style: styles$69.button,
35728
35799
  "aria-label": backLabel,
35729
35800
  disabled: backDisabled,
35730
35801
  onClick: onBack,
@@ -35734,18 +35805,18 @@ AI 额度充值流程|AI point purchase
35734
35805
  })
35735
35806
  }),
35736
35807
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
35737
- style: styles$68.heading,
35808
+ style: styles$69.heading,
35738
35809
  children: [heading ?? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
35739
35810
  id: titleId,
35740
- style: styles$68.title,
35811
+ style: styles$69.title,
35741
35812
  children: title
35742
35813
  }), subtitle !== void 0 && subtitle !== null && subtitle !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
35743
- style: styles$68.subtitle,
35814
+ style: styles$69.subtitle,
35744
35815
  children: subtitle
35745
35816
  })]
35746
35817
  }),
35747
35818
  actions !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
35748
- style: styles$68.actions,
35819
+ style: styles$69.actions,
35749
35820
  children: actions
35750
35821
  }),
35751
35822
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
@@ -35753,7 +35824,7 @@ AI 额度充值流程|AI point purchase
35753
35824
  ref: closeRef,
35754
35825
  type: "button",
35755
35826
  className: "arkme-right-panel-header-button",
35756
- style: styles$68.button,
35827
+ style: styles$69.button,
35757
35828
  "aria-label": closeLabel,
35758
35829
  title: tr$1("关闭"),
35759
35830
  disabled: closeDisabled,
@@ -53219,7 +53290,7 @@ function(test) {
53219
53290
  return (tree, file) => {
53220
53291
  const source = String(file.value ?? "");
53221
53292
  const visit = (node) => {
53222
- if (options?.articleImages && node.type === "image" && /^arkme-asset:[A-Za-z0-9._:-]{1,256}$/u.test(node.url ?? "")) {
53293
+ if (options?.articleImages && node.type === "image" && (options.localArticleImages ? arkmeArticleImageReference(node.url ?? "") : /^arkme-asset:[A-Za-z0-9._:-]{1,256}$/u.test(node.url ?? ""))) {
53223
53294
  node.data = {
53224
53295
  hName: "span",
53225
53296
  hProperties: {
@@ -54292,7 +54363,7 @@ yoga yokohama you youtube yt yun za zappos zara zero zip zm zone zuerich zw
54292
54363
  }
54293
54364
  //#endregion
54294
54365
  //#region src/client/ArkmeDetailShell.tsx
54295
- const styles$67 = {
54366
+ const styles$68 = {
54296
54367
  drawer: {
54297
54368
  position: "absolute",
54298
54369
  top: 68,
@@ -54371,7 +54442,7 @@ yoga yokohama you youtube yt yun za zappos zara zero zip zm zone zuerich zw
54371
54442
  "aria-label": label,
54372
54443
  "aria-labelledby": headerContent === void 0 ? titleId : void 0,
54373
54444
  style: {
54374
- ...styles$67.drawer,
54445
+ ...styles$68.drawer,
54375
54446
  ...resize.style
54376
54447
  },
54377
54448
  "data-arkme-note-detail": "true",
@@ -54393,12 +54464,12 @@ yoga yokohama you youtube yt yun za zappos zara zero zip zm zone zuerich zw
54393
54464
  }),
54394
54465
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
54395
54466
  ref: bodyRef,
54396
- style: styles$67.body,
54467
+ style: styles$68.body,
54397
54468
  children
54398
54469
  }),
54399
54470
  footer !== void 0 && footer !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("footer", {
54400
54471
  hidden: footerHidden,
54401
- style: typeof footer === "string" ? styles$67.footer : styles$67.extensionFooter,
54472
+ style: typeof footer === "string" ? styles$68.footer : styles$68.extensionFooter,
54402
54473
  children: footer
54403
54474
  })
54404
54475
  ]
@@ -59893,7 +59964,7 @@ body[data-ds-dark-theme] .arkme-bot-identity {
59893
59964
  }
59894
59965
  //#endregion
59895
59966
  //#region src/client/ArkmeConfirmDialog.tsx
59896
- const styles$66 = {
59967
+ const styles$67 = {
59897
59968
  backdrop: {
59898
59969
  position: "fixed",
59899
59970
  inset: 0,
@@ -59986,7 +60057,7 @@ body[data-ds-dark-theme] .arkme-bot-identity {
59986
60057
  };
59987
60058
  function ArkmeConfirmDialogPreview({ children, title }) {
59988
60059
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
59989
- style: styles$66.preview,
60060
+ style: styles$67.preview,
59990
60061
  title,
59991
60062
  children
59992
60063
  });
@@ -60037,7 +60108,7 @@ body[data-ds-dark-theme] .arkme-bot-identity {
60037
60108
  }
60038
60109
  };
60039
60110
  const dialog = /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
60040
- style: styles$66.backdrop,
60111
+ style: styles$67.backdrop,
60041
60112
  role: "presentation",
60042
60113
  "data-arkme-confirm-dialog-backdrop": "true",
60043
60114
  onMouseDown: (event) => {
@@ -60052,7 +60123,7 @@ body[data-ds-dark-theme] .arkme-bot-identity {
60052
60123
  "aria-busy": props.busy || void 0,
60053
60124
  "data-arkme-confirm-dialog": "true",
60054
60125
  style: {
60055
- ...styles$66.dialog,
60126
+ ...styles$67.dialog,
60056
60127
  ...props.layout === "picker" ? {
60057
60128
  width: "min(440px, 100%)",
60058
60129
  padding: 0,
@@ -60076,27 +60147,27 @@ body[data-ds-dark-theme] .arkme-bot-identity {
60076
60147
  }),
60077
60148
  props.layout !== "picker" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h2", {
60078
60149
  id: props.titleId,
60079
- style: styles$66.title,
60150
+ style: styles$67.title,
60080
60151
  children: props.title
60081
60152
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
60082
- style: styles$66.description,
60153
+ style: styles$67.description,
60083
60154
  children: props.description
60084
60155
  })] }),
60085
60156
  props.children,
60086
60157
  props.error === void 0 || props.error === "" ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
60087
60158
  role: "alert",
60088
- style: styles$66.error,
60159
+ style: styles$67.error,
60089
60160
  children: props.error
60090
60161
  }),
60091
60162
  props.layout !== "picker" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("footer", {
60092
- style: styles$66.footer,
60163
+ style: styles$67.footer,
60093
60164
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
60094
60165
  "data-arkme-feedback": "neutral",
60095
60166
  ref: cancelRef,
60096
60167
  type: "button",
60097
60168
  style: {
60098
- ...styles$66.button,
60099
- ...closeDisabled ? styles$66.disabled : {}
60169
+ ...styles$67.button,
60170
+ ...closeDisabled ? styles$67.disabled : {}
60100
60171
  },
60101
60172
  disabled: closeDisabled,
60102
60173
  onClick: props.onClose,
@@ -60105,9 +60176,9 @@ body[data-ds-dark-theme] .arkme-bot-identity {
60105
60176
  "data-arkme-feedback": "primary",
60106
60177
  type: "button",
60107
60178
  style: {
60108
- ...styles$66.button,
60109
- ...styles$66[props.confirmTone ?? "primary"],
60110
- ...props.busy || props.confirmDisabled ? styles$66.disabled : {}
60179
+ ...styles$67.button,
60180
+ ...styles$67[props.confirmTone ?? "primary"],
60181
+ ...props.busy || props.confirmDisabled ? styles$67.disabled : {}
60111
60182
  },
60112
60183
  disabled: props.busy || props.confirmDisabled,
60113
60184
  onClick: props.onConfirm,
@@ -60481,7 +60552,7 @@ body[data-ds-dark-theme] .arkme-bot-identity {
60481
60552
  }
60482
60553
  //#endregion
60483
60554
  //#region src/client/ArkmeFileViewer.tsx
60484
- const sdk = createArkmeSdk();
60555
+ const sdk$1 = createArkmeSdk();
60485
60556
  const markdownLabels = {
60486
60557
  code: {
60487
60558
  copyLabel: "复制",
@@ -60497,7 +60568,7 @@ body[data-ds-dark-theme] .arkme-bot-identity {
60497
60568
  function publishReception(identity, value) {
60498
60569
  for (const listener of receptionListeners.get(identity) ?? []) listener(value);
60499
60570
  }
60500
- const arkmeLocalFileUrl = (ref, download = false) => sdk.localFileUrl(ref, download);
60571
+ const arkmeLocalFileUrl = (ref, download = false) => sdk$1.localFileUrl(ref, download);
60501
60572
  function arkmeFileSize(size) {
60502
60573
  return size >= 1024 * 1024 ? `${(size / 1024 / 1024).toFixed(1)} MB` : size >= 1024 ? `${(size / 1024).toFixed(1)} KB` : `${size} B`;
60503
60574
  }
@@ -60542,7 +60613,7 @@ body[data-ds-dark-theme] .arkme-bot-identity {
60542
60613
  receptionListeners.set(identity, listeners);
60543
60614
  const poll = async (start) => {
60544
60615
  try {
60545
- const value = await sdk.receiveFile(block.originalRef, start, controller.signal);
60616
+ const value = await sdk$1.receiveFile(block.originalRef, start, controller.signal);
60546
60617
  if (!active) return;
60547
60618
  publishReception(identity, value);
60548
60619
  if (value.state === "receiving") timer = setTimeout(() => {
@@ -60827,7 +60898,7 @@ body[data-ds-dark-theme] .arkme-bot-identity {
60827
60898
  controller.signal.throwIfAborted();
60828
60899
  let saveRef = localRef;
60829
60900
  if (saveRef === void 0) {
60830
- let value = await sdk.receiveFile(block.originalRef, true, controller.signal);
60901
+ let value = await sdk$1.receiveFile(block.originalRef, true, controller.signal);
60831
60902
  const deadline = Date.now() + 12e4;
60832
60903
  publishReception(block.originalRef, value);
60833
60904
  while (value.state === "receiving" || value.state === "missing") {
@@ -60844,7 +60915,7 @@ body[data-ds-dark-theme] .arkme-bot-identity {
60844
60915
  controller.signal.addEventListener("abort", abort, { once: true });
60845
60916
  if (controller.signal.aborted) abort();
60846
60917
  });
60847
- value = await sdk.receiveFile(block.originalRef, false, controller.signal);
60918
+ value = await sdk$1.receiveFile(block.originalRef, false, controller.signal);
60848
60919
  publishReception(block.originalRef, value);
60849
60920
  }
60850
60921
  if (value.state !== "ready" || value.file === void 0) throw new Error(value.error ?? "原文件不可用");
@@ -61010,8 +61081,8 @@ body[data-ds-dark-theme] .arkme-bot-identity {
61010
61081
  setOpening(true);
61011
61082
  setError("");
61012
61083
  try {
61013
- if (target === "folder") await sdk.openLocalFileFolder(fileRef, controller.signal);
61014
- else await sdk.openLocalFile(fileRef, controller.signal);
61084
+ if (target === "folder") await sdk$1.openLocalFileFolder(fileRef, controller.signal);
61085
+ else await sdk$1.openLocalFile(fileRef, controller.signal);
61015
61086
  if (!controller.signal.aborted && target === "file") onOpened();
61016
61087
  } catch (reason) {
61017
61088
  if (!controller.signal.aborted) setError(reason instanceof Error ? reason.message : target === "folder" ? "文件夹打开失败,请重试" : "文件打开失败,请重试");
@@ -61283,6 +61354,19 @@ body[data-ds-dark-theme] .arkme-bot-identity {
61283
61354
  if (original.localRef === void 0) original.receive();
61284
61355
  };
61285
61356
  const contentMaxHeight = filePanel ? "calc(65vh - 56px)" : "65vh";
61357
+ const fillTextWindow = standalone && showContent && textFile;
61358
+ const textWindowPanelStyle = fillTextWindow ? {
61359
+ width: "100%",
61360
+ height: "100%",
61361
+ maxHeight: "none",
61362
+ minWidth: 0,
61363
+ minHeight: 0,
61364
+ boxSizing: "border-box",
61365
+ padding: 0,
61366
+ borderRadius: 0,
61367
+ display: "flex",
61368
+ flexDirection: "column"
61369
+ } : {};
61286
61370
  const mediaStyle = {
61287
61371
  width: "100%",
61288
61372
  maxHeight: contentMaxHeight,
@@ -61295,7 +61379,9 @@ body[data-ds-dark-theme] .arkme-bot-identity {
61295
61379
  zIndex: 11e3,
61296
61380
  background: standalone ? arkmeTheme.menu : "rgba(0,0,0,.72)",
61297
61381
  display: "grid",
61298
- placeItems: "center",
61382
+ placeItems: fillTextWindow ? "stretch" : "center",
61383
+ gridTemplateRows: fillTextWindow ? "minmax(0, 1fr)" : void 0,
61384
+ gridTemplateColumns: fillTextWindow ? "minmax(0, 1fr)" : void 0,
61299
61385
  padding: 24
61300
61386
  },
61301
61387
  onMouseDown: (event) => {
@@ -61315,7 +61401,8 @@ body[data-ds-dark-theme] .arkme-bot-identity {
61315
61401
  borderRadius: 16,
61316
61402
  padding: showContent ? "56px 20px 20px" : "48px 40px 32px",
61317
61403
  color: arkmeTheme.text,
61318
- background: arkmeTheme.menu
61404
+ background: arkmeTheme.menu,
61405
+ ...textWindowPanelStyle
61319
61406
  },
61320
61407
  onKeyDown: (event) => {
61321
61408
  if (event.key === "Escape") {
@@ -61431,7 +61518,9 @@ body[data-ds-dark-theme] .arkme-bot-identity {
61431
61518
  controls: true
61432
61519
  }) : textFile ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
61433
61520
  style: {
61434
- maxHeight: contentMaxHeight,
61521
+ maxHeight: fillTextWindow ? void 0 : contentMaxHeight,
61522
+ flex: fillTextWindow ? "1 1 0" : void 0,
61523
+ minHeight: fillTextWindow ? 0 : void 0,
61435
61524
  overflow: "auto",
61436
61525
  overflowWrap: "anywhere"
61437
61526
  },
@@ -61447,7 +61536,10 @@ body[data-ds-dark-theme] .arkme-bot-identity {
61447
61536
  })
61448
61537
  }) : null,
61449
61538
  filePanel && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
61450
- style: { marginTop: 16 },
61539
+ style: {
61540
+ marginTop: 16,
61541
+ flexShrink: fillTextWindow ? 0 : void 0
61542
+ },
61451
61543
  children: [
61452
61544
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
61453
61545
  role: "group",
@@ -61455,7 +61547,13 @@ body[data-ds-dark-theme] .arkme-bot-identity {
61455
61547
  style: {
61456
61548
  display: "flex",
61457
61549
  flexWrap: "wrap",
61458
- gap: 8
61550
+ gap: 8,
61551
+ ...fillTextWindow ? {
61552
+ display: "grid",
61553
+ gridTemplateColumns: "repeat(2, minmax(0, 1fr))",
61554
+ maxWidth: 488,
61555
+ marginInline: "auto"
61556
+ } : {}
61459
61557
  },
61460
61558
  children: [
61461
61559
  !showContent && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
@@ -61537,7 +61635,8 @@ body[data-ds-dark-theme] .arkme-bot-identity {
61537
61635
  }),
61538
61636
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
61539
61637
  style: {
61540
- position: standalone ? "fixed" : "absolute",
61638
+ position: fillTextWindow ? "static" : standalone ? "fixed" : "absolute",
61639
+ flexShrink: fillTextWindow ? 0 : void 0,
61541
61640
  left: 0,
61542
61641
  right: 0,
61543
61642
  bottom: standalone ? 0 : -56,
@@ -66688,7 +66787,7 @@ body[data-ds-dark-theme] .arkme-bot-identity {
66688
66787
  .arkme-markdown .ProseMirror { outline:none; min-height:inherit; white-space:pre-wrap; }
66689
66788
  .arkme-markdown .ProseMirror > :first-child { margin-top:0; }
66690
66789
  `;
66691
- function ArkmeMarkdownBody({ text, highlightMentions = true, renderLink, textStyle, onMentionClick, isMentionClickable, renderImage, mentionTargets, readMentionMembers }) {
66790
+ function ArkmeMarkdownBody({ text, highlightMentions = true, renderLink, textStyle, onMentionClick, isMentionClickable, renderImage, localArticleImages = false, mentionTargets, readMentionMembers }) {
66692
66791
  const rich = (children) => react$1.Children.map(children, (child) => typeof child === "string" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ArkmeRichText, {
66693
66792
  text: child,
66694
66793
  highlightMentions,
@@ -66714,7 +66813,10 @@ body[data-ds-dark-theme] .arkme-bot-identity {
66714
66813
  remarkGfm,
66715
66814
  remarkBreaks,
66716
66815
  [arkmeMarkdownBusinessNodes, mentionTargets === void 0 ? {} : { mentions: mentionTargets }],
66717
- [arkmeLiteralMarkdownNodes, { articleImages: Boolean(renderImage) }]
66816
+ [arkmeLiteralMarkdownNodes, {
66817
+ articleImages: Boolean(renderImage),
66818
+ localArticleImages
66819
+ }]
66718
66820
  ],
66719
66821
  components: {
66720
66822
  span: ({ children, node }) => {
@@ -97876,10 +97978,221 @@ Please report this to https://github.com/markedjs/marked.`, e) {
97876
97978
  });
97877
97979
  }
97878
97980
  //#endregion
97981
+ //#region src/client/ArkmeLongArticleDraftDialog.tsx
97982
+ const sdk = createArkmeSdk();
97983
+ const button$7 = {
97984
+ border: 0,
97985
+ borderRadius: 8,
97986
+ padding: "8px 12px",
97987
+ background: "transparent",
97988
+ color: arkmeTheme.text,
97989
+ cursor: "pointer",
97990
+ font: "inherit",
97991
+ fontSize: 14
97992
+ };
97993
+ function ArkmeLongArticleDraftDialog({ draft, blocks = [], preview, onPreview, onClose, onOriginal, onRestore }) {
97994
+ useArkmeLocale();
97995
+ const closeRef = (0, react$1.useRef)(null);
97996
+ (0, react$1.useEffect)(() => {
97997
+ const previous = document.activeElement;
97998
+ closeRef.current?.focus();
97999
+ return () => {
98000
+ previous?.focus?.();
98001
+ };
98002
+ }, [preview]);
98003
+ const date = new Date(draft.updatedAtMillis);
98004
+ const validDate = draft.updatedAtMillis > 0 && Number.isFinite(date.getTime());
98005
+ const two = (value) => String(value).padStart(2, "0");
98006
+ const savedTime = validDate ? `${date.getFullYear()}-${two(date.getMonth() + 1)}-${two(date.getDate())} ${two(date.getHours())}:${two(date.getMinutes())}:${two(date.getSeconds())}` : tr$1("保存时间未知");
98007
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
98008
+ style: {
98009
+ position: "fixed",
98010
+ inset: 0,
98011
+ zIndex: 1300,
98012
+ display: "grid",
98013
+ placeItems: "center",
98014
+ padding: 24,
98015
+ background: "rgba(0,0,0,.52)"
98016
+ },
98017
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
98018
+ role: "dialog",
98019
+ "aria-modal": "true",
98020
+ "aria-label": tr$1(preview ? "草稿预览" : "发现未发布的草稿"),
98021
+ onKeyDown: (event) => {
98022
+ if (event.key !== "Tab") return;
98023
+ const focusable = [...event.currentTarget.querySelectorAll("button:not(:disabled), a[href]")];
98024
+ const first = focusable[0], last = focusable.at(-1);
98025
+ if (event.shiftKey && document.activeElement === first) {
98026
+ event.preventDefault();
98027
+ last?.focus();
98028
+ } else if (!event.shiftKey && document.activeElement === last) {
98029
+ event.preventDefault();
98030
+ first?.focus();
98031
+ }
98032
+ },
98033
+ style: {
98034
+ position: "relative",
98035
+ width: preview ? "min(760px, 90vw)" : "min(440px, 90vw)",
98036
+ maxHeight: "80vh",
98037
+ display: "flex",
98038
+ flexDirection: "column",
98039
+ padding: 24,
98040
+ boxSizing: "border-box",
98041
+ borderRadius: 16,
98042
+ background: arkmeTheme.base,
98043
+ color: arkmeTheme.text,
98044
+ boxShadow: arkmeTheme.shadow
98045
+ },
98046
+ children: [
98047
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
98048
+ style: {
98049
+ margin: "0 32px 16px 0",
98050
+ fontSize: 18
98051
+ },
98052
+ children: tr$1(preview ? "草稿预览" : "发现未发布的草稿")
98053
+ }),
98054
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
98055
+ ref: closeRef,
98056
+ autoFocus: true,
98057
+ type: "button",
98058
+ "aria-label": tr$1(preview ? "关闭草稿预览" : "关闭草稿恢复弹窗"),
98059
+ style: {
98060
+ ...button$7,
98061
+ position: "absolute",
98062
+ top: 12,
98063
+ right: 12,
98064
+ fontSize: 26
98065
+ },
98066
+ onClick: () => preview ? onPreview(false) : onClose(),
98067
+ children: "×"
98068
+ }),
98069
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
98070
+ style: {
98071
+ display: "flex",
98072
+ alignItems: "center",
98073
+ gap: 8,
98074
+ flexWrap: "wrap",
98075
+ fontSize: 14
98076
+ },
98077
+ children: [
98078
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
98079
+ style: { color: arkmeTheme.secondary },
98080
+ children: tr$1("保存时间:")
98081
+ }),
98082
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("time", {
98083
+ dateTime: validDate ? date.toISOString() : void 0,
98084
+ style: { color: arkmeTheme.info },
98085
+ children: savedTime
98086
+ }),
98087
+ !preview && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
98088
+ type: "button",
98089
+ "aria-label": tr$1("预览草稿"),
98090
+ title: tr$1("预览草稿"),
98091
+ style: {
98092
+ ...button$7,
98093
+ display: "inline-flex",
98094
+ padding: 4,
98095
+ color: arkmeTheme.info
98096
+ },
98097
+ onClick: () => onPreview(true),
98098
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
98099
+ width: "20",
98100
+ height: "20",
98101
+ viewBox: "0 0 24 24",
98102
+ fill: "none",
98103
+ stroke: "currentColor",
98104
+ strokeWidth: "1.6",
98105
+ "aria-hidden": "true",
98106
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M2 12s3.5-7 10-7 10 7 10 7-3.5 7-10 7S2 12 2 12Z" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("circle", {
98107
+ cx: "12",
98108
+ cy: "12",
98109
+ r: "3"
98110
+ })]
98111
+ })
98112
+ })
98113
+ ]
98114
+ }),
98115
+ preview && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
98116
+ style: {
98117
+ minHeight: 0,
98118
+ overflowY: "auto",
98119
+ marginTop: 16,
98120
+ paddingTop: 16,
98121
+ borderTop: `1px solid ${arkmeTheme.border}`
98122
+ },
98123
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h2", {
98124
+ style: {
98125
+ margin: "0 0 16px",
98126
+ overflowWrap: "anywhere"
98127
+ },
98128
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ArkmeRichText, {
98129
+ text: draft.title || tr$1("无标题长文"),
98130
+ presentation: "preview"
98131
+ })
98132
+ }), draft.textFormat === "markdown" || draft.document ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ArkmeMarkdownBody, {
98133
+ text: draft.textContent,
98134
+ localArticleImages: true,
98135
+ renderImage: (ref, alt) => {
98136
+ const block = blocks.find((value) => value.kind === "image" && `arkme-asset:${value.fileAssetUid}` === ref);
98137
+ let url = block ? articleImageUrl(block) : void 0;
98138
+ if (ref.startsWith("arkme-local:")) try {
98139
+ url = sdk.localFileUrl(ref.slice(12));
98140
+ } catch {}
98141
+ return url ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
98142
+ src: url,
98143
+ alt,
98144
+ style: {
98145
+ maxWidth: "100%",
98146
+ height: "auto"
98147
+ }
98148
+ }) : void 0;
98149
+ }
98150
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
98151
+ style: {
98152
+ margin: 0,
98153
+ whiteSpace: "pre-wrap",
98154
+ overflowWrap: "anywhere",
98155
+ lineHeight: 1.7
98156
+ },
98157
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ArkmeRichText, {
98158
+ text: draft.textContent,
98159
+ linkLabelMode: "raw"
98160
+ })
98161
+ })]
98162
+ }),
98163
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
98164
+ style: {
98165
+ flex: "none",
98166
+ display: "flex",
98167
+ justifyContent: "flex-end",
98168
+ gap: 8,
98169
+ marginTop: 24
98170
+ },
98171
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
98172
+ type: "button",
98173
+ style: button$7,
98174
+ onClick: () => preview ? onPreview(false) : onOriginal(),
98175
+ children: tr$1(preview ? "返回" : "编辑原文")
98176
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
98177
+ type: "button",
98178
+ style: {
98179
+ ...button$7,
98180
+ background: arkmeTheme.primaryAction,
98181
+ color: arkmeTheme.onPrimaryAction
98182
+ },
98183
+ onClick: onRestore,
98184
+ children: tr$1("恢复草稿")
98185
+ })]
98186
+ })
98187
+ ]
98188
+ })
98189
+ });
98190
+ }
98191
+ //#endregion
97879
98192
  //#region src/client/ArkmeLongArticleDialog.tsx
97880
98193
  const MAX_TITLE_LENGTH = 100;
97881
98194
  const MAX_CONTENT_LENGTH = 4e4;
97882
- const styles$65 = {
98195
+ const styles$66 = {
97883
98196
  overlay: {
97884
98197
  position: "fixed",
97885
98198
  inset: 0,
@@ -98061,7 +98374,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
98061
98374
  }, [onClose]);
98062
98375
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
98063
98376
  style: {
98064
- ...styles$65.overlay,
98377
+ ...styles$66.overlay,
98065
98378
  ...standalone ? {
98066
98379
  padding: 0,
98067
98380
  background: arkmeTheme.base
@@ -98075,7 +98388,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
98075
98388
  },
98076
98389
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("article", {
98077
98390
  style: {
98078
- ...styles$65.dialog,
98391
+ ...styles$66.dialog,
98079
98392
  ...standalone ? {
98080
98393
  width: "100%",
98081
98394
  maxWidth: "100%",
@@ -98087,9 +98400,9 @@ Please report this to https://github.com/markedjs/marked.`, e) {
98087
98400
  "data-arkme-long-article-dialog": "snapshot",
98088
98401
  children: [
98089
98402
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("header", {
98090
- style: styles$65.header,
98403
+ style: styles$66.header,
98091
98404
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h2", {
98092
- style: styles$65.titleRead,
98405
+ style: styles$66.titleRead,
98093
98406
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ArkmeRichText, {
98094
98407
  text: item.title || "无标题长文",
98095
98408
  presentation: "preview"
@@ -98098,19 +98411,19 @@ Please report this to https://github.com/markedjs/marked.`, e) {
98098
98411
  "data-arkme-feedback": "neutral",
98099
98412
  autoFocus: true,
98100
98413
  type: "button",
98101
- style: styles$65.close,
98414
+ style: styles$66.close,
98102
98415
  "aria-label": tr$1("关闭长文"),
98103
98416
  onClick: onClose,
98104
98417
  children: "×"
98105
98418
  })]
98106
98419
  }),
98107
98420
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
98108
- style: styles$65.metaRow,
98421
+ style: styles$66.metaRow,
98109
98422
  children: [item.sendAtMillis > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
98110
- style: styles$65.meta,
98423
+ style: styles$66.meta,
98111
98424
  children: ["▦ ", formatDate(item.sendAtMillis)]
98112
98425
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
98113
- style: styles$65.meta,
98426
+ style: styles$66.meta,
98114
98427
  children: [
98115
98428
  "▤ ",
98116
98429
  String(item.textContent.length),
@@ -98119,16 +98432,16 @@ Please report this to https://github.com/markedjs/marked.`, e) {
98119
98432
  })]
98120
98433
  }),
98121
98434
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
98122
- style: styles$65.body,
98435
+ style: styles$66.body,
98123
98436
  children: item.textFormat === "markdown" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ArkmeLongArticleBody, {
98124
98437
  text: item.textContent,
98125
98438
  blocks: item.contentBlocks,
98126
98439
  textStyle: {
98127
- fontSize: styles$65.bodyRead?.fontSize,
98128
- lineHeight: styles$65.bodyRead?.lineHeight
98440
+ fontSize: styles$66.bodyRead?.fontSize,
98441
+ lineHeight: styles$66.bodyRead?.lineHeight
98129
98442
  }
98130
98443
  }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
98131
- style: styles$65.bodyRead,
98444
+ style: styles$66.bodyRead,
98132
98445
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ArkmeRichText, {
98133
98446
  text: item.textContent,
98134
98447
  linkLabelMode: "raw"
@@ -98157,10 +98470,14 @@ Please report this to https://github.com/markedjs/marked.`, e) {
98157
98470
  const [submitting, setSubmitting] = (0, react$1.useState)(false);
98158
98471
  const [error, setError] = (0, react$1.useState)("");
98159
98472
  const [closePrompt, setClosePrompt] = (0, react$1.useState)(false);
98473
+ const [recoveryDraft, setRecoveryDraft] = (0, react$1.useState)();
98474
+ const [draftPreview, setDraftPreview] = (0, react$1.useState)(false);
98475
+ const checkingDraft = (0, react$1.useRef)(false);
98160
98476
  const [closingDraft, setClosingDraft] = (0, react$1.useState)(false);
98161
98477
  const closingDraftRef = (0, react$1.useRef)(false);
98162
98478
  const submittingRef = (0, react$1.useRef)(false);
98163
98479
  const [draftState, setDraftState] = (0, react$1.useState)("unsaved");
98480
+ const [savedAtMillis, setSavedAtMillis] = (0, react$1.useState)();
98164
98481
  const changeRevision = (0, react$1.useRef)(0);
98165
98482
  const windowModeRef = (0, react$1.useRef)(windowMode);
98166
98483
  windowModeRef.current = windowMode;
@@ -98237,7 +98554,10 @@ Please report this to https://github.com/markedjs/marked.`, e) {
98237
98554
  });
98238
98555
  try {
98239
98556
  await saving.current;
98240
- if (revision === changeRevision.current) setDraftState("saved");
98557
+ if (revision === changeRevision.current) {
98558
+ setSavedAtMillis(Date.now());
98559
+ setDraftState("saved");
98560
+ }
98241
98561
  } catch (caught) {
98242
98562
  setDraftState("failed");
98243
98563
  throw caught;
@@ -98431,7 +98751,9 @@ Please report this to https://github.com/markedjs/marked.`, e) {
98431
98751
  const onKeyDown = (event) => {
98432
98752
  if (event.key === "Escape") {
98433
98753
  event.stopPropagation();
98434
- if (windowMode && closePrompt && !closingDraft) {
98754
+ if (recoveryDraft) if (draftPreview) setDraftPreview(false);
98755
+ else setRecoveryDraft(void 0);
98756
+ else if (windowMode && closePrompt && !closingDraft) {
98435
98757
  setClosePrompt(false);
98436
98758
  windowMode.cancelClose();
98437
98759
  } else requestClose();
@@ -98445,7 +98767,9 @@ Please report this to https://github.com/markedjs/marked.`, e) {
98445
98767
  requestClose,
98446
98768
  windowMode,
98447
98769
  closePrompt,
98448
- closingDraft
98770
+ closingDraft,
98771
+ recoveryDraft,
98772
+ draftPreview
98449
98773
  ]);
98450
98774
  const requestCloseRef = (0, react$1.useRef)(requestClose);
98451
98775
  requestCloseRef.current = requestClose;
@@ -98470,25 +98794,33 @@ Please report this to https://github.com/markedjs/marked.`, e) {
98470
98794
  }
98471
98795
  };
98472
98796
  const beginEditing = async () => {
98473
- if (detail === void 0 || !detail.editable) return;
98474
- let nextVersion = detail.version;
98475
- let nextTitle = detail.title;
98476
- let nextText = detail.textContent;
98477
- let nextDuration = detail.editDurationMillis;
98478
- let document = detail.textFormat === "markdown" ? void 0 : arkmePlainEditorDocument(detail.textContent);
98479
- let images = (detail.contentBlocks ?? []).flatMap((block) => block.kind === "image" && block.fileAssetUid ? [{ fileAssetUid: block.fileAssetUid }] : []);
98797
+ if (detail === void 0 || !detail.editable || accountChanged || checkingDraft.current) return;
98798
+ checkingDraft.current = true;
98480
98799
  try {
98481
98800
  const draft = await callArkme("source.long-article.draft.get", draftParams);
98482
- if (draft !== void 0 && (draft.title !== detail.title || draft.textContent !== detail.textContent || draft.document !== void 0) && window.confirm("发现这篇长文的未发布修改,是否恢复?")) {
98483
- nextVersion = draft.baseVersion ?? 0;
98484
- nextTitle = draft.title;
98485
- nextText = draft.textContent;
98486
- document = draft.document ?? (draft.textFormat === "markdown" ? void 0 : arkmePlainEditorDocument(draft.textContent));
98487
- setDraftFormat(draft.textFormat ?? detail.textFormat ?? "plain");
98488
- images = draft.images ?? images;
98489
- nextDuration = Math.max(detail.editDurationMillis, draft.durationMillis);
98801
+ if (skipUnmountSaveRef.current) return;
98802
+ if (draft !== void 0 && (draft.title !== detail.title || draft.textContent !== detail.textContent || draft.document !== void 0)) {
98803
+ setDraftPreview(false);
98804
+ setRecoveryDraft(draft);
98805
+ return;
98490
98806
  }
98491
- } catch {}
98807
+ } catch {} finally {
98808
+ checkingDraft.current = false;
98809
+ }
98810
+ enterEditing();
98811
+ };
98812
+ const enterEditing = (draft) => {
98813
+ if (detail === void 0 || !detail.editable || accountChanged || skipUnmountSaveRef.current) return;
98814
+ const nextVersion = draft ? draft.baseVersion ?? 0 : detail.version;
98815
+ const nextTitle = draft?.title ?? detail.title;
98816
+ const nextText = draft?.textContent ?? detail.textContent;
98817
+ const nextDuration = draft ? Math.max(detail.editDurationMillis, draft.durationMillis) : detail.editDurationMillis;
98818
+ const format = draft?.textFormat ?? detail.textFormat ?? "plain";
98819
+ const document = draft?.document ?? (format === "markdown" ? void 0 : arkmePlainEditorDocument(nextText));
98820
+ const images = draft?.images ?? (detail.contentBlocks ?? []).flatMap((block) => block.kind === "image" && block.fileAssetUid ? [{ fileAssetUid: block.fileAssetUid }] : []);
98821
+ setDraftFormat(format);
98822
+ setRecoveryDraft(void 0);
98823
+ setDraftPreview(false);
98492
98824
  baseVersionRef.current = nextVersion;
98493
98825
  setInitialDocument(document);
98494
98826
  imagesRef.current = images;
@@ -98509,18 +98841,6 @@ Please report this to https://github.com/markedjs/marked.`, e) {
98509
98841
  setEditing(true);
98510
98842
  setError(nextVersion !== detail.version ? "此草稿基于旧版本,正文已有新修改;草稿已保留,请核对后重新编辑。" : "");
98511
98843
  };
98512
- const autoEditStarted = (0, react$1.useRef)(false);
98513
- (0, react$1.useEffect)(() => {
98514
- if (windowMode?.editOnOpen && detail?.editable && !loading && !accountChanged && !autoEditStarted.current) {
98515
- autoEditStarted.current = true;
98516
- beginEditing();
98517
- }
98518
- }, [
98519
- detail,
98520
- loading,
98521
- accountChanged,
98522
- windowMode?.editOnOpen
98523
- ]);
98524
98844
  const publish = async () => {
98525
98845
  if (loading || !capabilityReady || draftFormat === "markdown" && !markdownEnabled || markdownEnabled && !article) return;
98526
98846
  if (!creating && baseVersionRef.current !== detail?.version) {
@@ -98670,11 +98990,29 @@ Please report this to https://github.com/markedjs/marked.`, e) {
98670
98990
  const metaDuration = editing ? displayedDurationMillis : staticDuration;
98671
98991
  const wordCount = article || readFormat === "markdown" ? arkmeMarkdownPlainText(textValue).replace(/\[图片\]/g, "").length : textValue.length;
98672
98992
  const sendAt = detail?.sendAtMillis ?? item?.sendAtMillis ?? 0;
98993
+ const statsInFooter = Boolean(windowMode && editing);
98994
+ const articleStats = /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
98995
+ style: styles$66.meta,
98996
+ children: ["◷ ", formatDuration$2(metaDuration)]
98997
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
98998
+ style: styles$66.meta,
98999
+ children: [
99000
+ "▤ ",
99001
+ String(wordCount),
99002
+ tr$1("字")
99003
+ ]
99004
+ })] });
99005
+ const savedAt = savedAtMillis === void 0 ? void 0 : new Date(savedAtMillis);
99006
+ const savedTime = savedAt && [
99007
+ savedAt.getHours(),
99008
+ savedAt.getMinutes(),
99009
+ savedAt.getSeconds()
99010
+ ].map((value) => String(value).padStart(2, "0")).join(":");
98673
99011
  const publishAction = /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
98674
99012
  "data-arkme-feedback": "neutral",
98675
99013
  type: "button",
98676
99014
  style: {
98677
- ...styles$65.action,
99015
+ ...styles$66.action,
98678
99016
  ...windowMode ? {
98679
99017
  background: arkmeTheme.primaryAction,
98680
99018
  color: arkmeTheme.onPrimaryAction,
@@ -98687,11 +99025,11 @@ Please report this to https://github.com/markedjs/marked.`, e) {
98687
99025
  onClick: () => {
98688
99026
  publish();
98689
99027
  },
98690
- children: windowMode ? creating ? submitting ? tr$1("发送中…") : tr$1("发送") : submitting ? tr$1("正在保存…") : tr$1("保存修改") : creating && onPrepared ? submitting ? "正在添加…" : "添加到待发送" : submitting ? "发布中…" : tr$1("发布")
99028
+ children: windowMode ? creating ? submitting ? tr$1("发送中…") : tr$1("发送") : submitting ? tr$1("正在保存…") : tr$1("确认修改") : creating && onPrepared ? submitting ? "正在添加…" : "添加到待发送" : submitting ? "发布中…" : tr$1("发布")
98691
99029
  });
98692
99030
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
98693
99031
  style: {
98694
- ...styles$65.overlay,
99032
+ ...styles$66.overlay,
98695
99033
  ...overlayZIndex === void 0 ? {} : { zIndex: overlayZIndex },
98696
99034
  ...windowMode ? {
98697
99035
  padding: 0,
@@ -98710,7 +99048,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
98710
99048
  children: [
98711
99049
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("article", {
98712
99050
  style: {
98713
- ...styles$65.dialog,
99051
+ ...styles$66.dialog,
98714
99052
  ...windowMode ? {
98715
99053
  width: "100%",
98716
99054
  maxWidth: "100%",
@@ -98746,10 +99084,13 @@ Please report this to https://github.com/markedjs/marked.`, e) {
98746
99084
  }), editing && publishAction]
98747
99085
  }),
98748
99086
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("header", {
98749
- style: styles$65.header,
99087
+ style: {
99088
+ ...styles$66.header,
99089
+ ...windowMode && editing ? { paddingBottom: 12 } : {}
99090
+ },
98750
99091
  children: [editing ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
98751
99092
  autoFocus: true,
98752
- style: styles$65.titleInput,
99093
+ style: styles$66.titleInput,
98753
99094
  value: title,
98754
99095
  maxLength: MAX_TITLE_LENGTH,
98755
99096
  placeholder: tr$1("请输入标题"),
@@ -98762,7 +99103,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
98762
99103
  setTitle(event.target.value);
98763
99104
  }
98764
99105
  }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h2", {
98765
- style: styles$65.titleRead,
99106
+ style: styles$66.titleRead,
98766
99107
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ArkmeRichText, {
98767
99108
  text: titleValue || "无标题长文",
98768
99109
  presentation: "preview"
@@ -98770,36 +99111,31 @@ Please report this to https://github.com/markedjs/marked.`, e) {
98770
99111
  }), !windowMode && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
98771
99112
  "data-arkme-feedback": "neutral",
98772
99113
  type: "button",
98773
- style: styles$65.close,
99114
+ style: styles$66.close,
98774
99115
  "aria-label": tr$1("关闭长文"),
98775
99116
  disabled: submitting,
98776
99117
  onClick: requestClose,
98777
99118
  children: "×"
98778
99119
  })]
98779
99120
  }),
98780
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
98781
- style: styles$65.metaRow,
99121
+ windowMode && editing && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("hr", { style: {
99122
+ flex: "none",
99123
+ border: 0,
99124
+ borderTop: `1px solid ${arkmeTheme.border}`,
99125
+ margin: "0 32px"
99126
+ } }),
99127
+ !statsInFooter && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
99128
+ style: styles$66.metaRow,
98782
99129
  children: [
98783
99130
  !creating && sendAt > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
98784
- style: styles$65.meta,
99131
+ style: styles$66.meta,
98785
99132
  children: ["▦ ", formatDate(sendAt)]
98786
99133
  }),
98787
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
98788
- style: styles$65.meta,
98789
- children: ["◷ ", formatDuration$2(metaDuration)]
98790
- }),
98791
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
98792
- style: styles$65.meta,
98793
- children: [
98794
- "▤ ",
98795
- String(wordCount),
98796
- tr$1("字")
98797
- ]
98798
- }),
99134
+ articleStats,
98799
99135
  editing ? !windowMode && publishAction : detail?.editable === true && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
98800
99136
  "data-arkme-feedback": "neutral",
98801
99137
  type: "button",
98802
- style: styles$65.action,
99138
+ style: styles$66.action,
98803
99139
  onClick: () => {
98804
99140
  beginEditing();
98805
99141
  },
@@ -98808,12 +99144,12 @@ Please report this to https://github.com/markedjs/marked.`, e) {
98808
99144
  ]
98809
99145
  }),
98810
99146
  error !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
98811
- style: styles$65.error,
99147
+ style: styles$66.error,
98812
99148
  role: "alert",
98813
99149
  children: [error, !creating && detail === void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
98814
99150
  "data-arkme-feedback": "neutral",
98815
99151
  type: "button",
98816
- style: styles$65.retry,
99152
+ style: styles$66.retry,
98817
99153
  onClick: () => {
98818
99154
  loadDetail();
98819
99155
  },
@@ -98821,11 +99157,14 @@ Please report this to https://github.com/markedjs/marked.`, e) {
98821
99157
  })]
98822
99158
  }),
98823
99159
  loading || editing && !capabilityReady ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
98824
- style: styles$65.state,
99160
+ style: styles$66.state,
98825
99161
  role: "status",
98826
99162
  children: tr$1("正在加载长文…")
98827
99163
  }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
98828
- style: styles$65.body,
99164
+ style: {
99165
+ ...styles$66.body,
99166
+ ...windowMode && editing ? { paddingTop: 12 } : {}
99167
+ },
98829
99168
  children: editing && draftFormat === "markdown" && !markdownEnabled ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
98830
99169
  role: "status",
98831
99170
  children: [tr$1("Markdown 长文暂不可编辑,草稿已保留。"), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
@@ -98875,7 +99214,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
98875
99214
  }
98876
99215
  }, editorEpoch) : editing ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("textarea", {
98877
99216
  autoFocus: creating,
98878
- style: styles$65.bodyInput,
99217
+ style: styles$66.bodyInput,
98879
99218
  value: textContent,
98880
99219
  maxLength: MAX_CONTENT_LENGTH,
98881
99220
  placeholder: tr$1("请输入正文内容"),
@@ -98891,32 +99230,61 @@ Please report this to https://github.com/markedjs/marked.`, e) {
98891
99230
  text: textValue,
98892
99231
  blocks: readBlocks,
98893
99232
  textStyle: {
98894
- fontSize: styles$65.bodyRead?.fontSize,
98895
- lineHeight: styles$65.bodyRead?.lineHeight
99233
+ fontSize: styles$66.bodyRead?.fontSize,
99234
+ lineHeight: styles$66.bodyRead?.lineHeight
98896
99235
  }
98897
99236
  }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
98898
- style: styles$65.bodyRead,
99237
+ style: styles$66.bodyRead,
98899
99238
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ArkmeRichText, {
98900
99239
  text: textValue,
98901
99240
  linkLabelMode: "raw"
98902
99241
  })
98903
99242
  })
98904
99243
  }),
98905
- windowMode && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("footer", {
98906
- role: "status",
99244
+ windowMode && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("footer", {
98907
99245
  style: {
99246
+ flex: "none",
99247
+ display: "flex",
99248
+ alignItems: "center",
99249
+ flexWrap: "wrap",
99250
+ gap: "8px 20px",
98908
99251
  padding: "12px 32px",
98909
99252
  borderTop: `1px solid ${arkmeTheme.border}`,
98910
- color: draftState === "failed" ? arkmeTheme.danger : arkmeTheme.secondary,
99253
+ color: arkmeTheme.secondary,
98911
99254
  fontSize: 12
98912
99255
  },
98913
- children: accountChanged ? tr$1("账号已切换") : !editing ? tr$1("只读") : tr$1(draftState === "saved" ? "草稿已保存" : draftState === "saving" ? "正在保存草稿…" : draftState === "failed" ? "草稿保存失败,请重试" : "未保存")
99256
+ children: [statsInFooter && articleStats, /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
99257
+ role: "status",
99258
+ style: {
99259
+ display: "inline-flex",
99260
+ alignItems: "center",
99261
+ gap: 8,
99262
+ color: draftState === "failed" ? arkmeTheme.danger : void 0
99263
+ },
99264
+ children: [accountChanged ? tr$1("账号已切换") : !editing ? tr$1("只读") : tr$1(draftState === "saved" ? "草稿已保存" : draftState === "saving" ? "正在保存草稿…" : draftState === "failed" ? "草稿保存失败,请重试" : "未保存"), !accountChanged && editing && draftState === "saved" && savedAt && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("time", {
99265
+ dateTime: savedAt.toISOString(),
99266
+ title: formatDate(savedAtMillis),
99267
+ children: savedTime
99268
+ })]
99269
+ })]
98914
99270
  })
98915
99271
  ]
98916
99272
  }),
99273
+ recoveryDraft && !accountChanged && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ArkmeLongArticleDraftDialog, {
99274
+ draft: recoveryDraft,
99275
+ blocks: detail?.contentBlocks,
99276
+ preview: draftPreview,
99277
+ onPreview: setDraftPreview,
99278
+ onClose: () => {
99279
+ setRecoveryDraft(void 0);
99280
+ setDraftPreview(false);
99281
+ },
99282
+ onOriginal: () => enterEditing(),
99283
+ onRestore: () => enterEditing(recoveryDraft)
99284
+ }),
98917
99285
  windowMode && closePrompt && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
98918
99286
  style: {
98919
- ...styles$65.overlay,
99287
+ ...styles$66.overlay,
98920
99288
  zIndex: 1300
98921
99289
  },
98922
99290
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
@@ -98936,6 +99304,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
98936
99304
  }
98937
99305
  },
98938
99306
  style: {
99307
+ position: "relative",
98939
99308
  width: "min(420px, 90vw)",
98940
99309
  borderRadius: 16,
98941
99310
  padding: 24,
@@ -98947,9 +99316,27 @@ Please report this to https://github.com/markedjs/marked.`, e) {
98947
99316
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
98948
99317
  style: {
98949
99318
  margin: "0 0 12px",
99319
+ paddingRight: 32,
98950
99320
  fontSize: 18
98951
99321
  },
98952
- children: tr$1("保留这篇长文的修改?")
99322
+ children: tr$1("是否暂存草稿")
99323
+ }),
99324
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
99325
+ autoFocus: true,
99326
+ type: "button",
99327
+ "data-arkme-feedback": "neutral",
99328
+ "aria-label": tr$1("关闭草稿确认弹窗"),
99329
+ style: {
99330
+ ...styles$66.close,
99331
+ top: 18,
99332
+ right: 18
99333
+ },
99334
+ disabled: closingDraft,
99335
+ onClick: () => {
99336
+ setClosePrompt(false);
99337
+ windowMode.cancelClose();
99338
+ },
99339
+ children: "×"
98953
99340
  }),
98954
99341
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
98955
99342
  style: {
@@ -98973,51 +99360,33 @@ Please report this to https://github.com/markedjs/marked.`, e) {
98973
99360
  gap: 8,
98974
99361
  marginTop: 24
98975
99362
  },
98976
- children: [
98977
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
98978
- autoFocus: true,
98979
- style: {
98980
- ...styles$65.action,
98981
- marginLeft: 0,
98982
- color: arkmeTheme.text,
98983
- fontSize: 14
98984
- },
98985
- disabled: closingDraft,
98986
- onClick: () => {
98987
- setClosePrompt(false);
98988
- windowMode.cancelClose();
98989
- },
98990
- children: tr$1("继续编辑")
98991
- }),
98992
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
98993
- style: {
98994
- ...styles$65.action,
98995
- marginLeft: 0,
98996
- color: arkmeTheme.danger,
98997
- fontSize: 14
98998
- },
98999
- disabled: submitting || preparingImages || closingDraft,
99000
- onClick: () => {
99001
- finishWindowClose(false);
99002
- },
99003
- children: tr$1("放弃修改")
99004
- }),
99005
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
99006
- style: {
99007
- ...styles$65.action,
99008
- marginLeft: 0,
99009
- background: arkmeTheme.primaryAction,
99010
- color: arkmeTheme.onPrimaryAction,
99011
- padding: "8px 12px",
99012
- fontSize: 14
99013
- },
99014
- disabled: submitting || preparingImages || closingDraft || accountChanged,
99015
- onClick: () => {
99016
- finishWindowClose(true);
99017
- },
99018
- children: closingDraft ? tr$1("正在保存…") : tr$1("保存并关闭")
99019
- })
99020
- ]
99363
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
99364
+ style: {
99365
+ ...styles$66.action,
99366
+ marginLeft: 0,
99367
+ color: arkmeTheme.danger,
99368
+ fontSize: 14
99369
+ },
99370
+ disabled: submitting || preparingImages || closingDraft,
99371
+ onClick: () => {
99372
+ finishWindowClose(false);
99373
+ },
99374
+ children: tr$1("放弃修改")
99375
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
99376
+ style: {
99377
+ ...styles$66.action,
99378
+ marginLeft: 0,
99379
+ background: arkmeTheme.primaryAction,
99380
+ color: arkmeTheme.onPrimaryAction,
99381
+ padding: "8px 12px",
99382
+ fontSize: 14
99383
+ },
99384
+ disabled: submitting || preparingImages || closingDraft || accountChanged,
99385
+ onClick: () => {
99386
+ finishWindowClose(true);
99387
+ },
99388
+ children: closingDraft ? tr$1("正在保存…") : tr$1("保存草稿")
99389
+ })]
99021
99390
  })
99022
99391
  ]
99023
99392
  })
@@ -112522,7 +112891,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
112522
112891
  }
112523
112892
  //#endregion
112524
112893
  //#region src/client/ArkmeVoiceContent.tsx
112525
- const styles$64 = {
112894
+ const styles$65 = {
112526
112895
  root: {
112527
112896
  maxWidth: "100%",
112528
112897
  minWidth: 0,
@@ -112775,13 +113144,13 @@ Please report this to https://github.com/markedjs/marked.`, e) {
112775
113144
  };
112776
113145
  const label = status === "loading" ? tr$1("正在加载{v0}", { v0: normalizedContentLabel }) : unavailable ? tr$1("{v0}暂不可播放", { v0: normalizedContentLabel }) : status === "error" ? tr$1("重试播放{v0}", { v0: normalizedContentLabel }) : status === "playing" ? tr$1("暂停{v0}", { v0: normalizedContentLabel }) : tr$1("播放{v0}", { v0: normalizedContentLabel });
112777
113146
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
112778
- style: styles$64.root,
113147
+ style: styles$65.root,
112779
113148
  "data-arkme-voice": "inline",
112780
113149
  "data-arkme-voice-state": status,
112781
113150
  children: [
112782
113151
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
112783
113152
  style: {
112784
- ...styles$64.content,
113153
+ ...styles$65.content,
112785
113154
  ...!expanded && collapsible ? {
112786
113155
  display: "-webkit-box",
112787
113156
  WebkitBoxOrient: "vertical",
@@ -112792,7 +113161,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
112792
113161
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
112793
113162
  type: "button",
112794
113163
  style: {
112795
- ...styles$64.control,
113164
+ ...styles$65.control,
112796
113165
  ...unavailable ? {
112797
113166
  opacity: .5,
112798
113167
  cursor: "default"
@@ -112837,19 +113206,19 @@ Please report this to https://github.com/markedjs/marked.`, e) {
112837
113206
  children: visualization
112838
113207
  }),
112839
113208
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
112840
- style: styles$64.duration,
113209
+ style: styles$65.duration,
112841
113210
  children: status === "playing" ? arkmeVoiceDuration(position, true) : totalLabel
112842
113211
  })
112843
113212
  ]
112844
113213
  }), children !== void 0 && children !== null && children !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
112845
- style: styles$64.transcript,
113214
+ style: styles$65.transcript,
112846
113215
  "data-arkme-voice-transcript": "true",
112847
113216
  children
112848
113217
  })]
112849
113218
  }),
112850
113219
  collapsible && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
112851
113220
  type: "button",
112852
- style: styles$64.action,
113221
+ style: styles$65.action,
112853
113222
  "aria-expanded": expanded,
112854
113223
  onClick: (event) => {
112855
113224
  event.stopPropagation();
@@ -112864,7 +113233,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
112864
113233
  children: expanded ? tr$1("收起") : tr$1("展开")
112865
113234
  }),
112866
113235
  status === "error" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
112867
- style: styles$64.error,
113236
+ style: styles$65.error,
112868
113237
  role: "status",
112869
113238
  children: [
112870
113239
  normalizedContentLabel,
@@ -112872,7 +113241,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
112872
113241
  resolvedSrc !== "" && downloadName !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [" ", /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("a", {
112873
113242
  href: resolvedSrc,
112874
113243
  download: downloadName,
112875
- style: styles$64.action,
113244
+ style: styles$65.action,
112876
113245
  onClick: (event) => {
112877
113246
  event.stopPropagation();
112878
113247
  },
@@ -113544,7 +113913,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
113544
113913
  const textCollapseMaxLines = 5;
113545
113914
  const mediaGap = 5;
113546
113915
  const fileSdk = createArkmeSdk();
113547
- const styles$63 = {
113916
+ const styles$64 = {
113548
113917
  stack: {
113549
113918
  width: "max-content",
113550
113919
  maxWidth: "100%",
@@ -114017,7 +114386,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
114017
114386
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
114018
114387
  role: "link",
114019
114388
  tabIndex: 0,
114020
- style: styles$63.inlineLink,
114389
+ style: styles$64.inlineLink,
114021
114390
  "data-arkme-inline-link": "message-copy-link",
114022
114391
  title: href,
114023
114392
  onClick: (event) => {
@@ -114032,7 +114401,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
114032
114401
  }
114033
114402
  },
114034
114403
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ArkmeLinkIcon, {}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
114035
- style: linkLabelMode === "raw" ? styles$63.inlineRawLinkTitle : styles$63.inlineLinkTitle,
114404
+ style: linkLabelMode === "raw" ? styles$64.inlineRawLinkTitle : styles$64.inlineLinkTitle,
114036
114405
  "data-arkme-link-label": "true",
114037
114406
  children: linkLabelMode === "raw" ? text : "快记分享链接"
114038
114407
  })]
@@ -114165,8 +114534,8 @@ Please report this to https://github.com/markedjs/marked.`, e) {
114165
114534
  const content = /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ArkmeMessageRichText, {
114166
114535
  text,
114167
114536
  textStyle: {
114168
- fontSize: styles$63.text?.fontSize,
114169
- lineHeight: expanded ? 1.7 : styles$63.text?.lineHeight
114537
+ fontSize: styles$64.text?.fontSize,
114538
+ lineHeight: expanded ? 1.7 : styles$64.text?.lineHeight
114170
114539
  },
114171
114540
  ...textFormat === void 0 ? {} : { textFormat },
114172
114541
  highlightMentions,
@@ -114180,7 +114549,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
114180
114549
  });
114181
114550
  if (!markdown && !collapsible) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
114182
114551
  style: {
114183
- ...styles$63.text,
114552
+ ...styles$64.text,
114184
114553
  ...expanded ? {
114185
114554
  width: "100%",
114186
114555
  lineHeight: 1.7
@@ -114189,7 +114558,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
114189
114558
  children: content
114190
114559
  });
114191
114560
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
114192
- style: styles$63.textFrame,
114561
+ style: styles$64.textFrame,
114193
114562
  ...collapsible ? { "data-arkme-text-collapsible": "true" } : {},
114194
114563
  children: [
114195
114564
  markdown ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
@@ -114203,22 +114572,22 @@ Please report this to https://github.com/markedjs/marked.`, e) {
114203
114572
  })
114204
114573
  }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
114205
114574
  style: {
114206
- ...styles$63.text,
114575
+ ...styles$64.text,
114207
114576
  ...expanded ? {
114208
114577
  width: "100%",
114209
114578
  lineHeight: 1.7
114210
114579
  } : {},
114211
- ...collapsible && collapsed ? styles$63.collapsedText : {}
114580
+ ...collapsible && collapsed ? styles$64.collapsedText : {}
114212
114581
  },
114213
114582
  children: content
114214
114583
  }),
114215
114584
  collapsible && collapsed && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
114216
114585
  "aria-hidden": true,
114217
- style: styles$63.textFade
114586
+ style: styles$64.textFade
114218
114587
  }),
114219
114588
  collapsible && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
114220
114589
  type: "button",
114221
- style: styles$63.collapseToggle,
114590
+ style: styles$64.collapseToggle,
114222
114591
  "aria-expanded": !collapsed,
114223
114592
  onClick: (event) => {
114224
114593
  preserveTextTogglePosition(event.currentTarget, () => {
@@ -114245,7 +114614,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
114245
114614
  "data-arkme-media-fallback": unsupported ? `${block.kind}-unsupported` : block.kind,
114246
114615
  onClick: unsupported ? onOpenAsFile : onRetry,
114247
114616
  style: {
114248
- ...styles$63.mediaTile,
114617
+ ...styles$64.mediaTile,
114249
114618
  ...style,
114250
114619
  display: "grid",
114251
114620
  placeItems: "center",
@@ -114290,7 +114659,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
114290
114659
  })] })]
114291
114660
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: unsupported ? tr$1("接收{v0}", { v0: label }) : `${label}加载失败,点击重试` })]
114292
114661
  }), video && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
114293
- style: styles$63.videoBadge,
114662
+ style: styles$64.videoBadge,
114294
114663
  "aria-hidden": true,
114295
114664
  children: ["▶ ", durationLabel$4(block.durationSec)]
114296
114665
  })]
@@ -114302,7 +114671,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
114302
114671
  const width = tileSize * columns + mediaGap * (columns - 1);
114303
114672
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
114304
114673
  style: {
114305
- ...styles$63.mediaGrid,
114674
+ ...styles$64.mediaGrid,
114306
114675
  width,
114307
114676
  gridTemplateColumns: `repeat(${String(columns)}, ${String(tileSize)}px)`
114308
114677
  },
@@ -114323,7 +114692,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
114323
114692
  const src = mediaAttemptUrl(block, retryVersions.get(block.mediaRef) ?? 0);
114324
114693
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
114325
114694
  type: "button",
114326
- style: styles$63.mediaTile,
114695
+ style: styles$64.mediaTile,
114327
114696
  "aria-label": block.kind === "video" ? `播放视频 ${block.fileName}` : tr$1("预览图片 {v0}", { v0: block.fileName }),
114328
114697
  onClick: () => {
114329
114698
  onOpen(block);
@@ -114333,7 +114702,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
114333
114702
  src,
114334
114703
  alt: block.fileName,
114335
114704
  loading: "lazy",
114336
- style: styles$63.mediaImage,
114705
+ style: styles$64.mediaImage,
114337
114706
  onError: () => {
114338
114707
  onFailure(block, arkmeCanInlineLocalFile(block.mimeType, block.fileName) ? "retryable" : "unsupported");
114339
114708
  }
@@ -114342,13 +114711,13 @@ Please report this to https://github.com/markedjs/marked.`, e) {
114342
114711
  muted: true,
114343
114712
  playsInline: true,
114344
114713
  preload: "metadata",
114345
- style: styles$63.videoPreview,
114714
+ style: styles$64.videoPreview,
114346
114715
  "aria-hidden": true,
114347
114716
  onError: (event) => {
114348
114717
  onFailure(block, event.currentTarget.error?.code === 4 || !arkmeCanInlineLocalFile(block.mimeType, block.fileName) ? "unsupported" : "retryable");
114349
114718
  }
114350
114719
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
114351
- style: styles$63.videoBadge,
114720
+ style: styles$64.videoBadge,
114352
114721
  "aria-hidden": true,
114353
114722
  children: ["▶ ", durationLabel$4(block.durationSec)]
114354
114723
  })] }),
@@ -114415,7 +114784,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
114415
114784
  activate();
114416
114785
  },
114417
114786
  style: {
114418
- ...styles$63.file,
114787
+ ...styles$64.file,
114419
114788
  border: 0,
114420
114789
  textAlign: "left",
114421
114790
  cursor: opening ? "progress" : "pointer",
@@ -114425,7 +114794,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
114425
114794
  children: [
114426
114795
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
114427
114796
  style: {
114428
- ...styles$63.fileIconBox,
114797
+ ...styles$64.fileIconBox,
114429
114798
  position: "relative"
114430
114799
  },
114431
114800
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ArkmeFileIcon, {
@@ -114439,7 +114808,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
114439
114808
  flex: "1 1 auto"
114440
114809
  },
114441
114810
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
114442
- style: styles$63.fileName,
114811
+ style: styles$64.fileName,
114443
114812
  title: block.fileName || "未知文件",
114444
114813
  children: block.fileName || "未知文件"
114445
114814
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("small", {
@@ -114474,7 +114843,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
114474
114843
  }
114475
114844
  function LongArticleWordCountIcon() {
114476
114845
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
114477
- style: styles$63.articleWordIcon,
114846
+ style: styles$64.articleWordIcon,
114478
114847
  viewBox: "0 0 14 14",
114479
114848
  fill: "none",
114480
114849
  "aria-hidden": true,
@@ -114548,8 +114917,8 @@ Please report this to https://github.com/markedjs/marked.`, e) {
114548
114917
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
114549
114918
  type: "button",
114550
114919
  style: {
114551
- ...styles$63.article,
114552
- ...styles$63.articleButton
114920
+ ...styles$64.article,
114921
+ ...styles$64.articleButton
114553
114922
  },
114554
114923
  "data-arkme-long-article": "preview",
114555
114924
  "data-arkme-long-article-inner": "true",
@@ -114557,9 +114926,9 @@ Please report this to https://github.com/markedjs/marked.`, e) {
114557
114926
  onClick: onOpen,
114558
114927
  children: [
114559
114928
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
114560
- style: styles$63.articleHeading,
114929
+ style: styles$64.articleHeading,
114561
114930
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
114562
- style: styles$63.articleTitle,
114931
+ style: styles$64.articleTitle,
114563
114932
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ArkmeRichText, {
114564
114933
  text: heading,
114565
114934
  presentation: "preview"
@@ -114568,7 +114937,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
114568
114937
  }),
114569
114938
  hasTitle && text.trim() !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
114570
114939
  style: {
114571
- ...styles$63.articlePreview,
114940
+ ...styles$64.articlePreview,
114572
114941
  WebkitLineClamp: 2
114573
114942
  },
114574
114943
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ArkmeRichText, {
@@ -114577,7 +114946,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
114577
114946
  })
114578
114947
  }),
114579
114948
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
114580
- style: styles$63.articleMeta,
114949
+ style: styles$64.articleMeta,
114581
114950
  children: [
114582
114951
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LongArticleWordCountIcon, {}),
114583
114952
  String(count),
@@ -114878,7 +115247,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
114878
115247
  ref: dialogRef,
114879
115248
  tabIndex: -1,
114880
115249
  style: {
114881
- ...styles$63.previewOverlay,
115250
+ ...styles$64.previewOverlay,
114882
115251
  ...standalone ? { outline: "none" } : {}
114883
115252
  },
114884
115253
  role: "dialog",
@@ -114904,7 +115273,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
114904
115273
  }
114905
115274
  },
114906
115275
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
114907
- style: styles$63.previewBody,
115276
+ style: styles$64.previewBody,
114908
115277
  onClick: standalone ? void 0 : closeOnBlankClick,
114909
115278
  children: [
114910
115279
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("style", { children: `
@@ -114915,7 +115284,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
114915
115284
  ` }),
114916
115285
  !standalone && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
114917
115286
  type: "button",
114918
- style: styles$63.previewClose,
115287
+ style: styles$64.previewClose,
114919
115288
  "data-arkme-preview-close": true,
114920
115289
  "aria-label": tr$1("关闭预览"),
114921
115290
  title: tr$1("关闭预览"),
@@ -114930,11 +115299,11 @@ Please report this to https://github.com/markedjs/marked.`, e) {
114930
115299
  })
114931
115300
  }),
114932
115301
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
114933
- style: styles$63.previewStage,
115302
+ style: styles$64.previewStage,
114934
115303
  children: selected.kind === "image" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
114935
115304
  ref: viewportRef,
114936
115305
  style: {
114937
- ...styles$63.previewViewport,
115306
+ ...styles$64.previewViewport,
114938
115307
  overflow: "hidden",
114939
115308
  visibility: livePhoto.playing ? "hidden" : "visible",
114940
115309
  cursor: "default"
@@ -114955,7 +115324,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
114955
115324
  onPointerCancel: endImageDrag,
114956
115325
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
114957
115326
  style: {
114958
- ...imageMode === "contained" ? styles$63.previewCanvasContained : {
115327
+ ...imageMode === "contained" ? styles$64.previewCanvasContained : {
114959
115328
  width: zoomSize?.width,
114960
115329
  height: zoomSize?.height,
114961
115330
  minWidth: "100%",
@@ -114971,7 +115340,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
114971
115340
  alt: selected.fileName,
114972
115341
  draggable: false,
114973
115342
  style: {
114974
- ...imageMode === "contained" ? styles$63.previewImageContained : {
115343
+ ...imageMode === "contained" ? styles$64.previewImageContained : {
114975
115344
  display: "block",
114976
115345
  width: zoomSize?.width,
114977
115346
  height: zoomSize?.height,
@@ -115000,16 +115369,16 @@ Please report this to https://github.com/markedjs/marked.`, e) {
115000
115369
  controls: true,
115001
115370
  autoPlay: true,
115002
115371
  playsInline: true,
115003
- style: styles$63.previewMedia,
115372
+ style: styles$64.previewMedia,
115004
115373
  "aria-label": selected.fileName
115005
115374
  })
115006
115375
  }),
115007
115376
  livePhoto.video !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
115008
- style: styles$63.previewStage,
115377
+ style: styles$64.previewStage,
115009
115378
  children: livePhoto.video
115010
115379
  }),
115011
115380
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
115012
- style: styles$63.previewActions,
115381
+ style: styles$64.previewActions,
115013
115382
  "data-arkme-media-preview-actions": "bottom",
115014
115383
  children: [
115015
115384
  (!standalone || blocks.length > 1) && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
@@ -115034,7 +115403,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
115034
115403
  ]
115035
115404
  }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
115036
115405
  "aria-hidden": true,
115037
- style: styles$63.previewActionWideGap
115406
+ style: styles$64.previewActionWideGap
115038
115407
  }),
115039
115408
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ArkmeFileActionNavButton, {
115040
115409
  label: tr$1("下一个媒体"),
@@ -115048,7 +115417,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
115048
115417
  ] }),
115049
115418
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
115050
115419
  "aria-hidden": true,
115051
- style: styles$63.previewActionWideGap
115420
+ style: styles$64.previewActionWideGap
115052
115421
  }),
115053
115422
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ArkmeFileActions, {
115054
115423
  block: selected,
@@ -115058,13 +115427,13 @@ Please report this to https://github.com/markedjs/marked.`, e) {
115058
115427
  onDownloadNotice: standalone ? showActionNotice : void 0,
115059
115428
  showDownloadStatus: false,
115060
115429
  hideDownloadAfterSave: false,
115061
- style: styles$63.previewActionPair
115430
+ style: styles$64.previewActionPair
115062
115431
  })
115063
115432
  ]
115064
115433
  }),
115065
115434
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ArkmeFileActionToast, {
115066
115435
  notice: actionNotice,
115067
- style: styles$63.previewActionToast
115436
+ style: styles$64.previewActionToast
115068
115437
  })
115069
115438
  ]
115070
115439
  })
@@ -115186,19 +115555,19 @@ Please report this to https://github.com/markedjs/marked.`, e) {
115186
115555
  });
115187
115556
  const previewLines = (itemLines.length > 0 ? itemLines : item.forwardRecords.summaryLines).slice(0, 3);
115188
115557
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
115189
- style: styles$63.forwardCard,
115558
+ style: styles$64.forwardCard,
115190
115559
  "data-arkme-forward-records-card": "true",
115191
115560
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
115192
- style: styles$63.forwardTitle,
115561
+ style: styles$64.forwardTitle,
115193
115562
  title: arkmeEmojiPlainText(item.forwardRecords.title),
115194
115563
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ArkmeRichText, {
115195
115564
  text: item.forwardRecords.title,
115196
115565
  presentation: "preview"
115197
115566
  })
115198
115567
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
115199
- style: styles$63.forwardLines,
115568
+ style: styles$64.forwardLines,
115200
115569
  children: (previewLines.length > 0 ? previewLines : ["原快记暂不可查看"]).map((line, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
115201
- style: styles$63.forwardLine,
115570
+ style: styles$64.forwardLine,
115202
115571
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ArkmeRichText, {
115203
115572
  text: line,
115204
115573
  presentation: "preview",
@@ -115212,25 +115581,25 @@ Please report this to https://github.com/markedjs/marked.`, e) {
115212
115581
  const timeText = arkmeSharedRecordingTimeText(item.sharedRecording);
115213
115582
  const participantsText = arkmeSharedRecordingParticipantsText(item.sharedRecording);
115214
115583
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
115215
- style: styles$63.sharedRecordingCard,
115584
+ style: styles$64.sharedRecordingCard,
115216
115585
  "data-arkme-shared-recording-card": "true",
115217
115586
  children: [
115218
115587
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
115219
- style: styles$63.sharedRecordingTop,
115588
+ style: styles$64.sharedRecordingTop,
115220
115589
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
115221
- style: styles$63.sharedRecordingTitle,
115590
+ style: styles$64.sharedRecordingTitle,
115222
115591
  title: arkmeEmojiPlainText(item.sharedRecording.title),
115223
115592
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ArkmeRichText, {
115224
115593
  text: item.sharedRecording.title,
115225
115594
  presentation: "preview"
115226
115595
  })
115227
115596
  }), timeText !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
115228
- style: styles$63.sharedRecordingTime,
115597
+ style: styles$64.sharedRecordingTime,
115229
115598
  children: timeText
115230
115599
  })]
115231
115600
  }),
115232
115601
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
115233
- style: styles$63.sharedRecordingSummary,
115602
+ style: styles$64.sharedRecordingSummary,
115234
115603
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ArkmeRichText, {
115235
115604
  text: item.sharedRecording.summary,
115236
115605
  presentation: "preview",
@@ -115238,7 +115607,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
115238
115607
  })
115239
115608
  }),
115240
115609
  participantsText !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
115241
- style: styles$63.sharedRecordingParticipants,
115610
+ style: styles$64.sharedRecordingParticipants,
115242
115611
  children: participantsText
115243
115612
  })
115244
115613
  ]
@@ -115308,7 +115677,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
115308
115677
  }, block.mediaRef);
115309
115678
  const renderRows = splitVisualRuns(blocks.filter((block) => block !== inlineVoice)).map((row, rowIndex) => {
115310
115679
  if (Array.isArray(row)) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
115311
- style: styles$63.stack,
115680
+ style: styles$64.stack,
115312
115681
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MediaGallery, {
115313
115682
  blocks: row,
115314
115683
  failures,
@@ -115329,14 +115698,14 @@ Please report this to https://github.com/markedjs/marked.`, e) {
115329
115698
  onOpenAsFile: () => {
115330
115699
  openAsFile(row);
115331
115700
  },
115332
- ...styles$63.sticker === void 0 ? {} : { style: styles$63.sticker }
115701
+ ...styles$64.sticker === void 0 ? {} : { style: styles$64.sticker }
115333
115702
  }, row.mediaRef);
115334
115703
  if (row.renderRole === 3 && row.kind === "image") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
115335
115704
  src: mediaAttemptUrl(row, retryVersions.get(row.mediaRef) ?? 0),
115336
115705
  alt: row.fileName,
115337
115706
  title: row.fileName,
115338
115707
  draggable: false,
115339
- style: styles$63.sticker,
115708
+ style: styles$64.sticker,
115340
115709
  "data-arkme-chat-sticker": "true",
115341
115710
  onClick: () => {
115342
115711
  openPreview(row);
@@ -115356,7 +115725,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
115356
115725
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
115357
115726
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
115358
115727
  style: {
115359
- ...styles$63.stack,
115728
+ ...styles$64.stack,
115360
115729
  ...presentation === "detail" ? { width: "100%" } : {}
115361
115730
  },
115362
115731
  "data-arkme-message-content": isArticle ? "article" : "message",
@@ -115419,14 +115788,14 @@ Please report this to https://github.com/markedjs/marked.`, e) {
115419
115788
  })] }), !(isArticle && bodyTextFormat === "markdown") && renderRows] }),
115420
115789
  item.mediaUnavailable === true && (blocks.length > 0 || text !== "") && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
115421
115790
  style: {
115422
- ...styles$63.text,
115791
+ ...styles$64.text,
115423
115792
  color: arkmeTheme.tertiary,
115424
115793
  fontSize: 12
115425
115794
  },
115426
115795
  children: tr$1("部分媒体暂时无法加载,请刷新对话后重试")
115427
115796
  }),
115428
115797
  !isArticle && blocks.length === 0 && text === "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
115429
- style: styles$63.text,
115798
+ style: styles$64.text,
115430
115799
  children: item.mediaUnavailable === true ? "媒体暂时无法加载" : "暂不支持的非文本内容"
115431
115800
  })
115432
115801
  ]
@@ -115655,7 +116024,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
115655
116024
  function errorMessage$12(caught) {
115656
116025
  return caught instanceof Error ? caught.message : String(caught);
115657
116026
  }
115658
- const styles$62 = {
116027
+ const styles$63 = {
115659
116028
  cardScrim: {
115660
116029
  position: "absolute",
115661
116030
  inset: 0,
@@ -116040,24 +116409,24 @@ Please report this to https://github.com/markedjs/marked.`, e) {
116040
116409
  const buttonBackground = props.busy ? arkmeTheme.layer1 : buttonState === "active" ? arkmeTheme.active : buttonState === "hover" ? arkmeTheme.hover : arkmeTheme.elevated;
116041
116410
  const names = arkmeMemberProfileNames(props.member, props.showTopicNickname === true);
116042
116411
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
116043
- style: styles$62.cardScrim,
116412
+ style: styles$63.cardScrim,
116044
116413
  role: "presentation",
116045
116414
  onMouseDown: (event) => {
116046
116415
  if (event.target === event.currentTarget) props.onClose();
116047
116416
  },
116048
116417
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
116049
- style: styles$62.card,
116418
+ style: styles$63.card,
116050
116419
  role: "dialog",
116051
116420
  "aria-modal": "true",
116052
116421
  "aria-label": tr$1("{v0} 的用户卡片", { v0: names.displayName }),
116053
116422
  children: [backdrop !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
116054
116423
  "aria-hidden": true,
116055
116424
  style: {
116056
- ...styles$62.cardBackdrop,
116425
+ ...styles$63.cardBackdrop,
116057
116426
  backgroundImage: `url(${JSON.stringify(backdrop).slice(1, -1)})`
116058
116427
  }
116059
116428
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
116060
- style: styles$62.cardContent,
116429
+ style: styles$63.cardContent,
116061
116430
  children: [
116062
116431
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ArkmeUserAvatar, {
116063
116432
  ...props.member.avatarRef === void 0 ? {} : { avatarRef: props.member.avatarRef },
@@ -116066,18 +116435,18 @@ Please report this to https://github.com/markedjs/marked.`, e) {
116066
116435
  label: tr$1("{v0} 的头像", { v0: names.displayName })
116067
116436
  }),
116068
116437
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
116069
- style: styles$62.cardName,
116438
+ style: styles$63.cardName,
116070
116439
  children: names.displayName
116071
116440
  }),
116072
116441
  names.topicNickname !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
116073
- style: styles$62.cardSecondaryName,
116442
+ style: styles$63.cardSecondaryName,
116074
116443
  children: [tr$1("主题内昵称:"), names.topicNickname]
116075
116444
  }),
116076
116445
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
116077
116446
  "data-arkme-feedback": "neutral",
116078
116447
  type: "button",
116079
116448
  style: {
116080
- ...styles$62.cardButton,
116449
+ ...styles$63.cardButton,
116081
116450
  background: buttonBackground,
116082
116451
  borderColor: buttonState === "idle" || props.busy ? arkmeTheme.border : arkmeTheme.accent,
116083
116452
  cursor: props.busy ? "default" : "pointer",
@@ -116332,7 +116701,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
116332
116701
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
116333
116702
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
116334
116703
  ref: dismissRef,
116335
- style: styles$62.drawerDismiss,
116704
+ style: styles$63.drawerDismiss,
116336
116705
  "data-arkme-member-records-dismiss": "true",
116337
116706
  onPointerDown: props.onClose
116338
116707
  }),
@@ -116345,7 +116714,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
116345
116714
  "data-arkme-member-records-resize-handle": "true",
116346
116715
  "data-resizing": resizing ? "true" : "false",
116347
116716
  style: {
116348
- ...styles$62.drawerResizeHandle,
116717
+ ...styles$63.drawerResizeHandle,
116349
116718
  right: handleRight
116350
116719
  },
116351
116720
  onPointerEnter: () => {
@@ -116385,7 +116754,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
116385
116754
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
116386
116755
  "aria-hidden": true,
116387
116756
  style: {
116388
- ...styles$62.drawerResizeIndicator,
116757
+ ...styles$63.drawerResizeIndicator,
116389
116758
  ...drawerUsesAllAvailableWidth ? { left: 0 } : { right: 0 },
116390
116759
  opacity: resizeHovered || resizing ? 1 : 0
116391
116760
  }
@@ -116393,7 +116762,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
116393
116762
  }),
116394
116763
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("aside", {
116395
116764
  style: {
116396
- ...styles$62.drawer,
116765
+ ...styles$63.drawer,
116397
116766
  width: effectiveWidth
116398
116767
  },
116399
116768
  role: "dialog",
@@ -116411,22 +116780,22 @@ Please report this to https://github.com/markedjs/marked.`, e) {
116411
116780
  closeLabel: tr$1("关闭成员快记")
116412
116781
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
116413
116782
  ref: bodyRef,
116414
- style: styles$62.drawerBody,
116783
+ style: styles$63.drawerBody,
116415
116784
  onScroll: (event) => {
116416
116785
  if (shouldLoadOlderArkmeMemberRecords(event.currentTarget.scrollTop, hasMore, cursor, loadingRef.current)) load(cursor);
116417
116786
  },
116418
116787
  children: [
116419
116788
  loading && items.length === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
116420
- style: styles$62.state,
116789
+ style: styles$63.state,
116421
116790
  children: tr$1("正在加载快记…")
116422
116791
  }),
116423
116792
  error !== "" && items.length === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
116424
- style: styles$62.state,
116793
+ style: styles$63.state,
116425
116794
  role: "alert",
116426
116795
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { children: error }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
116427
116796
  "data-arkme-feedback": "neutral",
116428
116797
  type: "button",
116429
- style: styles$62.retry,
116798
+ style: styles$63.retry,
116430
116799
  onClick: () => {
116431
116800
  load();
116432
116801
  },
@@ -116434,23 +116803,23 @@ Please report this to https://github.com/markedjs/marked.`, e) {
116434
116803
  })]
116435
116804
  }),
116436
116805
  !loading && error === "" && items.length === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
116437
- style: styles$62.state,
116806
+ style: styles$63.state,
116438
116807
  children: tr$1("暂无快记")
116439
116808
  }),
116440
116809
  loading && items.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
116441
- style: styles$62.loadMoreState,
116810
+ style: styles$63.loadMoreState,
116442
116811
  role: "status",
116443
116812
  "aria-live": "polite",
116444
116813
  children: tr$1("正在加载快记…")
116445
116814
  }),
116446
116815
  error !== "" && items.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
116447
- style: styles$62.loadMoreState,
116816
+ style: styles$63.loadMoreState,
116448
116817
  role: "alert",
116449
116818
  title: error,
116450
116819
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: tr$1("加载快记失败") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
116451
116820
  "data-arkme-feedback": "neutral",
116452
116821
  type: "button",
116453
- style: styles$62.loadMoreRetry,
116822
+ style: styles$63.loadMoreRetry,
116454
116823
  onClick: () => {
116455
116824
  load(lastLoadRef.current.beforeSequence, lastLoadRef.current.refresh);
116456
116825
  },
@@ -116458,12 +116827,12 @@ Please report this to https://github.com/markedjs/marked.`, e) {
116458
116827
  })]
116459
116828
  }),
116460
116829
  timeline.map((entry) => entry.kind === "time" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
116461
- style: styles$62.recordTime,
116830
+ style: styles$63.recordTime,
116462
116831
  "data-arkme-record-time": entry.timestamp,
116463
116832
  children: entry.label
116464
116833
  }, entry.key) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react$1.Fragment, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("article", {
116465
116834
  style: {
116466
- ...styles$62.recordRow,
116835
+ ...styles$63.recordRow,
116467
116836
  justifyContent: entry.item.isMe ? "flex-end" : "flex-start"
116468
116837
  },
116469
116838
  "data-arkme-member-record-row": entry.item.isMe ? "self" : "other",
@@ -116476,16 +116845,16 @@ Please report this to https://github.com/markedjs/marked.`, e) {
116476
116845
  }),
116477
116846
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
116478
116847
  style: {
116479
- ...styles$62.recordMain,
116848
+ ...styles$63.recordMain,
116480
116849
  alignItems: entry.item.isMe ? "flex-end" : "flex-start"
116481
116850
  },
116482
116851
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
116483
- style: styles$62.recordName,
116852
+ style: styles$63.recordName,
116484
116853
  children: entry.item.senderName
116485
116854
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
116486
116855
  style: {
116487
- ...styles$62.recordBubble,
116488
- ...entry.item.isMe ? styles$62.recordBubbleSelf : {}
116856
+ ...styles$63.recordBubble,
116857
+ ...entry.item.isMe ? styles$63.recordBubbleSelf : {}
116489
116858
  },
116490
116859
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ArkmeMessageContent, {
116491
116860
  item: entry.item,
@@ -116572,7 +116941,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
116572
116941
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
116573
116942
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
116574
116943
  ref: dismissRef,
116575
- style: styles$62.drawerDismiss,
116944
+ style: styles$63.drawerDismiss,
116576
116945
  "data-arkme-bot-records-dismiss": "true",
116577
116946
  onPointerDown: props.onClose
116578
116947
  }),
@@ -116585,7 +116954,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
116585
116954
  "data-arkme-bot-records-resize-handle": "true",
116586
116955
  "data-resizing": resizing ? "true" : "false",
116587
116956
  style: {
116588
- ...styles$62.drawerResizeHandle,
116957
+ ...styles$63.drawerResizeHandle,
116589
116958
  right: handleRight
116590
116959
  },
116591
116960
  onPointerEnter: () => {
@@ -116625,7 +116994,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
116625
116994
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
116626
116995
  "aria-hidden": true,
116627
116996
  style: {
116628
- ...styles$62.drawerResizeIndicator,
116997
+ ...styles$63.drawerResizeIndicator,
116629
116998
  ...allAvailable ? { left: 0 } : { right: 0 },
116630
116999
  opacity: resizeHovered || resizing ? 1 : 0
116631
117000
  }
@@ -116633,7 +117002,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
116633
117002
  }),
116634
117003
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("aside", {
116635
117004
  style: {
116636
- ...styles$62.drawer,
117005
+ ...styles$63.drawer,
116637
117006
  width: effectiveWidth
116638
117007
  },
116639
117008
  role: "dialog",
@@ -116649,17 +117018,17 @@ Please report this to https://github.com/markedjs/marked.`, e) {
116649
117018
  closeLabel: tr$1("关闭 Bot 消息")
116650
117019
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
116651
117020
  ref: bodyRef,
116652
- style: styles$62.drawerBody,
117021
+ style: styles$63.drawerBody,
116653
117022
  children: [timeline.length === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
116654
- style: styles$62.state,
117023
+ style: styles$63.state,
116655
117024
  children: tr$1("当前已加载消息中暂无匹配内容")
116656
117025
  }), timeline.map((entry) => entry.kind === "time" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
116657
- style: styles$62.recordTime,
117026
+ style: styles$63.recordTime,
116658
117027
  "data-arkme-record-time": entry.timestamp,
116659
117028
  children: entry.label
116660
117029
  }, entry.key) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("article", {
116661
117030
  style: {
116662
- ...styles$62.recordRow,
117031
+ ...styles$63.recordRow,
116663
117032
  justifyContent: entry.item.isMe ? "flex-end" : "flex-start"
116664
117033
  },
116665
117034
  "data-arkme-bot-record-id": entry.item.itemUid,
@@ -116672,16 +117041,16 @@ Please report this to https://github.com/markedjs/marked.`, e) {
116672
117041
  }),
116673
117042
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
116674
117043
  style: {
116675
- ...styles$62.recordMain,
117044
+ ...styles$63.recordMain,
116676
117045
  alignItems: entry.item.isMe ? "flex-end" : "flex-start"
116677
117046
  },
116678
117047
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
116679
- style: styles$62.recordName,
117048
+ style: styles$63.recordName,
116680
117049
  children: entry.item.senderName
116681
117050
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
116682
117051
  style: {
116683
- ...styles$62.recordBubble,
116684
- ...entry.item.isMe ? styles$62.recordBubbleSelf : {}
117052
+ ...styles$63.recordBubble,
117053
+ ...entry.item.isMe ? styles$63.recordBubbleSelf : {}
116685
117054
  },
116686
117055
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ArkmeMessageContent, {
116687
117056
  item: entry.item,
@@ -119890,6 +120259,223 @@ Please report this to https://github.com/markedjs/marked.`, e) {
119890
120259
  })
119891
120260
  ] });
119892
120261
  }
120262
+ //#endregion
120263
+ //#region src/client/ArkmeSelfRoleMenu.tsx
120264
+ /** A role selector has two sibling controls per row: selection and management.
120265
+ * Keep command menus native; don't nest interactive buttons inside native menu items. */
120266
+ function ArkmeSelfRoleMenu({ open, anchor, actions, selectedIds, onClose }) {
120267
+ const host = (0, react$1.useRef)(null);
120268
+ const panel = (0, react$1.useRef)(null);
120269
+ const [managedId, setManagedId] = (0, react$1.useState)("");
120270
+ const [position, setPosition] = (0, react$1.useState)({
120271
+ left: 0,
120272
+ top: 0
120273
+ });
120274
+ const browser = typeof document !== "undefined" && typeof document.createElement === "function";
120275
+ (0, react$1.useLayoutEffect)(() => {
120276
+ if (!open) {
120277
+ setManagedId("");
120278
+ return;
120279
+ }
120280
+ if (!browser) return;
120281
+ const doc = host.current.ownerDocument, win = doc.defaultView;
120282
+ const layout = () => {
120283
+ const rect = host.current?.getBoundingClientRect(), size = panel.current?.getBoundingClientRect();
120284
+ if (!rect || !size) return;
120285
+ setPosition({
120286
+ left: Math.max(8, Math.min(rect.right - size.width, win.innerWidth - size.width - 8)),
120287
+ top: Math.max(8, rect.top - size.height - 8)
120288
+ });
120289
+ };
120290
+ const dismiss = (event) => {
120291
+ const target = event.target;
120292
+ if (host.current?.contains(target) || panel.current?.contains(target)) return;
120293
+ if (target instanceof Element && target.closest("[role=\"menu\"][aria-label=\"角色操作\"]")) return;
120294
+ onClose();
120295
+ };
120296
+ layout();
120297
+ const resize = typeof ResizeObserver === "undefined" ? void 0 : new ResizeObserver(layout);
120298
+ if (panel.current) resize?.observe(panel.current);
120299
+ doc.addEventListener("pointerdown", dismiss, true);
120300
+ win.addEventListener("resize", layout);
120301
+ doc.addEventListener("scroll", layout, true);
120302
+ const stopFrames = watchFrameMenuDismissal(doc, onClose, (event) => {
120303
+ if (event.key === "Escape") onClose();
120304
+ });
120305
+ return () => {
120306
+ resize?.disconnect();
120307
+ stopFrames();
120308
+ doc.removeEventListener("pointerdown", dismiss, true);
120309
+ win.removeEventListener("resize", layout);
120310
+ doc.removeEventListener("scroll", layout, true);
120311
+ };
120312
+ }, [
120313
+ open,
120314
+ browser,
120315
+ onClose
120316
+ ]);
120317
+ (0, react$1.useLayoutEffect)(() => {
120318
+ if (open) panel.current?.querySelector("[data-role-action]:not(:disabled)")?.focus();
120319
+ }, [open]);
120320
+ const content = open && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
120321
+ ref: panel,
120322
+ className: "arkme-self-role-menu",
120323
+ role: "dialog",
120324
+ "aria-label": "选择发言角色",
120325
+ style: {
120326
+ ...styles$62.panel,
120327
+ ...position
120328
+ },
120329
+ onKeyDown: (event) => {
120330
+ const choices = [...panel.current?.querySelectorAll("[data-role-action]:not(:disabled)") ?? []];
120331
+ if (!managedId && [
120332
+ "ArrowDown",
120333
+ "ArrowUp",
120334
+ "Home",
120335
+ "End"
120336
+ ].includes(event.key) && choices.length) {
120337
+ event.preventDefault();
120338
+ const index = choices.indexOf(event.target);
120339
+ choices[event.key === "Home" ? 0 : event.key === "End" ? choices.length - 1 : (index + (event.key === "ArrowDown" ? 1 : -1) + choices.length) % choices.length]?.focus();
120340
+ }
120341
+ if (event.key === "Escape" && !managedId) {
120342
+ event.preventDefault();
120343
+ event.stopPropagation();
120344
+ onClose();
120345
+ host.current?.querySelector("button")?.focus();
120346
+ }
120347
+ },
120348
+ children: actions.map((action) => {
120349
+ if ("type" in action) return action.type === "separator" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
120350
+ role: "separator",
120351
+ style: styles$62.separator
120352
+ }, action.id) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
120353
+ style: styles$62.note,
120354
+ children: action.text
120355
+ }, action.id);
120356
+ const selected = selectedIds.includes(action.id);
120357
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
120358
+ style: {
120359
+ ...styles$62.row,
120360
+ ...selected ? styles$62.selected : {}
120361
+ },
120362
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
120363
+ type: "button",
120364
+ "data-role-action": action.id,
120365
+ disabled: action.disabled,
120366
+ "aria-pressed": selected,
120367
+ style: styles$62.select,
120368
+ onClick: action.onSelect,
120369
+ children: [action.icon, /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
120370
+ style: styles$62.name,
120371
+ children: action.label
120372
+ })]
120373
+ }), action.managementActions && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ArkmeActionMenu, {
120374
+ open: managedId === action.id,
120375
+ label: "角色操作",
120376
+ side: "right",
120377
+ autoFocus: true,
120378
+ onClose: () => setManagedId(""),
120379
+ actions: action.managementActions,
120380
+ anchor: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
120381
+ type: "button",
120382
+ style: styles$62.manage,
120383
+ "aria-label": `管理${String(action.label)}`,
120384
+ title: "管理角色",
120385
+ "aria-haspopup": "menu",
120386
+ "aria-expanded": managedId === action.id,
120387
+ onClick: () => setManagedId(managedId === action.id ? "" : action.id),
120388
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconEllipsisOutline16, {})
120389
+ })
120390
+ })]
120391
+ }, action.id);
120392
+ })
120393
+ });
120394
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
120395
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("style", { children: `
120396
+ [data-arkme-action-menu="true"][role="menu"][aria-label="角色操作"] {
120397
+ min-width: 120px;
120398
+ width: max-content;
120399
+ max-width: min(360px, calc(100vw - 16px));
120400
+ }
120401
+ .arkme-self-role-menu button { border-radius: 6px; }
120402
+ .arkme-self-role-menu button:hover:not(:disabled) { background: var(--dsw-alias-interactive-bg-hover, #f1f2f4); }
120403
+ .arkme-self-role-menu button:disabled { opacity: .4; cursor: default; }
120404
+ .arkme-self-role-menu button:focus-visible { outline: 2px solid var(--dsw-alias-label-secondary, #68707c); outline-offset: -2px; }
120405
+ ` }),
120406
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
120407
+ ref: host,
120408
+ style: { display: "inline-flex" },
120409
+ children: anchor
120410
+ }),
120411
+ browser && content ? (0, react_dom$1.createPortal)(content, document.body) : content
120412
+ ] });
120413
+ }
120414
+ const styles$62 = {
120415
+ panel: {
120416
+ position: "fixed",
120417
+ zIndex: 100,
120418
+ width: 248,
120419
+ maxWidth: "calc(100vw - 16px)",
120420
+ maxHeight: "calc(100vh - 16px)",
120421
+ overflowY: "auto",
120422
+ boxSizing: "border-box",
120423
+ padding: 6,
120424
+ borderRadius: 12,
120425
+ background: "var(--dsw-alias-bg-base, #fff)",
120426
+ color: "var(--dsw-alias-label-primary, #292929)",
120427
+ border: "1px solid var(--dsw-alias-border-l1, #e6e8ec)",
120428
+ boxShadow: "0 8px 28px rgba(0,0,0,.12)"
120429
+ },
120430
+ row: {
120431
+ display: "flex",
120432
+ alignItems: "center",
120433
+ borderRadius: 8,
120434
+ minHeight: 40
120435
+ },
120436
+ selected: { background: "var(--dsw-alias-bg-active, #eef0f3)" },
120437
+ select: {
120438
+ flex: 1,
120439
+ minWidth: 0,
120440
+ display: "flex",
120441
+ alignItems: "center",
120442
+ gap: 8,
120443
+ padding: "10px 8px",
120444
+ border: 0,
120445
+ background: "transparent",
120446
+ color: "inherit",
120447
+ font: "inherit",
120448
+ fontSize: 13,
120449
+ textAlign: "left",
120450
+ cursor: "pointer"
120451
+ },
120452
+ name: {
120453
+ overflow: "hidden",
120454
+ textOverflow: "ellipsis",
120455
+ whiteSpace: "nowrap"
120456
+ },
120457
+ manage: {
120458
+ display: "grid",
120459
+ placeItems: "center",
120460
+ width: 32,
120461
+ height: 32,
120462
+ border: 0,
120463
+ borderRadius: 6,
120464
+ background: "transparent",
120465
+ color: "var(--dsw-alias-label-secondary, #68707c)",
120466
+ cursor: "pointer"
120467
+ },
120468
+ separator: {
120469
+ height: 1,
120470
+ margin: "4px 6px",
120471
+ background: "var(--dsw-alias-border-l1, #e6e8ec)"
120472
+ },
120473
+ note: {
120474
+ padding: 8,
120475
+ fontSize: 12,
120476
+ color: "var(--dsw-alias-label-secondary, #68707c)"
120477
+ }
120478
+ };
119893
120479
  function extensionAvatarSourceError(file) {
119894
120480
  if (!Number.isFinite(file.size) || file.size <= 0) return "头像文件不能为空";
119895
120481
  if (!file.type.toLowerCase().startsWith("image/")) return "请选择图片文件";
@@ -120384,9 +120970,16 @@ Please report this to https://github.com/markedjs/marked.`, e) {
120384
120970
  error: ""
120385
120971
  };
120386
120972
  const [refreshRevision, setRefreshRevision] = (0, react$1.useState)(0);
120973
+ (0, react$1.useEffect)(() => {
120974
+ if (typeof window === "undefined") return;
120975
+ const refresh = () => setRefreshRevision((value) => value + 1);
120976
+ window.addEventListener("arkme-self-roles-changed", refresh);
120977
+ return () => window.removeEventListener("arkme-self-roles-changed", refresh);
120978
+ }, []);
120387
120979
  const [menuOpen, setMenuOpen] = (0, react$1.useState)(false);
120388
120980
  const [createOpen, setCreateOpen] = (0, react$1.useState)(false);
120389
120981
  const [name, setName] = (0, react$1.useState)("");
120982
+ const [editingRole, setEditingRole] = (0, react$1.useState)();
120390
120983
  const [avatarFile, setAvatarFile] = (0, react$1.useState)();
120391
120984
  const [avatarPreviewUrl, setAvatarPreviewUrl] = (0, react$1.useState)("");
120392
120985
  const [cropSource, setCropSource] = (0, react$1.useState)();
@@ -120398,6 +120991,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
120398
120991
  setMenuOpen(false);
120399
120992
  setCreateOpen(false);
120400
120993
  setName("");
120994
+ setEditingRole(void 0);
120401
120995
  setAvatarFile(void 0);
120402
120996
  setCropSource(void 0);
120403
120997
  setSaving(false);
@@ -120469,6 +121063,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
120469
121063
  if (saveControllerRef.current !== void 0) return;
120470
121064
  setCreateOpen(false);
120471
121065
  setName("");
121066
+ setEditingRole(void 0);
120472
121067
  setAvatarFile(void 0);
120473
121068
  setCropSource(void 0);
120474
121069
  setFormError("");
@@ -120476,7 +121071,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
120476
121071
  const createRole = async (event) => {
120477
121072
  event.preventDefault();
120478
121073
  const roleName = name.trim();
120479
- if (disabled || saveControllerRef.current !== void 0 || visibleState.loading || visibleState.error !== "" || visibleState.roles.length >= MAX_ROLES || !roleName || Array.from(roleName).length > MAX_NAME_LENGTH) return;
121074
+ if (disabled || saveControllerRef.current !== void 0 || visibleState.loading || visibleState.error !== "" || editingRole === void 0 && visibleState.roles.length >= MAX_ROLES || !roleName || Array.from(roleName).length > MAX_NAME_LENGTH) return;
120480
121075
  const controller = new AbortController();
120481
121076
  saveControllerRef.current = controller;
120482
121077
  const submittingScope = scope;
@@ -120485,9 +121080,10 @@ Please report this to https://github.com/markedjs/marked.`, e) {
120485
121080
  try {
120486
121081
  const avatarRef = avatarFile === void 0 ? void 0 : await saveLocalRoleAvatar(avatarFile, userId, controller.signal);
120487
121082
  if (controller.signal.aborted || scopeRef.current !== submittingScope) return;
120488
- const created = await callArkme("self-roles.create", {
121083
+ const created = await callArkme(editingRole === void 0 ? "self-roles.create" : "self-roles.update", {
121084
+ ...editingRole === void 0 ? {} : { roleId: editingRole.roleId },
120489
121085
  expectedUserId: userId,
120490
- name: roleName,
121086
+ ...editingRole?.name === roleName ? {} : { name: roleName },
120491
121087
  ...avatarRef === void 0 ? {} : { avatarRef }
120492
121088
  }, controller.signal);
120493
121089
  if (controller.signal.aborted || scopeRef.current !== submittingScope) return;
@@ -120497,6 +121093,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
120497
121093
  } : current);
120498
121094
  setCreateOpen(false);
120499
121095
  setName("");
121096
+ setEditingRole(void 0);
120500
121097
  setAvatarFile(void 0);
120501
121098
  onSelect(created);
120502
121099
  } catch (caught) {
@@ -120556,6 +121153,33 @@ Please report this to https://github.com/markedjs/marked.`, e) {
120556
121153
  })
120557
121154
  ]
120558
121155
  });
121156
+ const editRole = (role) => {
121157
+ setMenuOpen(false);
121158
+ setEditingRole(role);
121159
+ setName(role.name);
121160
+ setAvatarFile(void 0);
121161
+ setFormError("");
121162
+ setCreateOpen(true);
121163
+ };
121164
+ const deleteRole = (role) => {
121165
+ setMenuOpen(false);
121166
+ callArkme("self-roles.delete", {
121167
+ expectedUserId: userId,
121168
+ roleId: role.roleId
121169
+ }).then(() => {
121170
+ if (scopeRef.current !== scope) return;
121171
+ setRoleState((current) => current.scope === scope ? {
121172
+ ...current,
121173
+ roles: current.roles.filter((item) => item.roleId !== role.roleId)
121174
+ } : current);
121175
+ setRefreshRevision((value) => value + 1);
121176
+ }).catch((error) => {
121177
+ if (scopeRef.current === scope) setRoleState((current) => ({
121178
+ ...current,
121179
+ error: error instanceof Error ? error.message : "删除失败"
121180
+ }));
121181
+ });
121182
+ };
120559
121183
  const menuActions = [
120560
121184
  {
120561
121185
  id: "me",
@@ -120573,10 +121197,6 @@ Please report this to https://github.com/markedjs/marked.`, e) {
120573
121197
  onSelect(void 0);
120574
121198
  }
120575
121199
  },
120576
- {
120577
- type: "separator",
120578
- id: "role-separator"
120579
- },
120580
121200
  ...visibleState.roles.map((role) => ({
120581
121201
  id: `role:${role.roleId}`,
120582
121202
  label: role.name,
@@ -120587,7 +121207,17 @@ Please report this to https://github.com/markedjs/marked.`, e) {
120587
121207
  onSelect: () => {
120588
121208
  setMenuOpen(false);
120589
121209
  onSelect(role);
120590
- }
121210
+ },
121211
+ managementActions: [{
121212
+ id: "role-edit",
121213
+ label: "编辑",
121214
+ onSelect: () => editRole(role)
121215
+ }, {
121216
+ id: "role-delete",
121217
+ label: "删除",
121218
+ danger: true,
121219
+ onSelect: () => deleteRole(role)
121220
+ }]
120591
121221
  })),
120592
121222
  ...visibleState.loading ? [{
120593
121223
  type: "label",
@@ -120615,22 +121245,17 @@ Please report this to https://github.com/markedjs/marked.`, e) {
120615
121245
  disabled: visibleState.loading || visibleState.error !== "" || visibleState.roles.length >= MAX_ROLES,
120616
121246
  onSelect: () => {
120617
121247
  setMenuOpen(false);
121248
+ setEditingRole(void 0);
121249
+ setName("");
121250
+ setAvatarFile(void 0);
120618
121251
  setFormError("");
120619
121252
  setCreateOpen(true);
120620
121253
  }
120621
- },
120622
- {
120623
- type: "label",
120624
- id: "role-local-note",
120625
- text: visibleState.roles.length >= MAX_ROLES ? "最多 20 个角色 · 角色资料和头像仅保存在此设备" : "角色资料和头像仅保存在此设备"
120626
121254
  }
120627
121255
  ];
120628
121256
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
120629
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ArkmeActionMenu, {
121257
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ArkmeSelfRoleMenu, {
120630
121258
  open: menuOpen,
120631
- label: "选择发言角色",
120632
- side: "top",
120633
- align: "end",
120634
121259
  selectedIds: [selectedId],
120635
121260
  anchor: trigger,
120636
121261
  onClose: () => setMenuOpen(false),
@@ -120644,7 +121269,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
120644
121269
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
120645
121270
  role: "dialog",
120646
121271
  "aria-modal": "true",
120647
- "aria-label": "创建发言角色",
121272
+ "aria-label": editingRole ? "编辑发言角色" : "创建发言角色",
120648
121273
  style: styles$60.dialog,
120649
121274
  onKeyDown: (event) => {
120650
121275
  if (event.key === "Escape" && !saving && cropSource === void 0) {
@@ -120655,7 +121280,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
120655
121280
  children: [
120656
121281
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
120657
121282
  style: styles$60.title,
120658
- children: "创建角色"
121283
+ children: editingRole ? "编辑角色" : "创建角色"
120659
121284
  }),
120660
121285
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
120661
121286
  style: styles$60.description,
@@ -120682,7 +121307,8 @@ Please report this to https://github.com/markedjs/marked.`, e) {
120682
121307
  }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ArkmeSelfRoleAvatar, {
120683
121308
  role: {
120684
121309
  roleId: "draft",
120685
- name: name.trim() || "角"
121310
+ name: name.trim() || "角",
121311
+ ...editingRole?.avatarRef ? { avatarRef: editingRole.avatarRef } : {}
120686
121312
  },
120687
121313
  size: 48
120688
121314
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
@@ -120722,10 +121348,6 @@ Please report this to https://github.com/markedjs/marked.`, e) {
120722
121348
  setCropSource(file);
120723
121349
  }
120724
121350
  }),
120725
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
120726
- style: styles$60.localNote,
120727
- children: "角色资料、头像和发言归属仅保存在此设备。其他设备暂不会同步。"
120728
- }),
120729
121351
  formError && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
120730
121352
  role: "alert",
120731
121353
  style: styles$60.error,
@@ -120742,8 +121364,8 @@ Please report this to https://github.com/markedjs/marked.`, e) {
120742
121364
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
120743
121365
  type: "submit",
120744
121366
  style: styles$60.submit,
120745
- disabled: saving || !name.trim() || visibleState.roles.length >= MAX_ROLES,
120746
- children: saving ? "创建中…" : "创建并选用"
121367
+ disabled: saving || !name.trim() || editingRole === void 0 && visibleState.roles.length >= MAX_ROLES,
121368
+ children: saving ? "保存中…" : editingRole ? "保存并选用" : "创建并选用"
120747
121369
  })]
120748
121370
  })
120749
121371
  ]
@@ -120874,12 +121496,6 @@ Please report this to https://github.com/markedjs/marked.`, e) {
120874
121496
  font: "inherit",
120875
121497
  fontSize: 13
120876
121498
  },
120877
- localNote: {
120878
- margin: "16px 0 0",
120879
- color: "var(--dsw-alias-label-secondary, #717780)",
120880
- fontSize: 11,
120881
- lineHeight: "17px"
120882
- },
120883
121499
  error: {
120884
121500
  margin: "10px 0 0",
120885
121501
  color: "#b42318",
@@ -127321,15 +127937,29 @@ body[data-ds-dark-theme] .arkme-mention-all-avatar [data-arkme-theme-image="dark
127321
127937
  }
127322
127938
  function RecordRow$1({ item, avatarRef, onOpen, onSelectSource }) {
127323
127939
  const sourceLabel = arkmeCalendarRecordSourceLabel(item);
127940
+ const role = !item.protected && (item.sourceKind === "self" || item.sourceKind === "topic") ? item.content?.selfRole : void 0;
127324
127941
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("article", {
127325
- style: styles$55.recordRow,
127942
+ "data-arkme-calendar-role": role?.roleId,
127943
+ style: {
127944
+ ...styles$55.recordRow,
127945
+ ...role === void 0 ? {} : {
127946
+ flexDirection: "row-reverse",
127947
+ justifyContent: "flex-end"
127948
+ }
127949
+ },
127326
127950
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
127327
- style: styles$55.recordStack,
127951
+ style: {
127952
+ ...styles$55.recordStack,
127953
+ ...role === void 0 ? {} : { alignItems: "flex-start" }
127954
+ },
127328
127955
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
127329
- style: styles$55.recordHeader,
127956
+ style: {
127957
+ ...styles$55.recordHeader,
127958
+ ...role === void 0 ? {} : { justifyContent: "flex-start" }
127959
+ },
127330
127960
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
127331
127961
  style: styles$55.recordTitle,
127332
- children: tr$1("你")
127962
+ children: role?.name ?? tr$1("你")
127333
127963
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("time", {
127334
127964
  style: styles$55.recordTime,
127335
127965
  children: timeLabel$4(item.sendAtMillis)
@@ -127337,6 +127967,10 @@ body[data-ds-dark-theme] .arkme-mention-all-avatar [data-arkme-theme-image="dark
127337
127967
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
127338
127968
  style: {
127339
127969
  ...styles$55.recordBubble,
127970
+ ...role === void 0 ? {} : {
127971
+ borderRadius: "5px 16px 16px 16px",
127972
+ background: arkmeTheme.subtle
127973
+ },
127340
127974
  cursor: "pointer"
127341
127975
  },
127342
127976
  tabIndex: 0,
@@ -127369,10 +128003,15 @@ body[data-ds-dark-theme] .arkme-mention-all-avatar [data-arkme-theme-image="dark
127369
128003
  })
127370
128004
  ]
127371
128005
  })]
127372
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ArkmeUserAvatar, {
128006
+ }), role === void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ArkmeUserAvatar, {
127373
128007
  ...avatarRef === void 0 || avatarRef === "" ? {} : { avatarRef },
127374
128008
  size: 30,
127375
128009
  label: tr$1("当前用户头像")
128010
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ArkmeUserAvatar, {
128011
+ ...role.avatarRef ? { avatarRef: role.avatarRef } : {},
128012
+ fallback: arkmeSelfRoleAvatarFallback(role),
128013
+ size: 30,
128014
+ label: `${role.name}的头像`
127376
128015
  })]
127377
128016
  });
127378
128017
  }
@@ -127814,14 +128453,16 @@ body[data-ds-dark-theme] .arkme-mention-all-avatar [data-arkme-theme-image="dark
127814
128453
  item: detailItem,
127815
128454
  onPrivateChatOpened: selectSource,
127816
128455
  onClose: () => setSelectedRecord(void 0)
127817
- }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ArkmeTimelineDetailDrawer, {
128456
+ }) : /* @__PURE__ */ (0, react$1.createElement)(ArkmeTimelineDetailDrawer, {
127818
128457
  sourceBadge,
128458
+ ...detailItem.selfRole === void 0 ? {} : selectedItem?.sourceKind === "self" ? { sourceKind: "send_to_self" } : selectedItem?.sourceKind === "topic" ? { sourceKind: "topic" } : {},
128459
+ key: detailItem.itemUid,
127819
128460
  item: detailItem,
127820
128461
  canExtend: false,
127821
128462
  showOriginal,
127822
128463
  onToggleOriginal: () => setShowOriginal((value) => !value),
127823
128464
  onClose: () => setSelectedRecord(void 0)
127824
- }, detailItem.itemUid)
128465
+ })
127825
128466
  })
127826
128467
  })
127827
128468
  ]
@@ -150040,7 +150681,7 @@ body:has([data-arkme-self-topic-menu]) > [role="menu"] { z-index: 10030; }
150040
150681
  return value.replace(/\s+/g, " ").trim();
150041
150682
  }
150042
150683
  function recordTitle(item) {
150043
- return item.title || item.nickname || "快记";
150684
+ return item.title || item.selfRole?.name || item.nickname || "快记";
150044
150685
  }
150045
150686
  function recordSummary(item) {
150046
150687
  const value = item.snippet || item.textContent || (item.media.length + item.files.length > 0 || item.voice !== void 0 ? "媒体内容" : "暂无文字内容");
@@ -150085,7 +150726,7 @@ body:has([data-arkme-self-topic-menu]) > [role="menu"] { z-index: 10030; }
150085
150726
  const initialUrl = item.voice?.mediaRef === void 0 ? displayUrl(asset) : mediaUrl(item.voice.mediaRef);
150086
150727
  const durationMillis = item.voice?.durationMillis ?? item.recordDurationMillis;
150087
150728
  const transcript = item.snippet || item.textContent || "暂无转写内容";
150088
- const sender = item.nickname || recordTitle(item);
150729
+ const sender = item.selfRole?.name || item.nickname || recordTitle(item);
150089
150730
  const resolveFromConversation = (0, react$1.useCallback)(async (signal) => {
150090
150731
  if (item.targetSource === void 0) return "";
150091
150732
  if (item.sourceKind === 3) {
@@ -162181,13 +162822,13 @@ html body {
162181
162822
  };
162182
162823
  }
162183
162824
  const colors$7 = {
162184
- panel: "#fff",
162825
+ panel: arkmeTheme.base,
162185
162826
  text: arkmeTheme.text,
162186
162827
  secondary: arkmeTheme.secondary,
162187
162828
  caption: arkmeTheme.caption,
162188
162829
  border: arkmeTheme.borderSoft,
162189
- active: "#f1f2f6",
162190
- accent: "#9eadff",
162830
+ active: arkmeTheme.active,
162831
+ accent: arkmeTheme.accent,
162191
162832
  mention: "#20c66a"
162192
162833
  };
162193
162834
  const styles$32 = {
@@ -162288,10 +162929,10 @@ html body {
162288
162929
  alignItems: "center",
162289
162930
  gap: 8,
162290
162931
  boxSizing: "border-box",
162291
- border: "1px solid #e2e3e6",
162932
+ border: `1px solid ${arkmeTheme.border}`,
162292
162933
  borderRadius: 11,
162293
- color: "#92959e",
162294
- background: "#fff"
162934
+ color: arkmeTheme.tertiary,
162935
+ background: arkmeTheme.input
162295
162936
  },
162296
162937
  conversationToolbar: directorySearchLayout.toolbar,
162297
162938
  embeddedSearchField: {
@@ -162316,10 +162957,10 @@ html body {
162316
162957
  display: "grid",
162317
162958
  placeItems: "center",
162318
162959
  padding: 0,
162319
- border: "1px solid #e2e3e6",
162960
+ border: `1px solid ${arkmeTheme.border}`,
162320
162961
  borderRadius: 11,
162321
- background: "#fff",
162322
- color: "#555a64",
162962
+ background: arkmeTheme.input,
162963
+ color: arkmeTheme.secondary,
162323
162964
  cursor: "pointer"
162324
162965
  },
162325
162966
  list: {
@@ -183184,15 +183825,10 @@ registerProcessor('arkme-pcm-journal', ArkmePcmJournal);
183184
183825
  }
183185
183826
  return [...speakers.values()].sort((left, right) => right.durationMillis - left.durationMillis);
183186
183827
  }, [items]);
183187
- const visibleSpeakers = (0, react$1.useMemo)(() => allDaySpeakers.filter((speaker) => speaker.items.some((item) => item.endAtMillis > windowStart && item.startAtMillis < windowEnd)), [
183188
- allDaySpeakers,
183189
- windowEnd,
183190
- windowStart
183191
- ]);
183192
183828
  const totalSpeakerDurationMillis = allDaySpeakers.reduce((sum, speaker) => sum + speaker.durationMillis, 0);
183193
183829
  (0, react$1.useEffect)(() => {
183194
- if (zoomIndex === 0 || visibleSpeakers.length === 0) setLegendOpen(false);
183195
- }, [visibleSpeakers.length, zoomIndex]);
183830
+ if (allDaySpeakers.length === 0) setLegendOpen(false);
183831
+ }, [allDaySpeakers.length]);
183196
183832
  const zoomTo = (targetIndex, anchorRatio = .5, anchorMillis) => {
183197
183833
  const nextIndex = Math.min(RECORDING_TIMELINE_ZOOM_LEVELS_SECONDS.length - 1, Math.max(0, targetIndex));
183198
183834
  const targetVisibleMillis = RECORDING_TIMELINE_ZOOM_LEVELS_SECONDS[nextIndex] * 1e3;
@@ -183643,10 +184279,10 @@ registerProcessor('arkme-pcm-journal', ArkmePcmJournal);
183643
184279
  })]
183644
184280
  })
183645
184281
  ]
183646
- }) : zoomIndex > 0 && visibleSpeakers.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [legendOpen && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
184282
+ }) : allDaySpeakers.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [legendOpen && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
183647
184283
  type: "button",
183648
184284
  tabIndex: -1,
183649
- "aria-label": tr$1("关闭当前窗口说话人统计"),
184285
+ "aria-label": tr$1("关闭全天说话人统计"),
183650
184286
  style: styles$22.legendBackdrop,
183651
184287
  onClick: () => {
183652
184288
  if (legendRef.current !== null) legendRef.current.open = false;
@@ -183662,11 +184298,11 @@ registerProcessor('arkme-pcm-journal', ArkmePcmJournal);
183662
184298
  },
183663
184299
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("summary", {
183664
184300
  style: styles$22.legendSummary,
183665
- "aria-label": tr$1("当前窗口说话人图例"),
184301
+ "aria-label": tr$1("全天说话人图例"),
183666
184302
  children: [
183667
184303
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
183668
184304
  style: styles$22.legendItems,
183669
- children: visibleSpeakers.slice(0, 3).map((speaker) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
184305
+ children: allDaySpeakers.slice(0, 3).map((speaker) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
183670
184306
  "data-arkme-feedback": "neutral",
183671
184307
  type: "button",
183672
184308
  "aria-label": tr$1("编辑说话人 {v0}", { v0: speaker.label }),
@@ -183693,9 +184329,9 @@ registerProcessor('arkme-pcm-journal', ArkmePcmJournal);
183693
184329
  })]
183694
184330
  }, speaker.key))
183695
184331
  }),
183696
- visibleSpeakers.length > 3 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
184332
+ allDaySpeakers.length > 3 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
183697
184333
  style: styles$22.moreChip,
183698
- children: ["+", visibleSpeakers.length - 3]
184334
+ children: ["+", allDaySpeakers.length - 3]
183699
184335
  }),
183700
184336
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(s$10, {
183701
184337
  size: 16,
@@ -183706,7 +184342,7 @@ registerProcessor('arkme-pcm-journal', ArkmePcmJournal);
183706
184342
  style: styles$22.legendPanel,
183707
184343
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
183708
184344
  style: styles$22.legendPanelList,
183709
- children: visibleSpeakers.map((speaker) => {
184345
+ children: allDaySpeakers.map((speaker) => {
183710
184346
  const percentage = totalSpeakerDurationMillis <= 0 ? 0 : speaker.durationMillis / totalSpeakerDurationMillis * 100;
183711
184347
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
183712
184348
  style: styles$22.legendPanelItem,
@@ -187095,19 +187731,32 @@ registerProcessor('arkme-pcm-journal', ArkmePcmJournal);
187095
187731
  eventList: {
187096
187732
  display: "flex",
187097
187733
  flexDirection: "column",
187098
- gap: 12
187734
+ gap: 4
187099
187735
  },
187100
187736
  event: {
187101
- padding: 14,
187102
- border: `1px solid ${colors$4.border}`,
187103
- borderRadius: 12,
187104
- background: colors$4.layer1
187737
+ minWidth: 0,
187738
+ borderBottom: `1px solid ${colors$4.border}`
187739
+ },
187740
+ eventButton: {
187741
+ width: "100%",
187742
+ minWidth: 0,
187743
+ padding: "12px 8px 13px",
187744
+ display: "block",
187745
+ border: 0,
187746
+ borderRadius: 9,
187747
+ background: "transparent",
187748
+ color: colors$4.text,
187749
+ cursor: "pointer",
187750
+ font: "inherit",
187751
+ textAlign: "left"
187105
187752
  },
187753
+ eventButtonHover: { background: colors$4.hover },
187106
187754
  eventHeader: {
187755
+ minWidth: 0,
187107
187756
  display: "flex",
187108
187757
  alignItems: "baseline",
187109
187758
  gap: 10,
187110
- marginBottom: 8
187759
+ marginBottom: 5
187111
187760
  },
187112
187761
  eventTime: {
187113
187762
  flex: "none",
@@ -187117,19 +187766,40 @@ registerProcessor('arkme-pcm-journal', ArkmePcmJournal);
187117
187766
  fontWeight: 650
187118
187767
  },
187119
187768
  eventTitle: {
187769
+ minWidth: 0,
187770
+ flex: 1,
187120
187771
  margin: 0,
187121
- fontSize: 15
187772
+ overflow: "hidden",
187773
+ textOverflow: "ellipsis",
187774
+ whiteSpace: "nowrap",
187775
+ fontSize: 15,
187776
+ fontWeight: 600
187777
+ },
187778
+ eventScene: {
187779
+ flex: "none",
187780
+ maxWidth: "30%",
187781
+ overflow: "hidden",
187782
+ textOverflow: "ellipsis",
187783
+ whiteSpace: "nowrap"
187784
+ },
187785
+ eventArrow: {
187786
+ flex: "none",
187787
+ color: colors$4.tertiary,
187788
+ fontSize: 14
187122
187789
  },
187123
187790
  eventText: {
187124
- margin: "5px 0",
187791
+ maxHeight: 42,
187792
+ margin: 0,
187793
+ overflow: "hidden",
187125
187794
  whiteSpace: "pre-wrap",
187126
- color: colors$4.text,
187795
+ color: colors$4.secondary,
187127
187796
  fontSize: 13,
187128
- lineHeight: 1.65
187797
+ lineHeight: "21px"
187129
187798
  },
187130
187799
  metaRow: {
187131
187800
  display: "flex",
187132
187801
  flexWrap: "wrap",
187802
+ alignItems: "center",
187133
187803
  gap: 6,
187134
187804
  marginTop: 8
187135
187805
  },
@@ -187139,6 +187809,123 @@ registerProcessor('arkme-pcm-journal', ArkmePcmJournal);
187139
187809
  background: colors$4.subtle,
187140
187810
  color: colors$4.secondary,
187141
187811
  fontSize: 11
187812
+ },
187813
+ eventMore: {
187814
+ color: colors$4.tertiary,
187815
+ fontSize: 11
187816
+ },
187817
+ timelineDetailBackdrop: {
187818
+ position: "fixed",
187819
+ zIndex: 1110,
187820
+ inset: 0,
187821
+ display: "grid",
187822
+ placeItems: "center",
187823
+ padding: "min(48px,5vh) min(48px,5vw)",
187824
+ boxSizing: "border-box",
187825
+ background: "rgba(0,0,0,.28)"
187826
+ },
187827
+ timelineDetailDialog: {
187828
+ width: 720,
187829
+ maxWidth: "100%",
187830
+ maxHeight: "100%",
187831
+ display: "flex",
187832
+ flexDirection: "column",
187833
+ boxSizing: "border-box",
187834
+ borderRadius: 14,
187835
+ background: colors$4.layer2,
187836
+ boxShadow: "0 16px 48px rgba(0,0,0,.24)"
187837
+ },
187838
+ timelineDetailHeader: {
187839
+ minWidth: 0,
187840
+ padding: "18px 20px 14px",
187841
+ display: "flex",
187842
+ alignItems: "flex-start",
187843
+ gap: 12,
187844
+ borderBottom: `1px solid ${colors$4.border}`
187845
+ },
187846
+ timelineDetailHeading: {
187847
+ minWidth: 0,
187848
+ flex: 1
187849
+ },
187850
+ timelineDetailTitle: {
187851
+ margin: 0,
187852
+ color: colors$4.text,
187853
+ fontSize: 18,
187854
+ lineHeight: "25px",
187855
+ fontWeight: 600
187856
+ },
187857
+ timelineDetailRange: {
187858
+ margin: "4px 0 0",
187859
+ color: colors$4.accent,
187860
+ fontSize: 12,
187861
+ fontVariantNumeric: "tabular-nums"
187862
+ },
187863
+ timelineDetailClose: {
187864
+ width: 32,
187865
+ height: 32,
187866
+ flex: "none",
187867
+ padding: 0,
187868
+ display: "grid",
187869
+ placeItems: "center",
187870
+ border: 0,
187871
+ borderRadius: 8,
187872
+ background: "transparent",
187873
+ color: colors$4.secondary,
187874
+ cursor: "pointer"
187875
+ },
187876
+ timelineDetailBody: {
187877
+ minHeight: 0,
187878
+ padding: "18px 20px 24px",
187879
+ overflowY: "auto"
187880
+ },
187881
+ timelineDetailSection: { marginBottom: 20 },
187882
+ timelineDetailSectionLast: { marginBottom: 0 },
187883
+ timelineDetailSectionTitle: {
187884
+ margin: "0 0 8px",
187885
+ color: colors$4.text,
187886
+ fontSize: 14,
187887
+ lineHeight: "20px",
187888
+ fontWeight: 600
187889
+ },
187890
+ timelineDetailCopy: {
187891
+ margin: 0,
187892
+ color: colors$4.secondary,
187893
+ fontSize: 13,
187894
+ lineHeight: "21px",
187895
+ whiteSpace: "pre-wrap"
187896
+ },
187897
+ timelineDetailParticipantRow: {
187898
+ display: "flex",
187899
+ flexWrap: "wrap",
187900
+ gap: 7
187901
+ },
187902
+ timelineDetailParticipant: {
187903
+ padding: "3px 8px",
187904
+ borderRadius: 999,
187905
+ background: colors$4.subtle,
187906
+ color: colors$4.secondary,
187907
+ fontSize: 12
187908
+ },
187909
+ timelineDetailQuote: {
187910
+ margin: "0 0 10px",
187911
+ padding: "9px 11px",
187912
+ borderLeft: `3px solid ${colors$4.accent}`,
187913
+ background: colors$4.base,
187914
+ color: colors$4.secondary,
187915
+ fontSize: 13,
187916
+ lineHeight: "21px",
187917
+ whiteSpace: "pre-wrap"
187918
+ },
187919
+ timelineDetailInfoRow: {
187920
+ display: "grid",
187921
+ gridTemplateColumns: "96px minmax(0,1fr)",
187922
+ gap: 10,
187923
+ marginBottom: 9
187924
+ },
187925
+ timelineDetailInfoLabel: {
187926
+ color: colors$4.tertiary,
187927
+ fontSize: 12,
187928
+ lineHeight: "20px"
187142
187929
  }
187143
187930
  };
187144
187931
  function ArkmeRecordingEmptyState({ recorded = false }) {
@@ -187869,64 +188656,232 @@ registerProcessor('arkme-pcm-journal', ArkmePcmJournal);
187869
188656
  });
187870
188657
  return typeof document === "undefined" || document.body === void 0 ? dialog : (0, react_dom$1.createPortal)(dialog, document.body);
187871
188658
  }
187872
- function RecordingTimelineEvents({ events }) {
188659
+ function RecordingTimelineDetailDialog({ event, onClose }) {
188660
+ const titleId = `arkme-recording-timeline-detail-${event.eventId}`;
188661
+ const participants = [...new Set([...event.participants, ...(event.dialoguePoints ?? []).map((point) => point.speakerName)].map((value) => value.trim()).filter((value) => value !== ""))];
188662
+ const summaries = (event.dialoguePoints ?? []).filter((point) => point.summary.trim() !== "");
188663
+ const quotes = (event.dialoguePoints ?? []).filter((point) => point.quote.trim() !== "");
188664
+ const info = [
188665
+ ...event.scene === "" ? [] : [{
188666
+ label: tr$1("场景类型"),
188667
+ value: event.scene
188668
+ }],
188669
+ ...event.emotion === "" ? [] : [{
188670
+ label: tr$1("心情"),
188671
+ value: event.emotion
188672
+ }],
188673
+ ...event.positionNote === void 0 || event.positionNote === "" ? [] : [{
188674
+ label: tr$1("场景说明"),
188675
+ value: event.positionNote
188676
+ }],
188677
+ ...event.environmentNote === void 0 || event.environmentNote === "" ? [] : [{
188678
+ label: tr$1("环境说明"),
188679
+ value: event.environmentNote
188680
+ }],
188681
+ ...event.praise === void 0 || event.praise === "" ? [] : [{
188682
+ label: tr$1("评价"),
188683
+ value: event.praise
188684
+ }],
188685
+ ...event.praisePoint === void 0 ? [] : [{
188686
+ label: tr$1("评价分数"),
188687
+ value: String(event.praisePoint)
188688
+ }],
188689
+ ...event.tags.length === 0 ? [] : [{
188690
+ label: tr$1("事件标签"),
188691
+ value: event.tags.join(" · ")
188692
+ }],
188693
+ ...event.otherInfo ?? []
188694
+ ];
188695
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
188696
+ style: styles$21.timelineDetailBackdrop,
188697
+ role: "presentation",
188698
+ onKeyDown: (eventKey) => {
188699
+ if (eventKey.key === "Escape") onClose();
188700
+ },
188701
+ onMouseDown: (eventMouse) => {
188702
+ if (eventMouse.target === eventMouse.currentTarget) onClose();
188703
+ },
188704
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
188705
+ role: "dialog",
188706
+ "aria-modal": "true",
188707
+ "aria-labelledby": titleId,
188708
+ style: styles$21.timelineDetailDialog,
188709
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("header", {
188710
+ style: styles$21.timelineDetailHeader,
188711
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
188712
+ style: styles$21.timelineDetailHeading,
188713
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h2", {
188714
+ id: titleId,
188715
+ style: styles$21.timelineDetailTitle,
188716
+ children: event.title || tr$1("时间轴记录")
188717
+ }), (event.timeRange !== "" || event.durationText !== void 0) && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
188718
+ style: styles$21.timelineDetailRange,
188719
+ children: [event.timeRange || tr$1("时间未标注"), event.durationText !== void 0 && event.durationText !== "" ? ` · ${event.durationText}` : ""]
188720
+ })]
188721
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
188722
+ "data-arkme-feedback": "neutral",
188723
+ type: "button",
188724
+ "aria-label": tr$1("关闭"),
188725
+ style: styles$21.timelineDetailClose,
188726
+ onClick: onClose,
188727
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(n$14, {
188728
+ size: 18,
188729
+ "aria-hidden": true
188730
+ })
188731
+ })]
188732
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
188733
+ style: styles$21.timelineDetailBody,
188734
+ children: [
188735
+ event.description !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
188736
+ style: styles$21.timelineDetailSection,
188737
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
188738
+ style: styles$21.timelineDetailSectionTitle,
188739
+ children: tr$1("时段总结")
188740
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
188741
+ style: styles$21.timelineDetailCopy,
188742
+ children: event.description
188743
+ })]
188744
+ }),
188745
+ (participants.length > 0 || event.speakerNote !== void 0 && event.speakerNote !== "") && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
188746
+ style: styles$21.timelineDetailSection,
188747
+ children: [
188748
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
188749
+ style: styles$21.timelineDetailSectionTitle,
188750
+ children: tr$1("参与者")
188751
+ }),
188752
+ participants.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
188753
+ style: styles$21.timelineDetailParticipantRow,
188754
+ children: participants.map((person) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
188755
+ style: styles$21.timelineDetailParticipant,
188756
+ children: person
188757
+ }, person))
188758
+ }),
188759
+ event.speakerNote !== void 0 && event.speakerNote !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
188760
+ style: {
188761
+ ...styles$21.timelineDetailCopy,
188762
+ marginTop: participants.length > 0 ? 10 : 0
188763
+ },
188764
+ children: event.speakerNote
188765
+ })
188766
+ ]
188767
+ }),
188768
+ event.todo !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
188769
+ style: styles$21.timelineDetailSection,
188770
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
188771
+ style: styles$21.timelineDetailSectionTitle,
188772
+ children: tr$1("待办")
188773
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
188774
+ style: styles$21.timelineDetailCopy,
188775
+ children: event.todo
188776
+ })]
188777
+ }),
188778
+ quotes.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
188779
+ style: styles$21.timelineDetailSection,
188780
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
188781
+ style: styles$21.timelineDetailSectionTitle,
188782
+ children: tr$1("代表性原话")
188783
+ }), quotes.map((point, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
188784
+ style: styles$21.timelineDetailQuote,
188785
+ children: [point.speakerName !== "" ? `${point.speakerName}:` : "", point.quote]
188786
+ }, `quote:${index}`))]
188787
+ }),
188788
+ summaries.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
188789
+ style: styles$21.timelineDetailSection,
188790
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
188791
+ style: styles$21.timelineDetailSectionTitle,
188792
+ children: tr$1("对话摘要")
188793
+ }), summaries.map((point, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
188794
+ style: styles$21.timelineDetailCopy,
188795
+ children: [point.speakerName !== "" ? `${point.speakerName}:` : "", point.summary]
188796
+ }, `summary:${index}`))]
188797
+ }),
188798
+ info.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
188799
+ style: {
188800
+ ...styles$21.timelineDetailSection,
188801
+ ...styles$21.timelineDetailSectionLast
188802
+ },
188803
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
188804
+ style: styles$21.timelineDetailSectionTitle,
188805
+ children: tr$1("其他信息")
188806
+ }), info.map((item, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
188807
+ style: styles$21.timelineDetailInfoRow,
188808
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
188809
+ style: styles$21.timelineDetailInfoLabel,
188810
+ children: item.label
188811
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
188812
+ style: styles$21.timelineDetailCopy,
188813
+ children: item.value
188814
+ })]
188815
+ }, `${item.label}:${index}`))]
188816
+ })
188817
+ ]
188818
+ })]
188819
+ })
188820
+ });
188821
+ }
188822
+ function RecordingTimelineEvents({ events, onOpen }) {
187873
188823
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
187874
188824
  style: styles$21.eventList,
187875
- children: events.map((event) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("article", {
188825
+ children: events.map((event) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("article", {
187876
188826
  style: styles$21.event,
187877
- children: [
187878
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("header", {
187879
- style: styles$21.eventHeader,
187880
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("time", {
187881
- style: styles$21.eventTime,
187882
- children: event.timeRange || "时间未标注"
187883
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
187884
- style: styles$21.eventTitle,
187885
- children: event.title
187886
- })]
187887
- }),
187888
- event.description !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
187889
- style: styles$21.eventText,
187890
- children: event.description
187891
- }),
187892
- event.todo !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
187893
- style: styles$21.eventText,
187894
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: tr$1("待办:") }), event.todo]
187895
- }),
187896
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
187897
- style: styles$21.metaRow,
187898
- children: [
187899
- event.scene !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
187900
- style: styles$21.chip,
187901
- children: [
187902
- tr$1("场景 ·"),
187903
- " ",
187904
- event.scene
187905
- ]
187906
- }),
187907
- event.emotion !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
187908
- style: styles$21.chip,
187909
- children: [
187910
- tr$1("心情 ·"),
187911
- " ",
187912
- event.emotion
187913
- ]
187914
- }),
187915
- event.participants.map((person) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
188827
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
188828
+ "data-arkme-feedback": "neutral",
188829
+ type: "button",
188830
+ style: styles$21.eventButton,
188831
+ "aria-label": `${event.timeRange || tr$1("时间未标注")} ${event.title}`,
188832
+ onClick: () => {
188833
+ onOpen(event);
188834
+ },
188835
+ children: [
188836
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("header", {
188837
+ "data-arkme-recording-timeline-event-header": true,
188838
+ style: styles$21.eventHeader,
188839
+ children: [
188840
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("time", {
188841
+ style: styles$21.eventTime,
188842
+ children: event.timeRange || tr$1("时间未标注")
188843
+ }),
188844
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
188845
+ style: styles$21.eventTitle,
188846
+ children: event.title || tr$1("时间轴记录")
188847
+ }),
188848
+ event.scene !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
188849
+ "data-arkme-recording-timeline-scene": true,
188850
+ style: {
188851
+ ...styles$21.chip,
188852
+ ...styles$21.eventScene
188853
+ },
188854
+ children: event.scene
188855
+ }),
188856
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
188857
+ "aria-hidden": true,
188858
+ style: styles$21.eventArrow,
188859
+ children: "›"
188860
+ })
188861
+ ]
188862
+ }),
188863
+ event.description !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
188864
+ style: styles$21.eventText,
188865
+ children: event.description
188866
+ }),
188867
+ event.participants.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
188868
+ "data-arkme-recording-timeline-participants": true,
188869
+ style: styles$21.metaRow,
188870
+ children: [event.participants.slice(0, 3).map((person) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
187916
188871
  style: styles$21.chip,
187917
188872
  children: person
187918
- }, `person:${person}`)),
187919
- event.tags.map((tag) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
187920
- style: styles$21.chip,
187921
- children: ["#", tag]
187922
- }, `tag:${tag}`))
187923
- ]
187924
- })
187925
- ]
188873
+ }, `person:${person}`)), event.participants.length > 3 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
188874
+ style: styles$21.eventMore,
188875
+ children: ["+", event.participants.length - 3]
188876
+ })]
188877
+ })
188878
+ ]
188879
+ })
187926
188880
  }, event.eventId))
187927
188881
  });
187928
188882
  }
187929
188883
  function RecordingTourSample({ tab, onTab }) {
188884
+ const [detailEvent, setDetailEvent] = (0, react$1.useState)();
187930
188885
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
187931
188886
  "data-arkme-recording-tour-sample": true,
187932
188887
  "aria-label": tr$1("示例体验 · 我的一天"),
@@ -188010,7 +188965,16 @@ registerProcessor('arkme-pcm-journal', ArkmePcmJournal);
188010
188965
  selected: false,
188011
188966
  readOnly: true
188012
188967
  }, item.itemId))
188013
- }) : tab === "summary" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SafeMarkdown, { content: recordingTourSample.summary.items[0].content }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RecordingTimelineEvents, { events: recordingTourSample.timeline.items[0].timelineEvents })
188968
+ }) : tab === "summary" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SafeMarkdown, { content: recordingTourSample.summary.items[0].content }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RecordingTimelineEvents, {
188969
+ events: recordingTourSample.timeline.items[0].timelineEvents,
188970
+ onOpen: setDetailEvent
188971
+ })
188972
+ }),
188973
+ detailEvent !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RecordingTimelineDetailDialog, {
188974
+ event: detailEvent,
188975
+ onClose: () => {
188976
+ setDetailEvent(void 0);
188977
+ }
188014
188978
  })
188015
188979
  ]
188016
188980
  });
@@ -188057,6 +189021,7 @@ registerProcessor('arkme-pcm-journal', ArkmePcmJournal);
188057
189021
  const modelConfigAbortRef = (0, react$1.useRef)();
188058
189022
  const [modelConfig, setModelConfig] = (0, react$1.useState)({ state: "loading" });
188059
189023
  const [modelDialogKind, setModelDialogKind] = (0, react$1.useState)();
189024
+ const [timelineDetailEvent, setTimelineDetailEvent] = (0, react$1.useState)();
188060
189025
  const [editingSpeaker, setEditingSpeaker] = (0, react$1.useState)();
188061
189026
  const [analysisMaximized, setAnalysisMaximized] = (0, react$1.useState)(false);
188062
189027
  const [exportNotice, setExportNotice] = (0, react$1.useState)("");
@@ -188282,6 +189247,7 @@ registerProcessor('arkme-pcm-journal', ArkmePcmJournal);
188282
189247
  setTranscriptSearch("");
188283
189248
  setTranscriptMatchIndex(0);
188284
189249
  setComparison(void 0);
189250
+ setTimelineDetailEvent(void 0);
188285
189251
  comparisonRequest.current?.abort();
188286
189252
  comparisonRequest.current = void 0;
188287
189253
  setComparisonLoading(false);
@@ -188544,7 +189510,10 @@ registerProcessor('arkme-pcm-journal', ArkmePcmJournal);
188544
189510
  openModelDialog("timeline");
188545
189511
  }
188546
189512
  }),
188547
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RecordingTimelineEvents, { events: selectedTimeline.timelineEvents })
189513
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RecordingTimelineEvents, {
189514
+ events: selectedTimeline.timelineEvents,
189515
+ onOpen: setTimelineDetailEvent
189516
+ })
188548
189517
  ] });
188549
189518
  };
188550
189519
  const downloadCurrent = () => {
@@ -189162,6 +190131,12 @@ registerProcessor('arkme-pcm-journal', ArkmePcmJournal);
189162
190131
  setEditingSpeaker(void 0);
189163
190132
  }
189164
190133
  }),
190134
+ workbenchEnabled && timelineDetailEvent !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RecordingTimelineDetailDialog, {
190135
+ event: timelineDetailEvent,
190136
+ onClose: () => {
190137
+ setTimelineDetailEvent(void 0);
190138
+ }
190139
+ }),
189165
190140
  modelDialogKind !== void 0 && modelConfig.state === "ready" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RecordingModelDialog, {
189166
190141
  kind: modelDialogKind,
189167
190142
  config: modelConfig.value,
@@ -211558,7 +212533,7 @@ registerProcessor('arkme-pcm-journal', ArkmePcmJournal);
211558
212533
  const c$3 = e$20;
211559
212534
  //#endregion
211560
212535
  //#region package.json
211561
- var version = "0.1.84";
212536
+ var version = "0.1.85";
211562
212537
  //#endregion
211563
212538
  //#region src/client/arkme-membership.ts
211564
212539
  function membershipLabel(state) {
@@ -221272,9 +222247,9 @@ registerProcessor('arkme-pcm-journal', ArkmePcmJournal);
221272
222247
  flexDirection: "column",
221273
222248
  alignItems: "stretch",
221274
222249
  gap: 5,
221275
- borderRight: "1px solid #e7e7e9",
221276
- background: "#fff",
221277
- color: "#3e4149"
222250
+ borderRight: `1px solid ${arkmeTheme.borderSoft}`,
222251
+ background: arkmeTheme.sidebar,
222252
+ color: arkmeTheme.text
221278
222253
  },
221279
222254
  compactRail: {
221280
222255
  width: "100%",
@@ -221284,7 +222259,7 @@ registerProcessor('arkme-pcm-journal', ArkmePcmJournal);
221284
222259
  flexDirection: "row",
221285
222260
  alignItems: "center",
221286
222261
  borderRight: 0,
221287
- borderBottom: "1px solid #e7e7e9"
222262
+ borderBottom: `1px solid ${arkmeTheme.borderSoft}`
221288
222263
  },
221289
222264
  hostedRail: {
221290
222265
  width: "100%",
@@ -221310,7 +222285,7 @@ registerProcessor('arkme-pcm-journal', ArkmePcmJournal);
221310
222285
  background: "transparent"
221311
222286
  },
221312
222287
  brandVersion: {
221313
- color: "#a5a8af",
222288
+ color: arkmeTheme.tertiary,
221314
222289
  fontSize: 10,
221315
222290
  lineHeight: "13px",
221316
222291
  whiteSpace: "nowrap"
@@ -221358,8 +222333,8 @@ registerProcessor('arkme-pcm-journal', ArkmePcmJournal);
221358
222333
  borderRadius: 13
221359
222334
  },
221360
222335
  activeButton: {
221361
- background: "#f1f2f6",
221362
- color: "#151722"
222336
+ background: arkmeTheme.active,
222337
+ color: arkmeTheme.text
221363
222338
  },
221364
222339
  activeMarker: { left: -8 },
221365
222340
  compactMarker: {
@@ -221387,9 +222362,9 @@ registerProcessor('arkme-pcm-journal', ArkmePcmJournal);
221387
222362
  alignItems: "center",
221388
222363
  justifyContent: "center",
221389
222364
  borderRadius: 8,
221390
- background: "#ff5a52",
221391
- color: "#fff",
221392
- boxShadow: "0 0 0 2px #fff",
222365
+ background: arkmeTheme.danger,
222366
+ color: arkmeTheme.onPrimaryAction,
222367
+ boxShadow: `0 0 0 2px ${arkmeTheme.sidebar}`,
221393
222368
  fontSize: 10,
221394
222369
  fontWeight: 600,
221395
222370
  lineHeight: "16px",
@@ -240843,6 +241818,10 @@ registerProcessor('arkme-pcm-journal', ArkmePcmJournal);
240843
241818
  return;
240844
241819
  }
240845
241820
  if (update.type === "projection-invalidated") {
241821
+ if (update.projection === "self_role") {
241822
+ window.dispatchEvent(new Event("arkme-self-roles-changed"));
241823
+ return;
241824
+ }
240846
241825
  if (update.projection === "chat.direct_message_admission") {
240847
241826
  invalidateDirectMessageAdmission();
240848
241827
  return;
@@ -250148,7 +251127,6 @@ body[data-ds-dark-theme] .arkme-day-arrangement-status[data-arrangement-status="
250148
251127
  const mode = (0, react$1.useMemo)(() => ({
250149
251128
  displayName: target?.displayName ?? "",
250150
251129
  invalidated,
250151
- editOnOpen: target?.article?.mode === "existing",
250152
251130
  verifyAccount: async () => {
250153
251131
  if (!bridge || !target || invalidated || !await bridge.active()) throw new Error("账号已切换,请关闭后重新打开长文");
250154
251132
  await arkmeAuthStore.refresh();
@@ -257771,14 +258749,14 @@ body[data-ds-dark-theme] .arkme-day-arrangement-status[data-arrangement-status="
257771
258749
  minHeight: 0,
257772
258750
  display: "flex",
257773
258751
  overflow: "hidden",
257774
- background: "#fff"
258752
+ background: arkmeTheme.sidebar
257775
258753
  },
257776
258754
  taskDirectory: {
257777
258755
  minWidth: 0,
257778
258756
  flex: 1,
257779
258757
  overflow: "hidden",
257780
- borderLeft: "1px solid #ececef",
257781
- background: "#fff"
258758
+ borderLeft: `1px solid ${arkmeTheme.borderSoft}`,
258759
+ background: arkmeTheme.layer1
257782
258760
  },
257783
258761
  sidebarResizeHandle: {
257784
258762
  position: "relative",
@@ -257795,7 +258773,7 @@ body[data-ds-dark-theme] .arkme-day-arrangement-status[data-arrangement-status="
257795
258773
  minWidth: 0,
257796
258774
  minHeight: 0,
257797
258775
  overflow: "hidden",
257798
- background: "#fff",
258776
+ background: arkmeTheme.base,
257799
258777
  position: "relative"
257800
258778
  },
257801
258779
  conversationLayer: {