release: bump version to 0.29.1
This commit is contained in:
@@ -2,8 +2,13 @@
|
||||
|
||||
let statusTimeoutId = null;
|
||||
let statusHideTimeoutId = null;
|
||||
let statusReplayTimeoutId = null;
|
||||
const STATUS_BASE_CLASS = "earth-status-message";
|
||||
const STATUS_DISPLAY_MS = 3000;
|
||||
const STATUS_FADE_MS = 280;
|
||||
let statusQueue = [];
|
||||
let statusBusy = false;
|
||||
let loadingActive = false;
|
||||
let loadingLockedWidth = 0;
|
||||
|
||||
function getElement(id) {
|
||||
return document.getElementById(id);
|
||||
@@ -19,53 +24,97 @@ function clearStatusTimers() {
|
||||
clearTimeout(statusTimeoutId);
|
||||
statusTimeoutId = null;
|
||||
}
|
||||
|
||||
if (statusHideTimeoutId) {
|
||||
clearTimeout(statusHideTimeoutId);
|
||||
statusHideTimeoutId = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (statusReplayTimeoutId) {
|
||||
clearTimeout(statusReplayTimeoutId);
|
||||
statusReplayTimeoutId = null;
|
||||
function clearLoadingWidthLock(statusEl) {
|
||||
loadingLockedWidth = 0;
|
||||
if (statusEl) {
|
||||
statusEl.style.minWidth = "";
|
||||
}
|
||||
}
|
||||
|
||||
// Show status message
|
||||
export function showStatusMessage(message, type = "info") {
|
||||
function updateLoadingWidthLock(statusEl) {
|
||||
if (!statusEl || !loadingActive) return;
|
||||
const nextWidth = Math.ceil(statusEl.getBoundingClientRect().width || statusEl.scrollWidth || 0);
|
||||
if (nextWidth <= 0) return;
|
||||
loadingLockedWidth = Math.max(loadingLockedWidth, nextWidth);
|
||||
statusEl.style.minWidth = `${loadingLockedWidth}px`;
|
||||
}
|
||||
|
||||
function buildStatusContent(statusEl, message, type) {
|
||||
statusEl.innerHTML = "";
|
||||
|
||||
const indicator = document.createElement("span");
|
||||
indicator.className = "earth-status-indicator";
|
||||
indicator.setAttribute("aria-hidden", "true");
|
||||
|
||||
const dotCount = type === "loading" ? 3 : 1;
|
||||
for (let i = 0; i < dotCount; i++) {
|
||||
const dot = document.createElement("span");
|
||||
dot.className = "earth-status-dot";
|
||||
indicator.appendChild(dot);
|
||||
}
|
||||
|
||||
const text = document.createElement("span");
|
||||
text.className = "earth-status-text";
|
||||
text.textContent = message;
|
||||
|
||||
statusEl.appendChild(indicator);
|
||||
statusEl.appendChild(text);
|
||||
}
|
||||
|
||||
function hideStatusElement(statusEl, onHidden) {
|
||||
statusEl.classList.remove("visible");
|
||||
statusHideTimeoutId = setTimeout(() => {
|
||||
if (!statusEl.classList.contains("visible")) {
|
||||
setElementDisplay(statusEl, false);
|
||||
statusEl.className = STATUS_BASE_CLASS;
|
||||
statusEl.innerHTML = "";
|
||||
}
|
||||
statusHideTimeoutId = null;
|
||||
if (typeof onHidden === "function") {
|
||||
onHidden();
|
||||
}
|
||||
}, STATUS_FADE_MS);
|
||||
}
|
||||
|
||||
function processStatusQueue() {
|
||||
if (loadingActive || statusBusy || statusQueue.length === 0) return;
|
||||
const next = statusQueue.shift();
|
||||
if (!next) return;
|
||||
startTransientStatus(next.message, next.type);
|
||||
}
|
||||
|
||||
function startTransientStatus(message, type = "info") {
|
||||
const statusEl = getElement("status-message");
|
||||
if (!statusEl) return;
|
||||
|
||||
clearStatusTimers();
|
||||
statusBusy = true;
|
||||
|
||||
const startShow = () => {
|
||||
statusEl.textContent = message;
|
||||
statusEl.className = `${STATUS_BASE_CLASS} ${type}`;
|
||||
setElementDisplay(statusEl, true);
|
||||
statusEl.offsetHeight;
|
||||
statusEl.classList.add("visible");
|
||||
buildStatusContent(statusEl, message, type);
|
||||
statusEl.className = `${STATUS_BASE_CLASS} ${type}`;
|
||||
setElementDisplay(statusEl, true, "inline-flex");
|
||||
statusEl.offsetHeight;
|
||||
statusEl.classList.add("visible");
|
||||
|
||||
statusTimeoutId = setTimeout(() => {
|
||||
statusEl.classList.remove("visible");
|
||||
statusHideTimeoutId = setTimeout(() => {
|
||||
setElementDisplay(statusEl, false);
|
||||
statusEl.textContent = "";
|
||||
statusHideTimeoutId = null;
|
||||
}, 280);
|
||||
statusTimeoutId = null;
|
||||
}, 3000);
|
||||
};
|
||||
statusTimeoutId = setTimeout(() => {
|
||||
hideStatusElement(statusEl, () => {
|
||||
statusBusy = false;
|
||||
processStatusQueue();
|
||||
});
|
||||
statusTimeoutId = null;
|
||||
}, STATUS_DISPLAY_MS);
|
||||
}
|
||||
|
||||
if (statusEl.classList.contains("visible")) {
|
||||
statusEl.classList.remove("visible");
|
||||
statusReplayTimeoutId = setTimeout(() => {
|
||||
startShow();
|
||||
statusReplayTimeoutId = null;
|
||||
}, 180);
|
||||
return;
|
||||
}
|
||||
|
||||
startShow();
|
||||
// Show status message
|
||||
export function showStatusMessage(message, type = "info") {
|
||||
statusQueue.push({ message, type });
|
||||
processStatusQueue();
|
||||
}
|
||||
|
||||
// Update coordinates display
|
||||
@@ -120,23 +169,49 @@ export function updateEarthStats(stats) {
|
||||
textureQualityEl.textContent = stats.textureQuality || "8K 卫星图";
|
||||
}
|
||||
|
||||
// Show/hide loading
|
||||
// Show/hide loading via status message
|
||||
export function setLoading(loading) {
|
||||
const loadingEl = getElement("loading");
|
||||
if (!loadingEl) return;
|
||||
setElementDisplay(loadingEl, loading);
|
||||
const statusEl = getElement("status-message");
|
||||
if (!statusEl) return;
|
||||
|
||||
if (loading) {
|
||||
clearStatusTimers();
|
||||
loadingActive = true;
|
||||
statusBusy = false;
|
||||
clearLoadingWidthLock(statusEl);
|
||||
buildStatusContent(statusEl, "正在加载...", "loading");
|
||||
statusEl.className = `${STATUS_BASE_CLASS} loading`;
|
||||
setElementDisplay(statusEl, true, "inline-flex");
|
||||
statusEl.offsetHeight;
|
||||
statusEl.classList.add("visible");
|
||||
requestAnimationFrame(() => {
|
||||
updateLoadingWidthLock(statusEl);
|
||||
});
|
||||
} else {
|
||||
if (!statusEl.classList.contains("loading")) {
|
||||
loadingActive = false;
|
||||
clearLoadingWidthLock(statusEl);
|
||||
processStatusQueue();
|
||||
return;
|
||||
}
|
||||
loadingActive = false;
|
||||
hideStatusElement(statusEl, () => {
|
||||
clearLoadingWidthLock(statusEl);
|
||||
statusBusy = false;
|
||||
processStatusQueue();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export function setLoadingMessage(title, subtitle = "") {
|
||||
const titleEl = getElement("loading-title");
|
||||
const subtitleEl = getElement("loading-subtitle");
|
||||
|
||||
if (titleEl) {
|
||||
titleEl.textContent = title;
|
||||
}
|
||||
|
||||
if (subtitleEl) {
|
||||
subtitleEl.textContent = subtitle;
|
||||
export function setLoadingMessage(title) {
|
||||
const statusEl = getElement("status-message");
|
||||
if (!statusEl || !statusEl.classList.contains("loading")) return;
|
||||
const textEl = statusEl.querySelector(".earth-status-text");
|
||||
if (textEl) {
|
||||
textEl.textContent = title;
|
||||
requestAnimationFrame(() => {
|
||||
updateLoadingWidthLock(statusEl);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -177,12 +252,16 @@ export function hideError() {
|
||||
|
||||
export function clearUiState() {
|
||||
clearStatusTimers();
|
||||
statusQueue = [];
|
||||
statusBusy = false;
|
||||
loadingActive = false;
|
||||
|
||||
const statusEl = getElement("status-message");
|
||||
if (statusEl) {
|
||||
statusEl.className = STATUS_BASE_CLASS;
|
||||
setElementDisplay(statusEl, false);
|
||||
statusEl.textContent = "";
|
||||
statusEl.innerHTML = "";
|
||||
clearLoadingWidthLock(statusEl);
|
||||
}
|
||||
|
||||
hideTooltip();
|
||||
|
||||
Reference in New Issue
Block a user