@senguoyun/dsh-arkme 0.1.50 → 0.1.51

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/client.js CHANGED
@@ -5862,7 +5862,7 @@ window.__ModuleLoader__.load({
5862
5862
  qrcode.stringToBytes;
5863
5863
  //#endregion
5864
5864
  //#region package.json
5865
- var version$1 = "0.1.50";
5865
+ var version$1 = "0.1.51";
5866
5866
  //#endregion
5867
5867
  //#region src/client/arkme-billing.css?inline
5868
5868
  var arkme_billing_default = ".arkme-billing-backdrop {\n z-index: 120;\n backdrop-filter: blur(3px);\n background: #181b223d;\n place-items: center;\n padding: 28px;\n display: grid;\n position: fixed;\n inset: 0;\n}\n\n.arkme-billing-recharge-dialog, .arkme-billing-payment-dialog {\n color: #20232c;\n background: #fff;\n border: 1px solid #dedfe3;\n border-radius: 20px;\n width: min(620px, 100%);\n max-height: min(720px, 100vh - 56px);\n overflow-y: auto;\n box-shadow: 0 24px 72px #191c232e;\n}\n\n.arkme-billing-payment-dialog {\n width: min(420px, 100%);\n}\n\n.arkme-billing-dialog-header {\n border-bottom: 1px solid #ececef;\n justify-content: space-between;\n align-items: flex-start;\n gap: 18px;\n min-height: 78px;\n padding: 20px 22px 16px;\n display: flex;\n}\n\n.arkme-billing-dialog-header h2 {\n margin: 0;\n font-size: 18px;\n font-weight: 600;\n line-height: 25px;\n}\n\n.arkme-billing-dialog-header p {\n overflow-wrap: anywhere;\n color: #8a8e96;\n margin: 4px 0 0;\n font-size: 12px;\n line-height: 18px;\n}\n\n.arkme-billing-dialog-header > button {\n color: #777c85;\n width: 32px;\n height: 32px;\n font: inherit;\n cursor: pointer;\n background: none;\n border: 0;\n border-radius: 9px;\n flex: none;\n place-items: center;\n font-size: 22px;\n display: grid;\n}\n\n.arkme-billing-dialog-header > button:hover {\n color: #20232c;\n background: #f3f3f5;\n}\n\n.arkme-billing-dialog-body {\n padding: 18px 22px 22px;\n}\n\n.arkme-billing-dialog-balance {\n border-bottom: 1px solid #ececef;\n grid-template-columns: minmax(0, 1fr) auto;\n align-items: center;\n column-gap: 12px;\n min-height: 48px;\n padding: 0 2px 16px;\n display: grid;\n}\n\n.arkme-billing-dialog-balance > span {\n color: #8a8e96;\n grid-column: 1;\n font-size: 11px;\n line-height: 16px;\n}\n\n.arkme-billing-dialog-balance > strong {\n grid-column: 1;\n font-size: 22px;\n font-weight: 600;\n line-height: 28px;\n}\n\n.arkme-billing-dialog-balance > button, .arkme-billing-error > button {\n color: #626772;\n height: 30px;\n font: inherit;\n cursor: pointer;\n background: #fff;\n border: 1px solid #dfe1e5;\n border-radius: 9px;\n grid-area: 1 / 2 / span 2;\n padding: 0 12px;\n font-size: 11px;\n}\n\n.arkme-billing-products-section, .arkme-billing-payment-section {\n padding-top: 17px;\n}\n\n.arkme-billing-products-section h3, .arkme-billing-payment-section h3 {\n color: #747984;\n margin: 0 0 11px;\n font-size: 12px;\n font-weight: 500;\n line-height: 18px;\n}\n\n.arkme-billing-product-grid {\n width: 100%;\n}\n\n.arkme-billing-product-grid > button {\n color: #20232c;\n min-width: 0;\n min-height: 62px;\n font: inherit;\n text-align: left;\n cursor: pointer;\n background: #fff;\n border: 1px solid #dfe1e5;\n border-radius: 11px;\n align-content: center;\n gap: 4px;\n padding: 9px 11px;\n display: grid;\n}\n\n.arkme-billing-product-grid > button:hover {\n background: #f8f8f9;\n border-color: #cfd2d8;\n}\n\n.arkme-billing-product-grid > button.is-selected {\n border-color: #75839e;\n box-shadow: 0 0 0 1px #75839e;\n}\n\n.arkme-billing-product-grid > button > span {\n white-space: nowrap;\n text-overflow: ellipsis;\n font-size: 12px;\n font-weight: 500;\n line-height: 17px;\n overflow: hidden;\n}\n\n.arkme-billing-product-grid > button > strong {\n font-size: 14px;\n font-weight: 600;\n line-height: 19px;\n}\n\n.arkme-billing-payment-actions {\n flex-wrap: wrap;\n gap: 10px;\n display: flex;\n}\n\n.arkme-billing-payment-actions > button {\n color: #333842;\n min-width: 154px;\n height: 38px;\n font: inherit;\n cursor: pointer;\n background: #fff;\n border: 1px solid #dfe1e5;\n border-radius: 10px;\n justify-content: center;\n align-items: center;\n gap: 8px;\n padding: 0 14px;\n font-size: 12px;\n display: inline-flex;\n}\n\n.arkme-billing-payment-actions > button:hover {\n background: #f7f7f8;\n border-color: #cfd3da;\n}\n\n.arkme-billing-payment-actions > button:disabled, .arkme-billing-product-grid > button:disabled {\n opacity: .48;\n cursor: default;\n}\n\n.arkme-billing-platform-icon {\n flex: none;\n width: 18px;\n height: 18px;\n}\n\n.arkme-billing-platform-icon.is-alipay {\n color: #1677ff;\n}\n\n.arkme-billing-platform-icon.is-wechat {\n color: #07c160;\n}\n\n.arkme-billing-state {\n color: #858992;\n margin: 12px 0 2px;\n font-size: 12px;\n line-height: 18px;\n}\n\n.arkme-billing-error {\n color: #b54841;\n justify-content: space-between;\n align-items: center;\n gap: 12px;\n margin-top: 10px;\n font-size: 12px;\n line-height: 18px;\n display: flex;\n}\n\n.arkme-billing-error.is-purchase {\n justify-content: flex-start;\n}\n\n.arkme-billing-payment-content {\n text-align: center;\n justify-items: center;\n gap: 10px;\n padding: 28px 24px 18px;\n display: grid;\n}\n\n.arkme-billing-payment-content > .arkme-billing-platform-icon {\n width: 38px;\n height: 38px;\n margin-bottom: 4px;\n}\n\n.arkme-billing-payment-content > img {\n border-radius: 10px;\n width: 210px;\n height: 210px;\n}\n\n.arkme-billing-payment-content > strong {\n font-size: 14px;\n font-weight: 600;\n line-height: 21px;\n}\n\n.arkme-billing-payment-content > p {\n color: #858992;\n margin: 0;\n font-size: 12px;\n line-height: 18px;\n}\n\n.arkme-billing-payment-content.is-paid > strong {\n color: #16794f;\n font-size: 18px;\n line-height: 25px;\n}\n\n.arkme-billing-payment-content.is-paid > .arkme-billing-error {\n justify-content: center;\n}\n\n.arkme-billing-payment-content.is-crediting > strong {\n color: #335f9e;\n}\n\n.arkme-billing-dialog-actions {\n flex-wrap: wrap;\n justify-content: center;\n gap: 9px;\n padding: 0 22px 20px;\n display: flex;\n}\n\n.arkme-billing-dialog-actions > button, .arkme-billing-primary-action {\n color: #3c424d;\n height: 34px;\n font: inherit;\n cursor: pointer;\n background: #fff;\n border: 1px solid #dfe1e5;\n border-radius: 9px;\n padding: 0 14px;\n font-size: 12px;\n}\n\n.arkme-billing-dialog-actions > .arkme-billing-primary-action, .arkme-billing-payment-content > .arkme-billing-primary-action {\n color: #fff;\n background: #20232d;\n border-color: #20232d;\n}\n";
@@ -98784,7 +98784,25 @@ function(test) {
98784
98784
  background: arkmeTheme.info,
98785
98785
  color: arkmeTheme.foreground
98786
98786
  },
98787
- composer: { ...arkmeConversationComposerLayout.composer },
98787
+ composer: {
98788
+ ...arkmeConversationComposerLayout.composer,
98789
+ flexDirection: "column",
98790
+ gap: 8
98791
+ },
98792
+ capabilityShortcut: {
98793
+ alignSelf: "flex-start",
98794
+ display: "inline-flex",
98795
+ alignItems: "center",
98796
+ gap: 4,
98797
+ padding: "6px 8px",
98798
+ borderRadius: 8,
98799
+ border: `1px solid ${colors$11.border}`,
98800
+ background: arkmeTheme.layer1,
98801
+ color: colors$11.text,
98802
+ fontFamily: "inherit",
98803
+ fontSize: 14,
98804
+ lineHeight: "20px"
98805
+ },
98788
98806
  composerInner: {
98789
98807
  ...arkmeConversationComposerLayout.composerInner,
98790
98808
  border: "1px solid var(--dsw-alias-border-l2-darkmode-thin, rgba(0,0,0,.1))",
@@ -98994,6 +99012,7 @@ function(test) {
98994
99012
  const composerRef = (0, react.useRef)(null);
98995
99013
  const textareaRef = (0, react.useRef)(null);
98996
99014
  const pendingComposerFocusRef = (0, react.useRef)(false);
99015
+ const sendInFlightRef = (0, react.useRef)(false);
98997
99016
  const authSnapshot = (0, react.useSyncExternalStore)(arkmeAuthStore.subscribe, arkmeAuthStore.getSnapshot, arkmeAuthStore.getSnapshot);
98998
99017
  const profileSnapshot = (0, react.useSyncExternalStore)(arkmeArkoProfileStore.subscribe, arkmeArkoProfileStore.getSnapshot, arkmeArkoProfileStore.getSnapshot);
98999
99018
  const profileUserId = authSnapshot.auth?.status === "authenticated" ? authSnapshot.auth.userId : void 0;
@@ -99372,61 +99391,66 @@ function(test) {
99372
99391
  profileUserId,
99373
99392
  sending
99374
99393
  ]);
99375
- const send = (0, react.useCallback)(async () => {
99376
- const text = draft.trim();
99377
- if (text === "" || sending || activeRun !== void 0 || pendingTurn !== void 0 || session === void 0 || profileUserId === void 0 || composerDraftKey === void 0) return;
99378
- const continuation = latestContinuation(messages, session.sessionId);
99379
- const createdAtMillis = Date.now();
99380
- const turn = {
99381
- userId: profileUserId,
99382
- sessionId: session.sessionId,
99383
- clientTurnUid: crypto.randomUUID(),
99384
- text,
99385
- createdAtMillis,
99386
- localUserMessageId: crypto.randomUUID(),
99387
- localAssistantMessageId: crypto.randomUUID(),
99388
- ...continuation === void 0 ? { ...catalog === void 0 ? {} : { modelRouteKey: catalog.effectiveRouteKey } } : {
99389
- replyToRunUid: continuation.runUid,
99390
- replyToAssistantMsgId: continuation.assistantMsgId
99391
- }
99392
- };
99393
- writeArkoPendingTurn(turn);
99394
- pendingComposerFocusRef.current = true;
99395
- setPendingTurn(turn);
99396
- arkmeComposerDraftStore.clear(composerDraftKey);
99397
- setMessages((current) => [
99398
- ...current,
99399
- {
99400
- id: turn.localUserMessageId,
99401
- sessionId: turn.sessionId,
99402
- role: "user",
99394
+ const interactionLocked = sending || pendingTurn !== void 0 || activeRun !== void 0;
99395
+ const sendDisabled = loading || interactionLocked || clearing || selectingModel || session === void 0 || profileUserId === void 0;
99396
+ const send = (0, react.useCallback)(async (presetText) => {
99397
+ const text = (presetText ?? draft).trim();
99398
+ if (text === "" || sendInFlightRef.current || sendDisabled || session === void 0 || profileUserId === void 0 || composerDraftKey === void 0) return;
99399
+ sendInFlightRef.current = true;
99400
+ try {
99401
+ const continuation = latestContinuation(messages, session.sessionId);
99402
+ const createdAtMillis = Date.now();
99403
+ const turn = {
99404
+ userId: profileUserId,
99405
+ sessionId: session.sessionId,
99406
+ clientTurnUid: crypto.randomUUID(),
99403
99407
  text,
99404
- status: "done",
99405
- createdAtMillis
99406
- },
99407
- {
99408
- id: turn.localAssistantMessageId,
99409
- sessionId: turn.sessionId,
99410
- role: "assistant",
99411
- text: "",
99412
- status: "sending",
99413
- meta: "正在思考",
99414
- runStatus: "accepted",
99415
- createdAtMillis: createdAtMillis + 1
99416
- }
99417
- ]);
99418
- scrollToBottom();
99419
- await submitTurn(turn);
99408
+ createdAtMillis,
99409
+ localUserMessageId: crypto.randomUUID(),
99410
+ localAssistantMessageId: crypto.randomUUID(),
99411
+ ...continuation === void 0 ? { ...catalog === void 0 ? {} : { modelRouteKey: catalog.effectiveRouteKey } } : {
99412
+ replyToRunUid: continuation.runUid,
99413
+ replyToAssistantMsgId: continuation.assistantMsgId
99414
+ }
99415
+ };
99416
+ writeArkoPendingTurn(turn);
99417
+ pendingComposerFocusRef.current = true;
99418
+ setPendingTurn(turn);
99419
+ if (presetText === void 0) arkmeComposerDraftStore.clear(composerDraftKey);
99420
+ setMessages((current) => [
99421
+ ...current,
99422
+ {
99423
+ id: turn.localUserMessageId,
99424
+ sessionId: turn.sessionId,
99425
+ role: "user",
99426
+ text,
99427
+ status: "done",
99428
+ createdAtMillis
99429
+ },
99430
+ {
99431
+ id: turn.localAssistantMessageId,
99432
+ sessionId: turn.sessionId,
99433
+ role: "assistant",
99434
+ text: "",
99435
+ status: "sending",
99436
+ meta: "正在思考",
99437
+ runStatus: "accepted",
99438
+ createdAtMillis: createdAtMillis + 1
99439
+ }
99440
+ ]);
99441
+ scrollToBottom();
99442
+ await submitTurn(turn);
99443
+ } finally {
99444
+ sendInFlightRef.current = false;
99445
+ }
99420
99446
  }, [
99421
- activeRun,
99422
99447
  catalog,
99423
99448
  composerDraftKey,
99424
99449
  draft,
99425
99450
  messages,
99426
- pendingTurn,
99427
99451
  profileUserId,
99428
99452
  scrollToBottom,
99429
- sending,
99453
+ sendDisabled,
99430
99454
  session,
99431
99455
  submitTurn
99432
99456
  ]);
@@ -99499,7 +99523,6 @@ function(test) {
99499
99523
  const selectedModel = selectedModelName(catalog);
99500
99524
  const canChooseModel = (catalog?.options.length ?? 0) > 1;
99501
99525
  const continuation = (0, react.useMemo)(() => latestContinuation(messages, session?.sessionId), [messages, session?.sessionId]);
99502
- const interactionLocked = sending || pendingTurn !== void 0 || activeRun !== void 0;
99503
99526
  (0, react.useEffect)(() => {
99504
99527
  if (!pendingComposerFocusRef.current || loading || interactionLocked || session === void 0 || profileUserId === void 0) return;
99505
99528
  pendingComposerFocusRef.current = false;
@@ -99516,7 +99539,7 @@ function(test) {
99516
99539
  profileUserId,
99517
99540
  session
99518
99541
  ]);
99519
- const hint = loading ? "正在恢复会话" : pendingTurn !== void 0 && !sending ? "请先确认上一次发送结果" : sending ? "等待回复" : continuation === void 0 ? selectedModel : "继续当前任务";
99542
+ const hint = loading ? "正在恢复会话" : clearing ? "正在清除上下文" : selectingModel ? "正在切换模型" : pendingTurn !== void 0 && !sending ? "请先确认上一次发送结果" : sending ? "等待回复" : continuation === void 0 ? selectedModel : "继续当前任务";
99520
99543
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
99521
99544
  style: styles$45.shell,
99522
99545
  children: [
@@ -99859,10 +99882,26 @@ function(test) {
99859
99882
  ]
99860
99883
  })
99861
99884
  }),
99862
- messageActions.selecting ? messageActions.selectionBar : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("footer", {
99885
+ messageActions.selecting ? messageActions.selectionBar : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("footer", {
99886
+ ref: composerRef,
99863
99887
  style: styles$45.composer,
99864
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
99865
- ref: composerRef,
99888
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
99889
+ type: "button",
99890
+ "aria-label": "Arko 能干什么",
99891
+ style: {
99892
+ ...styles$45.capabilityShortcut,
99893
+ opacity: sendDisabled ? .45 : 1,
99894
+ cursor: sendDisabled ? "default" : "pointer"
99895
+ },
99896
+ disabled: sendDisabled,
99897
+ onClick: () => {
99898
+ send("你能帮我干什么");
99899
+ },
99900
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(t$5, {
99901
+ size: 17,
99902
+ "aria-hidden": true
99903
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "Arko 能干什么" })]
99904
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
99866
99905
  style: styles$45.composerInner,
99867
99906
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("textarea", {
99868
99907
  ref: textareaRef,
@@ -99879,7 +99918,7 @@ function(test) {
99879
99918
  onKeyDown: (event) => {
99880
99919
  if (event.key === "Enter" && !event.shiftKey && !event.nativeEvent.isComposing) {
99881
99920
  event.preventDefault();
99882
- if (!loading && !interactionLocked && draft.trim() !== "" && session !== void 0 && profileUserId !== void 0) send();
99921
+ if (!sendDisabled && draft.trim() !== "" && session !== void 0 && profileUserId !== void 0) send();
99883
99922
  }
99884
99923
  }
99885
99924
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
@@ -99892,9 +99931,9 @@ function(test) {
99892
99931
  title: "发送",
99893
99932
  style: {
99894
99933
  ...styles$45.send,
99895
- opacity: loading || interactionLocked || draft.trim() === "" || session === void 0 || profileUserId === void 0 ? .45 : 1
99934
+ opacity: sendDisabled || draft.trim() === "" ? .45 : 1
99896
99935
  },
99897
- disabled: loading || interactionLocked || draft.trim() === "" || session === void 0 || profileUserId === void 0,
99936
+ disabled: sendDisabled || draft.trim() === "",
99898
99937
  onClick: () => {
99899
99938
  send();
99900
99939
  },
@@ -99921,7 +99960,7 @@ function(test) {
99921
99960
  })
99922
99961
  })]
99923
99962
  })]
99924
- })
99963
+ })]
99925
99964
  }),
99926
99965
  messageActions.overlay
99927
99966
  ]
@@ -147360,14 +147399,15 @@ Please report this to https://github.com/markedjs/marked.`, e) {
147360
147399
  body.removeEventListener("scroll", onScroll);
147361
147400
  };
147362
147401
  }
147363
- function useConversationResizeAnchor(body, scope, endAccessory) {
147402
+ function useConversationResizeAnchor(body, scope, endAccessory, selecting = false) {
147364
147403
  (0, react.useLayoutEffect)(() => {
147365
147404
  if (scope === void 0 || body.current === null || typeof ResizeObserver === "undefined") return;
147366
147405
  return observeConversationResize(body.current, endAccessory?.current ?? void 0);
147367
147406
  }, [
147368
147407
  body,
147369
147408
  scope,
147370
- endAccessory
147409
+ endAccessory,
147410
+ selecting
147371
147411
  ]);
147372
147412
  }
147373
147413
  //#endregion
@@ -177420,7 +177460,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
177420
177460
  const requestRef = (0, react.useRef)();
177421
177461
  const triggerRef = (0, react.useRef)(null);
177422
177462
  const popoverRef = (0, react.useRef)(null);
177423
- const createRequestRef = (0, react.useRef)();
177463
+ const createRequestRef = (0, react.useRef)(false);
177424
177464
  const selectedSourceRef = (0, react.useRef)(selectedSource);
177425
177465
  selectedSourceRef.current = selectedSource;
177426
177466
  const [open, setOpen] = (0, react.useState)(false);
@@ -177437,9 +177477,6 @@ Please report this to https://github.com/markedjs/marked.`, e) {
177437
177477
  const [topicCreateSubmitting, setTopicCreateSubmitting] = (0, react.useState)(false);
177438
177478
  const sourcesRef = (0, react.useRef)(sources);
177439
177479
  sourcesRef.current = sources;
177440
- (0, react.useEffect)(() => () => {
177441
- createRequestRef.current = void 0;
177442
- }, []);
177443
177480
  const persist = (0, react.useCallback)((nextSources, selectedRef) => {
177444
177481
  writeNavigationCache(cacheWithTopics(userId, nextSources, selectedRef));
177445
177482
  }, [userId]);
@@ -177465,6 +177502,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
177465
177502
  loaded = mergeArkmeTopicSourcePages(loaded, page.items);
177466
177503
  sourcesRef.current = loaded;
177467
177504
  setSources(loaded);
177505
+ persist(loaded);
177468
177506
  const nextCursor = page.nextCursor;
177469
177507
  hasNextPage = page.hasMore && nextCursor !== void 0;
177470
177508
  if (!hasNextPage || nextCursor === void 0) break;
@@ -177587,12 +177625,12 @@ Please report this to https://github.com/markedjs/marked.`, e) {
177587
177625
  sourceSort
177588
177626
  ]);
177589
177627
  const rows = (0, react.useMemo)(() => flattenVisibleArkmeSourceTree(buildArkmeSourceTree(filteredSources), collapsedSourceRefs), [collapsedSourceRefs, filteredSources]);
177590
- const selectSource = (nextSource, nextSources = sources) => {
177628
+ const selectSource = (nextSource) => {
177591
177629
  selectedSourceRef.current = nextSource;
177592
- persist(nextSources, nextSource.sourceRef);
177630
+ onSelect(nextSource);
177631
+ persist(sources, nextSource.sourceRef);
177593
177632
  setOpen(false);
177594
177633
  setQuery("");
177595
- onSelect(nextSource);
177596
177634
  };
177597
177635
  const selectRow = (row) => {
177598
177636
  setCollapsedSourceRefs((current) => expandTopicFromRowClick(row, current));
@@ -177625,44 +177663,27 @@ Please report this to https://github.com/markedjs/marked.`, e) {
177625
177663
  setTopicCreateError("主题最多支持五级层级,无法继续创建子主题");
177626
177664
  return;
177627
177665
  }
177628
- const contextSource = parent ?? selectedSourceRef.current ?? sourcesRef.current.find((source) => source.kind === "send_to_self");
177629
- if (contextSource === void 0) {
177630
- setTopicCreateError("主题列表尚未加载完成,请稍后重试");
177631
- return;
177632
- }
177633
- const request = Symbol();
177634
- createRequestRef.current = request;
177666
+ createRequestRef.current = true;
177635
177667
  setTopicCreateSubmitting(true);
177636
177668
  setTopicCreateError("");
177637
177669
  try {
177638
177670
  const result = await callArkme("topic.create", {
177639
177671
  title,
177640
- contextSourceRef: contextSource.sourceRef,
177641
177672
  ...parent === null ? {} : { parentSourceRef: parent.sourceRef }
177642
177673
  });
177643
- if (createRequestRef.current !== request) return;
177644
- const nextSources = mergeCreatedTopicSource(sourcesRef.current, result.source);
177645
- sourcesRef.current = nextSources;
177674
+ const nextSources = mergeCreatedTopicSource(sources, result.source);
177646
177675
  setSources(nextSources);
177647
177676
  setCollapsedSourceRefs((current) => expandAncestorsForReveal(nextSources, result.source.sourceRef, current));
177677
+ persist(nextSources);
177648
177678
  setTopicCreateParent(void 0);
177649
177679
  setTopicCreateParentLevel(void 0);
177650
177680
  setQuery("");
177651
- if (result.warning !== void 0) {
177652
- persist(nextSources);
177653
- setError(result.warning);
177654
- } else {
177655
- requestRef.current?.abort();
177656
- setBusy(false);
177657
- selectSource(result.source, nextSources);
177658
- }
177681
+ if (result.warning !== void 0) setError(result.warning);
177659
177682
  } catch (caught) {
177660
- if (createRequestRef.current === request) setTopicCreateError(caught instanceof Error ? caught.message : String(caught));
177683
+ setTopicCreateError(caught instanceof Error ? caught.message : String(caught));
177661
177684
  } finally {
177662
- if (createRequestRef.current === request) {
177663
- createRequestRef.current = void 0;
177664
- setTopicCreateSubmitting(false);
177665
- }
177685
+ createRequestRef.current = false;
177686
+ setTopicCreateSubmitting(false);
177666
177687
  }
177667
177688
  };
177668
177689
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
@@ -185000,7 +185021,6 @@ Please report this to https://github.com/markedjs/marked.`, e) {
185000
185021
  padding: "22px 22px 12px",
185001
185022
  background: arkmeTheme.base
185002
185023
  },
185003
- bodySelectMode: { paddingBottom: 86 },
185004
185024
  utilityBody: {
185005
185025
  flex: 1,
185006
185026
  minHeight: 0,
@@ -185098,7 +185118,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
185098
185118
  alignItems: "start",
185099
185119
  columnGap: ARKME_MESSAGE_SELECT_GAP,
185100
185120
  marginBottom: 18,
185101
- padding: "6px 0 6px 6px",
185121
+ paddingLeft: 6,
185102
185122
  boxSizing: "border-box",
185103
185123
  cursor: "pointer"
185104
185124
  },
@@ -185560,9 +185580,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
185560
185580
  },
185561
185581
  selectBar: {
185562
185582
  position: "absolute",
185563
- left: 0,
185564
- right: 0,
185565
- bottom: 0,
185583
+ inset: 0,
185566
185584
  zIndex: 35,
185567
185585
  minHeight: 72,
185568
185586
  display: "flex",
@@ -188613,7 +188631,6 @@ Please report this to https://github.com/markedjs/marked.`, e) {
188613
188631
  (0, react.useEffect)(() => {
188614
188632
  setTopicAssignment(void 0);
188615
188633
  }, [topicAssignmentScopeKey]);
188616
- const pendingSelectRevealItemUidRef = (0, react.useRef)("");
188617
188634
  const [forwardTargetPicker, setForwardTargetPicker] = (0, react.useState)();
188618
188635
  const needsChatDirectory = activeConversation && detailState?.kind === "success";
188619
188636
  const chatDirectory = (0, react.useSyncExternalStore)(needsChatDirectory ? arkmeChatDirectory.subscribe : NOOP_SUBSCRIBE, () => needsChatDirectory ? arkmeChatDirectory.getSnapshot() : EMPTY_CHAT_DIRECTORY_SNAPSHOT, () => EMPTY_CHAT_DIRECTORY_SNAPSHOT);
@@ -188719,7 +188736,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
188719
188736
  if (recordReeditHighlightTimerRef.current !== void 0) window.clearTimeout(recordReeditHighlightTimerRef.current);
188720
188737
  }, []);
188721
188738
  (0, react.useEffect)(() => {
188722
- if (!active) return;
188739
+ if (!active || selectMode?.sourceKey === conversationKey) return;
188723
188740
  const pendingDraftKey = pendingComposerFocusDraftKeyRef.current;
188724
188741
  if (pendingDraftKey === void 0 || busy) return;
188725
188742
  if (pendingDraftKey !== composerDraftKey) {
@@ -188737,7 +188754,9 @@ Please report this to https://github.com/markedjs/marked.`, e) {
188737
188754
  }, [
188738
188755
  active,
188739
188756
  busy,
188740
- composerDraftKey
188757
+ composerDraftKey,
188758
+ conversationKey,
188759
+ selectMode?.sourceKey
188741
188760
  ]);
188742
188761
  (0, react.useEffect)(() => {
188743
188762
  let active = true;
@@ -191571,17 +191590,17 @@ Please report this to https://github.com/markedjs/marked.`, e) {
191571
191590
  arkmeUi.consumeConversationTarget(pending.revision);
191572
191591
  }, [displayRows, timelineStateKey]);
191573
191592
  const activeSelectMode = selectMode?.sourceKey === conversationKey ? selectMode : void 0;
191593
+ const exitMessageSelectMode = (0, react.useCallback)(() => {
191594
+ const body = bodyRef.current;
191595
+ if (activeSelectMode !== void 0 && body !== null) pendingViewportRestoreRef.current = {
191596
+ sourceKey: timelineStateKey,
191597
+ viewport: arkmeConversationViewport(body, true)
191598
+ };
191599
+ setSelectMode(void 0);
191600
+ }, [activeSelectMode, timelineStateKey]);
191574
191601
  const selectedMessageItems = (0, react.useMemo)(() => activeSelectMode === void 0 ? [] : arkmeSelectedTimelineItems(displayItems, activeSelectMode.selectedIds), [activeSelectMode, displayItems]);
191575
191602
  const selectedMessageCount = activeSelectMode?.selectedIds.size ?? 0;
191576
191603
  const selectedMessagesHaveSnapshots = selectedMessageCount > 0 && selectedMessageItems.length === selectedMessageCount && selectedMessageItems.every((item) => arkmeTimelineMessageActionRef(item) !== "");
191577
- (0, react.useLayoutEffect)(() => {
191578
- if (activeSelectMode === void 0) return;
191579
- const itemUid = pendingSelectRevealItemUidRef.current;
191580
- if (itemUid === "") return;
191581
- pendingSelectRevealItemUidRef.current = "";
191582
- const body = bodyRef.current;
191583
- (body === null ? void 0 : [...body.querySelectorAll("[data-arkme-message-item-uid]")].find((element) => element.dataset.arkmeMessageItemUid === itemUid))?.scrollIntoView({ block: "center" });
191584
- }, [activeSelectMode, displayRows]);
191585
191604
  const forwardVisibleTargets = (0, react.useMemo)(() => forwardTargetPicker === void 0 ? [] : arkmeForwardTargetVisibleSources(forwardTargetPicker.targets, forwardTargetPicker.keyword), [forwardTargetPicker]);
191586
191605
  const forwardSelectedTargets = (0, react.useMemo)(() => forwardTargetPicker === void 0 ? [] : forwardTargetPicker.selectedSourceRefs.map((sourceRef) => forwardTargetPicker.targets.find((target) => target.sourceRef === sourceRef)).filter((target) => target !== void 0), [forwardTargetPicker]);
191587
191606
  const forwardPickerMessageItems = forwardTargetPicker?.items ?? [];
@@ -191592,7 +191611,8 @@ Please report this to https://github.com/markedjs/marked.`, e) {
191592
191611
  setSnapshot((current) => current === void 0 || visibleOccurrenceKeys.has(arkmeTimelineOccurrenceKey(current.item)) ? current : void 0);
191593
191612
  setMessageReportItem((current) => current === void 0 || visibleOccurrenceKeys.has(arkmeTimelineOccurrenceKey(current)) ? current : void 0);
191594
191613
  setMessageWithdrawalItem((current) => current === void 0 || visibleOccurrenceKeys.has(arkmeTimelineOccurrenceKey(current)) ? current : void 0);
191595
- setSelectMode((current) => {
191614
+ if (activeSelectMode !== void 0 && activeSelectMode.selectedIds.size > 0 && ![...activeSelectMode.selectedIds].some((key) => visibleOccurrenceKeys.has(key))) exitMessageSelectMode();
191615
+ else setSelectMode((current) => {
191596
191616
  if (current === void 0 || current.sourceKey !== conversationKey) return current;
191597
191617
  const selectedIds = new Set([...current.selectedIds].filter((key) => visibleOccurrenceKeys.has(key)));
191598
191618
  if (selectedIds.size === current.selectedIds.size) return current;
@@ -191611,7 +191631,12 @@ Please report this to https://github.com/markedjs/marked.`, e) {
191611
191631
  itemUids: items.map((item) => item.itemUid)
191612
191632
  };
191613
191633
  });
191614
- }, [conversationKey, displayItems]);
191634
+ }, [
191635
+ activeSelectMode,
191636
+ conversationKey,
191637
+ displayItems,
191638
+ exitMessageSelectMode
191639
+ ]);
191615
191640
  const showMessageActionStatus = (0, react.useCallback)((message, autoClear = true) => {
191616
191641
  if (messageActionStatusTimerRef.current !== void 0) {
191617
191642
  window.clearTimeout(messageActionStatusTimerRef.current);
@@ -192230,7 +192255,22 @@ Please report this to https://github.com/markedjs/marked.`, e) {
192230
192255
  showMessageActionStatus("当前消息暂不支持多选");
192231
192256
  return;
192232
192257
  }
192233
- pendingSelectRevealItemUidRef.current = item.itemUid;
192258
+ setAddMenuOpen(false);
192259
+ pendingComposerFocusDraftKeyRef.current = void 0;
192260
+ const focused = typeof document === "undefined" ? null : document.activeElement;
192261
+ if (typeof HTMLElement !== "undefined" && focused instanceof HTMLElement && composerRef.current?.contains(focused)) focused.blur();
192262
+ const body = bodyRef.current;
192263
+ const anchorId = displayRows.find((row) => row.kind === "message" && arkmeTimelineOccurrenceKey(row.item) === arkmeTimelineOccurrenceKey(item))?.id;
192264
+ const anchorOffset = body === null ? void 0 : arkmeConversationAnchorOffset(body, anchorId);
192265
+ if (body !== null) pendingViewportRestoreRef.current = {
192266
+ sourceKey: timelineStateKey,
192267
+ viewport: {
192268
+ scrollTop: body.scrollTop,
192269
+ stickToBottom: false,
192270
+ ...anchorId === void 0 ? {} : { anchorId },
192271
+ ...anchorOffset === void 0 ? {} : { anchorOffset }
192272
+ }
192273
+ };
192234
192274
  setSelectMode({
192235
192275
  sourceKey: conversationKey,
192236
192276
  selectedIds: /* @__PURE__ */ new Set([arkmeTimelineOccurrenceKey(item)])
@@ -192238,8 +192278,10 @@ Please report this to https://github.com/markedjs/marked.`, e) {
192238
192278
  }, [
192239
192279
  closeMessageMenu,
192240
192280
  conversationKey,
192281
+ displayRows,
192241
192282
  showMessageActionStatus,
192242
- source
192283
+ source,
192284
+ timelineStateKey
192243
192285
  ]);
192244
192286
  const toggleSelectedMessage = (0, react.useCallback)((item) => {
192245
192287
  if (source === void 0 || !canSelectTimelineItem(item)) return;
@@ -192415,7 +192457,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
192415
192457
  return;
192416
192458
  }
192417
192459
  const successfulTargets = results.filter((outcome) => outcome.status === "fulfilled").map((outcome) => outcome.value.targetSource);
192418
- setSelectMode(void 0);
192460
+ exitMessageSelectMode();
192419
192461
  setForwardTargetPicker(void 0);
192420
192462
  closeMessageMenu();
192421
192463
  showForwardSuccessFeedback(successfulTargets, successCount, failureCount);
@@ -192437,6 +192479,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
192437
192479
  }, [
192438
192480
  closeMessageMenu,
192439
192481
  conversationKey,
192482
+ exitMessageSelectMode,
192440
192483
  loadTimeline,
192441
192484
  messageActionBusy,
192442
192485
  showForwardSuccessFeedback,
@@ -192497,10 +192540,11 @@ Please report this to https://github.com/markedjs/marked.`, e) {
192497
192540
  pendingViewportRestoreRef.current = void 0;
192498
192541
  }, [
192499
192542
  active,
192543
+ activeSelectMode,
192500
192544
  displayRows,
192501
192545
  timelineStateKey
192502
192546
  ]);
192503
- useConversationResizeAnchor(bodyRef, active && activeConversation ? conversationKey : void 0, endAccessoryRef);
192547
+ useConversationResizeAnchor(bodyRef, active && activeConversation ? conversationKey : void 0, endAccessoryRef, activeSelectMode !== void 0);
192504
192548
  const handleConversationScroll = (0, react.useCallback)(() => {
192505
192549
  const body = bodyRef.current;
192506
192550
  if (body === null || timelineStateKey === "") return;
@@ -192609,7 +192653,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
192609
192653
  },
192610
192654
  onRefresh: () => {
192611
192655
  if (topicAssignment.source.kind !== "send_to_self") confirmedSendRetention.forget(conversationKey, selectedMessageItems.map((item) => item.itemUid));
192612
- setSelectMode(void 0);
192656
+ exitMessageSelectMode();
192613
192657
  setTopicAssignment(void 0);
192614
192658
  setSelfSourcesRetryRevision((value) => value + 1);
192615
192659
  arkmeUi.recordChanged();
@@ -192617,7 +192661,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
192617
192661
  onAssigned: (result, target) => {
192618
192662
  if (topicAssignment.source.kind !== "send_to_self") confirmedSendRetention.forget(conversationKey, result.movedRecordUids);
192619
192663
  setTopicAssignment(void 0);
192620
- setSelectMode(void 0);
192664
+ exitMessageSelectMode();
192621
192665
  setSelfSourcesRetryRevision((value) => value + 1);
192622
192666
  arkmeUi.recordChanged();
192623
192667
  showMessageActionStatus(`${target ? "已指定主题" : "已移出主题"}${result.projectionRefreshPending ? ",列表正在刷新" : ""}`);
@@ -192939,8 +192983,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
192939
192983
  ...displayRows.length === 0 && interwovenWindow.prelude.length === 0 ? {
192940
192984
  display: "flex",
192941
192985
  flexDirection: "column"
192942
- } : {},
192943
- ...activeSelectMode === void 0 ? {} : styles$7.bodySelectMode
192986
+ } : {}
192944
192987
  },
192945
192988
  onScroll: handleConversationScroll,
192946
192989
  children: [
@@ -193298,11 +193341,14 @@ Please report this to https://github.com/markedjs/marked.`, e) {
193298
193341
  }),
193299
193342
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
193300
193343
  ref: endAccessoryRef,
193344
+ "data-arkme-conversation-end-accessory": true,
193345
+ "aria-hidden": activeSelectMode !== void 0 || void 0,
193301
193346
  style: {
193302
193347
  flexShrink: 0,
193348
+ visibility: activeSelectMode === void 0 ? "visible" : "hidden",
193303
193349
  ...displayRows.length === 0 ? { marginTop: "auto" } : {}
193304
193350
  },
193305
- children: activeConversation && activeSelectMode === void 0 && (source?.kind === "private_chat" || source?.kind === "group_chat") && source.sourceKey !== void 0 && authenticatedAccountKey !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ArkmeMessagePreparingIndicator, {
193351
+ children: activeConversation && (source?.kind === "private_chat" || source?.kind === "group_chat") && source.sourceKey !== void 0 && authenticatedAccountKey !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ArkmeMessagePreparingIndicator, {
193306
193352
  sourceKey: source.sourceKey,
193307
193353
  accountScope: authenticatedAccountKey
193308
193354
  })
@@ -193315,120 +193361,6 @@ Please report this to https://github.com/markedjs/marked.`, e) {
193315
193361
  })
193316
193362
  ]
193317
193363
  }),
193318
- activeSelectMode !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
193319
- style: styles$7.selectBar,
193320
- role: "toolbar",
193321
- "aria-label": `已选择 ${selectedMessageCount} 条消息`,
193322
- children: [
193323
- source !== void 0 && isArkmeSelfWorkspaceSource(source) && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
193324
- type: "button",
193325
- "aria-label": "指定主题",
193326
- style: styles$7.selectBarButton,
193327
- disabled: messageActionBusy !== void 0 || selectedMessageCount === 0 || selectedMessageItems.length !== selectedMessageCount || selectedMessageItems.some((item) => !item.recordTopicAssignmentRef),
193328
- onClick: () => {
193329
- if (messageActionBusy !== void 0 || selectedMessageItems.length === 0 || selectedMessageItems.length !== selectedMessageCount || selectedMessageItems.some((item) => !item.recordTopicAssignmentRef)) return;
193330
- const currentTopicKey = source.kind === "topic" ? source.topicHierarchyKey : selectedMessageItems[0]?.recordTopicAssignmentTopicKey;
193331
- const allInCurrentTopic = currentTopicKey !== void 0 && (source.kind === "topic" || selectedMessageItems.every((item) => item.recordTopicAssignmentTopicKey === currentTopicKey));
193332
- setTopicAssignment({
193333
- scopeKey: topicAssignmentScopeKey,
193334
- source,
193335
- ...allInCurrentTopic ? { currentTopicKey } : {},
193336
- assignmentRefs: selectedMessageItems.map((item) => item.recordTopicAssignmentRef),
193337
- firstRecordText: items.find((item) => item.itemUid === selectedMessageItems[0]?.itemUid)?.textContent ?? ""
193338
- });
193339
- },
193340
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
193341
- style: styles$7.selectBarIconTile,
193342
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ArkmeSelectActionIcon, {
193343
- kind: "assign",
193344
- size: 20
193345
- })
193346
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
193347
- style: styles$7.selectBarLabel,
193348
- children: "指定主题"
193349
- })]
193350
- }),
193351
- (() => {
193352
- const copyTextEnabled = arkmeCanCopySelectedMessageText(selectedMessageItems.length, messageActionBusy !== void 0);
193353
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
193354
- type: "button",
193355
- style: {
193356
- ...styles$7.selectBarButton,
193357
- ...!copyTextEnabled ? styles$7.selectBarButtonDisabled : {}
193358
- },
193359
- disabled: !copyTextEnabled,
193360
- onClick: () => {
193361
- copySelectedMessageText();
193362
- },
193363
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
193364
- style: styles$7.selectBarIconTile,
193365
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ArkmeSelectActionIcon, { kind: "copy" })
193366
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
193367
- style: styles$7.selectBarLabel,
193368
- children: ARKME_MESSAGE_SELECT_ACTION_LABELS[0]
193369
- })]
193370
- });
193371
- })(),
193372
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
193373
- type: "button",
193374
- style: {
193375
- ...styles$7.selectBarButton,
193376
- ...!selectedMessagesHaveSnapshots || messageActionBusy !== void 0 ? styles$7.selectBarButtonDisabled : {}
193377
- },
193378
- disabled: !selectedMessagesHaveSnapshots || messageActionBusy !== void 0,
193379
- onClick: () => {
193380
- copyMessageLink(selectedMessageItems);
193381
- },
193382
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
193383
- style: styles$7.selectBarIconTile,
193384
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ArkmeSelectActionIcon, { kind: "link" })
193385
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
193386
- style: styles$7.selectBarLabel,
193387
- children: ARKME_MESSAGE_SELECT_ACTION_LABELS[1]
193388
- })]
193389
- }),
193390
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
193391
- type: "button",
193392
- style: {
193393
- ...styles$7.selectBarButton,
193394
- ...!selectedMessagesHaveSnapshots || messageActionBusy !== void 0 ? styles$7.selectBarButtonDisabled : {}
193395
- },
193396
- disabled: !selectedMessagesHaveSnapshots || messageActionBusy !== void 0,
193397
- onClick: () => {
193398
- openForwardTargetPicker();
193399
- },
193400
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
193401
- style: styles$7.selectBarIconTile,
193402
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ArkmeSelectActionIcon, { kind: "forward" })
193403
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
193404
- style: styles$7.selectBarLabel,
193405
- children: messageActionBusy === "forward" ? "转发中" : ARKME_MESSAGE_SELECT_ACTION_LABELS[2]
193406
- })]
193407
- }),
193408
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
193409
- type: "button",
193410
- style: {
193411
- ...styles$7.selectBarButton,
193412
- ...messageActionBusy !== void 0 ? styles$7.selectBarButtonDisabled : {}
193413
- },
193414
- disabled: messageActionBusy !== void 0,
193415
- "aria-label": ARKME_MESSAGE_SELECT_ACTION_LABELS[3],
193416
- onClick: () => {
193417
- setSelectMode(void 0);
193418
- },
193419
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
193420
- style: styles$7.selectBarIconTile,
193421
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ArkmeSelectActionIcon, {
193422
- kind: "close",
193423
- size: 18
193424
- })
193425
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
193426
- style: styles$7.selectBarLabel,
193427
- children: ARKME_MESSAGE_SELECT_ACTION_LABELS[3]
193428
- })]
193429
- })
193430
- ]
193431
- }),
193432
193364
  activeConversation && forwardSuccessFeedback !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
193433
193365
  style: styles$7.forwardSuccessBannerWrap,
193434
193366
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
@@ -193479,540 +193411,666 @@ Please report this to https://github.com/markedjs/marked.`, e) {
193479
193411
  style: styles$7.messageActionToast,
193480
193412
  children: messageActionStatus
193481
193413
  }),
193482
- activeSelectMode === void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("footer", {
193483
- className: "arkme-conversation-composer",
193484
- style: styles$7.composer,
193485
- onClick: (event) => {
193486
- focusArkmeComposerFromClick(textareaRef.current, event);
193487
- },
193488
- onDragOver: (event) => {
193489
- if (!composerFileAddingDisabled && Array.from(event.dataTransfer.types).includes("Files")) {
193490
- event.preventDefault();
193491
- event.dataTransfer.dropEffect = "copy";
193492
- }
193493
- },
193494
- onDrop: (event) => {
193495
- if (!composerFileAddingDisabled && event.dataTransfer.files.length > 0) {
193496
- event.preventDefault();
193497
- selectFiles(event.dataTransfer.files);
193498
- }
193414
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
193415
+ className: "arkme-conversation-input-slot",
193416
+ style: {
193417
+ position: "relative",
193418
+ flex: "none"
193499
193419
  },
193500
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
193501
- style: styles$7.composerStack,
193502
- children: [
193503
- activeComposerExtensionTarget !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
193504
- style: styles$7.composerDestinationHint,
193505
- "data-arkme-composer-destination-hint": "true",
193506
- children: [
193507
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
193508
- style: styles$7.composerDestinationHintIcon,
193509
- "aria-hidden": true,
193510
- children: "💡"
193511
- }),
193512
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "正在给 " }),
193513
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
193514
- style: styles$7.composerDestinationHintName,
193515
- children: arkmeSourceDestinationLabel(source)
193516
- }),
193517
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: " 发消息" })
193518
- ]
193519
- }),
193520
- activeRecordReeditComposer !== void 0 && activeRecordReeditComposer.error !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
193521
- role: "alert",
193522
- style: styles$7.error,
193523
- children: activeRecordReeditComposer.error
193524
- }),
193525
- activeRecordReeditComposer !== void 0 && (activeRecordReeditComposer.conflict !== void 0 || activeRecordReeditComposer.snapshot?.draft !== void 0 && activeRecordReeditComposer.snapshot.draft.baseVersion !== void 0 && activeRecordReeditComposer.snapshot.draft.baseVersion !== activeRecordReeditComposer.snapshot.version) && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
193526
- type: "button",
193527
- style: styles$7.retry,
193528
- disabled: composerFilesDisabled,
193529
- "aria-label": activeRecordReeditComposer.conflict === "draft" ? "重新载入草稿" : "放弃草稿并重新载入",
193530
- onClick: () => setRecordReeditComposer((current) => sameArkmeRecordReeditSession(current, activeRecordReeditComposer) ? {
193531
- ...current,
193532
- recoveryConfirmation: true
193533
- } : current),
193534
- children: activeRecordReeditComposer.conflict === "draft" ? "重新载入草稿" : "放弃草稿并重新载入"
193535
- }),
193536
- activeRecordReeditComposer?.recoveryConfirmation && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ArkmeConfirmDialog, {
193537
- titleId: "arkme-reedit-recovery-title",
193538
- title: activeRecordReeditComposer.conflict === "draft" ? "重新载入最新草稿?" : "放弃草稿并重新载入?",
193539
- description: activeRecordReeditComposer.conflict === "draft" ? "当前输入区将替换为其他入口保存的最新草稿。不会删除草稿或修改已保存的快记。" : "本机这份重新编辑草稿中的正文和附件改动将被放弃,重新载入已保存的快记。此操作不会删除线上附件。",
193540
- busy: activeRecordReeditComposer.busy,
193541
- error: activeRecordReeditComposer.error,
193542
- confirmTone: activeRecordReeditComposer.conflict === "draft" ? "primary" : "danger",
193543
- confirmLabel: activeRecordReeditComposer.conflict === "draft" ? "重新载入" : "放弃并重新载入",
193544
- busyLabel: "正在重新载入…",
193545
- onClose: () => setRecordReeditComposer((current) => sameArkmeRecordReeditSession(current, activeRecordReeditComposer) && !current.busy ? {
193546
- ...current,
193547
- recoveryConfirmation: false
193548
- } : current),
193549
- onConfirm: () => {
193550
- recoverRecordReedit();
193551
- }
193552
- }),
193553
- activeComposerTargetItem !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
193554
- style: styles$7.composerExtensionTarget,
193555
- ...activeRecordReeditComposer === void 0 ? { "data-arkme-composer-extension-target": "true" } : { "data-arkme-composer-reedit-target": "true" },
193556
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
193557
- style: styles$7.composerExtensionTargetBody,
193420
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("footer", {
193421
+ className: "arkme-conversation-composer",
193422
+ "aria-hidden": activeSelectMode !== void 0 || void 0,
193423
+ ...activeSelectMode === void 0 ? {} : { inert: "" },
193424
+ style: {
193425
+ ...styles$7.composer,
193426
+ ...activeSelectMode === void 0 ? {} : {
193427
+ visibility: "hidden",
193428
+ pointerEvents: "none"
193429
+ }
193430
+ },
193431
+ onClick: (event) => {
193432
+ focusArkmeComposerFromClick(textareaRef.current, event);
193433
+ },
193434
+ onDragOver: (event) => {
193435
+ if (!composerFileAddingDisabled && Array.from(event.dataTransfer.types).includes("Files")) {
193436
+ event.preventDefault();
193437
+ event.dataTransfer.dropEffect = "copy";
193438
+ }
193439
+ },
193440
+ onDrop: (event) => {
193441
+ if (!composerFileAddingDisabled && event.dataTransfer.files.length > 0) {
193442
+ event.preventDefault();
193443
+ selectFiles(event.dataTransfer.files);
193444
+ }
193445
+ },
193446
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
193447
+ style: styles$7.composerStack,
193448
+ children: [
193449
+ activeComposerExtensionTarget !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
193450
+ style: styles$7.composerDestinationHint,
193451
+ "data-arkme-composer-destination-hint": "true",
193558
193452
  children: [
193559
- activeRecordReeditComposer !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
193560
- style: styles$7.composerReeditLabel,
193561
- children: "重新编辑:"
193453
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
193454
+ style: styles$7.composerDestinationHintIcon,
193455
+ "aria-hidden": true,
193456
+ children: "💡"
193562
193457
  }),
193563
- (activeComposerTargetItem.textContent.trim() || activeComposerTargetItem.title.trim()) !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
193564
- style: styles$7.composerExtensionTargetText,
193565
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ArkmeRichText, {
193566
- text: activeComposerTargetItem.textContent.trim() || activeComposerTargetItem.title.trim(),
193567
- presentation: "preview"
193568
- })
193458
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "正在给 " }),
193459
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
193460
+ style: styles$7.composerDestinationHintName,
193461
+ children: arkmeSourceDestinationLabel(source)
193569
193462
  }),
193570
- (activeComposerTargetItem.contentBlocks?.length ?? 0) > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
193571
- style: styles$7.composerExtensionTargetFiles,
193572
- children: activeComposerTargetItem.contentBlocks?.slice(0, 3).map((block, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
193573
- style: styles$7.composerExtensionTargetFile,
193574
- title: block.fileName || "附件",
193575
- children: block.kind === "image" ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
193576
- style: styles$7.composerExtensionTargetImage,
193577
- src: createArkmeSdk().mediaUrl(block.mediaRef),
193578
- alt: block.fileName || "图片附件"
193579
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
193580
- hidden: true,
193581
- children: block.fileName || "附件"
193582
- })] }) : block.fileName || "附件"
193583
- }, `${block.mediaRef}:${String(index)}`))
193584
- })
193463
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: " 发消息" })
193585
193464
  ]
193586
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
193465
+ }),
193466
+ activeRecordReeditComposer !== void 0 && activeRecordReeditComposer.error !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
193467
+ role: "alert",
193468
+ style: styles$7.error,
193469
+ children: activeRecordReeditComposer.error
193470
+ }),
193471
+ activeRecordReeditComposer !== void 0 && (activeRecordReeditComposer.conflict !== void 0 || activeRecordReeditComposer.snapshot?.draft !== void 0 && activeRecordReeditComposer.snapshot.draft.baseVersion !== void 0 && activeRecordReeditComposer.snapshot.draft.baseVersion !== activeRecordReeditComposer.snapshot.version) && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
193587
193472
  type: "button",
193588
- style: styles$7.composerExtensionTargetCancel,
193589
- "aria-label": activeRecordReeditComposer === void 0 ? "取消延展" : "关闭重新编辑",
193590
- disabled: activeRecordReeditComposer?.busy === true || preparingReeditFiles,
193591
- onClick: () => {
193592
- if (activeRecordReeditComposer === void 0) {
193593
- setComposerExtensionTarget(void 0);
193594
- textareaRef.current?.focus();
193595
- } else closeRecordReedit();
193596
- },
193597
- children: "×"
193598
- })]
193599
- }),
193600
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
193601
- ref: composerRef,
193602
- className: "arkme-conversation-composer-inner",
193603
- "data-arkme-primary-composer": "true",
193604
- "data-arkme-composer-focused": composerInputFocused ? "true" : "false",
193605
- style: {
193606
- ...styles$7.composerInner,
193607
- ...composerInputFocused ? styles$7.composerInnerFocused : {},
193608
- ...composerHasTarget ? styles$7.composerInnerExtension : {},
193609
- ...composerResize.highlighted ? {
193610
- border: "1px solid #09B83E",
193611
- borderRadius: 12
193612
- } : {}
193613
- },
193614
- children: [
193615
- composerResize.handle,
193616
- addMenuOpen && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
193617
- ref: addMenuRef,
193618
- style: styles$7.addMenu,
193619
- role: "menu",
193620
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
193621
- type: "button",
193622
- role: "menuitem",
193623
- style: styles$7.addMenuItem,
193624
- onClick: () => {
193625
- setAddMenuOpen(false);
193626
- fileInputRef.current?.click();
193627
- },
193628
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
193629
- "aria-hidden": true,
193630
- children: "📎"
193631
- }), "添加照片和文件"]
193632
- }), activeRecordReeditComposer === void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { style: styles$7.menuDivider }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
193633
- type: "button",
193634
- role: "menuitem",
193635
- style: styles$7.addMenuItem,
193636
- onClick: () => {
193637
- setLongArticleCreating(true);
193638
- setAddMenuOpen(false);
193639
- },
193640
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
193641
- "aria-hidden": true,
193642
- children: "✎"
193643
- }), "写长文"]
193644
- })] })]
193645
- }),
193646
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
193647
- ref: fileInputRef,
193648
- type: "file",
193649
- multiple: true,
193650
- hidden: true,
193651
- onChange: (event) => {
193652
- selectFiles(event.currentTarget.files);
193653
- }
193654
- }),
193655
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
193656
- className: "arkme-conversation-input-card",
193473
+ style: styles$7.retry,
193474
+ disabled: composerFilesDisabled,
193475
+ "aria-label": activeRecordReeditComposer.conflict === "draft" ? "重新载入草稿" : "放弃草稿并重新载入",
193476
+ onClick: () => setRecordReeditComposer((current) => sameArkmeRecordReeditSession(current, activeRecordReeditComposer) ? {
193477
+ ...current,
193478
+ recoveryConfirmation: true
193479
+ } : current),
193480
+ children: activeRecordReeditComposer.conflict === "draft" ? "重新载入草稿" : "放弃草稿并重新载入"
193481
+ }),
193482
+ activeRecordReeditComposer?.recoveryConfirmation && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ArkmeConfirmDialog, {
193483
+ titleId: "arkme-reedit-recovery-title",
193484
+ title: activeRecordReeditComposer.conflict === "draft" ? "重新载入最新草稿?" : "放弃草稿并重新载入?",
193485
+ description: activeRecordReeditComposer.conflict === "draft" ? "当前输入区将替换为其他入口保存的最新草稿。不会删除草稿或修改已保存的快记。" : "本机这份重新编辑草稿中的正文和附件改动将被放弃,重新载入已保存的快记。此操作不会删除线上附件。",
193486
+ busy: activeRecordReeditComposer.busy,
193487
+ error: activeRecordReeditComposer.error,
193488
+ confirmTone: activeRecordReeditComposer.conflict === "draft" ? "primary" : "danger",
193489
+ confirmLabel: activeRecordReeditComposer.conflict === "draft" ? "重新载入" : "放弃并重新载入",
193490
+ busyLabel: "正在重新载入…",
193491
+ onClose: () => setRecordReeditComposer((current) => sameArkmeRecordReeditSession(current, activeRecordReeditComposer) && !current.busy ? {
193492
+ ...current,
193493
+ recoveryConfirmation: false
193494
+ } : current),
193495
+ onConfirm: () => {
193496
+ recoverRecordReedit();
193497
+ }
193498
+ }),
193499
+ activeComposerTargetItem !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
193500
+ style: styles$7.composerExtensionTarget,
193501
+ ...activeRecordReeditComposer === void 0 ? { "data-arkme-composer-extension-target": "true" } : { "data-arkme-composer-reedit-target": "true" },
193502
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
193503
+ style: styles$7.composerExtensionTargetBody,
193657
193504
  children: [
193658
- visibleComposerAttachments.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ArkmeAttachmentStrip, {
193659
- attachments: visibleComposerAttachments,
193660
- disabled: composerFilesDisabled,
193661
- onMove: (from, to) => {
193662
- if (composerFilesDisabled) return;
193663
- if (activeRecordReeditComposer === void 0) arkmeComposerDraftStore.moveAttachment(composerDraftKey, from, to);
193664
- else setRecordReeditComposer((current) => {
193665
- if (!sameArkmeRecordReeditSession(current, activeRecordReeditComposer)) return current;
193666
- const next = [...current.attachments];
193667
- const attachment = next[from];
193668
- if (attachment === void 0 || to < 0 || to >= next.length) return current;
193669
- next.splice(from, 1);
193670
- next.splice(to, 0, attachment);
193671
- return {
193672
- ...current,
193673
- attachments: next,
193674
- error: ""
193675
- };
193676
- });
193677
- },
193678
- canPreview: (attachment) => activeRecordReeditComposer === void 0 ? attachment.localFile !== void 0 : activeRecordReeditComposer.attachments.some((view) => arkmeAttachmentId(view) === arkmeAttachmentId(attachment) && arkmeRecordReeditAttachmentBlock(view) !== void 0),
193679
- onPreview: (attachment) => {
193680
- if (activeRecordReeditComposer === void 0) {
193681
- if (attachment.localFile !== void 0) setDraftPreview(localFileBlock(attachment.localFile));
193682
- } else {
193683
- const view = activeRecordReeditComposer.attachments.find((view) => arkmeAttachmentId(view) === arkmeAttachmentId(attachment));
193684
- if (view !== void 0) setDraftPreview(arkmeRecordReeditAttachmentBlock(view));
193685
- }
193686
- },
193687
- onRemove: (attachment) => {
193688
- if (composerFilesDisabled) return;
193689
- if (activeRecordReeditComposer !== void 0) {
193690
- setRecordReeditComposer((current) => sameArkmeRecordReeditSession(current, activeRecordReeditComposer) ? {
193691
- ...current,
193692
- attachments: current.attachments.filter((view) => arkmeAttachmentId(view) !== arkmeAttachmentId(attachment)),
193693
- error: ""
193694
- } : current);
193695
- setDraftPreview(void 0);
193696
- return;
193697
- }
193698
- arkmeComposerDraftStore.removeAttachment(composerDraftKey, arkmeAttachmentId(attachment));
193699
- if (attachment.localFile !== void 0) callArkme("files.local.remove", { fileRef: attachment.localFile.fileRef }).catch((caught) => setError(errorMessage$2(caught)));
193700
- }
193505
+ activeRecordReeditComposer !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
193506
+ style: styles$7.composerReeditLabel,
193507
+ children: "重新编辑:"
193701
193508
  }),
193702
- activeRecordReeditComposer?.attachments.some((attachment) => attachment.unavailable) && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
193703
- role: "status",
193704
- style: styles$7.error,
193705
- children: "部分附件不可用,请移除后重新添加"
193509
+ (activeComposerTargetItem.textContent.trim() || activeComposerTargetItem.title.trim()) !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
193510
+ style: styles$7.composerExtensionTargetText,
193511
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ArkmeRichText, {
193512
+ text: activeComposerTargetItem.textContent.trim() || activeComposerTargetItem.title.trim(),
193513
+ presentation: "preview"
193514
+ })
193706
193515
  }),
193707
- activeConversation && draftPreview !== void 0 && typeof document !== "undefined" && (0, react_dom.createPortal)(/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ArkmeMediaPreview, {
193708
- selected: draftPreview,
193709
- blocks: activeRecordReeditComposer === void 0 ? attachments.flatMap((attachment) => attachment.localFile === void 0 ? [] : [localFileBlock(attachment.localFile)]) : activeRecordReeditComposer.attachments.flatMap((attachment) => {
193710
- const block = arkmeRecordReeditAttachmentBlock(attachment);
193711
- return block === void 0 ? [] : [block];
193712
- }),
193713
- onSelect: setDraftPreview,
193714
- onClose: () => setDraftPreview(void 0),
193715
- openLocalFile: false
193716
- }), document.body),
193717
- activeRecordReeditComposer === void 0 && hashTagTrigger !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
193718
- ref: hashTagSuggestionListRef,
193719
- style: styles$7.mentionSuggestions,
193720
- role: "listbox",
193721
- "aria-label": "选择标签",
193722
- children: hashTagCandidates.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
193723
- style: styles$7.mentionSuggestionsEmpty,
193724
- children: hashTagLoading ? "正在加载标签…" : "暂无匹配标签,可继续输入创建新标签"
193725
- }) : hashTagCandidates.map((item, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
193726
- type: "button",
193727
- role: "option",
193728
- "aria-selected": index === hashTagCandidateIndex,
193729
- style: {
193730
- ...styles$7.mentionSuggestionRow,
193731
- ...index === hashTagCandidateIndex ? styles$7.mentionSuggestionRowActive : {}
193732
- },
193733
- onMouseEnter: () => {
193734
- setHashTagCandidateIndex(index);
193516
+ (activeComposerTargetItem.contentBlocks?.length ?? 0) > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
193517
+ style: styles$7.composerExtensionTargetFiles,
193518
+ children: activeComposerTargetItem.contentBlocks?.slice(0, 3).map((block, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
193519
+ style: styles$7.composerExtensionTargetFile,
193520
+ title: block.fileName || "附件",
193521
+ children: block.kind === "image" ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
193522
+ style: styles$7.composerExtensionTargetImage,
193523
+ src: createArkmeSdk().mediaUrl(block.mediaRef),
193524
+ alt: block.fileName || "图片附件"
193525
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
193526
+ hidden: true,
193527
+ children: block.fileName || "附件"
193528
+ })] }) : block.fileName || "附件"
193529
+ }, `${block.mediaRef}:${String(index)}`))
193530
+ })
193531
+ ]
193532
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
193533
+ type: "button",
193534
+ style: styles$7.composerExtensionTargetCancel,
193535
+ "aria-label": activeRecordReeditComposer === void 0 ? "取消延展" : "关闭重新编辑",
193536
+ disabled: activeRecordReeditComposer?.busy === true || preparingReeditFiles,
193537
+ onClick: () => {
193538
+ if (activeRecordReeditComposer === void 0) {
193539
+ setComposerExtensionTarget(void 0);
193540
+ textareaRef.current?.focus();
193541
+ } else closeRecordReedit();
193542
+ },
193543
+ children: "×"
193544
+ })]
193545
+ }),
193546
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
193547
+ ref: composerRef,
193548
+ className: "arkme-conversation-composer-inner",
193549
+ "data-arkme-primary-composer": "true",
193550
+ "data-arkme-composer-focused": composerInputFocused ? "true" : "false",
193551
+ style: {
193552
+ ...styles$7.composerInner,
193553
+ ...composerInputFocused ? styles$7.composerInnerFocused : {},
193554
+ ...composerHasTarget ? styles$7.composerInnerExtension : {},
193555
+ ...composerResize.highlighted ? {
193556
+ border: "1px solid #09B83E",
193557
+ borderRadius: 12
193558
+ } : {}
193559
+ },
193560
+ children: [
193561
+ composerResize.handle,
193562
+ addMenuOpen && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
193563
+ ref: addMenuRef,
193564
+ style: styles$7.addMenu,
193565
+ role: "menu",
193566
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
193567
+ type: "button",
193568
+ role: "menuitem",
193569
+ style: styles$7.addMenuItem,
193570
+ onClick: () => {
193571
+ setAddMenuOpen(false);
193572
+ fileInputRef.current?.click();
193573
+ },
193574
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
193575
+ "aria-hidden": true,
193576
+ children: "📎"
193577
+ }), "添加照片和文件"]
193578
+ }), activeRecordReeditComposer === void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { style: styles$7.menuDivider }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
193579
+ type: "button",
193580
+ role: "menuitem",
193581
+ style: styles$7.addMenuItem,
193582
+ onClick: () => {
193583
+ setLongArticleCreating(true);
193584
+ setAddMenuOpen(false);
193585
+ },
193586
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
193587
+ "aria-hidden": true,
193588
+ children: "✎"
193589
+ }), "写长文"]
193590
+ })] })]
193591
+ }),
193592
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
193593
+ ref: fileInputRef,
193594
+ type: "file",
193595
+ multiple: true,
193596
+ hidden: true,
193597
+ onChange: (event) => {
193598
+ selectFiles(event.currentTarget.files);
193599
+ }
193600
+ }),
193601
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
193602
+ className: "arkme-conversation-input-card",
193603
+ children: [
193604
+ visibleComposerAttachments.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ArkmeAttachmentStrip, {
193605
+ attachments: visibleComposerAttachments,
193606
+ disabled: composerFilesDisabled,
193607
+ onMove: (from, to) => {
193608
+ if (composerFilesDisabled) return;
193609
+ if (activeRecordReeditComposer === void 0) arkmeComposerDraftStore.moveAttachment(composerDraftKey, from, to);
193610
+ else setRecordReeditComposer((current) => {
193611
+ if (!sameArkmeRecordReeditSession(current, activeRecordReeditComposer)) return current;
193612
+ const next = [...current.attachments];
193613
+ const attachment = next[from];
193614
+ if (attachment === void 0 || to < 0 || to >= next.length) return current;
193615
+ next.splice(from, 1);
193616
+ next.splice(to, 0, attachment);
193617
+ return {
193618
+ ...current,
193619
+ attachments: next,
193620
+ error: ""
193621
+ };
193622
+ });
193735
193623
  },
193736
- onMouseDown: (event) => {
193737
- event.preventDefault();
193738
- insertHashTagCandidate(item);
193624
+ canPreview: (attachment) => activeRecordReeditComposer === void 0 ? attachment.localFile !== void 0 : activeRecordReeditComposer.attachments.some((view) => arkmeAttachmentId(view) === arkmeAttachmentId(attachment) && arkmeRecordReeditAttachmentBlock(view) !== void 0),
193625
+ onPreview: (attachment) => {
193626
+ if (activeRecordReeditComposer === void 0) {
193627
+ if (attachment.localFile !== void 0) setDraftPreview(localFileBlock(attachment.localFile));
193628
+ } else {
193629
+ const view = activeRecordReeditComposer.attachments.find((view) => arkmeAttachmentId(view) === arkmeAttachmentId(attachment));
193630
+ if (view !== void 0) setDraftPreview(arkmeRecordReeditAttachmentBlock(view));
193631
+ }
193739
193632
  },
193740
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
193741
- style: {
193742
- ...styles$7.mentionSuggestionBotAvatar,
193743
- flex: "none",
193744
- fontWeight: 600
193745
- },
193746
- "aria-hidden": true,
193747
- children: "#"
193748
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
193749
- style: styles$7.mentionSuggestionText,
193750
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
193751
- style: styles$7.mentionSuggestionName,
193752
- children: item.tagText
193753
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
193754
- style: styles$7.mentionSuggestionSecondary,
193755
- children: [
193756
- "使用 ",
193757
- item.recordCount,
193758
- " "
193759
- ]
193760
- })]
193761
- })]
193762
- }, `${item.normalizedTag}:${item.tagText}`))
193763
- }),
193764
- activeRecordReeditComposer === void 0 && mentionTrigger !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
193765
- style: styles$7.mentionSuggestions,
193766
- role: "listbox",
193767
- "aria-label": "选择要 @ 的对象",
193768
- children: mentionCandidates.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
193769
- style: styles$7.mentionSuggestionsEmpty,
193770
- children: "暂无可 @ 的对象"
193771
- }) : mentionCandidates.map((member, index) => {
193772
- const primary = arkmeMentionCandidatePrimaryText(member);
193773
- const secondary = member.kind === "bot" ? (member.secondaryName ?? "Bot").trim() : "";
193774
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
193633
+ onRemove: (attachment) => {
193634
+ if (composerFilesDisabled) return;
193635
+ if (activeRecordReeditComposer !== void 0) {
193636
+ setRecordReeditComposer((current) => sameArkmeRecordReeditSession(current, activeRecordReeditComposer) ? {
193637
+ ...current,
193638
+ attachments: current.attachments.filter((view) => arkmeAttachmentId(view) !== arkmeAttachmentId(attachment)),
193639
+ error: ""
193640
+ } : current);
193641
+ setDraftPreview(void 0);
193642
+ return;
193643
+ }
193644
+ arkmeComposerDraftStore.removeAttachment(composerDraftKey, arkmeAttachmentId(attachment));
193645
+ if (attachment.localFile !== void 0) callArkme("files.local.remove", { fileRef: attachment.localFile.fileRef }).catch((caught) => setError(errorMessage$2(caught)));
193646
+ }
193647
+ }),
193648
+ activeRecordReeditComposer?.attachments.some((attachment) => attachment.unavailable) && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
193649
+ role: "status",
193650
+ style: styles$7.error,
193651
+ children: "部分附件不可用,请移除后重新添加"
193652
+ }),
193653
+ activeConversation && draftPreview !== void 0 && typeof document !== "undefined" && (0, react_dom.createPortal)(/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ArkmeMediaPreview, {
193654
+ selected: draftPreview,
193655
+ blocks: activeRecordReeditComposer === void 0 ? attachments.flatMap((attachment) => attachment.localFile === void 0 ? [] : [localFileBlock(attachment.localFile)]) : activeRecordReeditComposer.attachments.flatMap((attachment) => {
193656
+ const block = arkmeRecordReeditAttachmentBlock(attachment);
193657
+ return block === void 0 ? [] : [block];
193658
+ }),
193659
+ onSelect: setDraftPreview,
193660
+ onClose: () => setDraftPreview(void 0),
193661
+ openLocalFile: false
193662
+ }), document.body),
193663
+ activeRecordReeditComposer === void 0 && hashTagTrigger !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
193664
+ ref: hashTagSuggestionListRef,
193665
+ style: styles$7.mentionSuggestions,
193666
+ role: "listbox",
193667
+ "aria-label": "选择标签",
193668
+ children: hashTagCandidates.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
193669
+ style: styles$7.mentionSuggestionsEmpty,
193670
+ children: hashTagLoading ? "正在加载标签…" : "暂无匹配标签,可继续输入创建新标签"
193671
+ }) : hashTagCandidates.map((item, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
193775
193672
  type: "button",
193776
193673
  role: "option",
193777
- "aria-selected": index === mentionCandidateIndex,
193674
+ "aria-selected": index === hashTagCandidateIndex,
193778
193675
  style: {
193779
193676
  ...styles$7.mentionSuggestionRow,
193780
- ...index === mentionCandidateIndex ? styles$7.mentionSuggestionRowActive : {}
193677
+ ...index === hashTagCandidateIndex ? styles$7.mentionSuggestionRowActive : {}
193781
193678
  },
193782
193679
  onMouseEnter: () => {
193783
- setMentionCandidateIndex(index);
193680
+ setHashTagCandidateIndex(index);
193784
193681
  },
193785
193682
  onMouseDown: (event) => {
193786
193683
  event.preventDefault();
193787
- insertMentionCandidate(member);
193684
+ insertHashTagCandidate(item);
193788
193685
  },
193789
193686
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
193790
- style: styles$7.mentionSuggestionAvatar,
193687
+ style: {
193688
+ ...styles$7.mentionSuggestionBotAvatar,
193689
+ flex: "none",
193690
+ fontWeight: 600
193691
+ },
193791
193692
  "aria-hidden": true,
193792
- children: member.kind === "bot" ? member.avatarRef === void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
193793
- style: styles$7.mentionSuggestionBotAvatar,
193794
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(t$5, {
193795
- size: 14,
193796
- weight: "fill"
193797
- })
193798
- }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ArkmeUserAvatar, {
193799
- avatarRef: member.avatarRef,
193800
- size: 28,
193801
- label: member.displayName
193802
- }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ArkmeUserAvatar, {
193803
- ...member.kind === "member" && member.avatarRef !== void 0 ? { avatarRef: member.avatarRef } : {},
193804
- size: 28,
193805
- label: member.displayName
193806
- })
193693
+ children: "#"
193807
193694
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
193808
193695
  style: styles$7.mentionSuggestionText,
193809
193696
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
193810
193697
  style: styles$7.mentionSuggestionName,
193811
- children: primary
193812
- }), secondary !== "" && secondary !== member.displayName ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
193698
+ children: item.tagText
193699
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
193813
193700
  style: styles$7.mentionSuggestionSecondary,
193814
- children: secondary
193815
- }) : null]
193701
+ children: [
193702
+ "使用 ",
193703
+ item.recordCount,
193704
+ " 次"
193705
+ ]
193706
+ })]
193816
193707
  })]
193817
- }, member.kind === "all" ? "all" : member.kind === "bot" ? `bot:${member.botRef}` : `member:${member.mentionRef}`);
193818
- })
193819
- }),
193820
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ArkmeRichComposerInput, {
193821
- markdownEnabled: activeRecordReeditComposer === void 0 && markdownQuickNotesEnabled,
193822
- className: "arkme-conversation-textarea",
193823
- ref: textareaRef,
193824
- style: {
193825
- ...styles$7.textarea,
193826
- ...composerResize.editorStyle
193827
- },
193828
- value: visibleComposerText,
193829
- mentions: activeRecordReeditComposer === void 0 ? composerDraft.mentions : [],
193830
- emojis: activeRecordReeditComposer === void 0 ? composerDraft.emojis : [],
193831
- maxLength: activeRecordReeditComposer?.snapshot?.maxTextLength ?? 2e4,
193832
- placeholder: effectiveComposerPlaceholder,
193833
- ariaLabel: activeRecordReeditComposer === void 0 ? effectiveComposerPlaceholder : "重新编辑快记",
193834
- disabled: composerFilesDisabled,
193835
- markdown: activeRecordReeditComposer === void 0 && !directAdmission.blocked ? composerDraft.markdown : void 0,
193836
- onMarkdownChange: (markdown, text, mentions, emojis) => {
193837
- if (activeRecordReeditComposer === void 0 && !directAdmission.blocked) arkmeComposerDraftStore.setMarkdown(composerDraftKey, markdown, text, mentions, emojis);
193838
- },
193839
- onTextChange: updateComposerText,
193840
- onInputActivity: messagePreparing.input,
193841
- onFocus: () => {
193842
- messagePreparing.focus(true);
193843
- setComposerInputFocused(true);
193844
- },
193845
- onBlur: () => {
193846
- messagePreparing.focus(false);
193847
- setComposerInputFocused(false);
193848
- },
193849
- onSelectionChange: updateComposerRichTrigger,
193850
- onPaste: (event) => {
193851
- if (composerFileAddingDisabled) return;
193852
- const files = arkmeClipboardFiles(event.clipboardData);
193853
- if (files.length === 0) return;
193854
- event.preventDefault();
193855
- selectFiles(files);
193856
- },
193857
- onKeyDown: (event) => {
193858
- if (activeRecordReeditComposer === void 0 && hashTagTrigger !== void 0) {
193859
- if (event.key === "Escape") {
193860
- event.preventDefault();
193861
- dismissedHashTagStartRef.current = hashTagTrigger.startIndex;
193862
- setHashTagTrigger(void 0);
193863
- return;
193708
+ }, `${item.normalizedTag}:${item.tagText}`))
193709
+ }),
193710
+ activeRecordReeditComposer === void 0 && mentionTrigger !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
193711
+ style: styles$7.mentionSuggestions,
193712
+ role: "listbox",
193713
+ "aria-label": "选择要 @ 的对象",
193714
+ children: mentionCandidates.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
193715
+ style: styles$7.mentionSuggestionsEmpty,
193716
+ children: "暂无可 @ 的对象"
193717
+ }) : mentionCandidates.map((member, index) => {
193718
+ const primary = arkmeMentionCandidatePrimaryText(member);
193719
+ const secondary = member.kind === "bot" ? (member.secondaryName ?? "Bot").trim() : "";
193720
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
193721
+ type: "button",
193722
+ role: "option",
193723
+ "aria-selected": index === mentionCandidateIndex,
193724
+ style: {
193725
+ ...styles$7.mentionSuggestionRow,
193726
+ ...index === mentionCandidateIndex ? styles$7.mentionSuggestionRowActive : {}
193727
+ },
193728
+ onMouseEnter: () => {
193729
+ setMentionCandidateIndex(index);
193730
+ },
193731
+ onMouseDown: (event) => {
193732
+ event.preventDefault();
193733
+ insertMentionCandidate(member);
193734
+ },
193735
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
193736
+ style: styles$7.mentionSuggestionAvatar,
193737
+ "aria-hidden": true,
193738
+ children: member.kind === "bot" ? member.avatarRef === void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
193739
+ style: styles$7.mentionSuggestionBotAvatar,
193740
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(t$5, {
193741
+ size: 14,
193742
+ weight: "fill"
193743
+ })
193744
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ArkmeUserAvatar, {
193745
+ avatarRef: member.avatarRef,
193746
+ size: 28,
193747
+ label: member.displayName
193748
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ArkmeUserAvatar, {
193749
+ ...member.kind === "member" && member.avatarRef !== void 0 ? { avatarRef: member.avatarRef } : {},
193750
+ size: 28,
193751
+ label: member.displayName
193752
+ })
193753
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
193754
+ style: styles$7.mentionSuggestionText,
193755
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
193756
+ style: styles$7.mentionSuggestionName,
193757
+ children: primary
193758
+ }), secondary !== "" && secondary !== member.displayName ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
193759
+ style: styles$7.mentionSuggestionSecondary,
193760
+ children: secondary
193761
+ }) : null]
193762
+ })]
193763
+ }, member.kind === "all" ? "all" : member.kind === "bot" ? `bot:${member.botRef}` : `member:${member.mentionRef}`);
193764
+ })
193765
+ }),
193766
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ArkmeRichComposerInput, {
193767
+ markdownEnabled: activeRecordReeditComposer === void 0 && markdownQuickNotesEnabled,
193768
+ className: "arkme-conversation-textarea",
193769
+ ref: textareaRef,
193770
+ style: {
193771
+ ...styles$7.textarea,
193772
+ ...composerResize.editorStyle
193773
+ },
193774
+ value: visibleComposerText,
193775
+ mentions: activeRecordReeditComposer === void 0 ? composerDraft.mentions : [],
193776
+ emojis: activeRecordReeditComposer === void 0 ? composerDraft.emojis : [],
193777
+ maxLength: activeRecordReeditComposer?.snapshot?.maxTextLength ?? 2e4,
193778
+ placeholder: effectiveComposerPlaceholder,
193779
+ ariaLabel: activeRecordReeditComposer === void 0 ? effectiveComposerPlaceholder : "重新编辑快记",
193780
+ disabled: composerFilesDisabled,
193781
+ markdown: activeRecordReeditComposer === void 0 && !directAdmission.blocked ? composerDraft.markdown : void 0,
193782
+ onMarkdownChange: (markdown, text, mentions, emojis) => {
193783
+ if (activeRecordReeditComposer === void 0 && !directAdmission.blocked) arkmeComposerDraftStore.setMarkdown(composerDraftKey, markdown, text, mentions, emojis);
193784
+ },
193785
+ onTextChange: updateComposerText,
193786
+ onInputActivity: messagePreparing.input,
193787
+ onFocus: () => {
193788
+ messagePreparing.focus(true);
193789
+ setComposerInputFocused(true);
193790
+ },
193791
+ onBlur: () => {
193792
+ messagePreparing.focus(false);
193793
+ setComposerInputFocused(false);
193794
+ },
193795
+ onSelectionChange: updateComposerRichTrigger,
193796
+ onPaste: (event) => {
193797
+ if (composerFileAddingDisabled) return;
193798
+ const files = arkmeClipboardFiles(event.clipboardData);
193799
+ if (files.length === 0) return;
193800
+ event.preventDefault();
193801
+ selectFiles(files);
193802
+ },
193803
+ onKeyDown: (event) => {
193804
+ if (activeRecordReeditComposer === void 0 && hashTagTrigger !== void 0) {
193805
+ if (event.key === "Escape") {
193806
+ event.preventDefault();
193807
+ dismissedHashTagStartRef.current = hashTagTrigger.startIndex;
193808
+ setHashTagTrigger(void 0);
193809
+ return;
193810
+ }
193811
+ if (event.key === "ArrowDown" && hashTagCandidates.length > 0) {
193812
+ event.preventDefault();
193813
+ setHashTagCandidateIndex((index) => (index + 1) % hashTagCandidates.length);
193814
+ return;
193815
+ }
193816
+ if (event.key === "ArrowUp" && hashTagCandidates.length > 0) {
193817
+ event.preventDefault();
193818
+ setHashTagCandidateIndex((index) => (index + hashTagCandidates.length - 1) % hashTagCandidates.length);
193819
+ return;
193820
+ }
193821
+ if ((event.key === "Enter" || event.key === "Tab") && hashTagCandidates.length > 0) {
193822
+ event.preventDefault();
193823
+ const selectedCandidate = hashTagCandidates[Math.min(hashTagCandidateIndex, hashTagCandidates.length - 1)];
193824
+ if (selectedCandidate !== void 0) insertHashTagCandidate(selectedCandidate);
193825
+ return;
193826
+ }
193864
193827
  }
193865
- if (event.key === "ArrowDown" && hashTagCandidates.length > 0) {
193866
- event.preventDefault();
193867
- setHashTagCandidateIndex((index) => (index + 1) % hashTagCandidates.length);
193868
- return;
193828
+ if (activeRecordReeditComposer === void 0 && mentionTrigger !== void 0) {
193829
+ if (event.key === "Escape") {
193830
+ event.preventDefault();
193831
+ setMentionTrigger(void 0);
193832
+ return;
193833
+ }
193834
+ if (event.key === "ArrowDown" && mentionCandidates.length > 0) {
193835
+ event.preventDefault();
193836
+ setMentionCandidateIndex((index) => (index + 1) % mentionCandidates.length);
193837
+ return;
193838
+ }
193839
+ if (event.key === "ArrowUp" && mentionCandidates.length > 0) {
193840
+ event.preventDefault();
193841
+ setMentionCandidateIndex((index) => (index + mentionCandidates.length - 1) % mentionCandidates.length);
193842
+ return;
193843
+ }
193844
+ if ((event.key === "Enter" || event.key === "Tab") && mentionCandidates.length > 0) {
193845
+ event.preventDefault();
193846
+ const selectedCandidate = mentionCandidates[Math.min(mentionCandidateIndex, mentionCandidates.length - 1)];
193847
+ if (selectedCandidate !== void 0) insertMentionCandidate(selectedCandidate);
193848
+ return;
193849
+ }
193869
193850
  }
193870
- if (event.key === "ArrowUp" && hashTagCandidates.length > 0) {
193871
- event.preventDefault();
193872
- setHashTagCandidateIndex((index) => (index + hashTagCandidates.length - 1) % hashTagCandidates.length);
193873
- return;
193851
+ if (activeRecordReeditComposer === void 0 && !event.nativeEvent.isComposing && (event.key === "Backspace" || event.key === "Delete")) {
193852
+ const caret = arkmeComposerDraftStore.deleteMentionAtSelection(composerDraftKey, textareaRef.current?.selectionStart ?? draft.length, textareaRef.current?.selectionEnd ?? draft.length, event.key === "Backspace" ? "backward" : "forward");
193853
+ if (caret !== void 0) {
193854
+ event.preventDefault();
193855
+ focusEditedComposer(caret);
193856
+ return;
193857
+ }
193874
193858
  }
193875
- if ((event.key === "Enter" || event.key === "Tab") && hashTagCandidates.length > 0) {
193859
+ if (event.key === "Enter" && !event.shiftKey && !event.nativeEvent.isComposing) {
193876
193860
  event.preventDefault();
193877
- const selectedCandidate = hashTagCandidates[Math.min(hashTagCandidateIndex, hashTagCandidates.length - 1)];
193878
- if (selectedCandidate !== void 0) insertHashTagCandidate(selectedCandidate);
193879
- return;
193861
+ if (canSend) send();
193880
193862
  }
193881
193863
  }
193882
- if (activeRecordReeditComposer === void 0 && mentionTrigger !== void 0) {
193883
- if (event.key === "Escape") {
193884
- event.preventDefault();
193885
- setMentionTrigger(void 0);
193886
- return;
193887
- }
193888
- if (event.key === "ArrowDown" && mentionCandidates.length > 0) {
193889
- event.preventDefault();
193890
- setMentionCandidateIndex((index) => (index + 1) % mentionCandidates.length);
193891
- return;
193892
- }
193893
- if (event.key === "ArrowUp" && mentionCandidates.length > 0) {
193894
- event.preventDefault();
193895
- setMentionCandidateIndex((index) => (index + mentionCandidates.length - 1) % mentionCandidates.length);
193896
- return;
193897
- }
193898
- if ((event.key === "Enter" || event.key === "Tab") && mentionCandidates.length > 0) {
193899
- event.preventDefault();
193900
- const selectedCandidate = mentionCandidates[Math.min(mentionCandidateIndex, mentionCandidates.length - 1)];
193901
- if (selectedCandidate !== void 0) insertMentionCandidate(selectedCandidate);
193902
- return;
193903
- }
193864
+ }, activeRecordReeditComposer === void 0 ? composerDraftKey : `record-reedit:${activeRecordReeditComposer.generation}`)
193865
+ ]
193866
+ }),
193867
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
193868
+ "data-arkme-composer-footer": "tools",
193869
+ style: styles$7.tools,
193870
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
193871
+ style: styles$7.toolGroup,
193872
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
193873
+ ref: addMenuTriggerRef,
193874
+ type: "button",
193875
+ style: styles$7.plus,
193876
+ "aria-label": "添加内容",
193877
+ "aria-haspopup": "menu",
193878
+ "aria-expanded": addMenuOpen,
193879
+ disabled: composerFileAddingDisabled,
193880
+ onClick: () => {
193881
+ setAddMenuOpen((value) => !value);
193882
+ },
193883
+ children: (activeRecordReeditComposer === void 0 ? preparingFiles : preparingReeditFiles) ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ArkmeFilePreparingIndicator, {}) : "+"
193884
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ArkmeEmojiPicker, {
193885
+ disabled: activeSelectMode !== void 0 || preparingFiles || directAdmission.blocked || activeRecordReeditComposer !== void 0,
193886
+ scopeKey: composerDraftKey,
193887
+ ...source?.kind === "private_chat" || source?.kind === "group_chat" ? { sourceRef: source.sourceRef } : {},
193888
+ getCaretGeometry: () => textareaRef.current?.getCaretGeometry(),
193889
+ getEditorGeometry: () => textareaRef.current?.getEditorGeometry(),
193890
+ onSelect: insertEmoji,
193891
+ onUploadSticker: async (file) => {
193892
+ if (composerDraftKey === void 0) throw new Error("请先选择聊天");
193893
+ return await uploadFavoriteSticker(file);
193894
+ },
193895
+ onStickerSent: async () => {
193896
+ await loadTimeline();
193897
+ },
193898
+ onError: (message) => {
193899
+ setError(message);
193904
193900
  }
193905
- if (activeRecordReeditComposer === void 0 && !event.nativeEvent.isComposing && (event.key === "Backspace" || event.key === "Delete")) {
193906
- const caret = arkmeComposerDraftStore.deleteMentionAtSelection(composerDraftKey, textareaRef.current?.selectionStart ?? draft.length, textareaRef.current?.selectionEnd ?? draft.length, event.key === "Backspace" ? "backward" : "forward");
193907
- if (caret !== void 0) {
193908
- event.preventDefault();
193909
- focusEditedComposer(caret);
193910
- return;
193911
- }
193901
+ }, `emoji-picker:${conversationOverlayKey}`)]
193902
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
193903
+ style: styles$7.composerSendArea,
193904
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ArkmeComposerInputStats, {
193905
+ active: activeConversation,
193906
+ visible: composerStatsVisible,
193907
+ textLength: composerTextLength,
193908
+ ...composerInputStartedAtMillis === void 0 ? {} : { startedAtMillis: composerInputStartedAtMillis },
193909
+ showsInputTime: composerShowsInputTime,
193910
+ onToggle: () => {
193911
+ const next = !composerShowsInputTime;
193912
+ setComposerShowsInputTime(next);
193913
+ setArkmeComposerShowsInputTime(next);
193914
+ textareaRef.current?.focus();
193912
193915
  }
193913
- if (event.key === "Enter" && !event.shiftKey && !event.nativeEvent.isComposing) {
193916
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
193917
+ type: "button",
193918
+ style: {
193919
+ ...styles$7.send,
193920
+ ...canSend ? {} : styles$7.sendDisabled
193921
+ },
193922
+ disabled: !canSend,
193923
+ "aria-label": activeRecordReeditComposer === void 0 ? "发送消息" : "保存重新编辑",
193924
+ onMouseDown: (event) => {
193914
193925
  event.preventDefault();
193915
- if (canSend) send();
193916
- }
193917
- }
193918
- }, activeRecordReeditComposer === void 0 ? composerDraftKey : `record-reedit:${activeRecordReeditComposer.generation}`)
193919
- ]
193920
- }),
193921
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
193922
- "data-arkme-composer-footer": "tools",
193923
- style: styles$7.tools,
193924
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
193925
- style: styles$7.toolGroup,
193926
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
193927
- ref: addMenuTriggerRef,
193928
- type: "button",
193929
- style: styles$7.plus,
193930
- "aria-label": "添加内容",
193931
- "aria-haspopup": "menu",
193932
- "aria-expanded": addMenuOpen,
193933
- disabled: composerFileAddingDisabled,
193934
- onClick: () => {
193935
- setAddMenuOpen((value) => !value);
193936
- },
193937
- children: (activeRecordReeditComposer === void 0 ? preparingFiles : preparingReeditFiles) ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ArkmeFilePreparingIndicator, {}) : "+"
193938
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ArkmeEmojiPicker, {
193939
- disabled: preparingFiles || directAdmission.blocked || activeRecordReeditComposer !== void 0,
193940
- scopeKey: composerDraftKey,
193941
- ...source?.kind === "private_chat" || source?.kind === "group_chat" ? { sourceRef: source.sourceRef } : {},
193942
- getCaretGeometry: () => textareaRef.current?.getCaretGeometry(),
193943
- getEditorGeometry: () => textareaRef.current?.getEditorGeometry(),
193944
- onSelect: insertEmoji,
193945
- onUploadSticker: async (file) => {
193946
- if (composerDraftKey === void 0) throw new Error("请先选择聊天");
193947
- return await uploadFavoriteSticker(file);
193948
- },
193949
- onStickerSent: async () => {
193950
- await loadTimeline();
193951
- },
193952
- onError: (message) => {
193953
- setError(message);
193954
- }
193955
- }, `emoji-picker:${conversationOverlayKey}`)]
193956
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
193957
- style: styles$7.composerSendArea,
193958
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ArkmeComposerInputStats, {
193959
- active: activeConversation,
193960
- visible: composerStatsVisible,
193961
- textLength: composerTextLength,
193962
- ...composerInputStartedAtMillis === void 0 ? {} : { startedAtMillis: composerInputStartedAtMillis },
193963
- showsInputTime: composerShowsInputTime,
193964
- onToggle: () => {
193965
- const next = !composerShowsInputTime;
193966
- setComposerShowsInputTime(next);
193967
- setArkmeComposerShowsInputTime(next);
193968
- textareaRef.current?.focus();
193969
- }
193970
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
193971
- type: "button",
193972
- style: {
193973
- ...styles$7.send,
193974
- ...canSend ? {} : styles$7.sendDisabled
193975
- },
193976
- disabled: !canSend,
193977
- "aria-label": activeRecordReeditComposer === void 0 ? "发送消息" : "保存重新编辑",
193978
- onMouseDown: (event) => {
193979
- event.preventDefault();
193980
- },
193981
- onMouseEnter: (event) => {
193982
- if (!event.currentTarget.disabled) event.currentTarget.style.background = "#08A437";
193983
- },
193984
- onMouseLeave: (event) => {
193985
- if (!event.currentTarget.disabled) event.currentTarget.style.background = "#09B83E";
193986
- },
193987
- onClick: () => {
193988
- send();
193989
- },
193990
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("svg", {
193991
- viewBox: "9.7 6.1 16 16",
193992
- width: "16",
193993
- height: "16",
193994
- "aria-hidden": true,
193995
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
193996
- d: "M23.5521 7.04659L11.5965 10.7238C10.7646 10.9798 10.6133 12.092 11.3467 12.5609L14.879 14.8189C15.0627 14.9363 15.2792 14.9919 15.4967 14.9775C15.7142 14.9631 15.9214 14.8794 16.088 14.7388L20.4967 11.0186C20.7357 10.8169 21.0582 11.1392 20.8566 11.3784L17.1366 15.7879C16.996 15.9545 16.9124 16.1617 16.8981 16.3792C16.8837 16.5966 16.9393 16.813 17.0568 16.9966L19.3143 20.5285C19.783 21.2617 20.8954 21.1104 21.1513 20.2787L24.8286 8.32335C25.0696 7.53956 24.3356 6.80563 23.5521 7.04659Z",
193997
- fill: "currentColor"
193926
+ },
193927
+ onMouseEnter: (event) => {
193928
+ if (!event.currentTarget.disabled) event.currentTarget.style.background = "#08A437";
193929
+ },
193930
+ onMouseLeave: (event) => {
193931
+ if (!event.currentTarget.disabled) event.currentTarget.style.background = "#09B83E";
193932
+ },
193933
+ onClick: () => {
193934
+ send();
193935
+ },
193936
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("svg", {
193937
+ viewBox: "9.7 6.1 16 16",
193938
+ width: "16",
193939
+ height: "16",
193940
+ "aria-hidden": true,
193941
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
193942
+ d: "M23.5521 7.04659L11.5965 10.7238C10.7646 10.9798 10.6133 12.092 11.3467 12.5609L14.879 14.8189C15.0627 14.9363 15.2792 14.9919 15.4967 14.9775C15.7142 14.9631 15.9214 14.8794 16.088 14.7388L20.4967 11.0186C20.7357 10.8169 21.0582 11.1392 20.8566 11.3784L17.1366 15.7879C16.996 15.9545 16.9124 16.1617 16.8981 16.3792C16.8837 16.5966 16.9393 16.813 17.0568 16.9966L19.3143 20.5285C19.783 21.2617 20.8954 21.1104 21.1513 20.2787L24.8286 8.32335C25.0696 7.53956 24.3356 6.80563 23.5521 7.04659Z",
193943
+ fill: "currentColor"
193944
+ })
193998
193945
  })
193999
- })
193946
+ })]
194000
193947
  })]
194001
- })]
194002
- }),
194003
- activeRecordReeditComposer === void 0 && arkmeSourceSupportsRecordInputCapture(source?.kind) && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ArkmeBackgroundSoundWaveform, {
194004
- owner: recordInputCaptureOwner,
194005
- draftKey: composerDraftKey
193948
+ }),
193949
+ activeRecordReeditComposer === void 0 && arkmeSourceSupportsRecordInputCapture(source?.kind) && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ArkmeBackgroundSoundWaveform, {
193950
+ owner: recordInputCaptureOwner,
193951
+ draftKey: composerDraftKey
193952
+ })
193953
+ ]
193954
+ }),
193955
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
193956
+ "data-arkme-composer-footer": "hint",
193957
+ style: styles$7.composerHint,
193958
+ children: "Enter发送 / Shift+Enter换行"
193959
+ })
193960
+ ]
193961
+ })
193962
+ }), activeSelectMode !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
193963
+ style: styles$7.selectBar,
193964
+ role: "toolbar",
193965
+ "aria-label": `已选择 ${selectedMessageCount} 条消息`,
193966
+ children: [
193967
+ source !== void 0 && isArkmeSelfWorkspaceSource(source) && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
193968
+ type: "button",
193969
+ "aria-label": "指定主题",
193970
+ style: styles$7.selectBarButton,
193971
+ disabled: messageActionBusy !== void 0 || selectedMessageCount === 0 || selectedMessageItems.length !== selectedMessageCount || selectedMessageItems.some((item) => !item.recordTopicAssignmentRef),
193972
+ onClick: () => {
193973
+ if (messageActionBusy !== void 0 || selectedMessageItems.length === 0 || selectedMessageItems.length !== selectedMessageCount || selectedMessageItems.some((item) => !item.recordTopicAssignmentRef)) return;
193974
+ const currentTopicKey = source.kind === "topic" ? source.topicHierarchyKey : selectedMessageItems[0]?.recordTopicAssignmentTopicKey;
193975
+ const allInCurrentTopic = currentTopicKey !== void 0 && (source.kind === "topic" || selectedMessageItems.every((item) => item.recordTopicAssignmentTopicKey === currentTopicKey));
193976
+ setTopicAssignment({
193977
+ scopeKey: topicAssignmentScopeKey,
193978
+ source,
193979
+ ...allInCurrentTopic ? { currentTopicKey } : {},
193980
+ assignmentRefs: selectedMessageItems.map((item) => item.recordTopicAssignmentRef),
193981
+ firstRecordText: items.find((item) => item.itemUid === selectedMessageItems[0]?.itemUid)?.textContent ?? ""
193982
+ });
193983
+ },
193984
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
193985
+ style: styles$7.selectBarIconTile,
193986
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ArkmeSelectActionIcon, {
193987
+ kind: "assign",
193988
+ size: 20
194006
193989
  })
194007
- ]
193990
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
193991
+ style: styles$7.selectBarLabel,
193992
+ children: "指定主题"
193993
+ })]
194008
193994
  }),
194009
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
194010
- "data-arkme-composer-footer": "hint",
194011
- style: styles$7.composerHint,
194012
- children: "Enter发送 / Shift+Enter换行"
193995
+ (() => {
193996
+ const copyTextEnabled = arkmeCanCopySelectedMessageText(selectedMessageItems.length, messageActionBusy !== void 0);
193997
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
193998
+ type: "button",
193999
+ style: {
194000
+ ...styles$7.selectBarButton,
194001
+ ...!copyTextEnabled ? styles$7.selectBarButtonDisabled : {}
194002
+ },
194003
+ disabled: !copyTextEnabled,
194004
+ onClick: () => {
194005
+ copySelectedMessageText();
194006
+ },
194007
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
194008
+ style: styles$7.selectBarIconTile,
194009
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ArkmeSelectActionIcon, { kind: "copy" })
194010
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
194011
+ style: styles$7.selectBarLabel,
194012
+ children: ARKME_MESSAGE_SELECT_ACTION_LABELS[0]
194013
+ })]
194014
+ });
194015
+ })(),
194016
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
194017
+ type: "button",
194018
+ style: {
194019
+ ...styles$7.selectBarButton,
194020
+ ...!selectedMessagesHaveSnapshots || messageActionBusy !== void 0 ? styles$7.selectBarButtonDisabled : {}
194021
+ },
194022
+ disabled: !selectedMessagesHaveSnapshots || messageActionBusy !== void 0,
194023
+ onClick: () => {
194024
+ copyMessageLink(selectedMessageItems);
194025
+ },
194026
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
194027
+ style: styles$7.selectBarIconTile,
194028
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ArkmeSelectActionIcon, { kind: "link" })
194029
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
194030
+ style: styles$7.selectBarLabel,
194031
+ children: ARKME_MESSAGE_SELECT_ACTION_LABELS[1]
194032
+ })]
194033
+ }),
194034
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
194035
+ type: "button",
194036
+ style: {
194037
+ ...styles$7.selectBarButton,
194038
+ ...!selectedMessagesHaveSnapshots || messageActionBusy !== void 0 ? styles$7.selectBarButtonDisabled : {}
194039
+ },
194040
+ disabled: !selectedMessagesHaveSnapshots || messageActionBusy !== void 0,
194041
+ onClick: () => {
194042
+ openForwardTargetPicker();
194043
+ },
194044
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
194045
+ style: styles$7.selectBarIconTile,
194046
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ArkmeSelectActionIcon, { kind: "forward" })
194047
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
194048
+ style: styles$7.selectBarLabel,
194049
+ children: messageActionBusy === "forward" ? "转发中" : ARKME_MESSAGE_SELECT_ACTION_LABELS[2]
194050
+ })]
194051
+ }),
194052
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
194053
+ type: "button",
194054
+ style: {
194055
+ ...styles$7.selectBarButton,
194056
+ ...messageActionBusy !== void 0 ? styles$7.selectBarButtonDisabled : {}
194057
+ },
194058
+ disabled: messageActionBusy !== void 0,
194059
+ "aria-label": ARKME_MESSAGE_SELECT_ACTION_LABELS[3],
194060
+ onClick: exitMessageSelectMode,
194061
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
194062
+ style: styles$7.selectBarIconTile,
194063
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ArkmeSelectActionIcon, {
194064
+ kind: "close",
194065
+ size: 18
194066
+ })
194067
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
194068
+ style: styles$7.selectBarLabel,
194069
+ children: ARKME_MESSAGE_SELECT_ACTION_LABELS[3]
194070
+ })]
194013
194071
  })
194014
194072
  ]
194015
- })
194073
+ })]
194016
194074
  })
194017
194075
  ] }),
194018
194076
  activeConversation && forwardTargetPicker !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {