@olares/lares-mobile 0.15.5 → 0.15.7
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 +6 -2
- package/package.json +2 -2
- package/src/App.vue +918 -178
- package/src/chat/ChatBar.vue +2 -2
- package/src/chat/Composer.vue +467 -16
- package/src/chat/Deliverables.vue +22 -10
- package/src/chat/HistoryPanel.vue +747 -55
- package/src/chat/MessageActions.vue +88 -34
- package/src/chat/QuestionCard.vue +5 -5
- package/src/chat/StageRow.vue +8 -5
- package/src/chat/Transcript.vue +20 -6
- package/src/chat/composer-tokens.js +32 -0
- package/src/chat/format.js +37 -0
- package/src/desktop/DesktopComposer.vue +942 -0
- package/src/desktop/DesktopContextMeter.vue +81 -0
- package/src/desktop/DesktopGoal.vue +88 -0
- package/src/desktop/DesktopPreview.vue +58 -0
- package/src/desktop/DesktopPreviewTabs.vue +82 -0
- package/src/desktop/DesktopQuestions.vue +118 -0
- package/src/desktop/DesktopQueue.vue +203 -0
- package/src/desktop/DesktopShell.vue +229 -0
- package/src/desktop/DesktopSidebar.vue +645 -0
- package/src/desktop/DesktopTodos.vue +52 -0
- package/src/desktop/DirectoryBrowser.vue +231 -0
- package/src/desktop/DirectoryNewFolder.vue +124 -0
- package/src/desktop/ui/PcDialog.vue +100 -0
- package/src/desktop/ui/PcPopover.vue +110 -0
- package/src/desktop/ui/PcTooltip.vue +95 -0
- package/src/desktop/ui/place.js +24 -0
- package/src/desktop/workspace-view.js +121 -0
- package/src/host.js +20 -2
- package/src/index.d.ts +2 -0
- package/src/mobile/MobileDirectoryNewFolder.vue +121 -0
- package/src/mobile/MobileDirectorySheet.vue +162 -0
- package/src/mobile/MobileNewSession.vue +217 -0
- package/src/mobile/MobileShell.vue +367 -0
- package/src/motion.css +166 -0
- package/src/preview/Preview.vue +91 -150
- package/src/preview/PreviewBody.vue +185 -0
- package/src/settings/AgentSettings.vue +126 -36
- package/src/settings/Select.vue +183 -0
- package/src/settings/SettingRow.vue +5 -4
- package/src/settings/Sheet.vue +4 -4
- package/src/styles.css +9 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div class="lares-agent" :aria-busy="loading ? 'true' : 'false'">
|
|
2
|
+
<div class="lares-agent" :data-device="layoutDevice" :aria-busy="loading ? 'true' : 'false'">
|
|
3
3
|
<div v-if="loading" class="lares-agent__loading" role="status">
|
|
4
4
|
<span class="lares-agent__spinner" aria-hidden="true" />
|
|
5
5
|
<p>{{ t("agent.loading") }}</p>
|
|
@@ -7,7 +7,15 @@
|
|
|
7
7
|
<div class="lares-agent__body" :inert="loading || undefined">
|
|
8
8
|
<section class="lares-agent__group">
|
|
9
9
|
<h2>{{ tModel("settings.title") }}</h2>
|
|
10
|
-
<
|
|
10
|
+
<LaresSelect
|
|
11
|
+
v-if="isDesktop"
|
|
12
|
+
:value="modelCurrent"
|
|
13
|
+
:sections="modelSelectSections"
|
|
14
|
+
:disabled="busy || !models"
|
|
15
|
+
:empty="tModel('settings.empty')"
|
|
16
|
+
@select="(item) => pick(item, 'model')"
|
|
17
|
+
/>
|
|
18
|
+
<div v-else class="lares-agent__list">
|
|
11
19
|
<LaresSettingRow
|
|
12
20
|
:label="tModel('settings.default')"
|
|
13
21
|
:value="modelLabel"
|
|
@@ -22,6 +30,17 @@
|
|
|
22
30
|
</p>
|
|
23
31
|
<p v-if="modelError" class="lares-agent__hint" data-status="error">{{ modelError }}</p>
|
|
24
32
|
</section>
|
|
33
|
+
<section v-if="isDesktop" class="lares-agent__group">
|
|
34
|
+
<h2>{{ t("settings.input.title") }}</h2>
|
|
35
|
+
<LaresSelect
|
|
36
|
+
:value="conversation?.busyEnter || 'queue'"
|
|
37
|
+
:sections="busyEnterSections"
|
|
38
|
+
:disabled="busy || !conversation?.writable"
|
|
39
|
+
@select="chooseBusyEnter"
|
|
40
|
+
/>
|
|
41
|
+
<p class="lares-agent__hint">{{ t("settings.input.busyEnter.hint") }}</p>
|
|
42
|
+
<p v-if="conversationError" class="lares-agent__hint" data-status="error">{{ conversationError }}</p>
|
|
43
|
+
</section>
|
|
25
44
|
<!-- Voice input parked.
|
|
26
45
|
<section class="lares-agent__group">
|
|
27
46
|
<h2>{{ tVoice("settings.title") }}</h2>
|
|
@@ -48,7 +67,15 @@
|
|
|
48
67
|
-->
|
|
49
68
|
<section class="lares-agent__group">
|
|
50
69
|
<h2>{{ tSearch("settings.title") }}</h2>
|
|
51
|
-
<
|
|
70
|
+
<LaresSelect
|
|
71
|
+
v-if="isDesktop"
|
|
72
|
+
:value="searchMenuId"
|
|
73
|
+
:sections="searchSelectSections"
|
|
74
|
+
:disabled="busy || !search"
|
|
75
|
+
:empty="tSearch('settings.default.empty')"
|
|
76
|
+
@select="(item) => pick(item, 'search')"
|
|
77
|
+
/>
|
|
78
|
+
<div v-else class="lares-agent__list">
|
|
52
79
|
<LaresSettingRow
|
|
53
80
|
:label="tSearch('settings.default')"
|
|
54
81
|
:value="searchLabel"
|
|
@@ -60,7 +87,7 @@
|
|
|
60
87
|
</div>
|
|
61
88
|
<p v-if="searchError" class="lares-agent__hint" data-status="error">{{ searchError }}</p>
|
|
62
89
|
</section>
|
|
63
|
-
<LaresSheet :open="Boolean(panel)" :title="sheetTitle" @close="panel = ''">
|
|
90
|
+
<LaresSheet v-if="!isDesktop" :open="Boolean(panel)" :title="sheetTitle" @close="panel = ''">
|
|
64
91
|
<p v-if="sheetEmpty" class="lares-agent__hint lares-agent__hint--sheet">{{ sheetEmpty }}</p>
|
|
65
92
|
<template v-for="section in sheetSections" :key="section.heading || 'main'">
|
|
66
93
|
<p v-if="section.heading" class="lares-agent__heading">{{ section.heading }}</p>
|
|
@@ -100,8 +127,10 @@ import { hostKey as hostSessionKey } from "@olares/lares-core/larepass/host";
|
|
|
100
127
|
import { createHostClient } from "../host.js";
|
|
101
128
|
import { adoptHost } from "../runtime.js";
|
|
102
129
|
import { createT } from "../i18n.js";
|
|
130
|
+
import { chatDevice, DEVICE_DESKTOP } from "../layout.js";
|
|
103
131
|
import LaresSettingRow from "./SettingRow.vue";
|
|
104
132
|
import LaresSheet from "./Sheet.vue";
|
|
133
|
+
import LaresSelect from "./Select.vue";
|
|
105
134
|
|
|
106
135
|
const catalogs = {
|
|
107
136
|
model: { zh: MODEL_ZH, en: MODEL_EN },
|
|
@@ -115,10 +144,11 @@ function itemLabel(items, id) {
|
|
|
115
144
|
|
|
116
145
|
export default {
|
|
117
146
|
name: "LaresAgentSettings",
|
|
118
|
-
components: { LaresSettingRow, LaresSheet },
|
|
147
|
+
components: { LaresSettingRow, LaresSheet, LaresSelect },
|
|
119
148
|
expose: ["reload"],
|
|
120
149
|
props: {
|
|
121
150
|
locale: { type: String, default: "en" },
|
|
151
|
+
device: { type: String, default: "mobile" },
|
|
122
152
|
baseUrl: { type: String, default: undefined },
|
|
123
153
|
proxyPrefix: { type: String, default: undefined },
|
|
124
154
|
request: { type: Function, default: undefined },
|
|
@@ -133,15 +163,23 @@ export default {
|
|
|
133
163
|
models: remembered.models,
|
|
134
164
|
voice: remembered.voice,
|
|
135
165
|
search: remembered.search,
|
|
166
|
+
conversation: remembered.conversation,
|
|
136
167
|
modelError: "",
|
|
137
168
|
voiceError: "",
|
|
138
169
|
searchError: "",
|
|
170
|
+
conversationError: "",
|
|
139
171
|
};
|
|
140
172
|
},
|
|
141
173
|
computed: {
|
|
142
174
|
t() {
|
|
143
175
|
return createT(this.locale);
|
|
144
176
|
},
|
|
177
|
+
layoutDevice() {
|
|
178
|
+
return chatDevice(this.device);
|
|
179
|
+
},
|
|
180
|
+
isDesktop() {
|
|
181
|
+
return this.layoutDevice === DEVICE_DESKTOP;
|
|
182
|
+
},
|
|
145
183
|
ports() {
|
|
146
184
|
return {
|
|
147
185
|
baseUrl: this.baseUrl,
|
|
@@ -200,9 +238,33 @@ export default {
|
|
|
200
238
|
if (!this.voice) return "—";
|
|
201
239
|
return itemLabel(this.voiceLanguages, voiceMenuValue(this.voice.config?.language));
|
|
202
240
|
},
|
|
241
|
+
searchMenuId() {
|
|
242
|
+
return searchMenuValue(this.search?.defaultSearchModel);
|
|
243
|
+
},
|
|
203
244
|
searchLabel() {
|
|
204
245
|
if (!this.search) return "—";
|
|
205
|
-
return itemLabel(this.searchItems,
|
|
246
|
+
return itemLabel(this.searchItems, this.searchMenuId);
|
|
247
|
+
},
|
|
248
|
+
modelSelectSections() {
|
|
249
|
+
return this.modelGroups.map((group) => ({
|
|
250
|
+
heading: group.provider,
|
|
251
|
+
items: group.models.map((model) => ({
|
|
252
|
+
id: this.modelKey(model),
|
|
253
|
+
label: model.name,
|
|
254
|
+
model,
|
|
255
|
+
})),
|
|
256
|
+
}));
|
|
257
|
+
},
|
|
258
|
+
searchSelectSections() {
|
|
259
|
+
return [{ items: this.searchItems.map((item) => ({ id: item.id, label: item.label })) }];
|
|
260
|
+
},
|
|
261
|
+
busyEnterSections() {
|
|
262
|
+
return [{
|
|
263
|
+
items: [
|
|
264
|
+
{ id: "queue", label: this.t("settings.input.busyEnter.queue") },
|
|
265
|
+
{ id: "steer", label: this.t("settings.input.busyEnter.steer") },
|
|
266
|
+
],
|
|
267
|
+
}];
|
|
206
268
|
},
|
|
207
269
|
sheetTitle() {
|
|
208
270
|
if (this.panel === "model") return this.tModel("settings.title");
|
|
@@ -212,32 +274,17 @@ export default {
|
|
|
212
274
|
return "";
|
|
213
275
|
},
|
|
214
276
|
sheetCurrent() {
|
|
215
|
-
|
|
216
|
-
if (this.panel === "voiceModel") return voiceMenuValue(this.voice?.config?.model);
|
|
217
|
-
if (this.panel === "voiceLang") return voiceMenuValue(this.voice?.config?.language);
|
|
218
|
-
if (this.panel === "search") return searchMenuValue(this.search?.defaultSearchModel);
|
|
219
|
-
return "";
|
|
277
|
+
return this.sheetCurrentFor(this.panel);
|
|
220
278
|
},
|
|
221
279
|
sheetSections() {
|
|
222
|
-
if (this.panel === "model")
|
|
223
|
-
return this.modelGroups.map((group) => ({
|
|
224
|
-
heading: group.provider,
|
|
225
|
-
items: group.models.map((model) => ({
|
|
226
|
-
id: this.modelKey(model),
|
|
227
|
-
label: model.name,
|
|
228
|
-
model,
|
|
229
|
-
})),
|
|
230
|
-
}));
|
|
231
|
-
}
|
|
280
|
+
if (this.panel === "model") return this.modelSelectSections;
|
|
232
281
|
if (this.panel === "voiceModel") {
|
|
233
282
|
return [{ items: this.voiceModels.map((item) => ({ id: item.id, label: item.label })) }];
|
|
234
283
|
}
|
|
235
284
|
if (this.panel === "voiceLang") {
|
|
236
285
|
return [{ items: this.voiceLanguages.map((item) => ({ id: item.id, label: item.label })) }];
|
|
237
286
|
}
|
|
238
|
-
if (this.panel === "search")
|
|
239
|
-
return [{ items: this.searchItems.map((item) => ({ id: item.id, label: item.label })) }];
|
|
240
|
-
}
|
|
287
|
+
if (this.panel === "search") return this.searchSelectSections;
|
|
241
288
|
return [];
|
|
242
289
|
},
|
|
243
290
|
sheetEmpty() {
|
|
@@ -255,9 +302,11 @@ export default {
|
|
|
255
302
|
this.models = null;
|
|
256
303
|
this.voice = null;
|
|
257
304
|
this.search = null;
|
|
305
|
+
this.conversation = null;
|
|
258
306
|
this.modelError = "";
|
|
259
307
|
this.voiceError = "";
|
|
260
308
|
this.searchError = "";
|
|
309
|
+
this.conversationError = "";
|
|
261
310
|
this.load(true);
|
|
262
311
|
},
|
|
263
312
|
},
|
|
@@ -286,9 +335,8 @@ export default {
|
|
|
286
335
|
if (!ready) return;
|
|
287
336
|
this.panel = panel;
|
|
288
337
|
},
|
|
289
|
-
async pick(item) {
|
|
290
|
-
|
|
291
|
-
if (item.id === this.sheetCurrent) {
|
|
338
|
+
async pick(item, panel = this.panel) {
|
|
339
|
+
if (item.id === this.sheetCurrentFor(panel)) {
|
|
292
340
|
this.panel = "";
|
|
293
341
|
return;
|
|
294
342
|
}
|
|
@@ -298,6 +346,13 @@ export default {
|
|
|
298
346
|
if (panel === "voiceLang") await this.patchVoice("language", voiceValueFromMenu(item.id));
|
|
299
347
|
if (panel === "search") await this.chooseSearch(item.id);
|
|
300
348
|
},
|
|
349
|
+
sheetCurrentFor(panel) {
|
|
350
|
+
if (panel === "model") return this.modelCurrent;
|
|
351
|
+
if (panel === "voiceModel") return voiceMenuValue(this.voice?.config?.model);
|
|
352
|
+
if (panel === "voiceLang") return voiceMenuValue(this.voice?.config?.language);
|
|
353
|
+
if (panel === "search") return searchMenuValue(this.search?.defaultSearchModel);
|
|
354
|
+
return "";
|
|
355
|
+
},
|
|
301
356
|
reload() {
|
|
302
357
|
return this.load(true);
|
|
303
358
|
},
|
|
@@ -307,17 +362,20 @@ export default {
|
|
|
307
362
|
this.models = remembered.models ?? this.models;
|
|
308
363
|
this.voice = remembered.voice ?? this.voice;
|
|
309
364
|
this.search = remembered.search ?? this.search;
|
|
310
|
-
|
|
365
|
+
this.conversation = remembered.conversation ?? this.conversation;
|
|
366
|
+
if (this.models && this.voice && this.search && this.conversation) return;
|
|
311
367
|
}
|
|
312
368
|
this.panel = "";
|
|
313
369
|
this.loading = true;
|
|
314
370
|
this.modelError = "";
|
|
315
371
|
this.voiceError = "";
|
|
316
372
|
this.searchError = "";
|
|
317
|
-
|
|
373
|
+
this.conversationError = "";
|
|
374
|
+
const [models, voice, search, conversation] = await Promise.allSettled([
|
|
318
375
|
this.settings.models({ force }),
|
|
319
376
|
this.settings.voice(force),
|
|
320
377
|
this.settings.search({ force }),
|
|
378
|
+
this.settings.conversation({ force }),
|
|
321
379
|
]);
|
|
322
380
|
if (models.status === "fulfilled") this.models = models.value;
|
|
323
381
|
else this.modelError = this.failText(this.tModel, "settings.loadFailed", models.reason);
|
|
@@ -325,6 +383,8 @@ export default {
|
|
|
325
383
|
else this.voiceError = this.tVoice("settings.loadFailed");
|
|
326
384
|
if (search.status === "fulfilled") this.search = search.value;
|
|
327
385
|
else this.searchError = this.failText(this.tSearch, "settings.loadFailed", search.reason);
|
|
386
|
+
if (conversation.status === "fulfilled") this.conversation = conversation.value;
|
|
387
|
+
else this.conversationError = conversation.reason instanceof Error ? conversation.reason.message : String(conversation.reason);
|
|
328
388
|
this.loading = false;
|
|
329
389
|
},
|
|
330
390
|
async chooseModel(model) {
|
|
@@ -369,6 +429,18 @@ export default {
|
|
|
369
429
|
this.pending = "";
|
|
370
430
|
}
|
|
371
431
|
},
|
|
432
|
+
async chooseBusyEnter(item) {
|
|
433
|
+
if (!item?.id || item.id === this.conversation?.busyEnter || this.busy) return;
|
|
434
|
+
this.pending = "busyEnter";
|
|
435
|
+
this.conversationError = "";
|
|
436
|
+
try {
|
|
437
|
+
this.conversation = await this.settings.setBusyEnter(item.id);
|
|
438
|
+
} catch (err) {
|
|
439
|
+
this.conversationError = err instanceof Error ? err.message : String(err);
|
|
440
|
+
} finally {
|
|
441
|
+
this.pending = "";
|
|
442
|
+
}
|
|
443
|
+
},
|
|
372
444
|
},
|
|
373
445
|
};
|
|
374
446
|
</script>
|
|
@@ -382,6 +454,11 @@ export default {
|
|
|
382
454
|
color: var(--q-ink-1);
|
|
383
455
|
}
|
|
384
456
|
|
|
457
|
+
.lares-agent[data-device="desktop"] {
|
|
458
|
+
min-height: 0;
|
|
459
|
+
width: 100%;
|
|
460
|
+
}
|
|
461
|
+
|
|
385
462
|
.lares-agent__body {
|
|
386
463
|
display: flex;
|
|
387
464
|
flex-direction: column;
|
|
@@ -389,6 +466,15 @@ export default {
|
|
|
389
466
|
padding: 16px 20px 32px;
|
|
390
467
|
}
|
|
391
468
|
|
|
469
|
+
.lares-agent[data-device="desktop"] .lares-agent__body {
|
|
470
|
+
gap: 16px;
|
|
471
|
+
padding: 0;
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
.lares-agent[data-device="desktop"] .lares-agent__group h2 {
|
|
475
|
+
font-size: 16px;
|
|
476
|
+
}
|
|
477
|
+
|
|
392
478
|
.lares-agent__loading {
|
|
393
479
|
position: absolute;
|
|
394
480
|
inset: 0;
|
|
@@ -405,8 +491,12 @@ export default {
|
|
|
405
491
|
|
|
406
492
|
.lares-agent__loading p {
|
|
407
493
|
margin: 0;
|
|
408
|
-
font-size:
|
|
409
|
-
line-height:
|
|
494
|
+
font-size: 16px;
|
|
495
|
+
line-height: 22px;
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
.lares-agent[data-device="desktop"] .lares-agent__loading {
|
|
499
|
+
min-height: 96px;
|
|
410
500
|
}
|
|
411
501
|
|
|
412
502
|
.lares-agent__spinner {
|
|
@@ -436,9 +526,9 @@ export default {
|
|
|
436
526
|
|
|
437
527
|
.lares-agent__group h2 {
|
|
438
528
|
margin: 0;
|
|
439
|
-
font-size:
|
|
529
|
+
font-size: 18px;
|
|
440
530
|
font-weight: 500;
|
|
441
|
-
line-height:
|
|
531
|
+
line-height: 24px;
|
|
442
532
|
}
|
|
443
533
|
|
|
444
534
|
.lares-agent__list {
|
|
@@ -449,7 +539,7 @@ export default {
|
|
|
449
539
|
|
|
450
540
|
.lares-agent__hint {
|
|
451
541
|
margin: 0;
|
|
452
|
-
font-size:
|
|
542
|
+
font-size: 15px;
|
|
453
543
|
color: var(--q-ink-3);
|
|
454
544
|
}
|
|
455
545
|
|
|
@@ -465,8 +555,8 @@ export default {
|
|
|
465
555
|
margin: 0;
|
|
466
556
|
padding: 12px 16px 4px;
|
|
467
557
|
color: var(--q-ink-3);
|
|
468
|
-
font-size:
|
|
558
|
+
font-size: 14px;
|
|
469
559
|
font-weight: 500;
|
|
470
|
-
line-height:
|
|
560
|
+
line-height: 18px;
|
|
471
561
|
}
|
|
472
562
|
</style>
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="lares-select">
|
|
3
|
+
<LaresPcPopover v-model="open" width="anchor" placement="bottom-start">
|
|
4
|
+
<template #trigger="{ toggle }">
|
|
5
|
+
<button
|
|
6
|
+
type="button"
|
|
7
|
+
class="lares-select__trigger"
|
|
8
|
+
:disabled="disabled"
|
|
9
|
+
aria-haspopup="listbox"
|
|
10
|
+
:aria-expanded="open ? 'true' : 'false'"
|
|
11
|
+
@click="toggle"
|
|
12
|
+
>
|
|
13
|
+
<span class="lares-select__value">{{ currentLabel }}</span>
|
|
14
|
+
<svg class="lares-select__chevron" viewBox="0 0 24 24" aria-hidden="true">
|
|
15
|
+
<path d="M6.5 9 12 14.5 17.5 9" />
|
|
16
|
+
</svg>
|
|
17
|
+
</button>
|
|
18
|
+
</template>
|
|
19
|
+
<div class="lares-select__menu" role="listbox">
|
|
20
|
+
<p v-if="emptyText" class="lares-select__empty">{{ emptyText }}</p>
|
|
21
|
+
<template v-for="section in sections" :key="section.heading || 'main'">
|
|
22
|
+
<p v-if="section.heading" class="lares-select__heading">{{ section.heading }}</p>
|
|
23
|
+
<button
|
|
24
|
+
v-for="item in section.items"
|
|
25
|
+
:key="item.id"
|
|
26
|
+
type="button"
|
|
27
|
+
class="lares-select__option"
|
|
28
|
+
role="option"
|
|
29
|
+
:aria-selected="item.id === value"
|
|
30
|
+
:disabled="disabled"
|
|
31
|
+
@click="choose(item)"
|
|
32
|
+
>
|
|
33
|
+
<span>{{ item.label }}</span>
|
|
34
|
+
<svg v-if="item.id === value" class="lares-select__check" viewBox="0 0 24 24" aria-hidden="true">
|
|
35
|
+
<path d="M5 12.5 9.5 17 19 7.5" />
|
|
36
|
+
</svg>
|
|
37
|
+
</button>
|
|
38
|
+
</template>
|
|
39
|
+
</div>
|
|
40
|
+
</LaresPcPopover>
|
|
41
|
+
</div>
|
|
42
|
+
</template>
|
|
43
|
+
|
|
44
|
+
<script>
|
|
45
|
+
import LaresPcPopover from "../desktop/ui/PcPopover.vue";
|
|
46
|
+
|
|
47
|
+
export default {
|
|
48
|
+
name: "LaresSelect",
|
|
49
|
+
components: { LaresPcPopover },
|
|
50
|
+
props: {
|
|
51
|
+
value: { type: String, default: "" },
|
|
52
|
+
sections: { type: Array, default: () => [] },
|
|
53
|
+
disabled: { type: Boolean, default: false },
|
|
54
|
+
empty: { type: String, default: "" },
|
|
55
|
+
},
|
|
56
|
+
emits: ["select"],
|
|
57
|
+
data() {
|
|
58
|
+
return { open: false };
|
|
59
|
+
},
|
|
60
|
+
computed: {
|
|
61
|
+
currentLabel() {
|
|
62
|
+
for (const section of this.sections) {
|
|
63
|
+
for (const item of section.items) {
|
|
64
|
+
if (item.id === this.value) return item.label;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return "—";
|
|
68
|
+
},
|
|
69
|
+
itemCount() {
|
|
70
|
+
return this.sections.reduce((sum, section) => sum + section.items.length, 0);
|
|
71
|
+
},
|
|
72
|
+
emptyText() {
|
|
73
|
+
return this.itemCount === 0 ? this.empty : "";
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
methods: {
|
|
77
|
+
choose(item) {
|
|
78
|
+
this.open = false;
|
|
79
|
+
this.$emit("select", item);
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
};
|
|
83
|
+
</script>
|
|
84
|
+
|
|
85
|
+
<style scoped>
|
|
86
|
+
.lares-select {
|
|
87
|
+
width: 100%;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
.lares-select__trigger {
|
|
91
|
+
display: flex;
|
|
92
|
+
align-items: center;
|
|
93
|
+
gap: 8px;
|
|
94
|
+
box-sizing: border-box;
|
|
95
|
+
width: 100%;
|
|
96
|
+
height: 32px;
|
|
97
|
+
padding: 0 8px 0 12px;
|
|
98
|
+
border: 1px solid var(--q-separator);
|
|
99
|
+
border-radius: 8px;
|
|
100
|
+
background: transparent;
|
|
101
|
+
color: var(--q-ink-2);
|
|
102
|
+
text-align: left;
|
|
103
|
+
cursor: pointer;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
.lares-select__trigger:disabled {
|
|
107
|
+
cursor: default;
|
|
108
|
+
opacity: 0.5;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
.lares-select__value {
|
|
112
|
+
min-width: 0;
|
|
113
|
+
flex: 1;
|
|
114
|
+
overflow: hidden;
|
|
115
|
+
font-size: 15px;
|
|
116
|
+
line-height: 20px;
|
|
117
|
+
text-overflow: ellipsis;
|
|
118
|
+
white-space: nowrap;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
.lares-select__chevron,
|
|
122
|
+
.lares-select__check {
|
|
123
|
+
width: 20px;
|
|
124
|
+
height: 20px;
|
|
125
|
+
flex-shrink: 0;
|
|
126
|
+
fill: none;
|
|
127
|
+
stroke: var(--q-ink-3);
|
|
128
|
+
stroke-width: 1.75;
|
|
129
|
+
stroke-linecap: round;
|
|
130
|
+
stroke-linejoin: round;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
.lares-select__check {
|
|
134
|
+
width: 16px;
|
|
135
|
+
height: 16px;
|
|
136
|
+
stroke: var(--q-blue-default);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
.lares-select__menu {
|
|
140
|
+
margin: -2px;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
.lares-select__empty,
|
|
144
|
+
.lares-select__heading {
|
|
145
|
+
margin: 0;
|
|
146
|
+
padding: 8px;
|
|
147
|
+
color: var(--q-ink-3);
|
|
148
|
+
font-size: 14px;
|
|
149
|
+
font-weight: 500;
|
|
150
|
+
line-height: 18px;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
.lares-select__option {
|
|
154
|
+
display: flex;
|
|
155
|
+
align-items: center;
|
|
156
|
+
justify-content: space-between;
|
|
157
|
+
gap: 8px;
|
|
158
|
+
width: 100%;
|
|
159
|
+
padding: 8px;
|
|
160
|
+
border: 0;
|
|
161
|
+
border-radius: 4px;
|
|
162
|
+
background: transparent;
|
|
163
|
+
color: var(--q-ink-2);
|
|
164
|
+
font-size: 15px;
|
|
165
|
+
line-height: 20px;
|
|
166
|
+
text-align: left;
|
|
167
|
+
cursor: pointer;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
.lares-select__option span {
|
|
171
|
+
min-width: 0;
|
|
172
|
+
overflow: hidden;
|
|
173
|
+
text-overflow: ellipsis;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
.lares-select__option:hover:not(:disabled) {
|
|
177
|
+
background: var(--q-background-hover);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
.lares-select__option[aria-selected="true"] span {
|
|
181
|
+
color: var(--q-blue-default);
|
|
182
|
+
}
|
|
183
|
+
</style>
|
|
@@ -52,6 +52,7 @@ export default {
|
|
|
52
52
|
background: transparent;
|
|
53
53
|
color: var(--q-ink-1);
|
|
54
54
|
text-align: left;
|
|
55
|
+
transition: background var(--lares-duration-fast, 120ms) var(--lares-ease-out, ease);
|
|
55
56
|
}
|
|
56
57
|
|
|
57
58
|
.lares-set-row--boxed {
|
|
@@ -75,8 +76,8 @@ export default {
|
|
|
75
76
|
.lares-set-row__label {
|
|
76
77
|
min-width: 0;
|
|
77
78
|
flex: 1;
|
|
78
|
-
font-size:
|
|
79
|
-
line-height:
|
|
79
|
+
font-size: 16px;
|
|
80
|
+
line-height: 22px;
|
|
80
81
|
word-break: break-word;
|
|
81
82
|
}
|
|
82
83
|
|
|
@@ -91,8 +92,8 @@ export default {
|
|
|
91
92
|
|
|
92
93
|
.lares-set-row__value {
|
|
93
94
|
overflow: hidden;
|
|
94
|
-
font-size:
|
|
95
|
-
line-height:
|
|
95
|
+
font-size: 15px;
|
|
96
|
+
line-height: 20px;
|
|
96
97
|
color: var(--q-ink-2);
|
|
97
98
|
text-align: right;
|
|
98
99
|
text-overflow: ellipsis;
|
package/src/settings/Sheet.vue
CHANGED
|
@@ -52,7 +52,7 @@ export default {
|
|
|
52
52
|
inset: 0;
|
|
53
53
|
background: rgb(0 0 0 / 32%);
|
|
54
54
|
opacity: 0;
|
|
55
|
-
transition: opacity
|
|
55
|
+
transition: opacity var(--lares-duration-sheet, 280ms) var(--lares-ease-out, cubic-bezier(0.32, 0.72, 0, 1));
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
.lares-sheet[data-open="true"] .lares-sheet__backdrop {
|
|
@@ -73,7 +73,7 @@ export default {
|
|
|
73
73
|
background: var(--q-background-1);
|
|
74
74
|
box-shadow: 0 -8px 32px rgb(0 0 0 / 12%);
|
|
75
75
|
transform: translateY(100%);
|
|
76
|
-
transition: transform
|
|
76
|
+
transition: transform var(--lares-duration-sheet, 280ms) var(--lares-ease-out, cubic-bezier(0.32, 0.72, 0, 1));
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
.lares-sheet[data-open="true"] .lares-sheet__panel {
|
|
@@ -91,9 +91,9 @@ export default {
|
|
|
91
91
|
|
|
92
92
|
.lares-sheet__title {
|
|
93
93
|
margin: 0;
|
|
94
|
-
font-size:
|
|
94
|
+
font-size: 20px;
|
|
95
95
|
font-weight: 500;
|
|
96
|
-
line-height:
|
|
96
|
+
line-height: 26px;
|
|
97
97
|
}
|
|
98
98
|
|
|
99
99
|
.lares-sheet__close {
|
package/src/styles.css
CHANGED
|
@@ -1,12 +1,21 @@
|
|
|
1
|
+
@import "./motion.css";
|
|
2
|
+
|
|
3
|
+
/* Own the base size instead of inheriting the host page, so unstyled text
|
|
4
|
+
(user bubbles, composer textareas) matches the transcript body. */
|
|
1
5
|
.lares-shell {
|
|
2
6
|
position: relative;
|
|
3
7
|
display: flex;
|
|
4
8
|
flex-direction: column;
|
|
5
9
|
min-height: 0;
|
|
6
10
|
flex: 1;
|
|
11
|
+
font-size: 17px;
|
|
7
12
|
color: var(--q-ink-1);
|
|
8
13
|
}
|
|
9
14
|
|
|
15
|
+
.lares-shell[data-device="desktop"] {
|
|
16
|
+
font-size: 15px;
|
|
17
|
+
}
|
|
18
|
+
|
|
10
19
|
.lares-shell__conversation {
|
|
11
20
|
display: flex;
|
|
12
21
|
flex-direction: column;
|