release: bump version to 0.71.1
Some checks failed
ci / backend (push) Has been cancelled
ci / frontend (push) Has been cancelled
release / images (push) Has been cancelled
ci / delivery (push) Has been cancelled

This commit is contained in:
linkong
2026-06-26 17:34:19 +08:00
parent 899e3bce43
commit 3265d22af5
26 changed files with 1052 additions and 71 deletions

View File

@@ -107,6 +107,9 @@ export function getNewsDisplayTitle(item, locale = DEFAULT_LOCALE) {
if (localized || item?.display_title) {
return normalizeText(item?.display_title || localized);
}
if (item?.title) {
return normalizeText(item.title);
}
return normalizeText(
TITLE_PLACEHOLDERS[item?.enrichment_status]
|| "新闻汉化中",
@@ -118,6 +121,9 @@ export function getNewsDisplaySummary(item, locale = DEFAULT_LOCALE) {
if (localized || item?.display_summary) {
return normalizeText(item?.display_summary || localized);
}
if (item?.summary) {
return normalizeText(item.summary);
}
return normalizeText(
SUMMARY_PLACEHOLDERS[item?.enrichment_status]
|| "中文概要生成中,请稍后刷新。",
@@ -126,8 +132,8 @@ export function getNewsDisplaySummary(item, locale = DEFAULT_LOCALE) {
export function isNewsContentReady(item, locale = DEFAULT_LOCALE) {
const localized = getLocalization(item, locale);
const title = normalizeText(item?.display_title || localized.title);
const summary = normalizeText(item?.display_summary || localized.summary);
const title = normalizeText(item?.display_title || localized.title || item?.title);
const summary = normalizeText(item?.display_summary || localized.summary || item?.summary);
return Boolean(title && summary);
}

View File

@@ -39,6 +39,8 @@ const NEWS_SOURCE_FILTER_STORAGE_KEY = "planet.earth.newsSourceFilters.v1";
let initialized = false;
let refreshPromise = null;
let refreshRequestKey = "";
let activeRefreshToken = 0;
let payload = null;
let lastFocus = null;
let lastFetchAt = 0;
@@ -488,7 +490,8 @@ function getEnabledNewsSourceIds(nextPayload = payload) {
if (!available.length) return [];
if (!Array.isArray(activeNewsSourceFilters)) return available;
const allowed = new Set(activeNewsSourceFilters);
return available.filter((id) => allowed.has(id));
const enabled = available.filter((id) => allowed.has(id));
return enabled.length > 0 ? enabled : available;
}
function reconcileNewsSourceFilters(nextPayload = payload) {
@@ -522,6 +525,15 @@ function getNewsSourceSignature(nextPayload = payload) {
return enabled.join(",");
}
function getNewsSourceSignatureForFetch(lat, lon) {
const currentRegion = payload?.focus?.region || null;
const nextRegion = inferRegion(lat, lon);
if (currentRegion && nextRegion !== currentRegion) {
return "";
}
return getNewsSourceSignature();
}
function getNewsLimit() {
return newsFullListMode ? NEWS_FULL_LIMIT : NEWS_SUMMARY_LIMIT;
}
@@ -707,6 +719,7 @@ function renderEmptyState(message) {
function renderPayload(nextPayload) {
payload = nextPayload;
reconcileNewsSourceFilters(nextPayload);
const {
board,
empty,
@@ -945,9 +958,9 @@ function connectNewsRealtime() {
};
}
async function fetchNews(lat, lon) {
const categorySignature = getNewsCategorySignature();
const sourceSignature = getNewsSourceSignature();
async function fetchNews(lat, lon, context = {}) {
const categorySignature = context.categorySignature ?? getNewsCategorySignature();
const sourceSignature = context.sourceSignature ?? getNewsSourceSignatureForFetch(lat, lon);
if (categorySignature === "__none__" || sourceSignature === "__none__") {
return {
...(payload || {}),
@@ -990,15 +1003,30 @@ async function fetchNews(lat, lon) {
}
async function refreshNews(lat, lon, { silent = false } = {}) {
if (refreshPromise) return refreshPromise;
const targetRegion = inferRegion(lat, lon);
const categorySignature = getNewsCategorySignature();
const sourceSignature = getNewsSourceSignatureForFetch(lat, lon);
const requestKey = [
targetRegion,
categorySignature,
sourceSignature,
getNewsLimit(),
].join("|");
if (refreshPromise && refreshRequestKey === requestKey) return refreshPromise;
const requestToken = ++activeRefreshToken;
refreshRequestKey = requestKey;
const { status } = getElements();
if (status) {
status.textContent = "正在同步全球态势新闻...";
}
refreshPromise = fetchNews(lat, lon)
refreshPromise = fetchNews(lat, lon, { categorySignature, sourceSignature })
.then((nextPayload) => {
if (requestToken !== activeRefreshToken) {
return nextPayload;
}
renderPayload(nextPayload);
lastFetchAt = Date.now();
lastCategorySignature = getNewsCategorySignature();
@@ -1012,6 +1040,9 @@ async function refreshNews(lat, lon, { silent = false } = {}) {
return nextPayload;
})
.catch((error) => {
if (requestToken !== activeRefreshToken) {
return null;
}
console.error("加载 Earth RSS 新闻失败:", error);
const message = error?.name === "AbortError"
? "新闻聚合请求超时,请稍后重试"
@@ -1024,7 +1055,10 @@ async function refreshNews(lat, lon, { silent = false } = {}) {
throw error;
})
.finally(() => {
refreshPromise = null;
if (requestToken === activeRefreshToken) {
refreshPromise = null;
refreshRequestKey = "";
}
});
return refreshPromise;