Fix mobile color picker popup clipping and locale update for tabs/sections

Color picker popover now uses fixed positioning on small screens to
escape the header toolbar overflow container. Section titles, sub-tab
labels, and filter placeholders use data-i18n attributes so they update
automatically on language change. Display picker title switches to
"Select a Device" for engine-owned display lists.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-01 14:26:15 +03:00
parent ddfa7637d6
commit 6366b0b317
9 changed files with 61 additions and 32 deletions

View File

@@ -25,6 +25,12 @@ export function openDisplayPicker(callback, selectedIndex, engineType = null) {
_pickerEngineType = engineType || null;
const lightbox = document.getElementById('display-picker-lightbox');
// Use "Select a Device" title for engines with own display lists (camera, scrcpy, etc.)
const titleEl = lightbox.querySelector('.display-picker-title');
if (titleEl) {
titleEl.textContent = t(_pickerEngineType ? 'displays.picker.title.device' : 'displays.picker.title');
}
lightbox.classList.add('active');
requestAnimationFrame(() => {

View File

@@ -1295,8 +1295,8 @@ function renderPictureSourcesList(streams) {
];
const tabBar = `<div class="stream-tab-bar">${tabs.map(tab =>
`<button class="stream-tab-btn${tab.key === activeTab ? ' active' : ''}" data-stream-tab="${tab.key}" onclick="switchStreamTab('${tab.key}')">${tab.icon} ${t(tab.titleKey)} <span class="stream-tab-count">${tab.count}</span></button>`
).join('')}<span class="cs-expand-collapse-group"><button class="btn-expand-collapse" onclick="expandAllStreamSections()" title="${t('section.expand_all')}">⊞</button><button class="btn-expand-collapse" onclick="collapseAllStreamSections()" title="${t('section.collapse_all')}">⊟</button><button class="tutorial-trigger-btn" onclick="startSourcesTutorial()" title="${t('tour.restart')}">${ICON_HELP}</button></span></div>`;
`<button class="stream-tab-btn${tab.key === activeTab ? ' active' : ''}" data-stream-tab="${tab.key}" onclick="switchStreamTab('${tab.key}')">${tab.icon} <span data-i18n="${tab.titleKey}">${t(tab.titleKey)}</span> <span class="stream-tab-count">${tab.count}</span></button>`
).join('')}<span class="cs-expand-collapse-group"><button class="btn-expand-collapse" onclick="expandAllStreamSections()" data-i18n-title="section.expand_all" title="${t('section.expand_all')}">⊞</button><button class="btn-expand-collapse" onclick="collapseAllStreamSections()" data-i18n-title="section.collapse_all" title="${t('section.collapse_all')}">⊟</button><button class="tutorial-trigger-btn" onclick="startSourcesTutorial()" data-i18n-title="tour.restart" title="${t('tour.restart')}">${ICON_HELP}</button></span></div>`;
const renderAudioSourceCard = (src) => {
const isMono = src.source_type === 'mono';

View File

@@ -569,8 +569,8 @@ export async function loadTargetsTab() {
];
const tabBar = `<div class="stream-tab-bar">${subTabs.map(tab =>
`<button class="target-sub-tab-btn stream-tab-btn${tab.key === activeSubTab ? ' active' : ''}" data-target-sub-tab="${tab.key}" onclick="switchTargetSubTab('${tab.key}')">${tab.icon} ${t(tab.titleKey)} <span class="stream-tab-count">${tab.count}</span></button>`
).join('')}<span class="cs-expand-collapse-group"><button class="btn-expand-collapse" onclick="expandAllTargetSections()" title="${t('section.expand_all')}">⊞</button><button class="btn-expand-collapse" onclick="collapseAllTargetSections()" title="${t('section.collapse_all')}">⊟</button><button class="tutorial-trigger-btn" onclick="startTargetsTutorial()" title="${t('tour.restart')}">${ICON_HELP}</button></span></div>`;
`<button class="target-sub-tab-btn stream-tab-btn${tab.key === activeSubTab ? ' active' : ''}" data-target-sub-tab="${tab.key}" onclick="switchTargetSubTab('${tab.key}')">${tab.icon} <span data-i18n="${tab.titleKey}">${t(tab.titleKey)}</span> <span class="stream-tab-count">${tab.count}</span></button>`
).join('')}<span class="cs-expand-collapse-group"><button class="btn-expand-collapse" onclick="expandAllTargetSections()" data-i18n-title="section.expand_all" title="${t('section.expand_all')}">⊞</button><button class="btn-expand-collapse" onclick="collapseAllTargetSections()" data-i18n-title="section.collapse_all" title="${t('section.collapse_all')}">⊟</button><button class="tutorial-trigger-btn" onclick="startTargetsTutorial()" data-i18n-title="tour.restart" title="${t('tour.restart')}">${ICON_HELP}</button></span></div>`;
// Use window.createPatternTemplateCard to avoid circular import
const createPatternTemplateCard = window.createPatternTemplateCard || (() => '');