feat(desktop): обёртка Tauri 2 вокруг веб-клиента

Первый инкремент Фазы 6 (docs/client-tauri.md): окно с тем же веб-клиентом
(по умолчанию https://gl.mhspx.su, адрес настраивается), трей с меню и
индикатором непрочитанных, нативные уведомления, глобальный push-to-talk и
переключение микрофона/deafen, автозапуск, single-instance, сохранение
геометрии окна, deep links glchat://…, автообновление по подписанному
манифесту.

Связь страницы с обёрткой — через платформенный адаптер
(web/src/lib/platform.ts) и минимальный типизированный набор команд;
в веб-клиенте появились системные уведомления об упоминаниях и личных
сообщениях и переключатель в настройках.

В web/src/stores/gateway.ts вместе с вызовом уведомления лежат правки по
дефектам realtime (READY и сессии) из параллельной волны: файл коммитится
целиком по договорённости с координатором.
This commit is contained in:
2026-09-22 21:46:01 +03:00
parent 594a5c0af5
commit cffcec72b8
52 changed files with 8659 additions and 16 deletions
+90
View File
@@ -0,0 +1,90 @@
<!doctype html>
<html lang="ru" data-theme="dark">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="color-scheme" content="dark light" />
<title>glchat — настройки приложения</title>
<link rel="stylesheet" href="settings.css" />
</head>
<body>
<main class="page">
<header class="head">
<h1>Настройки приложения</h1>
<p class="muted">
Это настройки desktop-обёртки. Настройки аккаунта, серверов и голоса живут внутри самого
клиента.
</p>
</header>
<section class="card">
<h2>Инстанс</h2>
<label class="field">
<span>Адрес клиента</span>
<input id="instance-url" type="text" spellcheck="false" placeholder="https://gl.mhspx.su" />
</label>
<p class="hint">
Тот же адрес, что открывается в браузере. Сторонние ссылки уходят в системный браузер, а
не открываются внутри окна.
</p>
<div class="row">
<button id="open-client" class="primary" type="button">Сохранить и открыть клиент</button>
<button id="reload-client" type="button">Перезагрузить клиент</button>
</div>
</section>
<section class="card">
<h2>Поведение</h2>
<label class="check">
<input id="autostart" type="checkbox" />
<span>Запускать при входе в систему (свёрнутым в трей)</span>
</label>
<label class="check">
<input id="close-to-tray" type="checkbox" />
<span>Закрытие окна сворачивает приложение в трей</span>
</label>
<label class="check">
<input id="notifications" type="checkbox" />
<span>Показывать системные уведомления об упоминаниях и личных сообщениях</span>
</label>
</section>
<section class="card">
<h2>Глобальные горячие клавиши</h2>
<p class="hint">
Работают, когда окно неактивно. Push-to-talk включает микрофон, пока клавиша удерживается:
в клиенте должен быть выбран режим микрофона «Push-to-talk» (Настройки → Голос).
</p>
<label class="field">
<span>Push-to-talk</span>
<select id="ptt-shortcut"></select>
</label>
<label class="field">
<span>Микрофон вкл/выкл</span>
<select id="mute-shortcut"></select>
</label>
<label class="field">
<span>Не слышу (deafen)</span>
<select id="deafen-shortcut"></select>
</label>
</section>
<section class="card">
<h2>Обновления</h2>
<p class="hint" id="updates-hint">
Обновления проверяются при запуске и вручную. Манифест отдаёт сам инстанс.
</p>
<div class="row">
<button id="check-updates" type="button">Проверить обновления</button>
<span class="muted" id="version"></span>
</div>
</section>
<footer class="foot">
<button id="save" class="primary" type="button">Сохранить</button>
<span id="status" class="status" role="status"></span>
</footer>
</main>
<script type="module" src="settings.js"></script>
</body>
</html>