diff --git a/CloudServer/public/cablemanager.html b/CloudServer/public/cablemanager.html index 4bfd57d..a6e2f82 100644 --- a/CloudServer/public/cablemanager.html +++ b/CloudServer/public/cablemanager.html @@ -1519,16 +1519,65 @@ async function reloadAll(options) { const silent = !!(options && options.silent); try { + const prevGroups = audioCableGroups.slice(); + const prevStations = stations.slice(); await Promise.all([loadGroups(), loadStations()]); - renderGroupList(); - renderQuickSelects(); + const groupListChanged = JSON.stringify(prevGroups.map(g => ({ id: g.id, name: g.name, color: g.color, description: g.description }))) + !== JSON.stringify(audioCableGroups.map(g => ({ id: g.id, name: g.name, color: g.color, description: g.description }))); + const stationListChanged = prevStations.length !== stations.length + || prevStations.some((s, i) => stations[i] && (s.name !== stations[i].name || s.code !== stations[i].code)); + if (groupListChanged || stationListChanged) { + renderGroupList(); + renderQuickSelects(); + } if (currentGroupId) { const g = audioCableGroups.find(g => g.id === currentGroupId); - if (g) { - detailTempMembers = [...(g.stationNames || [])]; - selectedAvailable.clear(); - selectedMembers.clear(); - renderDualLists(); + if (!g) { + currentGroupId = null; + backToList(); + } else { + const pg = prevGroups.find(x => x.id === currentGroupId) || null; + const membersChanged = !pg || JSON.stringify(pg.stationNames || []) !== JSON.stringify(g.stationNames || []); + const metaChanged = !pg || pg.name !== g.name || pg.color !== g.color || pg.description !== g.description; + + if (silent) { + // 被动自动刷新:同步名字/描述/颜色的标题区,只在后台成员真的变了才同步成员(否则保留用户未保存的编辑) + const detailNameEl = document.getElementById('detail-name'); + const detailDescEl = document.getElementById('detail-description'); + const detailTitleEl = document.getElementById('detail-title'); + if (metaChanged) { + if (detailTitleEl && detailNameEl && !detailNameEl.matches(':focus')) { + detailNameEl.value = g.name || ''; + detailTitleEl.textContent = g.name || ''; + } + if (detailDescEl && !detailDescEl.matches(':focus')) { + detailDescEl.value = g.description || ''; + } + if (detailSelectedColor !== (g.color || PRESET_COLORS[0])) { + detailSelectedColor = g.color || PRESET_COLORS[0]; + document.getElementById('detail-color').style.background = detailSelectedColor; + _rebuildDetailColorPicker(); + } + } + if (membersChanged) { + // 后台分组成员已经变了(例如被别的端删除/改了分组)—— 同步掉成员,避免用户编辑的是已经不存在的状态 + detailTempMembers = [...(g.stationNames || [])]; + // 清理选择集中已经不存在的名字,保留仍然存在的 + for (const n of Array.from(selectedAvailable)) { + if (!stations.some(s => s.name === n)) selectedAvailable.delete(n); + } + for (const n of Array.from(selectedMembers)) { + if (!detailTempMembers.includes(n)) selectedMembers.delete(n); + } + } + if (membersChanged || stationListChanged || metaChanged) renderDualLists(); + } else { + // 用户主动点刷新:全同步(包括成员) + detailTempMembers = [...(g.stationNames || [])]; + selectedAvailable.clear(); + selectedMembers.clear(); + renderDualLists(); + } } } if (!silent) showToast('成功', '数据已刷新', 'success'); diff --git a/station_broadcast.lua b/station_broadcast.lua index 2ee9164..83a1a6f 100644 --- a/station_broadcast.lua +++ b/station_broadcast.lua @@ -1,6 +1,6 @@ -- 1. Configuration & Constants -local APP_VERSION_TEXT = "v1.0.110" +local APP_VERSION_TEXT = "v1.0.111" local CONFIG = { CLOUD_URL = "ws://stabadmin.fse-media.group",