- Added VoiceButton component (inline in App.jsx) with full
mousedown/mouseup/mouseleave + touchstart/touchend/touchcancel support
- Shows context-aware label: 🎙 按住说话 / ⏳ 准备中 / 🔴 松开发送 / ⚙ 思考中 / 🔊 播放中
- Pulsing red animation while recording, amber pulse while acquiring mic
- Disabled (gray) while AI is thinking or speaking
- Desktop: pill button docked at bottom of chat panel (max-width 380px)
- Mobile: fixed to bottom of viewport with safe-area-inset support,
height 60px for easy thumb tap; right-col padded so messages aren't hidden
- Updated hint text and listening status to be input-agnostic
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add JbotApiConfig Django model (DB singleton) for storing
Volcengine/OpenRouter credentials set via Settings UI
- New endpoint GET/POST /api/jbot/api-config/ — tokens masked as ***
on read; only non-placeholder values are updated on write
- views.py: _get_cfg() helper reads DB first, env vars as fallback
- Settings.jsx: new 🔑 API 配置 section with show/hide token fields
for VOLC App ID, Access Token, OpenRouter API Key, LLM Model, ASR Resource
- api.js: apiGetApiConfig() / apiSaveApiConfig() client helpers
- Dockerfile: COPY jbot/ in both builder + production stages (was missing)
- entrypoint.sh: runs migrate --noinput before gunicorn (auto-creates table)
- k8s/manifest.yaml: remove jbot-credentials secretKeyRef (no Secret needed);
keep LLM_MODEL/VOLC_TTS_VOICE/VOLC_ASR_RESOURCE as optional env defaults
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>