release: bump version to 0.38.0
This commit is contained in:
116
frontend/public/earth/js/controls.js
vendored
116
frontend/public/earth/js/controls.js
vendored
@@ -1,7 +1,13 @@
|
||||
// controls.js - Zoom, rotate and toggle controls
|
||||
|
||||
import * as THREE from "three";
|
||||
import { CONFIG, EARTH_CONFIG, ROTATION_MODE } from "./constants.js";
|
||||
import {
|
||||
CONFIG,
|
||||
CRUISE_MODULES,
|
||||
DEFAULT_CRUISE_MODULES,
|
||||
EARTH_CONFIG,
|
||||
ROTATION_MODE,
|
||||
} from "./constants.js";
|
||||
import { setEarthStatValue, updateZoomDisplay, showStatusMessage } from "./ui.js";
|
||||
import {
|
||||
toggleTerrain,
|
||||
@@ -109,6 +115,7 @@ let activeMobileDrawerId = null;
|
||||
let mobileDrawerOpen = false;
|
||||
let mobileDrawerCard = "layers";
|
||||
let mobileDrawerHintTimer = null;
|
||||
const ALLOWED_CRUISE_MODULES = new Set(Object.values(CRUISE_MODULES));
|
||||
|
||||
function detectLayoutMode() {
|
||||
const width = window.innerWidth;
|
||||
@@ -633,6 +640,7 @@ function getCurrentPanelVisibilitySnapshot() {
|
||||
function getCurrentSharedSettingsSnapshot() {
|
||||
return {
|
||||
rotationMode,
|
||||
cruiseModules: getCruiseModules(),
|
||||
layerVisibility: Object.fromEntries(
|
||||
getPersistedLayers().map((layer) => [layer.id, Boolean(layer.getVisible?.())]),
|
||||
),
|
||||
@@ -667,6 +675,7 @@ function cloneEarthSettings(settings) {
|
||||
version: 2,
|
||||
shared: {
|
||||
rotationMode: settings.shared.rotationMode,
|
||||
cruiseModules: [...(settings.shared.cruiseModules || DEFAULT_CRUISE_MODULES)],
|
||||
terrainOpacity: settings.shared.terrainOpacity,
|
||||
dayNightEnabled: settings.shared.dayNightEnabled,
|
||||
defaultEarthZoom: settings.shared.defaultEarthZoom,
|
||||
@@ -738,6 +747,14 @@ function normalizeEarthSettings(rawSettings, defaults) {
|
||||
sharedSettings?.rotationMode === ROTATION_MODE.CRUISE
|
||||
? ROTATION_MODE.CRUISE
|
||||
: defaults.shared.rotationMode;
|
||||
const requestedCruiseModules = Array.isArray(sharedSettings?.cruiseModules)
|
||||
? sharedSettings.cruiseModules
|
||||
: defaults.shared.cruiseModules;
|
||||
const nextCruiseModules = Array.from(
|
||||
new Set(
|
||||
requestedCruiseModules.filter((moduleId) => ALLOWED_CRUISE_MODULES.has(moduleId)),
|
||||
),
|
||||
);
|
||||
const nextTerrainOpacity = Number.parseFloat(sharedSettings?.terrainOpacity);
|
||||
const nextDayNightEnabled = typeof sharedSettings?.dayNightEnabled === "boolean"
|
||||
? sharedSettings.dayNightEnabled
|
||||
@@ -750,6 +767,9 @@ function normalizeEarthSettings(rawSettings, defaults) {
|
||||
version: 2,
|
||||
shared: {
|
||||
rotationMode: nextRotationMode,
|
||||
cruiseModules: nextCruiseModules.length > 0
|
||||
? nextCruiseModules
|
||||
: [...DEFAULT_CRUISE_MODULES],
|
||||
layerVisibility: normalizedLayerVisibility,
|
||||
terrainOpacity: Number.isFinite(nextTerrainOpacity)
|
||||
? nextTerrainOpacity
|
||||
@@ -832,6 +852,79 @@ function persistEarthSettings() {
|
||||
}
|
||||
}
|
||||
|
||||
function dispatchCruiseModulesChange() {
|
||||
window.dispatchEvent(
|
||||
new CustomEvent("earth:cruise-modules-change", {
|
||||
detail: {
|
||||
modules: getCruiseModules(),
|
||||
},
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
function normalizeCruiseModules(nextModules) {
|
||||
const sourceModules = Array.isArray(nextModules) ? nextModules : DEFAULT_CRUISE_MODULES;
|
||||
const normalizedModules = Array.from(
|
||||
new Set(sourceModules.filter((moduleId) => ALLOWED_CRUISE_MODULES.has(moduleId))),
|
||||
);
|
||||
return normalizedModules.length > 0
|
||||
? normalizedModules
|
||||
: [...DEFAULT_CRUISE_MODULES];
|
||||
}
|
||||
|
||||
function syncCruiseModuleControls() {
|
||||
const enabledModules = new Set(getCruiseModules());
|
||||
document.querySelectorAll("[data-cruise-module-toggle]").forEach((button) => {
|
||||
if (!(button instanceof HTMLButtonElement)) return;
|
||||
const moduleId = button.dataset.cruiseModuleToggle || "";
|
||||
const active = enabledModules.has(moduleId);
|
||||
button.classList.toggle("is-active", active);
|
||||
button.setAttribute("aria-pressed", active ? "true" : "false");
|
||||
});
|
||||
}
|
||||
|
||||
export function getCruiseModules() {
|
||||
const configuredModules = earthSettingsState?.shared?.cruiseModules;
|
||||
return normalizeCruiseModules(configuredModules);
|
||||
}
|
||||
|
||||
export function isCruiseModuleEnabled(moduleId) {
|
||||
return getCruiseModules().includes(moduleId);
|
||||
}
|
||||
|
||||
export function setCruiseModules(nextModules, { persist = true, suppressStatus = false } = {}) {
|
||||
const normalizedModules = normalizeCruiseModules(nextModules);
|
||||
const previousModules = getCruiseModules();
|
||||
const changed =
|
||||
normalizedModules.length !== previousModules.length ||
|
||||
normalizedModules.some((moduleId, index) => previousModules[index] !== moduleId);
|
||||
|
||||
if (!changed) {
|
||||
syncCruiseModuleControls();
|
||||
return normalizedModules;
|
||||
}
|
||||
|
||||
earthSettingsState = cloneEarthSettings(
|
||||
earthSettingsState || cloneEarthSettings(captureEarthSettingsDefaults()),
|
||||
);
|
||||
earthSettingsState.shared.cruiseModules = [...normalizedModules];
|
||||
syncCruiseModuleControls();
|
||||
dispatchCruiseModulesChange();
|
||||
|
||||
if (persist) {
|
||||
persistEarthSettings();
|
||||
}
|
||||
|
||||
if (!suppressStatus) {
|
||||
const labels = normalizedModules.map((moduleId) =>
|
||||
moduleId === CRUISE_MODULES.NEWS ? "新闻" : "BGP",
|
||||
);
|
||||
showStatusMessage(`巡航模块已切换为:${labels.join(" + ")}`, "info");
|
||||
}
|
||||
|
||||
return normalizedModules;
|
||||
}
|
||||
|
||||
function syncDefaultEarthZoomUi(nextZoom) {
|
||||
const sliders = document.querySelectorAll("#default-earth-size-slider, [data-default-earth-size-slider]");
|
||||
const values = document.querySelectorAll("#default-earth-size-value, [data-default-earth-size-value]");
|
||||
@@ -894,6 +987,7 @@ async function applyEarthSettings(settings) {
|
||||
});
|
||||
|
||||
setRotationMode(settings.shared.rotationMode, { persist: false, suppressStatus: true });
|
||||
setCruiseModules(settings.shared.cruiseModules, { persist: false, suppressStatus: true });
|
||||
|
||||
if (typeof settings.shared.dayNightEnabled === "boolean") {
|
||||
applyDayNightEnabled(settings.shared.dayNightEnabled, { persist: false });
|
||||
@@ -1702,6 +1796,7 @@ function setupSettingsControls() {
|
||||
const terrainOpacityValues = document.querySelectorAll("#terrain-opacity-value, [data-terrain-opacity-value]");
|
||||
const defaultEarthSizeSliders = document.querySelectorAll("#default-earth-size-slider, [data-default-earth-size-slider]");
|
||||
const rotationModeButtons = document.querySelectorAll("[data-rotation-mode]");
|
||||
const cruiseModuleButtons = document.querySelectorAll("[data-cruise-module-toggle]");
|
||||
const syncTerrainOpacityUi = (nextOpacity) => {
|
||||
const safeOpacity = Math.round(nextOpacity * 100);
|
||||
terrainOpacitySliders.forEach((slider) => {
|
||||
@@ -1756,6 +1851,24 @@ function setupSettingsControls() {
|
||||
});
|
||||
});
|
||||
|
||||
cruiseModuleButtons.forEach((button) => {
|
||||
bindListener(button, "click", (event) => {
|
||||
const target = event.currentTarget;
|
||||
if (!(target instanceof HTMLButtonElement)) return;
|
||||
const moduleId = target.dataset.cruiseModuleToggle;
|
||||
if (!moduleId) return;
|
||||
|
||||
const currentModules = new Set(getCruiseModules());
|
||||
if (currentModules.has(moduleId)) {
|
||||
currentModules.delete(moduleId);
|
||||
} else {
|
||||
currentModules.add(moduleId);
|
||||
}
|
||||
|
||||
setCruiseModules(Array.from(currentModules));
|
||||
});
|
||||
});
|
||||
|
||||
document.querySelectorAll("#toggle-daynight, [data-daynight-toggle]").forEach((dayNightToggle) => {
|
||||
if (!(dayNightToggle instanceof HTMLInputElement)) return;
|
||||
bindListener(dayNightToggle, "change", () => {
|
||||
@@ -1772,6 +1885,7 @@ function setupSettingsControls() {
|
||||
applyEarthSettings(loadEarthSettings());
|
||||
syncAllHudPanelToggles();
|
||||
syncRotationModeButtons();
|
||||
syncCruiseModuleControls();
|
||||
syncDayNightToggle(dayNightEnabled);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user