release: bump version to 0.28.2
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "planet-frontend",
|
||||
"version": "0.28.1",
|
||||
"version": "0.28.2",
|
||||
"private": true,
|
||||
"packageManager": "bun@1",
|
||||
"dependencies": {
|
||||
|
||||
@@ -32,6 +32,10 @@ let activeTab = "live";
|
||||
const failedSourceIds = new Set();
|
||||
let probeTimer = null;
|
||||
let reformCleanupTimer = null;
|
||||
const tabPanelState = {
|
||||
live: null,
|
||||
news: null,
|
||||
};
|
||||
|
||||
const META_AUTO_COLLAPSE_DELAY = 2500;
|
||||
const PROBE_INTERVAL_MS = 2 * 60 * 1000;
|
||||
@@ -129,6 +133,82 @@ function clearPanelPositioningForResize(panel) {
|
||||
panel.dataset.dragged = "true";
|
||||
}
|
||||
|
||||
function readPanelLayoutState(panel) {
|
||||
return {
|
||||
width: panel.style.width || "",
|
||||
height: panel.style.height || "",
|
||||
resized: panel.dataset.resized === "true",
|
||||
};
|
||||
}
|
||||
|
||||
function resetPanelLayoutState(panel) {
|
||||
panel.style.width = "";
|
||||
panel.style.height = "";
|
||||
delete panel.dataset.resized;
|
||||
}
|
||||
|
||||
function captureTabState(tab = activeTab) {
|
||||
const { panel } = getElements();
|
||||
if (!(panel instanceof HTMLElement)) return;
|
||||
tabPanelState[tab] = {
|
||||
layout: readPanelLayoutState(panel),
|
||||
metaCollapsed:
|
||||
tab === "live" ? (mediaPanel?.isCollapsed() ?? false) : null,
|
||||
};
|
||||
}
|
||||
|
||||
function restoreTabState(tab, panel, container, anchor = null) {
|
||||
if (!(panel instanceof HTMLElement)) return;
|
||||
|
||||
const snapshot = tabPanelState[tab];
|
||||
if (!snapshot?.layout) {
|
||||
resetPanelLayoutState(panel);
|
||||
return;
|
||||
}
|
||||
|
||||
const { layout } = snapshot;
|
||||
panel.style.width = layout.width;
|
||||
panel.style.height = layout.height;
|
||||
|
||||
if (layout.resized) {
|
||||
panel.dataset.resized = "true";
|
||||
} else {
|
||||
delete panel.dataset.resized;
|
||||
}
|
||||
|
||||
if (tab === "live" && snapshot.metaCollapsed !== null) {
|
||||
setMetaCollapsed(snapshot.metaCollapsed);
|
||||
}
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
if (anchor) {
|
||||
const panelRect = panel.getBoundingClientRect();
|
||||
const containerRect = container.getBoundingClientRect();
|
||||
const margin = Math.round(PANEL_RESIZE_MARGIN_PX * getHudScale());
|
||||
const targetLeft = anchor.right - containerRect.left - panelRect.width;
|
||||
const targetTop = anchor.bottom - containerRect.top - panelRect.height;
|
||||
const maxLeft = Math.max(0, containerRect.width - panelRect.width - margin);
|
||||
const maxTop = Math.max(0, containerRect.height - panelRect.height - margin);
|
||||
const clampedLeft = Math.min(maxLeft, Math.max(0, targetLeft));
|
||||
const clampedTop = Math.min(maxTop, Math.max(0, targetTop));
|
||||
|
||||
panel.style.left = `${clampedLeft}px`;
|
||||
panel.style.top = `${clampedTop}px`;
|
||||
panel.style.right = "auto";
|
||||
panel.style.bottom = "auto";
|
||||
panel.style.transform = "none";
|
||||
panel.dataset.dragged = "true";
|
||||
} else {
|
||||
panel.style.right = "";
|
||||
panel.style.bottom = "";
|
||||
panel.style.left = "";
|
||||
panel.style.top = "";
|
||||
panel.style.transform = "";
|
||||
delete panel.dataset.dragged;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function getHudScale() {
|
||||
const scale = Number.parseFloat(
|
||||
getComputedStyle(document.documentElement).getPropertyValue("--hud-scale"),
|
||||
@@ -136,6 +216,27 @@ function getHudScale() {
|
||||
return Number.isFinite(scale) && scale > 0 ? scale : 1;
|
||||
}
|
||||
|
||||
function clampPanelToContainer(panel, container) {
|
||||
if (!(panel instanceof HTMLElement) || !(container instanceof HTMLElement)) return;
|
||||
if (panel.dataset.dragged !== "true") return;
|
||||
|
||||
const containerRect = container.getBoundingClientRect();
|
||||
const panelRect = panel.getBoundingClientRect();
|
||||
const margin = Math.round(PANEL_RESIZE_MARGIN_PX * getHudScale());
|
||||
const maxLeft = Math.max(0, containerRect.width - panelRect.width - margin);
|
||||
const maxTop = Math.max(0, containerRect.height - panelRect.height - margin);
|
||||
const currentLeft = panelRect.left - containerRect.left;
|
||||
const currentTop = panelRect.top - containerRect.top;
|
||||
const clampedLeft = Math.min(maxLeft, Math.max(0, currentLeft));
|
||||
const clampedTop = Math.min(maxTop, Math.max(0, currentTop));
|
||||
|
||||
panel.style.left = `${clampedLeft}px`;
|
||||
panel.style.top = `${clampedTop}px`;
|
||||
panel.style.right = "auto";
|
||||
panel.style.bottom = "auto";
|
||||
panel.style.transform = "none";
|
||||
}
|
||||
|
||||
function setupResizeHandle() {
|
||||
const { panel } = getElements();
|
||||
const container = document.getElementById("container");
|
||||
@@ -280,6 +381,14 @@ function animateTabReform(applyChange) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (panel.dataset.resized === "true") {
|
||||
applyChange();
|
||||
requestAnimationFrame(() => {
|
||||
clampPanelToContainer(panel, container);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (panel.classList.contains("is-dragging") || panel.classList.contains("is-resizing")) {
|
||||
applyChange();
|
||||
return;
|
||||
@@ -351,7 +460,26 @@ function setActiveTab(tab) {
|
||||
const nextTab = tab === "news" ? "news" : "live";
|
||||
if (activeTab === nextTab) return;
|
||||
|
||||
animateTabReform(() => {
|
||||
captureTabState(activeTab);
|
||||
|
||||
const { panel } = getElements();
|
||||
const targetSnapshot = tabPanelState[nextTab];
|
||||
const currentIsCustom =
|
||||
panel instanceof HTMLElement && panel.dataset.resized === "true";
|
||||
const targetIsCustom = Boolean(targetSnapshot?.layout?.resized);
|
||||
const container = document.getElementById("container");
|
||||
const currentAnchor =
|
||||
panel instanceof HTMLElement && container instanceof HTMLElement
|
||||
? (() => {
|
||||
const panelRect = panel.getBoundingClientRect();
|
||||
return {
|
||||
right: panelRect.right,
|
||||
bottom: panelRect.bottom,
|
||||
};
|
||||
})()
|
||||
: null;
|
||||
|
||||
const applyTabSwitch = (restoreLayoutState = false) => {
|
||||
activeTab = nextTab;
|
||||
syncPanelActiveTab(nextTab);
|
||||
syncNewsDefaultMaxHeight();
|
||||
@@ -370,10 +498,30 @@ function setActiveTab(tab) {
|
||||
updateTabState(newsHeaderControls, nextTab === "news");
|
||||
updateTabState(livePane, nextTab === "live", "tv-tab-pane--active");
|
||||
updateTabState(newsPane, nextTab === "news", "tv-tab-pane--active");
|
||||
|
||||
if (
|
||||
restoreLayoutState &&
|
||||
panel instanceof HTMLElement &&
|
||||
container instanceof HTMLElement
|
||||
) {
|
||||
restoreTabState(nextTab, panel, container, currentAnchor);
|
||||
}
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
captureTabState(nextTab);
|
||||
});
|
||||
|
||||
window.dispatchEvent(new CustomEvent("earth:tv-tab-change", {
|
||||
detail: { tab: nextTab },
|
||||
}));
|
||||
});
|
||||
};
|
||||
|
||||
if (currentIsCustom || targetIsCustom) {
|
||||
applyTabSwitch(true);
|
||||
return;
|
||||
}
|
||||
|
||||
animateTabReform(() => applyTabSwitch(false));
|
||||
}
|
||||
|
||||
export function openTVPanelTab(tab = "live") {
|
||||
@@ -951,7 +1099,9 @@ export function initTVPanel() {
|
||||
setupResizeHandle();
|
||||
syncPanelActiveTab("live");
|
||||
syncNewsDefaultMaxHeight();
|
||||
setActiveTab("live");
|
||||
updateTabButtonState(liveTabBtn, true);
|
||||
updateTabButtonState(newsTabBtn, false);
|
||||
captureTabState("live");
|
||||
|
||||
window.addEventListener("resize", syncNewsDefaultMaxHeight);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user