dsh-xrxs-lingting 0.4.0-dev.51 → 0.4.0-dev.52

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-xrxs-lingting",
3
- "version": "0.4.0-dev.51",
3
+ "version": "0.4.0-dev.52",
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "dev": "vite --host 127.0.0.1",
@@ -1384,7 +1384,21 @@ var XinLingtingService = class {
1384
1384
  this.emit({ operation: null });
1385
1385
  }
1386
1386
  };
1387
- finish = async () => {
1387
+ finish = async (recordId) => {
1388
+ if (recordId && this.snapshot.active?.id !== recordId) {
1389
+ if (this.snapshot.operation) throw new Error("\u6B63\u5728\u5904\u7406\u5176\u4ED6\u5F55\u97F3\u64CD\u4F5C\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002");
1390
+ this.emit({ operation: "finishing" });
1391
+ try {
1392
+ const record = await this.loadDetail(recordId);
1393
+ if (record.id !== recordId || record.status !== "paused") throw new Error("\u8BB0\u5F55\u72B6\u6001\u5DF2\u53D8\u5316\uFF0C\u8BF7\u5237\u65B0\u540E\u91CD\u8BD5\u3002");
1394
+ await this.http.send(this.requests.stop(recordId, msToSeconds(record.durationMs)));
1395
+ this.emit({ catalogVersion: this.snapshot.catalogVersion + 1 });
1396
+ recordProgress(this).track(recordId);
1397
+ } finally {
1398
+ this.emit({ operation: null });
1399
+ }
1400
+ return;
1401
+ }
1388
1402
  const active = this.snapshot.active;
1389
1403
  if (this.snapshot.operation || !active || active.status === "finishing") return;
1390
1404
  const needTeardown = active.status !== "finish-error";
@@ -1774,6 +1788,12 @@ function publishAudioStatus(next) {
1774
1788
  status = next;
1775
1789
  listeners.forEach((listener) => listener());
1776
1790
  }
1791
+ var recoveries = [];
1792
+ function noteAudioRecovery(samples, rate) {
1793
+ if (!Number.isFinite(samples) || samples <= 0 || !Number.isFinite(rate) || rate < 8e3) return;
1794
+ recoveries.push({ at: Date.now(), droppedMs: samples / rate * 1e3 });
1795
+ if (recoveries.length > 50) recoveries.shift();
1796
+ }
1777
1797
 
1778
1798
  // src/audio/native-system.ts
1779
1799
  function nativeSystemAudio() {
@@ -1982,7 +2002,6 @@ var MeetingCapture = class {
1982
2002
  const sources = [context.createMediaStreamSource(microphone)];
1983
2003
  this.nodes.push(sources[0]);
1984
2004
  let startSystem;
1985
- let recoveryWarning;
1986
2005
  if (system) {
1987
2006
  const sessionId = crypto.randomUUID();
1988
2007
  const source = new AudioWorkletNode(context, "lingting-native-system", {
@@ -1996,8 +2015,7 @@ var MeetingCapture = class {
1996
2015
  if (generation !== this.generation) return;
1997
2016
  if (event.data?.error) fail(event.data.error);
1998
2017
  if (event.data?.droppedSamples > 0) {
1999
- recoveryWarning = "\u7CFB\u7EDF\u58F0\u97F3\u5904\u7406\u66FE\u77ED\u6682\u79EF\u538B\uFF0C\u5DF2\u6062\u590D\u5B9E\u65F6\u5F55\u97F3\uFF1B\u90E8\u5206\u7CFB\u7EDF\u58F0\u97F3\u53EF\u80FD\u7F3A\u5931\u3002";
2000
- publishAudioStatus({ mode: this.mode, microphone: 0, system: 0, warning: recoveryWarning });
2018
+ noteAudioRecovery(event.data.droppedSamples, event.data.sampleRate);
2001
2019
  }
2002
2020
  };
2003
2021
  const receivePort = (event) => {
@@ -2074,12 +2092,7 @@ var MeetingCapture = class {
2074
2092
  analyser.getFloatTimeDomainData(samples);
2075
2093
  return Math.min(1, Math.sqrt(samples.reduce((sum, sample) => sum + sample * sample, 0) / samples.length) * 4);
2076
2094
  });
2077
- publishAudioStatus({
2078
- mode: this.mode,
2079
- microphone: this.emitting ? levels[0] : 0,
2080
- system: this.emitting ? levels[1] ?? 0 : 0,
2081
- warning: recoveryWarning
2082
- });
2095
+ publishAudioStatus({ mode: this.mode, microphone: this.emitting ? levels[0] : 0, system: this.emitting ? levels[1] ?? 0 : 0 });
2083
2096
  }, 200);
2084
2097
  } catch (error) {
2085
2098
  if (generation === this.generation) await this.stop();
@@ -3140,6 +3153,23 @@ function RecordViewer({ service, recordId, onLoaded }) {
3140
3153
  const [refreshing, setRefreshing] = (0, import_react13.useState)(false);
3141
3154
  const [summaryError, setSummaryError] = (0, import_react13.useState)("");
3142
3155
  const [resuming, setResuming] = (0, import_react13.useState)(false);
3156
+ const [confirmFinish, setConfirmFinish] = (0, import_react13.useState)(false);
3157
+ const [finishing, setFinishing] = (0, import_react13.useState)(false);
3158
+ const finishRecording = async () => {
3159
+ if (finishing || resuming) return;
3160
+ setFinishing(true);
3161
+ setResumeError("");
3162
+ try {
3163
+ await service.finish(recordId);
3164
+ setLoaded((current) => current ? { ...current, status: "finishing" } : current);
3165
+ setConfirmFinish(false);
3166
+ } catch (e) {
3167
+ setResumeError(e instanceof Error ? e.message : "\u7ED3\u675F\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5\u3002");
3168
+ setConfirmFinish(false);
3169
+ } finally {
3170
+ setFinishing(false);
3171
+ }
3172
+ };
3143
3173
  const [resumeError, setResumeError] = (0, import_react13.useState)("");
3144
3174
  const [shareOpen, setShareOpen] = (0, import_react13.useState)(false);
3145
3175
  (0, import_react13.useEffect)(() => {
@@ -3272,12 +3302,20 @@ function RecordViewer({ service, recordId, onLoaded }) {
3272
3302
  ] })
3273
3303
  ] }),
3274
3304
  loaded.status === "paused" && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "lt-resume", children: [
3275
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("button", { className: "lt-primary", onClick: () => void resumeRecording(), disabled: resuming, children: [
3305
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("button", { className: "lt-primary", onClick: () => void resumeRecording(), disabled: resuming || finishing, children: [
3276
3306
  resuming ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Spinner, { size: 15 }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Mic, { size: 15 }),
3277
3307
  resuming ? "\u6B63\u5728\u7EE7\u7EED\u2026" : "\u7EE7\u7EED\u5F55\u97F3"
3278
3308
  ] }),
3309
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("button", { className: "button danger", disabled: resuming || finishing, onClick: () => setConfirmFinish(true), children: "\u7ED3\u675F\u7075\u542C" }),
3279
3310
  /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { children: "\u7EE7\u7EED\u540E\u5B9E\u65F6\u8F6C\u5199\u56DE\u5230\u8FD9\u4E2A\u9762\u677F" })
3280
3311
  ] }),
3312
+ confirmFinish && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(Modal, { title: "\u7ED3\u675F\u8FD9\u573A\u7075\u542C\uFF1F", busy: finishing, onClose: () => setConfirmFinish(false), children: [
3313
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { children: "\u7ED3\u675F\u540E\u5C06\u6574\u7406\u5DF2\u6709\u8F6C\u5199\uFF0C\u65E0\u6CD5\u7EE7\u7EED\u8FD9\u573A\u5F55\u97F3\u3002" }),
3314
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "modal-actions", children: [
3315
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("button", { className: "button", disabled: finishing, onClick: () => setConfirmFinish(false), children: "\u6682\u4E0D\u7ED3\u675F" }),
3316
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("button", { className: "button danger", disabled: finishing, onClick: () => void finishRecording(), children: finishing ? "\u6B63\u5728\u7ED3\u675F\u2026" : "\u7ED3\u675F\u7075\u542C" })
3317
+ ] })
3318
+ ] }),
3281
3319
  resumeError && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "lt-resume-error", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ErrorNotice, { action: "\u77E5\u9053\u4E86", onAction: () => setResumeError(""), children: resumeError }) }),
3282
3320
  (loaded.status === "finishing" || loaded.status === "interrupted") && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "lt-settling", children: [
3283
3321
  /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Spinner, { size: 13 }),
@@ -4424,7 +4462,7 @@ function MeetingPrompt({ service }) {
4424
4462
  const meeting = useMeetingPrompt({ service });
4425
4463
  if (!meeting.prompt) return null;
4426
4464
  const appName = meeting.prompt.appName;
4427
- const headline = meeting.pending ? "\u6B63\u5728\u5F00\u542F\u7075\u542C" : meeting.error ? "\u7075\u542C\u542F\u52A8\u672A\u5B8C\u6210" : meeting.confidence === "suspected" ? `\u68C0\u6D4B\u5230\u53EF\u80FD\u7684\u901A\u8BDD\u6D3B\u52A8\uFF08${appName}\uFF09` : `\u68C0\u6D4B\u5230${appName}\u4F1A\u8BAE`;
4465
+ const headline = meeting.pending ? "\u6B63\u5728\u5F00\u542F\u7075\u542C" : meeting.error ? "\u7075\u542C\u542F\u52A8\u672A\u5B8C\u6210" : meeting.confidence === "suspected" ? `\u68C0\u6D4B\u5230\u53EF\u80FD\u7684\u901A\u8BDD\u6D3B\u52A8\uFF08${appName}\uFF09` : `${appName}\u53EF\u80FD\u6B63\u5728\u901A\u8BDD`;
4428
4466
  return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("aside", { className: "lingting-root lt-meeting", "aria-label": "\u4F1A\u8BAE\u63D0\u9192", children: [
4429
4467
  /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "lt-meeting-head", children: [
4430
4468
  /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Headphones, { size: 16 }),
@@ -756,7 +756,7 @@ function createMeetingPolicy(options = {}) {
756
756
  }
757
757
  if (!config.enabled) return { prompt: null, suppressed: "disabled" };
758
758
  const candidates = sessions.filter(
759
- (session) => session.state === "meeting" && session.confidence !== "none" && (restartSuppression.get(session.appId) ?? 0) <= at && (config.apps.length === 0 || config.apps.includes(session.appId)) && !config.mutedApps.includes(session.appId)
759
+ (session) => session.state === "meeting" && session.confidence === "high" && (restartSuppression.get(session.appId) ?? 0) <= at && (config.apps.length === 0 || config.apps.includes(session.appId)) && !config.mutedApps.includes(session.appId)
760
760
  );
761
761
  if (candidates.length === 0) return { prompt: null, suppressed: null };
762
762
  if (inQuietHours(config, new Date(at))) return { prompt: null, suppressed: "quiet-hours" };
@@ -929,7 +929,7 @@ function createMeetingRuntime(options = {}) {
929
929
  const result = await supervisor.command("prompt.show", {
930
930
  promptId: record.promptId,
931
931
  title: "\u7075\u542C",
932
- subtitle: `\u68C0\u6D4B\u5230${record.appName}\u4F1A\u8BAE`,
932
+ subtitle: `${record.appName}\u53EF\u80FD\u6B63\u5728\u901A\u8BDD`,
933
933
  message: "\u9700\u8981\u6211\u5E2E\u4F60\u5F00\u542F\u5F55\u97F3\u8F6C\u5199\u5417\uFF1F\u53EF\u4EE5\u751F\u6210\u5F55\u97F3\u7EAA\u8981\u5E76\u5BF9\u5185\u5BB9\u63D0\u95EE",
934
934
  acceptLabel: "\u5F00\u542F\u5F55\u97F3\u8F6C\u5199",
935
935
  ignoreLabel: "\u5FFD\u7565",