diff --git a/miniapp/assets/clients.js b/miniapp/assets/clients.js
index 4e1b706..8861230 100644
--- a/miniapp/assets/clients.js
+++ b/miniapp/assets/clients.js
@@ -419,13 +419,52 @@ const Clients = (function () {
// Управление карточкой — кнопки прямо под шапкой
root.appendChild(renderClientManagement(client));
- // Быстрые действия для менеджера
+ // Быстрые действия для менеджера — кастомные SVG-иконки в орехе
+ const QA_ICON_PODBOR = `
+ `;
+ const QA_ICON_RULER = `
+ `;
+ const QA_ICON_WRENCH = `
+ `;
+ const QA_ICON_COPY = `
+ `;
const actionsRow = el(`
-
-
-
-
+
+
+
+
`);
actionsRow.querySelectorAll(".qa-btn").forEach(btn => {
@@ -1233,13 +1272,11 @@ const Clients = (function () {
}
let rec = null;
let recording = false;
- let baseText = ""; // текст до начала записи — чтобы не перетирать
+ let baseText = ""; // что было в textarea ДО старта записи
+ let confirmedFinal = ""; // финальная фраза текущей сессии записи
micBtn.addEventListener("click", () => {
- if (recording) {
- rec?.stop();
- return;
- }
+ if (recording) { rec?.stop(); return; }
try {
rec = new SR();
rec.lang = "ru-RU";
@@ -1251,7 +1288,7 @@ const Clients = (function () {
return;
}
baseText = (textarea.value || "").trim();
- const sep = baseText ? "\n" : "";
+ confirmedFinal = "";
rec.onstart = () => {
recording = true;
@@ -1261,20 +1298,21 @@ const Clients = (function () {
status.className = "note-status";
haptic && haptic("impact");
};
+ // Защита от дублей: пересчитываем ВСЕ финальные и interim с нуля
+ // на каждом событии. Не полагаемся на ev.resultIndex (в Chrome он
+ // ведёт себя нестабильно при паузах — отсюда дублирование слов).
rec.onresult = (ev) => {
- let interim = "";
- let final = "";
- for (let i = ev.resultIndex; i < ev.results.length; i++) {
+ let finalAll = "", interim = "";
+ for (let i = 0; i < ev.results.length; i++) {
const t = ev.results[i][0].transcript;
- if (ev.results[i].isFinal) final += t;
+ if (ev.results[i].isFinal) finalAll += t;
else interim += t;
}
- if (final) {
- baseText = (baseText + sep + final).trim();
- textarea.value = baseText;
- } else if (interim) {
- textarea.value = baseText + sep + interim;
- }
+ confirmedFinal = finalAll.trim();
+ const sep = baseText ? " " : "";
+ const fp = confirmedFinal ? sep + confirmedFinal : "";
+ const ip = interim.trim() ? ((baseText || confirmedFinal) ? " " : "") + interim.trim() : "";
+ textarea.value = baseText + fp + ip;
};
rec.onerror = (ev) => {
status.textContent = "Ошибка распознавания: " + (ev.error || "неизвестно");
@@ -1288,6 +1326,11 @@ const Clients = (function () {
micBtn.classList.remove("rec");
micBtn.textContent = "🎤 Диктовать";
if (status.textContent === "Слушаю...") status.textContent = "";
+ // Фиксируем подтверждённый текст в baseText на случай повторного запуска
+ if (confirmedFinal) {
+ baseText = (baseText + (baseText ? " " : "") + confirmedFinal).trim();
+ textarea.value = baseText;
+ }
haptic && haptic("impact");
};
try { rec.start(); }
diff --git a/miniapp/assets/podbor.css b/miniapp/assets/podbor.css
index 73d7b7d..82d7340 100644
--- a/miniapp/assets/podbor.css
+++ b/miniapp/assets/podbor.css
@@ -2134,34 +2134,74 @@
}
.client-call-btn:active { transform: scale(0.95); }
+/* ===== Быстрые действия — 2×2 объёмные кнопки-карточки ===== */
.client-quick-actions {
display: grid;
- grid-template-columns: 1fr 1fr 1fr;
- gap: 8px;
+ grid-template-columns: 1fr 1fr;
+ gap: 10px;
margin: 14px 0 18px;
}
-.client-quick-actions .qa-btn {
+
+.qa-btn {
+ position: relative;
display: flex;
flex-direction: column;
align-items: center;
- gap: 4px;
- padding: 12px 6px;
- background: var(--card, #fff);
- border: 1px solid rgba(107, 74, 43, 0.18);
- border-radius: 12px;
+ gap: 9px;
+ padding: 15px 10px 13px;
+ background:
+ linear-gradient(160deg,
+ rgba(255, 255, 255, 0.80) 0%,
+ rgba(245, 237, 220, 0.62) 100%);
+ border: 1px solid rgba(107, 74, 43, 0.16);
+ border-radius: 14px;
cursor: pointer;
font-family: inherit;
- font-size: 19px;
- line-height: 1;
+ box-shadow:
+ 0 2px 0 rgba(107, 74, 43, 0.20),
+ 0 1px 5px rgba(0, 0, 0, 0.07),
+ inset 0 1px 0 rgba(255, 255, 255, 0.90);
+ transition: transform 0.10s ease, box-shadow 0.10s ease;
+ -webkit-tap-highlight-color: transparent;
}
-.client-quick-actions .qa-btn:active { background: var(--paper-2, #F5EDDC); }
-.client-quick-actions .qa-btn span {
- font-size: 11px;
- font-weight: 500;
+
+.qa-btn:active {
+ transform: translateY(2px);
+ box-shadow:
+ 0 0px 0 rgba(107, 74, 43, 0.20),
+ inset 0 1px 4px rgba(0, 0, 0, 0.14),
+ inset 0 0 0 1px rgba(107, 74, 43, 0.10);
+}
+
+/* Круглый орехово-коричневый чип с иконкой */
+.qa-icon {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 46px;
+ height: 46px;
+ border-radius: 50%;
+ background: linear-gradient(145deg, #845A2E 0%, #5C3A1C 100%);
+ box-shadow:
+ 0 2px 0 rgba(0, 0, 0, 0.24),
+ inset 0 1px 0 rgba(255, 255, 255, 0.18);
+ color: #F5DAAA;
+ flex-shrink: 0;
+}
+
+.qa-icon svg {
+ width: 22px;
+ height: 22px;
+}
+
+/* Подпись под иконкой */
+.qa-label {
+ font-size: 11.5px;
+ font-weight: 600;
color: var(--ink, #1F1A14);
- margin-top: 4px;
- line-height: 1.2;
+ line-height: 1.25;
text-align: center;
+ letter-spacing: 0.01em;
}
/* ===== Хронология клиента ===== */
diff --git a/miniapp/index.html b/miniapp/index.html
index ddef96d..2c962da 100644
--- a/miniapp/index.html
+++ b/miniapp/index.html
@@ -12,14 +12,14 @@
-
-
+
+
-

+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+