|
141 | 141 | temporalInsights: [], |
142 | 142 | temporalFocus: null, |
143 | 143 | nextSessionId: 1, |
144 | | - activeCompassLens: "movement", |
145 | | - activeLensPreset: "", |
146 | | - shellFilter: null, |
147 | | - shellFilterEnabled: false, |
148 | | - constellationZoom: 1, |
149 | | - constellationPanX: 0, |
150 | | - constellationPanY: 0, |
151 | 144 | replayingSessionId: 0 |
152 | 145 | }; |
153 | 146 |
|
|
745 | 738 | runtimeState.queryNarrative = "Session cleared. Restoring the default Impressionism opening scene."; |
746 | 739 | runtimeState.temporalInsights = []; |
747 | 740 | runtimeState.temporalFocus = null; |
748 | | - runtimeState.activeLensPreset = ""; |
749 | | - runtimeState.activeCompassLens = "movement"; |
750 | | - runtimeState.shellFilterEnabled = false; |
| 741 | + browserAdapterState.activeLensPreset = ""; |
| 742 | + browserAdapterState.activeCompassLens = "movement"; |
| 743 | + browserAdapterState.shellFilterEnabled = false; |
751 | 744 | runtimeState.multilingualEntityLabels = {}; |
752 | | - runtimeState.constellationZoom = 1; |
753 | | - runtimeState.constellationPanX = 0; |
754 | | - runtimeState.constellationPanY = 0; |
| 745 | + browserAdapterState.constellationZoom = 1; |
| 746 | + browserAdapterState.constellationPanX = 0; |
| 747 | + browserAdapterState.constellationPanY = 0; |
755 | 748 | buildShellFilter(); |
756 | 749 | setActiveButton(modeButtons, modeButtons.find((button) => button.dataset.mode === "observatory")); |
757 | 750 | renderConstellationZoomControls(); |
|
1438 | 1431 | } |
1439 | 1432 |
|
1440 | 1433 | function selectedLensConfig(languageCode) { |
1441 | | - const activePreset = runtimeState.activeLensPreset; |
| 1434 | + const activePreset = browserAdapterState.activeLensPreset; |
1442 | 1435 | if (activePreset && lensPresetContent[activePreset]) { |
1443 | 1436 | return lensPresetContent[activePreset][languageCode] || lensPresetContent[activePreset].en; |
1444 | 1437 | } |
1445 | | - const activeLens = runtimeState.activeCompassLens || "movement"; |
| 1438 | + const activeLens = browserAdapterState.activeCompassLens || "movement"; |
1446 | 1439 | return (compassLensContent[activeLens] && (compassLensContent[activeLens][languageCode] || compassLensContent[activeLens].en)) || null; |
1447 | 1440 | } |
1448 | 1441 |
|
|
1484 | 1477 | } |
1485 | 1478 |
|
1486 | 1479 | function getEffectiveLensKey() { |
1487 | | - const preset = runtimeState.activeLensPreset; |
| 1480 | + const preset = browserAdapterState.activeLensPreset; |
1488 | 1481 | if (preset === "lineage") { |
1489 | 1482 | return "influence"; |
1490 | 1483 | } |
|
1497 | 1490 | if (preset === "cross-language") { |
1498 | 1491 | return ""; |
1499 | 1492 | } |
1500 | | - if (!runtimeState.shellFilterEnabled) { |
| 1493 | + if (!browserAdapterState.shellFilterEnabled) { |
1501 | 1494 | return ""; |
1502 | 1495 | } |
1503 | | - return runtimeState.activeCompassLens || "movement"; |
| 1496 | + return browserAdapterState.activeCompassLens || "movement"; |
1504 | 1497 | } |
1505 | 1498 |
|
1506 | 1499 | function buildShellFilter() { |
1507 | | - const preset = runtimeState.activeLensPreset || ""; |
| 1500 | + const preset = browserAdapterState.activeLensPreset || ""; |
1508 | 1501 | const effectiveLens = getEffectiveLensKey(); |
1509 | | - runtimeState.shellFilter = { |
1510 | | - lens: runtimeState.activeCompassLens || "", |
| 1502 | + browserAdapterState.shellFilter = { |
| 1503 | + lens: browserAdapterState.activeCompassLens || "", |
1511 | 1504 | preset, |
1512 | 1505 | effectiveLens |
1513 | 1506 | }; |
1514 | 1507 | } |
1515 | 1508 |
|
1516 | 1509 | function nodeMatchesShellFilter(node, snapshot) { |
1517 | | - const filter = runtimeState.shellFilter; |
| 1510 | + const filter = browserAdapterState.shellFilter; |
1518 | 1511 | if (!filter || (!filter.effectiveLens && !filter.preset)) { |
1519 | 1512 | return true; |
1520 | 1513 | } |
|
1531 | 1524 | } |
1532 | 1525 |
|
1533 | 1526 | function relationMatchesShellFilter(relation, visibleNodeIds) { |
1534 | | - const filter = runtimeState.shellFilter; |
| 1527 | + const filter = browserAdapterState.shellFilter; |
1535 | 1528 | if (!filter || (!filter.effectiveLens && !filter.preset)) { |
1536 | 1529 | return true; |
1537 | 1530 | } |
|
1607 | 1600 | const legendEl = document.getElementById("constellation-legend"); |
1608 | 1601 | if (!legendEl) return; |
1609 | 1602 | const selectedType = String((runtimeState.selectedEntity && runtimeState.selectedEntity.type) || "").toLowerCase(); |
1610 | | - const lens = runtimeState.activeCompassLens || "movement"; |
| 1603 | + const lens = browserAdapterState.activeCompassLens || "movement"; |
1611 | 1604 | const labels = getLegendLabels(selectedType, lens); |
1612 | 1605 | const set = (id, text) => { const el = document.getElementById(id); if (el) el.textContent = text || ""; }; |
1613 | 1606 | set("legend-top", labels.top); |
|
1626 | 1619 | function updateCompassCore() { |
1627 | 1620 | const coreEl = document.querySelector(".compass-core"); |
1628 | 1621 | if (!coreEl) return; |
1629 | | - const activeLens = runtimeState.activeCompassLens || "movement"; |
| 1622 | + const activeLens = browserAdapterState.activeCompassLens || "movement"; |
1630 | 1623 | const entity = runtimeState.selectedEntity; |
1631 | 1624 |
|
1632 | 1625 | const labelEl = coreEl.querySelector(".compass-core-label"); |
|
1653 | 1646 | } |
1654 | 1647 |
|
1655 | 1648 | function renderLensControls() { |
1656 | | - const hasPreset = Boolean(runtimeState.activeLensPreset); |
| 1649 | + const hasPreset = Boolean(browserAdapterState.activeLensPreset); |
1657 | 1650 | compassPoleButtons.forEach((button) => { |
1658 | | - const isActive = !hasPreset && button.dataset.lens === runtimeState.activeCompassLens; |
| 1651 | + const isActive = !hasPreset && button.dataset.lens === browserAdapterState.activeCompassLens; |
1659 | 1652 | button.classList.toggle("is-active", isActive); |
1660 | 1653 | button.classList.toggle("is-muted", hasPreset); |
1661 | 1654 | button.classList.toggle("is-primary", isActive); |
|
1668 | 1661 | } |
1669 | 1662 | }); |
1670 | 1663 | lensPresetButtons.forEach((button) => { |
1671 | | - const isActive = button.dataset.preset === runtimeState.activeLensPreset; |
| 1664 | + const isActive = button.dataset.preset === browserAdapterState.activeLensPreset; |
1672 | 1665 | button.classList.toggle("is-active", isActive); |
1673 | 1666 | button.classList.toggle("is-muted", !isActive && hasPreset); |
1674 | 1667 | }); |
|
1687 | 1680 | } |
1688 | 1681 |
|
1689 | 1682 | async function applyShellLens(lens, preset = "", enableFilter = true) { |
1690 | | - runtimeState.activeCompassLens = lens || runtimeState.activeCompassLens || "movement"; |
1691 | | - runtimeState.activeLensPreset = preset; |
1692 | | - runtimeState.shellFilterEnabled = enableFilter; |
| 1683 | + browserAdapterState.activeCompassLens = lens || browserAdapterState.activeCompassLens || "movement"; |
| 1684 | + browserAdapterState.activeLensPreset = preset; |
| 1685 | + browserAdapterState.shellFilterEnabled = enableFilter; |
1693 | 1686 | buildShellFilter(); |
1694 | 1687 | renderLensControls(); |
1695 | 1688 | updateLensNarrative(); |
|
1887 | 1880 | } |
1888 | 1881 |
|
1889 | 1882 | function renderConstellationZoomControls() { |
1890 | | - const zoom = runtimeState.constellationZoom || 1; |
1891 | | - const panX = runtimeState.constellationPanX || 0; |
1892 | | - const panY = runtimeState.constellationPanY || 0; |
| 1883 | + const zoom = browserAdapterState.constellationZoom || 1; |
| 1884 | + const panX = browserAdapterState.constellationPanX || 0; |
| 1885 | + const panY = browserAdapterState.constellationPanY || 0; |
1893 | 1886 | const transform = "translate(" + panX + "px, " + panY + "px) scale(" + zoom + ")"; |
1894 | 1887 | if (constellationLinksEl) { |
1895 | 1888 | constellationLinksEl.style.transform = transform; |
|
1917 | 1910 | function renderConstellationMinimap() { |
1918 | 1911 | const canvas = document.getElementById("constellation-minimap"); |
1919 | 1912 | if (!canvas) return; |
1920 | | - const zoom = runtimeState.constellationZoom || 1; |
| 1913 | + const zoom = browserAdapterState.constellationZoom || 1; |
1921 | 1914 | const isVisible = zoom > 1.05; |
1922 | 1915 | canvas.classList.toggle("is-visible", isVisible); |
1923 | 1916 | if (!isVisible) return; |
|
1961 | 1954 | const constellationEl = document.querySelector(".constellation"); |
1962 | 1955 | if (constellationEl) { |
1963 | 1956 | const cRect = constellationEl.getBoundingClientRect(); |
1964 | | - const panX = runtimeState.constellationPanX || 0; |
1965 | | - const panY = runtimeState.constellationPanY || 0; |
| 1957 | + const panX = browserAdapterState.constellationPanX || 0; |
| 1958 | + const panY = browserAdapterState.constellationPanY || 0; |
1966 | 1959 | const panXPct = panX / cRect.width * 100; |
1967 | 1960 | const panYPct = panY / cRect.height * 100; |
1968 | 1961 | const xMin = Math.max(0, 50 + (-50 - panXPct) / zoom); |
|
1976 | 1969 | } |
1977 | 1970 |
|
1978 | 1971 | function setConstellationZoom(nextZoom) { |
1979 | | - runtimeState.constellationZoom = clamp(nextZoom, 0.3, 2.5); |
| 1972 | + browserAdapterState.constellationZoom = clamp(nextZoom, 0.3, 2.5); |
1980 | 1973 | renderConstellationZoomControls(); |
1981 | 1974 | } |
1982 | 1975 |
|
|
2678 | 2671 | graphe: { |
2679 | 2672 | noeuds: new Map(), |
2680 | 2673 | relations: [] |
2681 | | - } |
| 2674 | + }, |
| 2675 | + activeCompassLens: "movement", |
| 2676 | + activeLensPreset: "", |
| 2677 | + shellFilterEnabled: false, |
| 2678 | + shellFilter: null, |
| 2679 | + constellationZoom: 1, |
| 2680 | + constellationPanX: 0, |
| 2681 | + constellationPanY: 0 |
2682 | 2682 | }; |
2683 | 2683 |
|
2684 | 2684 | if (chronologyLoadMoreEl) { |
|
2711 | 2711 |
|
2712 | 2712 | if (constellationZoomOutEl) { |
2713 | 2713 | constellationZoomOutEl.addEventListener("click", () => { |
2714 | | - setConstellationZoom((runtimeState.constellationZoom || 1) - 0.2); |
| 2714 | + setConstellationZoom((browserAdapterState.constellationZoom || 1) - 0.2); |
2715 | 2715 | }); |
2716 | 2716 | } |
2717 | 2717 |
|
2718 | 2718 | if (constellationZoomInEl) { |
2719 | 2719 | constellationZoomInEl.addEventListener("click", () => { |
2720 | | - setConstellationZoom((runtimeState.constellationZoom || 1) + 0.2); |
| 2720 | + setConstellationZoom((browserAdapterState.constellationZoom || 1) + 0.2); |
2721 | 2721 | }); |
2722 | 2722 | } |
2723 | 2723 |
|
2724 | 2724 | if (constellationZoomResetEl) { |
2725 | 2725 | constellationZoomResetEl.addEventListener("click", () => { |
2726 | | - runtimeState.constellationPanX = 0; |
2727 | | - runtimeState.constellationPanY = 0; |
| 2726 | + browserAdapterState.constellationPanX = 0; |
| 2727 | + browserAdapterState.constellationPanY = 0; |
2728 | 2728 | setConstellationZoom(1); |
2729 | 2729 | }); |
2730 | 2730 | } |
|
2740 | 2740 | e.preventDefault(); |
2741 | 2741 | const step = 0.15; |
2742 | 2742 | const delta = e.deltaY > 0 ? -step : step; |
2743 | | - setConstellationZoom((runtimeState.constellationZoom || 1) + delta); |
| 2743 | + setConstellationZoom((browserAdapterState.constellationZoom || 1) + delta); |
2744 | 2744 | }, { passive: false }); |
2745 | 2745 |
|
2746 | 2746 | let isPanning = false; |
|
2754 | 2754 | panStart = { |
2755 | 2755 | x: e.clientX, |
2756 | 2756 | y: e.clientY, |
2757 | | - panX: runtimeState.constellationPanX || 0, |
2758 | | - panY: runtimeState.constellationPanY || 0 |
| 2757 | + panX: browserAdapterState.constellationPanX || 0, |
| 2758 | + panY: browserAdapterState.constellationPanY || 0 |
2759 | 2759 | }; |
2760 | 2760 | constellationEl.setPointerCapture(e.pointerId); |
2761 | 2761 | constellationEl.classList.add("is-panning"); |
|
2768 | 2768 | } |
2769 | 2769 | const rect = constellationEl.getBoundingClientRect(); |
2770 | 2770 | const maxPan = Math.max(rect.width, rect.height) * 0.6; |
2771 | | - runtimeState.constellationPanX = Math.max(-maxPan, Math.min(maxPan, panStart.panX + (e.clientX - panStart.x))); |
2772 | | - runtimeState.constellationPanY = Math.max(-maxPan, Math.min(maxPan, panStart.panY + (e.clientY - panStart.y))); |
| 2771 | + browserAdapterState.constellationPanX = Math.max(-maxPan, Math.min(maxPan, panStart.panX + (e.clientX - panStart.x))); |
| 2772 | + browserAdapterState.constellationPanY = Math.max(-maxPan, Math.min(maxPan, panStart.panY + (e.clientY - panStart.y))); |
2773 | 2773 | renderConstellationZoomControls(); |
2774 | 2774 | }); |
2775 | 2775 |
|
|
2981 | 2981 | total_noeuds: browserAdapterState.graphe.noeuds.size, |
2982 | 2982 | total_relations: browserAdapterState.graphe.relations.length |
2983 | 2983 | } |
2984 | | - } |
| 2984 | + }, |
| 2985 | + lentille_compas: browserAdapterState.activeCompassLens, |
| 2986 | + preset_lentille: browserAdapterState.activeLensPreset, |
| 2987 | + filtre_actif: browserAdapterState.shellFilterEnabled, |
| 2988 | + zoom_constellation: browserAdapterState.constellationZoom, |
| 2989 | + pan_constellation_x: browserAdapterState.constellationPanX, |
| 2990 | + pan_constellation_y: browserAdapterState.constellationPanY |
2985 | 2991 | }; |
2986 | 2992 | } |
2987 | 2993 |
|
|
3202 | 3208 |
|
3203 | 3209 | function semanticLayoutSectors(selectedNode, nodes, relationByTarget, relationBySource) { |
3204 | 3210 | const selectedType = String((selectedNode && selectedNode.type) || "").toLowerCase(); |
3205 | | - const activeLens = runtimeState.activeCompassLens || "movement"; |
| 3211 | + const activeLens = browserAdapterState.activeCompassLens || "movement"; |
3206 | 3212 |
|
3207 | 3213 | const sectors = { |
3208 | 3214 | primary: { start: -150, end: 150, nodes: [], radii: [22, 32, 41, 47] }, |
|
3524 | 3530 | const nodeEl = document.createElement("button"); |
3525 | 3531 | nodeEl.type = "button"; |
3526 | 3532 | nodeEl.dataset.nodeId = node.id; |
3527 | | - nodeEl.className = "node " + constellationClassForType(node.type) + (node.id === selectedId ? " is-selected" : "") + (isContextDetail ? " is-context-detail" : "") + (snapshot.affichage_chargement && node.id === runtimeState.lastRequestedEntityId ? " is-loading" : "") + (isTemporalFocus ? " is-temporal-focus" : "") + (isMutedTemporally ? " is-muted-temporal" : "") + (runtimeState.shellFilter && runtimeState.shellFilter.effectiveLens && isFilterFocus ? " is-filter-focus" : ""); |
| 3533 | + nodeEl.className = "node " + constellationClassForType(node.type) + (node.id === selectedId ? " is-selected" : "") + (isContextDetail ? " is-context-detail" : "") + (snapshot.affichage_chargement && node.id === runtimeState.lastRequestedEntityId ? " is-loading" : "") + (isTemporalFocus ? " is-temporal-focus" : "") + (isMutedTemporally ? " is-muted-temporal" : "") + (browserAdapterState.shellFilter && browserAdapterState.shellFilter.effectiveLens && isFilterFocus ? " is-filter-focus" : ""); |
3528 | 3534 | nodeEl.style.left = position.x + "%"; |
3529 | 3535 | nodeEl.style.top = position.y + "%"; |
3530 | 3536 | const degree = nodeDegree.get(node.id) || 0; |
|
4318 | 4324 | lensPresetButtons.forEach((button) => { |
4319 | 4325 | button.addEventListener("click", async () => { |
4320 | 4326 | const preset = button.dataset.preset || ""; |
4321 | | - if (runtimeState.activeLensPreset === preset) { |
4322 | | - await applyShellLens(runtimeState.activeCompassLens || "movement", "", false); |
| 4327 | + if (browserAdapterState.activeLensPreset === preset) { |
| 4328 | + await applyShellLens(browserAdapterState.activeCompassLens || "movement", "", false); |
4323 | 4329 | return; |
4324 | 4330 | } |
4325 | | - await applyShellLens(runtimeState.activeCompassLens || "movement", preset, true); |
| 4331 | + await applyShellLens(browserAdapterState.activeCompassLens || "movement", preset, true); |
4326 | 4332 | }); |
4327 | 4333 | }); |
4328 | 4334 |
|
|
0 commit comments