@clowder-ai/companion 0.1.0-alpha.31 → 0.1.0-alpha.32
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/manifest.json +2 -2
- package/package.json +1 -1
- package/plugin.yaml +2 -2
- package/renderer/app-assist-controller.mjs +2 -1
- package/renderer/app-assist-countdown.mjs +16 -0
- package/renderer/index.html +4 -0
- package/renderer/style.css +10 -1
- package/renderer/surface.mjs +3 -0
package/manifest.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"pluginId": "official.companion",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.32",
|
|
4
4
|
"contractVersion": "0.1.0",
|
|
5
5
|
"name": "猫猫球",
|
|
6
6
|
"icon": {
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"bridgeVersion": "1.6.0",
|
|
41
41
|
"surface": {
|
|
42
42
|
"entrypoint": "renderer/index.html",
|
|
43
|
-
"integrity": "sha256-
|
|
43
|
+
"integrity": "sha256-0OpVp+p2y+xDJduVuzWZf48TNLBnWZZfq/TuGe0joyY="
|
|
44
44
|
},
|
|
45
45
|
"presentation": {
|
|
46
46
|
"width": 300,
|
package/package.json
CHANGED
package/plugin.yaml
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"pluginId": "official.companion",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.32",
|
|
4
4
|
"contractVersion": "0.1.0",
|
|
5
5
|
"name": "猫猫球",
|
|
6
6
|
"icon": {
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"bridgeVersion": "1.6.0",
|
|
41
41
|
"surface": {
|
|
42
42
|
"entrypoint": "renderer/index.html",
|
|
43
|
-
"integrity": "sha256-
|
|
43
|
+
"integrity": "sha256-0OpVp+p2y+xDJduVuzWZf48TNLBnWZZfq/TuGe0joyY="
|
|
44
44
|
},
|
|
45
45
|
"presentation": {
|
|
46
46
|
"width": 300,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const ACTIONS = new Set(['dismiss', 'timeout', 'accept']);
|
|
2
|
+
export const APP_ASSIST_TIMEOUT_MS = 15_000;
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* Renderer projection only. The Host owns offer creation, expiry and clearing;
|
|
@@ -12,7 +13,7 @@ export class AppAssistController {
|
|
|
12
13
|
accepted = () => {},
|
|
13
14
|
scheduleTimeout = setTimeout,
|
|
14
15
|
cancelTimeout = clearTimeout,
|
|
15
|
-
timeoutMs =
|
|
16
|
+
timeoutMs = APP_ASSIST_TIMEOUT_MS,
|
|
16
17
|
}) {
|
|
17
18
|
this.client = client;
|
|
18
19
|
this.changed = changed;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { APP_ASSIST_TIMEOUT_MS } from './app-assist-controller.mjs';
|
|
2
|
+
|
|
3
|
+
/** Projects the existing renderer deadline without owning or extending it. */
|
|
4
|
+
export function bindAppAssistCountdown(element, durationMs = APP_ASSIST_TIMEOUT_MS) {
|
|
5
|
+
let offerRef = null;
|
|
6
|
+
element.style.setProperty('--app-assist-duration', `${durationMs}ms`);
|
|
7
|
+
return offer => {
|
|
8
|
+
const nextRef = offer?.offerRef ?? null;
|
|
9
|
+
if (nextRef === offerRef) return;
|
|
10
|
+
offerRef = nextRef;
|
|
11
|
+
element.removeAttribute('data-active');
|
|
12
|
+
if (!nextRef) return;
|
|
13
|
+
void element.getBoundingClientRect?.();
|
|
14
|
+
element.setAttribute('data-active', 'true');
|
|
15
|
+
};
|
|
16
|
+
}
|
package/renderer/index.html
CHANGED
|
@@ -48,6 +48,10 @@
|
|
|
48
48
|
<p id="bubble-first" hidden></p><p id="bubble-second" hidden></p>
|
|
49
49
|
</section>
|
|
50
50
|
<section id="app-assist" class="floating app-assist" aria-label="应用旁的轻提示" data-candidate="true" hidden>
|
|
51
|
+
<svg id="app-assist-countdown" class="app-assist-countdown" viewBox="0 0 20 20" role="img" aria-label="提示将在约十五秒后自动收起">
|
|
52
|
+
<circle class="app-assist-countdown-track" cx="10" cy="10" r="7.5" pathLength="1"/>
|
|
53
|
+
<circle id="app-assist-countdown-progress" cx="10" cy="10" r="7.5" pathLength="1"/>
|
|
54
|
+
</svg>
|
|
51
55
|
<p>你打开了 <strong id="app-assist-name"></strong>。要我一起看吗?</p>
|
|
52
56
|
<div><button id="app-assist-dismiss" type="button">暂不</button><button id="app-assist-start" class="primary" type="button">打开通话控制</button></div>
|
|
53
57
|
</section>
|
package/renderer/style.css
CHANGED
|
@@ -79,10 +79,19 @@ button:disabled { opacity: .45; cursor: default; }
|
|
|
79
79
|
#bubble p + p { margin-top: 4px; }
|
|
80
80
|
#bubble [data-role="user"] { color: var(--cafe-text-secondary); }
|
|
81
81
|
.app-assist { width: 320px; padding: 12px; }
|
|
82
|
-
.app-assist p { margin: 0; color: var(--desktop-body); font-size: 13px; line-height: 1.5; }
|
|
82
|
+
.app-assist p { margin: 0; padding-right: 22px; color: var(--desktop-body); font-size: 13px; line-height: 1.5; }
|
|
83
83
|
.app-assist p strong { color: var(--desktop-ink); font-weight: 600; }
|
|
84
84
|
.app-assist > div { display: flex; justify-content: flex-end; gap: 6px; margin-top: 9px; }
|
|
85
85
|
.app-assist > div button { min-height: 30px; padding: 5px 10px; font-size: 12px; }
|
|
86
|
+
.app-assist-countdown { position: absolute; top: 10px; right: 10px; width: 16px; height: 16px; overflow: visible; transform: rotate(-90deg); }
|
|
87
|
+
.app-assist-countdown circle { fill: none; stroke-width: 2; }
|
|
88
|
+
.app-assist-countdown-track { stroke: var(--desktop-line-strong); }
|
|
89
|
+
#app-assist-countdown-progress { stroke: var(--desktop-muted); stroke-linecap: round; stroke-dasharray: 1; stroke-dashoffset: 0; }
|
|
90
|
+
.app-assist-countdown[data-active="true"] #app-assist-countdown-progress { animation: app-assist-expiry var(--app-assist-duration) linear forwards; }
|
|
91
|
+
@keyframes app-assist-expiry { to { stroke-dashoffset: 1; } }
|
|
92
|
+
@media (prefers-reduced-motion: reduce) {
|
|
93
|
+
.app-assist-countdown[data-active="true"] #app-assist-countdown-progress { animation-timing-function: steps(15, end); }
|
|
94
|
+
}
|
|
86
95
|
#call-bubble { width: 320px; max-height: 80px; overflow: hidden; padding: 9px 11px; pointer-events: none; }
|
|
87
96
|
#call-bubble:not(:has(p:not([hidden]))) { display: none; }
|
|
88
97
|
#call-bubble p { margin: 0; display: flex; min-width: 0; overflow: hidden; white-space: nowrap; font-size: 12px; line-height: 1.45; }
|
package/renderer/surface.mjs
CHANGED
|
@@ -24,6 +24,7 @@ import { ConversationSurface } from './conversation-surface.mjs';
|
|
|
24
24
|
import { CallControlsPresentation } from './call-controls-presentation.mjs';
|
|
25
25
|
import { CallDuration } from './call-duration.mjs';
|
|
26
26
|
import { AppAssistController } from './app-assist-controller.mjs';
|
|
27
|
+
import { bindAppAssistCountdown } from './app-assist-countdown.mjs';
|
|
27
28
|
const $ = id => document.getElementById(id);
|
|
28
29
|
const label = (id, text) => { $(id).querySelector('.label').textContent = text; };
|
|
29
30
|
const status = text => {
|
|
@@ -61,6 +62,7 @@ let previousControlPanel = 'none';
|
|
|
61
62
|
const ambientPanel = active => active ? 'actions' : appAssistOffer ? 'app-assist' : 'none';
|
|
62
63
|
const setTexts = (ids, text) => { for (const id of ids) $(id).textContent = text; };
|
|
63
64
|
const setHidden = (ids, hidden) => { for (const id of ids) $(id).hidden = hidden; };
|
|
65
|
+
const renderAppAssistCountdown = bindAppAssistCountdown($('app-assist-countdown'));
|
|
64
66
|
if (!window.clowderCompanion) {
|
|
65
67
|
$('actions').hidden = false; $('status').hidden = false;
|
|
66
68
|
status('请从 Clowder 的聊聊入口打开猫猫球');
|
|
@@ -144,6 +146,7 @@ if (!window.clowderCompanion) {
|
|
|
144
146
|
changed: value => {
|
|
145
147
|
appAssistOffer = value.offer;
|
|
146
148
|
$('app-assist-name').textContent = appAssistOffer?.appName ?? '';
|
|
149
|
+
renderAppAssistCountdown(appAssistOffer);
|
|
147
150
|
void controls.setAmbient(ambientPanel(previousPhase !== 'idle'));
|
|
148
151
|
},
|
|
149
152
|
accepted: () => {
|