004: отличать агента — цвет или картинка; картинку копировать себе, не по ссылке
This commit is contained in:
@@ -30,8 +30,10 @@ sketches/004-settings-agents/index.html # настройки агентов
|
|||||||
- **Счётчиков токенов и кольца заполнения не будет.** В библиотеке `client`
|
- **Счётчиков токенов и кольца заполнения не будет.** В библиотеке `client`
|
||||||
таких данных нет вообще: ни модели, ни отправлено/получено, ни предела
|
таких данных нет вообще: ни модели, ни отправлено/получено, ни предела
|
||||||
контекста. Правило: нет данных — нет цифры.
|
контекста. Правило: нет данных — нет цифры.
|
||||||
- **Несколько агентов** — предусмотреть. Различение: цвет (полоска у диалога,
|
- **Несколько агентов** — предусмотреть. Различение: **цвет или картинка** на выбор.
|
||||||
точка у группы, цвет аватара), возможно плюс метка.
|
Цвет помечает диалоги агента (полоска у строки, точка у группы); картинка
|
||||||
|
показывается кружком вместо цвета. **Картинку клиент копирует себе**, а не берёт
|
||||||
|
по исходному адресу — иначе значок пропадёт вместе с файлом.
|
||||||
- **Markdown** — показывать разметкой, а не сырыми символами. Готовая
|
- **Markdown** — показывать разметкой, а не сырыми символами. Готовая
|
||||||
библиотека уже используется в клиенте assistent, писать свою не надо.
|
библиотека уже используется в клиенте assistent, писать свою не надо.
|
||||||
- **Папки над списком диалогов** («Все чаты», «Работа», «Дом») — часть выбранного
|
- **Папки над списком диалогов** («Все чаты», «Работа», «Дом») — часть выбранного
|
||||||
|
|||||||
+17
-3
@@ -80,8 +80,21 @@
|
|||||||
чата**, не отдельная страница. Два состояния: список агентов и форма нового.
|
чата**, не отдельная страница. Два состояния: список агентов и форма нового.
|
||||||
- **R23.2.** В строке агента видно: имя, адрес, состояние («на связи» / «не отвечает»),
|
- **R23.2.** В строке агента видно: имя, адрес, состояние («на связи» / «не отвечает»),
|
||||||
кнопки изменить и удалить.
|
кнопки изменить и удалить.
|
||||||
- **R23.3.** Форма нового агента: название, адрес сервера, цвет для различения.
|
- **R23.3.** Форма нового агента: название, адрес сервера, и **чем отличать в списке —
|
||||||
Под каждым полем — пояснение простым языком.
|
цвет или картинка**. Под каждым полем — пояснение простым языком.
|
||||||
|
- **R23.3.1.** Переключатель «Цвет / Картинка»: выбирается что-то одно.
|
||||||
|
**Цвет** — простой выбор из готовых, им помечаются диалоги агента в списке
|
||||||
|
(полоска у строки, точка у группы).
|
||||||
|
**Картинка** — файл с диска; показывается круглым превью, рядом «Выбрать файл…»
|
||||||
|
и «Убрать».
|
||||||
|
- **R23.3.2.** **Картинку копировать себе, а не брать по исходному адресу.**
|
||||||
|
Выбранный файл сохраняется внутрь клиента (в свою папку), и дальше используется
|
||||||
|
только эта копия. Ссылку на исходный путь не хранить: файл могут удалить,
|
||||||
|
переименовать, флешку вынуть — и значок у агента пропадёт. Работает и для
|
||||||
|
картинки на диске, и для картинки по ссылке: скачать и положить себе.
|
||||||
|
- **R23.3.3.** Выбранная картинка показывается кружком там же, где был бы цвет:
|
||||||
|
в списке агентов, в списке диалогов, в шапке чата. Убрать её можно в любой
|
||||||
|
момент — тогда снова становится цвет.
|
||||||
- **R23.4.** **Проверка связи до сохранения** — в **отдельном окне поверх настроек**,
|
- **R23.4.** **Проверка связи до сохранения** — в **отдельном окне поверх настроек**,
|
||||||
не строкой внутри формы. Нажал «Проверить связь» — открылось второе окно, в нём
|
не строкой внутри формы. Нажал «Проверить связь» — открылось второе окно, в нём
|
||||||
идёт проверка. Пока идёт: «спрашиваю агента…» с крутящимся значком. Результат —
|
идёт проверка. Пока идёт: «спрашиваю агента…» с крутящимся значком. Результат —
|
||||||
@@ -136,7 +149,8 @@
|
|||||||
|
|
||||||
- Запись: по нажатию или на удержание.
|
- Запись: по нажатию или на удержание.
|
||||||
- Нужны ли вложения (картинки) в этом клиенте.
|
- Нужны ли вложения (картинки) в этом клиенте.
|
||||||
- Как именно различать агентов (см. R21–R22): одного цвета может быть мало.
|
- Как именно различать агентов (см. R21–R22): цвета или картинки достаточно?
|
||||||
|
- Нужен ли картинке размер/форма — показывать кружком без изменений или обрезать.
|
||||||
- Где хранится список агентов — в файле на диске или спрашивать сервер.
|
- Где хранится список агентов — в файле на диске или спрашивать сервер.
|
||||||
- Как выглядит показ хода работы агента в свёрнутом виде.
|
- Как выглядит показ хода работы агента в свёрнутом виде.
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,15 @@
|
|||||||
имени не сообщает (это из исходников, не догадка).
|
имени не сообщает (это из исходников, не догадка).
|
||||||
- **Адрес сервера** — целиком, вместе с путём `/agentik`. Прямо в строке адреса
|
- **Адрес сервера** — целиком, вместе с путём `/agentik`. Прямо в строке адреса
|
||||||
кнопка **«Проверить связь»**.
|
кнопка **«Проверить связь»**.
|
||||||
- **Цвет** для различения, пять вариантов.
|
- **Чем отличать в списке: цвет или картинка.** Переключатель, выбирается что-то одно.
|
||||||
|
- **Цвет** — простой выбор из пяти.
|
||||||
|
- **Картинка** — файл с диска: круглый превью, «Выбрать файл…» и «Убрать».
|
||||||
|
Картинка показывается там же, где был бы цвет: в списке агентов, в диалогах,
|
||||||
|
в шапке чата.
|
||||||
|
- ⚠️ **Картинку копировать себе, а не брать по исходному адресу.** Выбранный файл
|
||||||
|
сохраняется внутрь клиента; дальше используется только эта копия. Если держать
|
||||||
|
ссылку на исходный путь, значок пропадёт, когда файл удалят, переименуют или
|
||||||
|
вынут флешку. То же для картинки по ссылке: скачать и положить себе.
|
||||||
|
|
||||||
## Окно 2: проверка связи (отдельное, поверх настроек)
|
## Окно 2: проверка связи (отдельное, поверх настроек)
|
||||||
Три состояния, сменяются в одном окне:
|
Три состояния, сменяются в одном окне:
|
||||||
|
|||||||
@@ -141,6 +141,29 @@
|
|||||||
.swatch { width: 30px; height: 30px; border-radius: 50%; cursor: pointer; border: 2px solid transparent; }
|
.swatch { width: 30px; height: 30px; border-radius: 50%; cursor: pointer; border: 2px solid transparent; }
|
||||||
.swatch.on { border-color: var(--fg); }
|
.swatch.on { border-color: var(--fg); }
|
||||||
|
|
||||||
|
/* цвет ИЛИ картинка */
|
||||||
|
.appearance-tabs { display: flex; gap: 6px; margin-bottom: 11px; }
|
||||||
|
.appearance-tabs .tab {
|
||||||
|
padding: 6px 13px; border-radius: 9px; font-size: 12.5px; color: var(--dim);
|
||||||
|
background: var(--panel2); cursor: pointer; border: 1px solid transparent;
|
||||||
|
}
|
||||||
|
.appearance-tabs .tab.on { color: var(--fg); border-color: var(--accent); background: rgba(106,178,242,.12); }
|
||||||
|
.pane { display: none; }
|
||||||
|
.pane.on { display: block; }
|
||||||
|
|
||||||
|
.pic-row { display: flex; align-items: center; gap: 13px; }
|
||||||
|
.pic-preview {
|
||||||
|
width: 54px; height: 54px; border-radius: 50%; flex: 0 0 54px; background: var(--bg);
|
||||||
|
border: 1px dashed var(--line); display: grid; place-items: center; color: var(--dim);
|
||||||
|
font-size: 20px; overflow: hidden;
|
||||||
|
}
|
||||||
|
.pic-preview.filled { border-style: solid; border-color: var(--line); }
|
||||||
|
.pic-preview img { width: 100%; height: 100%; object-fit: cover; display: block; }
|
||||||
|
.pic-actions { display: flex; gap: 8px; flex-wrap: wrap; }
|
||||||
|
|
||||||
|
.avatar.pic { background: transparent; padding: 0; overflow: hidden; }
|
||||||
|
.avatar.pic img { width: 100%; height: 100%; object-fit: cover; display: block; }
|
||||||
|
|
||||||
/* кнопки */
|
/* кнопки */
|
||||||
.btn { border-radius: 10px; padding: 10px 17px; font-size: 13px; cursor: pointer; border: 1px solid var(--line);
|
.btn { border-radius: 10px; padding: 10px 17px; font-size: 13px; cursor: pointer; border: 1px solid var(--line);
|
||||||
background: transparent; color: var(--fg); font-family: inherit; white-space: nowrap; }
|
background: transparent; color: var(--fg); font-family: inherit; white-space: nowrap; }
|
||||||
@@ -308,7 +331,14 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label>Цвет — чтобы отличать в списке</label>
|
<label>Как отличать в списке</label>
|
||||||
|
<div class="appearance-tabs">
|
||||||
|
<div class="tab on" data-tab="color">Цвет</div>
|
||||||
|
<div class="tab" data-tab="pic">Картинка</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- цвет -->
|
||||||
|
<div class="pane on" id="paneColor">
|
||||||
<div class="colors">
|
<div class="colors">
|
||||||
<div class="swatch on" style="background:#6AB2F2"></div>
|
<div class="swatch on" style="background:#6AB2F2"></div>
|
||||||
<div class="swatch" style="background:#86C99A"></div>
|
<div class="swatch" style="background:#86C99A"></div>
|
||||||
@@ -316,6 +346,23 @@
|
|||||||
<div class="swatch" style="background:#B79AE0"></div>
|
<div class="swatch" style="background:#B79AE0"></div>
|
||||||
<div class="swatch" style="background:#E28C8C"></div>
|
<div class="swatch" style="background:#E28C8C"></div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="note">Цвет остаётся простым выбором: им помечаются диалоги агента
|
||||||
|
в списке — полоска у строки и точка у группы.</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- картинка -->
|
||||||
|
<div class="pane" id="panePic">
|
||||||
|
<div class="pic-row">
|
||||||
|
<div class="pic-preview" id="picPreview">🖼</div>
|
||||||
|
<div class="pic-actions">
|
||||||
|
<button class="btn sm" onclick="pickPic()">Выбрать файл…</button>
|
||||||
|
<button class="btn sm" id="picClear" onclick="clearPic()" style="display:none">Убрать</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="note">Картинка копируется <b>внутрь клиента</b> — по исходному
|
||||||
|
адресу не подтягивается. Иначе значок пропадёт, если файл удалят,
|
||||||
|
флешку вынут или папку переименуют.</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -538,6 +585,41 @@
|
|||||||
document.querySelectorAll('.swatch').forEach(x => x.classList.remove('on'));
|
document.querySelectorAll('.swatch').forEach(x => x.classList.remove('on'));
|
||||||
s.classList.add('on');
|
s.classList.add('on');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// ---------------- как отличать: цвет ИЛИ картинка ----------------
|
||||||
|
document.querySelectorAll('.appearance-tabs .tab').forEach(tab => tab.onclick = () => {
|
||||||
|
document.querySelectorAll('.appearance-tabs .tab').forEach(x => x.classList.remove('on'));
|
||||||
|
tab.classList.add('on');
|
||||||
|
const pic = (tab.dataset.tab === 'pic');
|
||||||
|
el('paneColor').classList.toggle('on', !pic);
|
||||||
|
el('panePic').classList.toggle('on', pic);
|
||||||
|
});
|
||||||
|
|
||||||
|
// выбор картинки: в настоящем клиенте — системный диалог выбора файла,
|
||||||
|
// а выбранный файл КОПИРУЕТСЯ в папку клиента (не ссылка на исходный путь)
|
||||||
|
function pickPic() {
|
||||||
|
// для макета показываем готовый пример вместо файлового диалога
|
||||||
|
setPic('data:image/svg+xml;utf8,' + encodeURIComponent(
|
||||||
|
`<svg xmlns="http://www.w3.org/2000/svg" width="54" height="54">
|
||||||
|
<rect width="54" height="54" fill="#86C99A"/>
|
||||||
|
<circle cx="27" cy="21" r="8" fill="#121218"/>
|
||||||
|
<path d="M10 50 Q27 30 44 50 Z" fill="#121218"/>
|
||||||
|
</svg>`));
|
||||||
|
}
|
||||||
|
|
||||||
|
function setPic(src) {
|
||||||
|
const p = el('picPreview');
|
||||||
|
p.innerHTML = `<img src="${src}" alt="">`;
|
||||||
|
p.classList.add('filled');
|
||||||
|
el('picClear').style.display = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
function clearPic() {
|
||||||
|
const p = el('picPreview');
|
||||||
|
p.innerHTML = '🖼';
|
||||||
|
p.classList.remove('filled');
|
||||||
|
el('picClear').style.display = 'none';
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
Reference in New Issue
Block a user