dsh-xrxs-lingting 0.4.0-dev.49 → 0.4.0-dev.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/README.md +5 -1
- package/package.json +1 -1
- package/plugin-dist/client.js +204 -11
package/README.md
CHANGED
|
@@ -98,7 +98,7 @@ LINGTING_XIN_PROBE=1 nohup "/path/to/DSH Desktop Dev.app/Contents/MacOS/DSH Desk
|
|
|
98
98
|
|
|
99
99
|
## 客户端兼容性验证
|
|
100
100
|
|
|
101
|
-
`0.4.0-dev.48` 起不再要求宿主提供旧版补丁的 `layout.business
|
|
101
|
+
`0.4.0-dev.48` 起不再要求宿主提供旧版补丁的 `layout.business`。`0.4.0-dev.50` 起,标准薪灵客户端通过渲染器公开的 `[data-slot="conversation"]` 标记,将原有灵听页面挂载到主内容区:保留侧栏,暂时隐藏而不卸载聊天,返回时恢复原聊天和草稿。弹窗、列表、实时转写仍复用原组件;转写面板继续使用 `shell.overlay`。提供业务页扩展的旧宿主仍沿用原入口。
|
|
102
102
|
|
|
103
103
|
发布前除单元测试外,应在构建后对目标薪灵源码运行客户端产物冒烟,验证真实布局对象、公开插槽、页面打开及返回聊天:
|
|
104
104
|
|
|
@@ -108,3 +108,7 @@ npm run smoke:client -- /path/to/cinlyn-desktop
|
|
|
108
108
|
```
|
|
109
109
|
|
|
110
110
|
该检查不代替安装后对授权、录音、转写和回放的人工验证。
|
|
111
|
+
|
|
112
|
+
布局回归验证:`node scripts/smoke-layout-browser.mjs <playwright/index.mjs 路径>`,使用 Chrome 无头浏览器运行真实插件产物,验证页面边界、弹窗居中、转写面板层级、窗口缩放与卸载后聊天恢复。使用合成录音状态,不访问业务数据、不采集声音。
|
|
113
|
+
|
|
114
|
+
设备切换:支持的桌面原生模块会在默认输出变化时重新连接系统采集,插件重新采样并替换默认麦克风输入,保留同一录音与转写连接。操作系统切换设备期间可能存在短暂音频缺口;持续无法恢复才报错暂停。
|
package/package.json
CHANGED
package/plugin-dist/client.js
CHANGED
|
@@ -30,7 +30,7 @@ module.exports = __toCommonJS(client_exports);
|
|
|
30
30
|
var define_import_meta_env_default = { VITE_XIN_PACKAGED: "1" };
|
|
31
31
|
|
|
32
32
|
// src/plugin/client.tsx
|
|
33
|
-
var
|
|
33
|
+
var import_react23 = require("react");
|
|
34
34
|
|
|
35
35
|
// node_modules/lucide-react/dist/esm/createLucideIcon.js
|
|
36
36
|
var import_react2 = require("react");
|
|
@@ -1606,6 +1606,117 @@ function toSegment(segment) {
|
|
|
1606
1606
|
return { id: segment.id, speaker: speakerLabel(segment.speakerId), text: segment.text, final: segment.final };
|
|
1607
1607
|
}
|
|
1608
1608
|
|
|
1609
|
+
// src/audio/microphone-switch.ts
|
|
1610
|
+
function followDefaultMicrophone(options) {
|
|
1611
|
+
let current = options.initial;
|
|
1612
|
+
let stopped = false;
|
|
1613
|
+
let running = false;
|
|
1614
|
+
let queued = false;
|
|
1615
|
+
let cancelAcquire;
|
|
1616
|
+
let cancelDelay;
|
|
1617
|
+
const delay = () => new Promise((resolve) => {
|
|
1618
|
+
const timer = setTimeout(() => {
|
|
1619
|
+
cancelDelay = void 0;
|
|
1620
|
+
resolve();
|
|
1621
|
+
}, 250);
|
|
1622
|
+
cancelDelay = () => {
|
|
1623
|
+
clearTimeout(timer);
|
|
1624
|
+
cancelDelay = void 0;
|
|
1625
|
+
resolve();
|
|
1626
|
+
};
|
|
1627
|
+
});
|
|
1628
|
+
const watch = (stream) => {
|
|
1629
|
+
stream.getAudioTracks().forEach((track) => {
|
|
1630
|
+
track.onended = () => {
|
|
1631
|
+
void reconnect();
|
|
1632
|
+
};
|
|
1633
|
+
});
|
|
1634
|
+
};
|
|
1635
|
+
const reconnect = async () => {
|
|
1636
|
+
if (stopped) return;
|
|
1637
|
+
if (running) {
|
|
1638
|
+
queued = true;
|
|
1639
|
+
return;
|
|
1640
|
+
}
|
|
1641
|
+
running = true;
|
|
1642
|
+
const began = Date.now();
|
|
1643
|
+
try {
|
|
1644
|
+
do {
|
|
1645
|
+
queued = false;
|
|
1646
|
+
try {
|
|
1647
|
+
const next = await new Promise((resolve, reject) => {
|
|
1648
|
+
let settled = false;
|
|
1649
|
+
const finishError = (error) => {
|
|
1650
|
+
if (settled) return;
|
|
1651
|
+
settled = true;
|
|
1652
|
+
clearTimeout(timer);
|
|
1653
|
+
cancelAcquire = void 0;
|
|
1654
|
+
reject(error);
|
|
1655
|
+
};
|
|
1656
|
+
const timer = setTimeout(() => finishError(new Error("Microphone recovery timed out")), Math.max(0, 8e3 - (Date.now() - began)));
|
|
1657
|
+
cancelAcquire = () => finishError(new Error("Recording stopped"));
|
|
1658
|
+
Promise.resolve().then(options.acquire).then((stream) => {
|
|
1659
|
+
if (settled || stopped) {
|
|
1660
|
+
stream.getTracks().forEach((track) => track.stop());
|
|
1661
|
+
return;
|
|
1662
|
+
}
|
|
1663
|
+
settled = true;
|
|
1664
|
+
clearTimeout(timer);
|
|
1665
|
+
cancelAcquire = void 0;
|
|
1666
|
+
resolve(stream);
|
|
1667
|
+
}, finishError);
|
|
1668
|
+
});
|
|
1669
|
+
if (stopped) {
|
|
1670
|
+
next.getTracks().forEach((track) => track.stop());
|
|
1671
|
+
return;
|
|
1672
|
+
}
|
|
1673
|
+
if (!next.getAudioTracks().some((track) => track.readyState === "live")) {
|
|
1674
|
+
next.getTracks().forEach((track) => track.stop());
|
|
1675
|
+
throw new Error("Microphone is not live");
|
|
1676
|
+
}
|
|
1677
|
+
const previous = current;
|
|
1678
|
+
try {
|
|
1679
|
+
options.replace(next, previous);
|
|
1680
|
+
} catch (error) {
|
|
1681
|
+
next.getTracks().forEach((track) => track.stop());
|
|
1682
|
+
throw error;
|
|
1683
|
+
}
|
|
1684
|
+
current = next;
|
|
1685
|
+
previous.getTracks().forEach((track) => {
|
|
1686
|
+
track.onended = null;
|
|
1687
|
+
track.stop();
|
|
1688
|
+
});
|
|
1689
|
+
watch(current);
|
|
1690
|
+
} catch {
|
|
1691
|
+
if (stopped) return;
|
|
1692
|
+
if (Date.now() - began >= 8e3) {
|
|
1693
|
+
if (!current.getAudioTracks().some((track) => track.readyState === "live")) options.failed();
|
|
1694
|
+
return;
|
|
1695
|
+
}
|
|
1696
|
+
await delay();
|
|
1697
|
+
queued = true;
|
|
1698
|
+
}
|
|
1699
|
+
} while (queued && !stopped);
|
|
1700
|
+
} finally {
|
|
1701
|
+
running = false;
|
|
1702
|
+
}
|
|
1703
|
+
};
|
|
1704
|
+
const changed = () => {
|
|
1705
|
+
void reconnect();
|
|
1706
|
+
};
|
|
1707
|
+
watch(current);
|
|
1708
|
+
options.devices.addEventListener?.("devicechange", changed);
|
|
1709
|
+
return () => {
|
|
1710
|
+
stopped = true;
|
|
1711
|
+
cancelDelay?.();
|
|
1712
|
+
cancelAcquire?.();
|
|
1713
|
+
options.devices.removeEventListener?.("devicechange", changed);
|
|
1714
|
+
current.getTracks().forEach((track) => {
|
|
1715
|
+
track.onended = null;
|
|
1716
|
+
});
|
|
1717
|
+
};
|
|
1718
|
+
}
|
|
1719
|
+
|
|
1609
1720
|
// src/audio/worklet-source.ts
|
|
1610
1721
|
var captureWorkletSource = `
|
|
1611
1722
|
class LingtingCaptureProcessor extends AudioWorkletProcessor {
|
|
@@ -1691,7 +1802,7 @@ class NativeSystemSource extends AudioWorkletProcessor {
|
|
|
1691
1802
|
accept(data) {
|
|
1692
1803
|
if (this.failed) return;
|
|
1693
1804
|
if (!data || !(data.samples instanceof Float32Array) || !Number.isFinite(data.sampleRate) || data.sampleRate < 8000 || data.sampleRate > 192000) return;
|
|
1694
|
-
if (this.rate && this.rate !== data.sampleRate) { this.
|
|
1805
|
+
if (this.rate && this.rate !== data.sampleRate) { this.read = 0; this.write = 0; this.started = false; this.buffer.fill(0); }
|
|
1695
1806
|
this.rate = data.sampleRate;
|
|
1696
1807
|
// Bound latency, not just memory. After a render stall, retain the newest
|
|
1697
1808
|
// 100 ms instead of spending minutes playing stale audio or killing capture.
|
|
@@ -1784,6 +1895,7 @@ var MeetingCapture = class {
|
|
|
1784
1895
|
emitting = false;
|
|
1785
1896
|
stopSystem = null;
|
|
1786
1897
|
systemNode = null;
|
|
1898
|
+
stopMicrophoneSwitch = null;
|
|
1787
1899
|
async start(onChunk, onError) {
|
|
1788
1900
|
if (this.context || this.starting) throw new Error("\u91C7\u96C6\u5DF2\u5728\u8FDB\u884C\u4E2D\u3002");
|
|
1789
1901
|
this.starting = true;
|
|
@@ -1822,7 +1934,6 @@ var MeetingCapture = class {
|
|
|
1822
1934
|
for (const stream of this.streams) {
|
|
1823
1935
|
for (const track of stream.getAudioTracks()) {
|
|
1824
1936
|
if (track.readyState !== "live") throw new Error("\u97F3\u9891\u8BBE\u5907\u5DF2\u65AD\u5F00\uFF0C\u8BF7\u91CD\u65B0\u5F00\u59CB\u5F55\u97F3\u3002");
|
|
1825
|
-
track.onended = () => fail(stream === microphone ? "\u9EA6\u514B\u98CE\u5DF2\u65AD\u5F00\uFF0C\u5F55\u97F3\u5DF2\u6682\u505C\uFF0C\u8BF7\u68C0\u67E5\u8BBE\u5907\u540E\u7EE7\u7EED\u3002" : "\u7CFB\u7EDF\u58F0\u97F3\u91C7\u96C6\u5DF2\u505C\u6B62\uFF0C\u5F55\u97F3\u5DF2\u6682\u505C\uFF0C\u8BF7\u91CD\u65B0\u6388\u6743\u540E\u7EE7\u7EED\u3002");
|
|
1826
1937
|
}
|
|
1827
1938
|
}
|
|
1828
1939
|
const context = new AudioContext();
|
|
@@ -1836,7 +1947,7 @@ var MeetingCapture = class {
|
|
|
1836
1947
|
return;
|
|
1837
1948
|
}
|
|
1838
1949
|
stalledSince ??= Date.now();
|
|
1839
|
-
if (Date.now() - stalledSince >=
|
|
1950
|
+
if (Date.now() - stalledSince >= 8e3) {
|
|
1840
1951
|
fail("\u97F3\u9891\u5904\u7406\u6062\u590D\u8D85\u65F6\uFF0C\u8BF7\u91CD\u65B0\u5F00\u59CB\u5F55\u97F3\u3002");
|
|
1841
1952
|
return;
|
|
1842
1953
|
}
|
|
@@ -1846,7 +1957,8 @@ var MeetingCapture = class {
|
|
|
1846
1957
|
return;
|
|
1847
1958
|
}
|
|
1848
1959
|
recovering = true;
|
|
1849
|
-
void context.resume().catch(() =>
|
|
1960
|
+
void context.resume().catch(() => {
|
|
1961
|
+
}).finally(() => {
|
|
1850
1962
|
recovering = false;
|
|
1851
1963
|
});
|
|
1852
1964
|
};
|
|
@@ -1924,6 +2036,24 @@ var MeetingCapture = class {
|
|
|
1924
2036
|
this.nodes.push(source, analyser, gain);
|
|
1925
2037
|
analysers.push(analyser);
|
|
1926
2038
|
}
|
|
2039
|
+
this.stopMicrophoneSwitch = followDefaultMicrophone({
|
|
2040
|
+
devices,
|
|
2041
|
+
initial: microphone,
|
|
2042
|
+
acquire: () => devices.getUserMedia({ audio: { channelCount: 1, echoCancellation: true, noiseSuppression: true, autoGainControl: true } }),
|
|
2043
|
+
replace: (next, previous) => {
|
|
2044
|
+
if (generation !== this.generation) throw new Error("\u5F55\u97F3\u5DF2\u53D6\u6D88\u3002");
|
|
2045
|
+
const replacement = context.createMediaStreamSource(next);
|
|
2046
|
+
replacement.connect(analysers[0]);
|
|
2047
|
+
const oldSource = sources[0];
|
|
2048
|
+
oldSource.disconnect();
|
|
2049
|
+
sources[0] = replacement;
|
|
2050
|
+
this.nodes = this.nodes.filter((item) => item !== oldSource);
|
|
2051
|
+
this.nodes.push(replacement);
|
|
2052
|
+
this.streams = this.streams.filter((item) => item !== previous);
|
|
2053
|
+
this.streams.push(next);
|
|
2054
|
+
},
|
|
2055
|
+
failed: () => fail("\u9EA6\u514B\u98CE\u5207\u6362\u540E\u672A\u80FD\u6062\u590D\uFF0C\u5F55\u97F3\u5DF2\u6682\u505C\uFF0C\u8BF7\u68C0\u67E5\u8BBE\u5907\u8FDE\u63A5\u3002")
|
|
2056
|
+
});
|
|
1927
2057
|
const mute = context.createGain();
|
|
1928
2058
|
mute.gain.value = 0;
|
|
1929
2059
|
node.connect(mute);
|
|
@@ -1970,6 +2100,8 @@ var MeetingCapture = class {
|
|
|
1970
2100
|
}
|
|
1971
2101
|
async stop() {
|
|
1972
2102
|
++this.generation;
|
|
2103
|
+
this.stopMicrophoneSwitch?.();
|
|
2104
|
+
this.stopMicrophoneSwitch = null;
|
|
1973
2105
|
this.emitting = false;
|
|
1974
2106
|
if (this.timer) clearInterval(this.timer);
|
|
1975
2107
|
this.timer = null;
|
|
@@ -5419,11 +5551,72 @@ function createBusinessNavigation() {
|
|
|
5419
5551
|
};
|
|
5420
5552
|
}
|
|
5421
5553
|
|
|
5554
|
+
// src/plugin/business-surface.tsx
|
|
5555
|
+
var import_react22 = require("react");
|
|
5556
|
+
var import_react_dom = require("react-dom");
|
|
5557
|
+
function mountBusinessSurface(doc) {
|
|
5558
|
+
const conversation = doc.querySelector('[data-slot="conversation"]');
|
|
5559
|
+
const center = conversation?.parentElement;
|
|
5560
|
+
if (!conversation || !center) return null;
|
|
5561
|
+
const target = doc.createElement("section");
|
|
5562
|
+
target.className = "lt-business-surface";
|
|
5563
|
+
target.setAttribute("aria-label", "\u7075\u542C");
|
|
5564
|
+
const display = conversation.style.getPropertyValue("display");
|
|
5565
|
+
const displayPriority = conversation.style.getPropertyPriority("display");
|
|
5566
|
+
const position = center.style.getPropertyValue("position");
|
|
5567
|
+
const positionPriority = center.style.getPropertyPriority("position");
|
|
5568
|
+
const inert = conversation.inert;
|
|
5569
|
+
conversation.style.setProperty("display", "none", "important");
|
|
5570
|
+
conversation.inert = true;
|
|
5571
|
+
center.style.setProperty("position", "relative");
|
|
5572
|
+
center.appendChild(target);
|
|
5573
|
+
let disposed = false;
|
|
5574
|
+
return { target, dispose() {
|
|
5575
|
+
if (disposed) return;
|
|
5576
|
+
disposed = true;
|
|
5577
|
+
target.remove();
|
|
5578
|
+
if (display) conversation.style.setProperty("display", display, displayPriority);
|
|
5579
|
+
else conversation.style.removeProperty("display");
|
|
5580
|
+
conversation.inert = inert;
|
|
5581
|
+
if (position) center.style.setProperty("position", position, positionPriority);
|
|
5582
|
+
else center.style.removeProperty("position");
|
|
5583
|
+
} };
|
|
5584
|
+
}
|
|
5585
|
+
function BusinessSurface({ children, onClose }) {
|
|
5586
|
+
const [target, setTarget] = (0, import_react22.useState)(null);
|
|
5587
|
+
(0, import_react22.useLayoutEffect)(() => {
|
|
5588
|
+
let mounted = null;
|
|
5589
|
+
const attach = () => {
|
|
5590
|
+
if (mounted?.target.isConnected) return;
|
|
5591
|
+
mounted?.dispose();
|
|
5592
|
+
mounted = mountBusinessSurface(document);
|
|
5593
|
+
setTarget(mounted?.target ?? null);
|
|
5594
|
+
};
|
|
5595
|
+
attach();
|
|
5596
|
+
const onSidebarClick = (event) => {
|
|
5597
|
+
const element = event.target instanceof Element ? event.target : null;
|
|
5598
|
+
const button = element?.closest("button");
|
|
5599
|
+
if (!button?.closest('[data-slot="sidebar"]')) return;
|
|
5600
|
+
const label = button.getAttribute("aria-label")?.trim();
|
|
5601
|
+
if (label && /^(新会话|新建会话|New session)$/i.test(label)) onClose();
|
|
5602
|
+
};
|
|
5603
|
+
document.addEventListener("click", onSidebarClick, true);
|
|
5604
|
+
const observer = new MutationObserver(attach);
|
|
5605
|
+
observer.observe(document.body, { childList: true, subtree: true });
|
|
5606
|
+
return () => {
|
|
5607
|
+
document.removeEventListener("click", onSidebarClick, true);
|
|
5608
|
+
observer.disconnect();
|
|
5609
|
+
mounted?.dispose();
|
|
5610
|
+
};
|
|
5611
|
+
}, []);
|
|
5612
|
+
return target ? (0, import_react_dom.createPortal)(children, target) : null;
|
|
5613
|
+
}
|
|
5614
|
+
|
|
5422
5615
|
// src/plugin/embedded.css
|
|
5423
5616
|
var tag3 = document.createElement("style");
|
|
5424
5617
|
tag3.dataset.plugin = "dsh-xrxs-lingting";
|
|
5425
5618
|
tag3.dataset.pluginCss = "dsh-xrxs-lingting/embedded.css";
|
|
5426
|
-
tag3.textContent = ".lingting-root { color-scheme: light; }\n/* Host \u9002\u914D\u5C42\u72B6\u6001\u63D0\u793A\uFF08\u6388\u6743/\u8EAB\u4EFD/\u76EE\u7684\u5730\u672A\u5C31\u7EEA\uFF09\uFF1A\u56FA\u5B9A\u9876\u90E8\uFF0C\u53EF\u5173\u95ED\uFF0C\u4E0D\u53C2\u4E0E\u9875\u9762\u5E03\u5C40 */\n.lt-host-notice { position: fixed; top: 12px; left: 50%; transform: translateX(-50%); z-index: 60; display: flex; align-items: center; gap: 12px; max-width: min(680px, calc(100vw - 32px)); padding: 10px 14px; border: 1px solid #e7e0fa; border-radius: 10px; background: #fff; box-shadow: 0 6px 24px rgb(40 28 74 / 16%); color: #605972; font-size: 13px; line-height: 1.5; }\n.lt-host-notice-text { flex: 1; }\n.lt-host-notice-close { flex-shrink: 0; border: 0; background: transparent; color: inherit; font-size: 16px; line-height: 1; padding: 2px 4px; border-radius: 6px; cursor: pointer; }\n.lt-host-notice-close:hover { background: #6650d814; }\n.lt-host-notice-close:focus-visible { outline: 2px solid #6650d8; outline-offset: 2px; }\n/* \u5D4C\u5165\u6A21\u5F0F\u4E0B\u6839\u5143\u7D20\u5373 .app\uFF08lingting-root app \u540C\u5143\u7D20\uFF09\uFF0C\u89C4\u5219\u9700\u7528\u7EC4\u5408\u9009\u62E9\u5668\uFF1B\u4FDD\u7559\u540E\u4EE3\u5F62\u5F0F\u517C\u5BB9\u53CC\u5C42\u5305\u88F9\u7ED3\u6784 */\n.lingting-root[data-embedded] { height: 100%; min-height: 0; container-type: inline-size; }\n.lingting-root[data-embedded].app, .lingting-root[data-embedded] .app { height: 100%; min-height: 0; display: flex; flex-direction: column; overflow: hidden; position: relative; padding-bottom: 0; }\n.lingting-root[data-embedded].app .app-header, .lingting-root[data-embedded] .app-header { height: 66px; flex-shrink: 0; }\n.lingting-root[data-embedded].app .header-inner, .lingting-root[data-embedded] .header-inner { padding: 0 28px; max-width: none; }\n.lingting-root[data-embedded].app .brand-caption, .lingting-root[data-embedded] .brand-caption { display: none; }\n.lingting-root[data-embedded].app .main-content, .lingting-root[data-embedded] .main-content { width: 100%; max-width: none; min-height: 0; flex: 1; overflow: auto; padding: 30px 28px 0; scrollbar-width: thin; }\n\n.lingting-root[data-embedded].app .toast, .lingting-root[data-embedded] .toast { position: absolute; top: 77px; }\n.lingting-root[data-global-status] { flex-shrink: 0; border-top: 1px solid #e7e0fa; background: white; padding: 0 24px; }\n.lingting-root[data-global-status] .recording-controls.compact { min-height: 76px; padding: 12px 0; }\n.lingting-root[data-global-status] .error-notice { margin: 8px 0 0; }\n.lingting-sidebar-entry { display: flex; align-items: center; gap: 10px; border: 0; background: transparent; color: var(--dsw-alias-text-primary, #605972); padding: 10px 12px; width: 100%; border-radius: 9px; cursor: pointer; font: inherit; font-size: 14px; }\n.lingting-sidebar-entry:hover, .lingting-sidebar-entry[data-active] { background: #6650d814; color: #6650d8; }\n.lingting-sidebar-entry:focus-visible { outline: 2px solid #6650d8; outline-offset: 2px; }\n@container (max-width: 900px) {\n .lingting-root[data-embedded] .overview-note { display: none; }\n .lingting-root[data-embedded] .overview { grid-template-columns: 1fr 1fr; }\n .lingting-root[data-embedded] .list-heading { flex-wrap: wrap; }\n .lingting-root[data-embedded] .source-label { display: none; }\n}\n\n/*
|
|
5619
|
+
tag3.textContent = ".lingting-root { color-scheme: light; }\n/* Host \u9002\u914D\u5C42\u72B6\u6001\u63D0\u793A\uFF08\u6388\u6743/\u8EAB\u4EFD/\u76EE\u7684\u5730\u672A\u5C31\u7EEA\uFF09\uFF1A\u56FA\u5B9A\u9876\u90E8\uFF0C\u53EF\u5173\u95ED\uFF0C\u4E0D\u53C2\u4E0E\u9875\u9762\u5E03\u5C40 */\n.lt-host-notice { position: fixed; top: 12px; left: 50%; transform: translateX(-50%); z-index: 60; display: flex; align-items: center; gap: 12px; max-width: min(680px, calc(100vw - 32px)); padding: 10px 14px; border: 1px solid #e7e0fa; border-radius: 10px; background: #fff; box-shadow: 0 6px 24px rgb(40 28 74 / 16%); color: #605972; font-size: 13px; line-height: 1.5; }\n.lt-host-notice-text { flex: 1; }\n.lt-host-notice-close { flex-shrink: 0; border: 0; background: transparent; color: inherit; font-size: 16px; line-height: 1; padding: 2px 4px; border-radius: 6px; cursor: pointer; }\n.lt-host-notice-close:hover { background: #6650d814; }\n.lt-host-notice-close:focus-visible { outline: 2px solid #6650d8; outline-offset: 2px; }\n/* \u5D4C\u5165\u6A21\u5F0F\u4E0B\u6839\u5143\u7D20\u5373 .app\uFF08lingting-root app \u540C\u5143\u7D20\uFF09\uFF0C\u89C4\u5219\u9700\u7528\u7EC4\u5408\u9009\u62E9\u5668\uFF1B\u4FDD\u7559\u540E\u4EE3\u5F62\u5F0F\u517C\u5BB9\u53CC\u5C42\u5305\u88F9\u7ED3\u6784 */\n.lingting-root[data-embedded] { height: 100%; min-height: 0; container-type: inline-size; }\n.lingting-root[data-embedded].app, .lingting-root[data-embedded] .app { height: 100%; min-height: 0; display: flex; flex-direction: column; overflow: hidden; position: relative; padding-bottom: 0; }\n.lingting-root[data-embedded].app .app-header, .lingting-root[data-embedded] .app-header { height: 66px; flex-shrink: 0; }\n.lingting-root[data-embedded].app .header-inner, .lingting-root[data-embedded] .header-inner { padding: 0 28px; max-width: none; }\n.lingting-root[data-embedded].app .brand-caption, .lingting-root[data-embedded] .brand-caption { display: none; }\n.lingting-root[data-embedded].app .main-content, .lingting-root[data-embedded] .main-content { width: 100%; max-width: none; min-height: 0; flex: 1; overflow: auto; padding: 30px 28px 0; scrollbar-width: thin; }\n\n.lingting-root[data-embedded].app .toast, .lingting-root[data-embedded] .toast { position: absolute; top: 77px; }\n.lingting-root[data-global-status] { flex-shrink: 0; border-top: 1px solid #e7e0fa; background: white; padding: 0 24px; }\n.lingting-root[data-global-status] .recording-controls.compact { min-height: 76px; padding: 12px 0; }\n.lingting-root[data-global-status] .error-notice { margin: 8px 0 0; }\n.lingting-sidebar-entry { display: flex; align-items: center; gap: 10px; border: 0; background: transparent; color: var(--dsw-alias-text-primary, #605972); padding: 10px 12px; width: 100%; border-radius: 9px; cursor: pointer; font: inherit; font-size: 14px; }\n.lingting-sidebar-entry:hover, .lingting-sidebar-entry[data-active] { background: #6650d814; color: #6650d8; }\n.lingting-sidebar-entry:focus-visible { outline: 2px solid #6650d8; outline-offset: 2px; }\n@container (max-width: 900px) {\n .lingting-root[data-embedded] .overview-note { display: none; }\n .lingting-root[data-embedded] .overview { grid-template-columns: 1fr 1fr; }\n .lingting-root[data-embedded] .list-heading { flex-wrap: wrap; }\n .lingting-root[data-embedded] .source-label { display: none; }\n}\n\n/* Use the real center column, preserving the host sidebar and conversation state. */\n.lt-business-surface { position: absolute; inset: 0; z-index: 1; min-width: 0; overflow: hidden; background: #f8f9fc; pointer-events: auto; -webkit-app-region: no-drag; }\n/* Host reset styles must not remove the native dialog's centered placement. */\n.lingting-root .modal { margin: auto; background: #fff; }\n";
|
|
5427
5620
|
document.querySelectorAll("style[data-plugin-css=" + JSON.stringify("dsh-xrxs-lingting/embedded.css") + "]").forEach((old) => old.remove());
|
|
5428
5621
|
document.head.appendChild(tag3);
|
|
5429
5622
|
|
|
@@ -5431,7 +5624,7 @@ document.head.appendChild(tag3);
|
|
|
5431
5624
|
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
5432
5625
|
var ID = "dsh-xrxs-lingting";
|
|
5433
5626
|
var inject = ["slots", "layout"];
|
|
5434
|
-
var PanelBoundary = class extends
|
|
5627
|
+
var PanelBoundary = class extends import_react23.Component {
|
|
5435
5628
|
state = { failed: false };
|
|
5436
5629
|
static getDerivedStateFromError() {
|
|
5437
5630
|
return { failed: true };
|
|
@@ -5472,8 +5665,8 @@ async function apply(ctx) {
|
|
|
5472
5665
|
}));
|
|
5473
5666
|
const unregisterPage = business.register(ID);
|
|
5474
5667
|
function Entry({ wide }) {
|
|
5475
|
-
const panel = (0,
|
|
5476
|
-
const layout = (0,
|
|
5668
|
+
const panel = (0, import_react23.useSyncExternalStore)(controller.subscribe, controller.getSnapshot);
|
|
5669
|
+
const layout = (0, import_react23.useSyncExternalStore)(business.subscribe, business.getSnapshot);
|
|
5477
5670
|
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("button", { type: "button", className: "lingting-sidebar-entry", "data-active": layout.activeId === ID || panel.open || void 0, title: "\u7075\u542C", "aria-label": "\u7075\u542C", onClick: () => business.open(ID), children: [
|
|
5478
5671
|
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Headphones, { size: 19 }),
|
|
5479
5672
|
wide && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { children: "\u7075\u542C" })
|
|
@@ -5483,9 +5676,9 @@ async function apply(ctx) {
|
|
|
5483
5676
|
return activeId === ID ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(PanelBoundary, { children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(LingtingApp, { service, navigation, visible: true, embedded: true, hostState, onBackToHost: () => business.close(), onOpenLive: () => controller.open(), onOpenRecord: (id) => controller.openRecord(id) }) }) : null;
|
|
5484
5677
|
}
|
|
5485
5678
|
function Overlay() {
|
|
5486
|
-
const page = (0,
|
|
5679
|
+
const page = (0, import_react23.useSyncExternalStore)(business.subscribe, business.getSnapshot, business.getSnapshot);
|
|
5487
5680
|
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
|
|
5488
|
-
!hostBusiness && page.activeId === ID && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
5681
|
+
!hostBusiness && page.activeId === ID && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(BusinessSurface, { onClose: () => business.close(), children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Page, { activeId: page.activeId }) }),
|
|
5489
5682
|
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(PanelBoundary, { children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(XinHostNotice, { store: hostState }) }),
|
|
5490
5683
|
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(PanelBoundary, { children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(LingtingSidebar, { service, controller, onOpenPage: () => business.open(ID) }) }),
|
|
5491
5684
|
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(PanelBoundary, { children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(MeetingPrompt, { service }) })
|