fix: make active tab local-only, stop Automerge from overriding it
The active tab was stored in Automerge's shared doc (activeLayerId), causing different browser windows/sessions to fight over which tab is highlighted. When one window switched to rInbox, another window showing rFlows would have its tab bar update to highlight rInbox while still displaying rFlows content. Changes: - Active tab is now always determined locally by the URL/currentModuleId - Automerge sync only manages the tab LIST (which modules are open) and flows, not which tab is active - Removed sync.setActiveLayer() calls on tab switch - Removed activeLayerId reads from Automerge on connect and on remote change events - TabCache continues to manage active state correctly when switching tabs within the same page load Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
0bf3b3430c
commit
2bc1b78f30
|
|
@ -419,10 +419,15 @@ export function renderShell(opts: ShellOptions): string {
|
|||
window.__rspaceTabBar = tabBar;
|
||||
|
||||
// ── CommunitySync: merge with Automerge once connected ──
|
||||
// NOTE: The TAB LIST is shared via Automerge (which modules are open),
|
||||
// but the ACTIVE TAB is always local (determined by the URL / currentModuleId).
|
||||
// This prevents windows from fighting over which tab is highlighted.
|
||||
document.addEventListener('community-sync-ready', (e) => {
|
||||
const sync = e.detail?.sync;
|
||||
if (!sync) return;
|
||||
|
||||
const localActiveId = 'layer-' + currentModuleId;
|
||||
|
||||
// Merge: Automerge layers win if they exist, otherwise seed from localStorage
|
||||
const remoteLayers = sync.getLayers();
|
||||
if (remoteLayers.length > 0) {
|
||||
|
|
@ -433,24 +438,21 @@ export function renderShell(opts: ShellOptions): string {
|
|||
}
|
||||
layers = sync.getLayers();
|
||||
tabBar.setLayers(layers);
|
||||
const activeId = sync.doc.activeLayerId;
|
||||
if (activeId) tabBar.setAttribute('active', activeId);
|
||||
tabBar.setFlows(sync.getFlows());
|
||||
} else {
|
||||
// First connection: push all localStorage tabs into Automerge
|
||||
for (const l of layers) {
|
||||
sync.addLayer(l);
|
||||
}
|
||||
sync.setActiveLayer('layer-' + currentModuleId);
|
||||
}
|
||||
|
||||
// Active tab stays local — always matches the URL
|
||||
tabBar.setAttribute('active', localActiveId);
|
||||
|
||||
// Keep localStorage in sync
|
||||
saveTabs();
|
||||
|
||||
// Sync layer changes back to Automerge
|
||||
tabBar.addEventListener('layer-switch', (e) => {
|
||||
sync.setActiveLayer(e.detail.layerId);
|
||||
});
|
||||
// Sync layer list changes to Automerge (not active tab)
|
||||
tabBar.addEventListener('layer-add', (e) => {
|
||||
const { moduleId } = e.detail;
|
||||
const newLayer = makeLayer(moduleId, sync.getLayers().length);
|
||||
|
|
@ -469,13 +471,13 @@ export function renderShell(opts: ShellOptions): string {
|
|||
tabBar.addEventListener('flow-remove', (e) => { sync.removeFlow(e.detail.flowId); });
|
||||
tabBar.addEventListener('view-toggle', (e) => { sync.setLayerViewMode(e.detail.mode); });
|
||||
|
||||
// Listen for remote changes
|
||||
// Listen for remote changes — sync tab list and flows only.
|
||||
// Never touch the active tab: it's managed locally by TabCache
|
||||
// and the tab-bar component via layer-switch events.
|
||||
sync.addEventListener('change', () => {
|
||||
layers = sync.getLayers();
|
||||
tabBar.setLayers(layers);
|
||||
tabBar.setFlows(sync.getFlows());
|
||||
const activeId = sync.doc.activeLayerId;
|
||||
if (activeId) tabBar.setAttribute('active', activeId);
|
||||
const viewMode = sync.doc.layerViewMode;
|
||||
if (viewMode) tabBar.setAttribute('view-mode', viewMode);
|
||||
saveTabs(); // keep localStorage in sync
|
||||
|
|
|
|||
Loading…
Reference in New Issue