release: bump version to 0.27.8

This commit is contained in:
linkong
2026-04-20 12:03:09 +08:00
parent 1cf1f32ddd
commit 51ae5e6ec9
8 changed files with 69 additions and 46 deletions

View File

@@ -1 +1 @@
0.27.7
0.27.8

View File

@@ -10,6 +10,20 @@ This project follows the repository versioning rule:
## [0.27.7] — 2026-04-16
## [0.27.8] — 2026-04-20
### 🔧 Improvements
- Earth HUD 共享 `HUDPanel` 默认展开/收缩逻辑继续收口,图例与图层面板统一使用同一套边缘阈值与箭头状态机
- 保持新闻直播面板现有特例折叠行为不变,避免播放器区域被默认折叠逻辑影响
### 🐛 Fixes
- 修复图例与图层面板展开/收缩箭头方向和实际动作不一致的问题
- 修复拖动到屏幕底边附近时初始箭头、拖动中箭头和点击后动作不同步的问题
---
## [0.27.7] — 2026-04-16
### 🔧 Improvements
- 用户管理、数据源配置、电视直播源表格统一接入可折叠操作列,窄宽度下自动收起到下拉菜单,减少操作区挤压
- 电视直播设置改为表格总览 + 弹窗编辑模式,主表内容更紧凑,适合控制台一屏浏览

View File

@@ -16,12 +16,13 @@
## Current Version
- `main` 当前主线历史推导到:`0.16.5`
- `dev` 当前开发分支历史推导到:`0.27.7`
- `dev` 当前开发分支历史推导到:`0.27.8`
## Timeline
| Version | Type | Branch | Commit | Summary |
| --- | --- | --- | --- | --- |
| `0.27.8` | bugfix | `dev` | `pending` | 统一 Earth HUD 默认折叠逻辑,修复图例与图层面板箭头和底边阈值行为 |
| `0.27.7` | bugfix | `dev` | `pending` | 修复电视直播源编辑持久化问题,清理表格空白占位列并统一可折叠操作列 |
| `0.27.6` | improvement | `dev` | `pending` | BGP/用户表格滚动条修复Playground 响应式按钮与输入框收起优化 |
| `0.27.5` | bugfix | `dev` | `pending` | 统一控制台自定义滚动条,修复 alerts/BGP 响应式滚动与采集进度完成态显示 |

View File

@@ -1,6 +1,6 @@
{
"name": "planet-frontend",
"version": "0.27.7",
"version": "0.27.8",
"private": true,
"packageManager": "bun@1",
"dependencies": {

View File

@@ -18,6 +18,7 @@ import {
import { getShowCables } from "./cables.js";
import { toggleBGP, getShowBGP, getBGPCount } from "./bgp.js";
import { ensureTVPanelReady } from "./tv.js";
import { createHUDPanel } from "./hud-panels.js";
import {
ensureNewsPanelReady,
setNewsPanelVisible,
@@ -631,13 +632,20 @@ function setupLayerPanel() {
const emptyState = document.getElementById("layer-panel-empty");
if (!panel) return;
const layerPanel = createHUDPanel({
panel,
header: ".layer-panel-header",
body: "#layer-panel-body",
collapseBtn,
collapsedClass: "layer-panel--collapsed",
preferredDirection: "down",
expandLabel: "展开图层列表",
collapseLabel: "折叠图层列表",
});
bindListener(collapseBtn, "click", (e) => {
e.stopPropagation();
const isCollapsed = panel.classList.toggle("layer-panel--collapsed");
collapseBtn.title = isCollapsed ? "展开" : "折叠";
collapseBtn.setAttribute("aria-label", isCollapsed ? "展开图层列表" : "折叠图层列表");
const icon = collapseBtn.querySelector(".material-symbols-rounded");
if (icon) icon.textContent = isCollapsed ? "expand_more" : "expand_less";
layerPanel.setCollapsed(!layerPanel.isCollapsed());
});
if (searchInput) {

View File

@@ -1,6 +1,20 @@
const DEFAULT_COLLAPSED_CLASS = "hud-panel--collapsed";
const DEFAULT_HIDDEN_CLASS = "hud-panel-hidden";
const EXPAND_DIRECTION_BUFFER_PX = 20;
function getHudScale() {
const rootStyle = getComputedStyle(document.documentElement);
const scale = parseFloat(rootStyle.getPropertyValue("--hud-scale"));
return Number.isFinite(scale) && scale > 0 ? scale : 1;
}
function getEdgeFlipThresholdPx() {
const rootStyle = getComputedStyle(document.documentElement);
const hudOffset = parseFloat(rootStyle.getPropertyValue("--hud-offset"));
if (Number.isFinite(hudOffset) && hudOffset > 0) {
return hudOffset;
}
return 20 * getHudScale();
}
function clampExpandDirection(direction) {
return direction === "up" ? "up" : "down";
@@ -16,41 +30,20 @@ function resolveElement(target, root = document) {
}
function pickExpandDirection({
headerRect,
expandedHeight,
panelRect,
preferredDirection,
currentDirection,
}) {
const spaceAbove = Math.max(0, headerRect.top);
const spaceBelow = Math.max(0, window.innerHeight - headerRect.bottom);
const spaceBelow = Math.max(0, window.innerHeight - panelRect.bottom);
const edgeFlipThresholdPx = getEdgeFlipThresholdPx();
const preferred = clampExpandDirection(preferredDirection);
const fitsAbove = expandedHeight <= spaceAbove;
const fitsBelow = expandedHeight <= spaceBelow;
const bufferedFitsBelow = expandedHeight + EXPAND_DIRECTION_BUFFER_PX <= spaceBelow;
const activeDirection = clampExpandDirection(currentDirection ?? preferred);
// Hysteresis:
// - if we're already in "up", keep it until bottom space drops below h
// - if we're already in "down", keep it until bottom space grows beyond h + 20
if (activeDirection === "up" && spaceBelow > expandedHeight && fitsAbove) {
return "up";
}
if (activeDirection === "down" && spaceBelow < expandedHeight + EXPAND_DIRECTION_BUFFER_PX && fitsBelow) {
return "down";
}
// Main contract:
// d = spaceBelow, h = expandedHeight
// - d > h + 20 => up
// - d <= h + 20 => down
// Only fall back when the preferred side cannot actually fit.
if (bufferedFitsBelow && fitsAbove) return "up";
if (!bufferedFitsBelow && fitsBelow) return "down";
if (fitsAbove && fitsBelow) return preferred;
if (fitsAbove) return "up";
if (fitsBelow) return "down";
return spaceAbove > spaceBelow ? "up" : "down";
// Pure edge-threshold contract:
// - d < threshold => "up" family
// - d >= threshold => "down" family
// Do not pre-flip early based on expanded height.
if (spaceBelow <= edgeFlipThresholdPx) return "up";
if (spaceBelow > edgeFlipThresholdPx) return "down";
return preferred;
}
function getCollapseButtonState({ collapsed, direction, expandLabel, collapseLabel }) {
@@ -125,10 +118,8 @@ export function createHUDPanel({
const syncDirection = () => {
const expandedHeight = Math.max(bodyEl.scrollHeight, bodyEl.getBoundingClientRect().height);
const nextDirection = pickExpandDirection({
headerRect: headerEl.getBoundingClientRect(),
expandedHeight,
panelRect: panelEl.getBoundingClientRect(),
preferredDirection,
currentDirection,
});
currentDirection = nextDirection;
@@ -194,15 +185,23 @@ export function createHUDPanel({
};
const handleViewportChange = () => {
if (!panelEl.classList.contains(collapsedClass) && !panelEl.classList.contains(hiddenClass)) {
if (!panelEl.classList.contains(hiddenClass)) {
syncLayout();
}
};
const handlePointerMove = () => {
if (!panelEl.classList.contains(hiddenClass) && panelEl.classList.contains("is-dragging")) {
syncLayout();
}
};
window.addEventListener("resize", handleViewportChange);
document.addEventListener("pointerup", handleViewportChange);
document.addEventListener("pointermove", handlePointerMove);
syncLayout();
requestAnimationFrame(syncLayout);
return {
panel: panelEl,
@@ -215,6 +214,7 @@ export function createHUDPanel({
destroy() {
window.removeEventListener("resize", handleViewportChange);
document.removeEventListener("pointerup", handleViewportChange);
document.removeEventListener("pointermove", handlePointerMove);
},
isCollapsed() {
return panelEl.classList.contains(collapsedClass);

View File

@@ -1,6 +1,6 @@
[project]
name = "planet"
version = "0.27.7"
version = "0.27.8"
description = "智能星球计划 - 态势感知系统"
requires-python = ">=3.14"
dependencies = [

2
uv.lock generated
View File

@@ -475,7 +475,7 @@ wheels = [
[[package]]
name = "planet"
version = "0.27.7"
version = "0.27.8"
source = { virtual = "." }
dependencies = [
{ name = "aiofiles" },