Merge pull request #6 from katelya77/cursor/update-documentation-and-release-notes-fb3a
Update documentation and release notescursor/update-documentation-and-release-notes-fb3a^2
commit
b25c738dbf
File diff suppressed because one or more lines are too long
|
@ -11,7 +11,7 @@ const publicDir = path.join(projectRoot, 'public');
|
||||||
const manifestPath = path.join(publicDir, 'manifest.json');
|
const manifestPath = path.join(publicDir, 'manifest.json');
|
||||||
|
|
||||||
// 从环境变量获取站点名称
|
// 从环境变量获取站点名称
|
||||||
const siteName = process.env.SITE_NAME || 'MoonTV';
|
const siteName = process.env.SITE_NAME || 'KatelyaTV';
|
||||||
|
|
||||||
// manifest.json 模板
|
// manifest.json 模板
|
||||||
const manifestTemplate = {
|
const manifestTemplate = {
|
||||||
|
|
|
@ -35,7 +35,10 @@ function VersionDisplay() {
|
||||||
return (
|
return (
|
||||||
<button
|
<button
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
window.open('https://github.com/senshinya/MoonTV', '_blank')
|
window.open(
|
||||||
|
process.env.NEXT_PUBLIC_REPO_URL || 'https://github.com/katelya77/KatelyaTV',
|
||||||
|
'_blank'
|
||||||
|
)
|
||||||
}
|
}
|
||||||
className='absolute bottom-4 left-1/2 transform -translate-x-1/2 flex items-center gap-2 text-xs text-gray-500 dark:text-gray-400 transition-colors cursor-pointer'
|
className='absolute bottom-4 left-1/2 transform -translate-x-1/2 flex items-center gap-2 text-xs text-gray-500 dark:text-gray-400 transition-colors cursor-pointer'
|
||||||
>
|
>
|
||||||
|
|
|
@ -66,7 +66,7 @@ const BottomKatelyaLogo = () => {
|
||||||
<div className='text-center'>
|
<div className='text-center'>
|
||||||
<div className='bottom-logo'>KatelyaTV</div>
|
<div className='bottom-logo'>KatelyaTV</div>
|
||||||
<div className='mt-2 text-sm text-gray-500 dark:text-gray-400 opacity-75'>
|
<div className='mt-2 text-sm text-gray-500 dark:text-gray-400 opacity-75'>
|
||||||
Powered by MoonTV Core
|
Powered by KatelyaTV Core
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { Metadata } from 'next';
|
import { Metadata } from 'next';
|
||||||
|
|
||||||
export const metadata: Metadata = {
|
export const metadata: Metadata = {
|
||||||
title: '安全警告 - MoonTV',
|
title: '安全警告 - KatelyaTV',
|
||||||
description: '站点安全配置警告',
|
description: '站点安全配置警告',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -151,7 +151,7 @@ async function initConfig() {
|
||||||
}
|
}
|
||||||
adminConfig = {
|
adminConfig = {
|
||||||
SiteConfig: {
|
SiteConfig: {
|
||||||
SiteName: process.env.SITE_NAME || 'MoonTV',
|
SiteName: process.env.SITE_NAME || 'KatelyaTV',
|
||||||
Announcement:
|
Announcement:
|
||||||
process.env.ANNOUNCEMENT ||
|
process.env.ANNOUNCEMENT ||
|
||||||
'本网站仅提供影视信息搜索服务,所有内容均来自第三方网站。本站不存储任何视频资源,不对任何内容的准确性、合法性、完整性负责。',
|
'本网站仅提供影视信息搜索服务,所有内容均来自第三方网站。本站不存储任何视频资源,不对任何内容的准确性、合法性、完整性负责。',
|
||||||
|
@ -190,7 +190,7 @@ async function initConfig() {
|
||||||
// 本地存储直接使用文件配置
|
// 本地存储直接使用文件配置
|
||||||
cachedConfig = {
|
cachedConfig = {
|
||||||
SiteConfig: {
|
SiteConfig: {
|
||||||
SiteName: process.env.SITE_NAME || 'MoonTV',
|
SiteName: process.env.SITE_NAME || 'KatelyaTV',
|
||||||
Announcement:
|
Announcement:
|
||||||
process.env.ANNOUNCEMENT ||
|
process.env.ANNOUNCEMENT ||
|
||||||
'本网站仅提供影视信息搜索服务,所有内容均来自第三方网站。本站不存储任何视频资源,不对任何内容的准确性、合法性、完整性负责。',
|
'本网站仅提供影视信息搜索服务,所有内容均来自第三方网站。本站不存储任何视频资源,不对任何内容的准确性、合法性、完整性负责。',
|
||||||
|
@ -230,7 +230,7 @@ export async function getConfig(): Promise<AdminConfig> {
|
||||||
}
|
}
|
||||||
if (adminConfig) {
|
if (adminConfig) {
|
||||||
// 合并一些环境变量配置
|
// 合并一些环境变量配置
|
||||||
adminConfig.SiteConfig.SiteName = process.env.SITE_NAME || 'MoonTV';
|
adminConfig.SiteConfig.SiteName = process.env.SITE_NAME || 'KatelyaTV';
|
||||||
adminConfig.SiteConfig.Announcement =
|
adminConfig.SiteConfig.Announcement =
|
||||||
process.env.ANNOUNCEMENT ||
|
process.env.ANNOUNCEMENT ||
|
||||||
'本网站仅提供影视信息搜索服务,所有内容均来自第三方网站。本站不存储任何视频资源,不对任何内容的准确性、合法性、完整性负责。';
|
'本网站仅提供影视信息搜索服务,所有内容均来自第三方网站。本站不存储任何视频资源,不对任何内容的准确性、合法性、完整性负责。';
|
||||||
|
@ -337,7 +337,7 @@ export async function resetConfig() {
|
||||||
}
|
}
|
||||||
const adminConfig = {
|
const adminConfig = {
|
||||||
SiteConfig: {
|
SiteConfig: {
|
||||||
SiteName: process.env.SITE_NAME || 'MoonTV',
|
SiteName: process.env.SITE_NAME || 'KatelyaTV',
|
||||||
Announcement:
|
Announcement:
|
||||||
process.env.ANNOUNCEMENT ||
|
process.env.ANNOUNCEMENT ||
|
||||||
'本网站仅提供影视信息搜索服务,所有内容均来自第三方网站。本站不存储任何视频资源,不对任何内容的准确性、合法性、完整性负责。',
|
'本网站仅提供影视信息搜索服务,所有内容均来自第三方网站。本站不存储任何视频资源,不对任何内容的准确性、合法性、完整性负责。',
|
||||||
|
|
|
@ -55,12 +55,17 @@ interface UserCacheStore {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---- 常量 ----
|
// ---- 常量 ----
|
||||||
const PLAY_RECORDS_KEY = 'moontv_play_records';
|
// 新的键名(KatelyaTV)与旧键名(MoonTV)保持向后兼容
|
||||||
const FAVORITES_KEY = 'moontv_favorites';
|
const PLAY_RECORDS_KEY = 'katelyatv_play_records';
|
||||||
const SEARCH_HISTORY_KEY = 'moontv_search_history';
|
const FAVORITES_KEY = 'katelyatv_favorites';
|
||||||
|
const SEARCH_HISTORY_KEY = 'katelyatv_search_history';
|
||||||
|
const LEGACY_PLAY_RECORDS_KEY = 'moontv_play_records';
|
||||||
|
const LEGACY_FAVORITES_KEY = 'moontv_favorites';
|
||||||
|
const LEGACY_SEARCH_HISTORY_KEY = 'moontv_search_history';
|
||||||
|
|
||||||
// 缓存相关常量
|
// 缓存相关常量
|
||||||
const CACHE_PREFIX = 'moontv_cache_';
|
const CACHE_PREFIX = 'katelyatv_cache_';
|
||||||
|
const LEGACY_CACHE_PREFIX = 'moontv_cache_';
|
||||||
const CACHE_VERSION = '1.0.0';
|
const CACHE_VERSION = '1.0.0';
|
||||||
const CACHE_EXPIRE_TIME = 60 * 60 * 1000; // 一小时缓存过期
|
const CACHE_EXPIRE_TIME = 60 * 60 * 1000; // 一小时缓存过期
|
||||||
|
|
||||||
|
@ -426,7 +431,9 @@ export async function getAllPlayRecords(): Promise<Record<string, PlayRecord>> {
|
||||||
|
|
||||||
// localstorage 模式
|
// localstorage 模式
|
||||||
try {
|
try {
|
||||||
const raw = localStorage.getItem(PLAY_RECORDS_KEY);
|
const primary = localStorage.getItem(PLAY_RECORDS_KEY);
|
||||||
|
const fallback = localStorage.getItem(LEGACY_PLAY_RECORDS_KEY);
|
||||||
|
const raw = primary ?? fallback;
|
||||||
if (!raw) return {};
|
if (!raw) return {};
|
||||||
return JSON.parse(raw) as Record<string, PlayRecord>;
|
return JSON.parse(raw) as Record<string, PlayRecord>;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
@ -614,7 +621,9 @@ export async function getSearchHistory(): Promise<string[]> {
|
||||||
|
|
||||||
// localStorage 模式
|
// localStorage 模式
|
||||||
try {
|
try {
|
||||||
const raw = localStorage.getItem(SEARCH_HISTORY_KEY);
|
const primary = localStorage.getItem(SEARCH_HISTORY_KEY);
|
||||||
|
const fallback = localStorage.getItem(LEGACY_SEARCH_HISTORY_KEY);
|
||||||
|
const raw = primary ?? fallback;
|
||||||
if (!raw) return [];
|
if (!raw) return [];
|
||||||
const arr = JSON.parse(raw) as string[];
|
const arr = JSON.parse(raw) as string[];
|
||||||
// 仅返回字符串数组
|
// 仅返回字符串数组
|
||||||
|
@ -835,7 +844,9 @@ export async function getAllFavorites(): Promise<Record<string, Favorite>> {
|
||||||
|
|
||||||
// localStorage 模式
|
// localStorage 模式
|
||||||
try {
|
try {
|
||||||
const raw = localStorage.getItem(FAVORITES_KEY);
|
const primary = localStorage.getItem(FAVORITES_KEY);
|
||||||
|
const fallback = localStorage.getItem(LEGACY_FAVORITES_KEY);
|
||||||
|
const raw = primary ?? fallback;
|
||||||
if (!raw) return {};
|
if (!raw) return {};
|
||||||
return JSON.parse(raw) as Record<string, Favorite>;
|
return JSON.parse(raw) as Record<string, Favorite>;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
@ -1053,6 +1064,7 @@ export async function clearAllPlayRecords(): Promise<void> {
|
||||||
// localStorage 模式
|
// localStorage 模式
|
||||||
if (typeof window === 'undefined') return;
|
if (typeof window === 'undefined') return;
|
||||||
localStorage.removeItem(PLAY_RECORDS_KEY);
|
localStorage.removeItem(PLAY_RECORDS_KEY);
|
||||||
|
localStorage.removeItem(LEGACY_PLAY_RECORDS_KEY);
|
||||||
window.dispatchEvent(
|
window.dispatchEvent(
|
||||||
new CustomEvent('playRecordsUpdated', {
|
new CustomEvent('playRecordsUpdated', {
|
||||||
detail: {},
|
detail: {},
|
||||||
|
@ -1094,6 +1106,7 @@ export async function clearAllFavorites(): Promise<void> {
|
||||||
// localStorage 模式
|
// localStorage 模式
|
||||||
if (typeof window === 'undefined') return;
|
if (typeof window === 'undefined') return;
|
||||||
localStorage.removeItem(FAVORITES_KEY);
|
localStorage.removeItem(FAVORITES_KEY);
|
||||||
|
localStorage.removeItem(LEGACY_FAVORITES_KEY);
|
||||||
window.dispatchEvent(
|
window.dispatchEvent(
|
||||||
new CustomEvent('favoritesUpdated', {
|
new CustomEvent('favoritesUpdated', {
|
||||||
detail: {},
|
detail: {},
|
||||||
|
|
|
@ -287,8 +287,9 @@ export class RedisStorage implements IStorage {
|
||||||
|
|
||||||
// 单例 Redis 客户端
|
// 单例 Redis 客户端
|
||||||
function getRedisClient(): RedisClientType {
|
function getRedisClient(): RedisClientType {
|
||||||
const globalKey = Symbol.for('__MOONTV_REDIS_CLIENT__');
|
const legacyKey = Symbol.for('__MOONTV_REDIS_CLIENT__');
|
||||||
let client: RedisClientType | undefined = (global as any)[globalKey];
|
const globalKey = Symbol.for('__KATELYATV_REDIS_CLIENT__');
|
||||||
|
let client: RedisClientType | undefined = (global as any)[globalKey] || (global as any)[legacyKey];
|
||||||
|
|
||||||
if (!client) {
|
if (!client) {
|
||||||
const url = process.env.REDIS_URL;
|
const url = process.env.REDIS_URL;
|
||||||
|
@ -349,6 +350,8 @@ function getRedisClient(): RedisClientType {
|
||||||
connectWithRetry();
|
connectWithRetry();
|
||||||
|
|
||||||
(global as any)[globalKey] = client;
|
(global as any)[globalKey] = client;
|
||||||
|
// 同步旧键,保持兼容
|
||||||
|
(global as any)[legacyKey] = client;
|
||||||
}
|
}
|
||||||
|
|
||||||
return client;
|
return client;
|
||||||
|
|
|
@ -271,8 +271,9 @@ export class UpstashRedisStorage implements IStorage {
|
||||||
|
|
||||||
// 单例 Upstash Redis 客户端
|
// 单例 Upstash Redis 客户端
|
||||||
function getUpstashRedisClient(): Redis {
|
function getUpstashRedisClient(): Redis {
|
||||||
const globalKey = Symbol.for('__MOONTV_UPSTASH_REDIS_CLIENT__');
|
const legacyKey = Symbol.for('__MOONTV_UPSTASH_REDIS_CLIENT__');
|
||||||
let client: Redis | undefined = (global as any)[globalKey];
|
const globalKey = Symbol.for('__KATELYATV_UPSTASH_REDIS_CLIENT__');
|
||||||
|
let client: Redis | undefined = (global as any)[globalKey] || (global as any)[legacyKey];
|
||||||
|
|
||||||
if (!client) {
|
if (!client) {
|
||||||
const upstashUrl = process.env.UPSTASH_URL;
|
const upstashUrl = process.env.UPSTASH_URL;
|
||||||
|
@ -299,6 +300,8 @@ function getUpstashRedisClient(): Redis {
|
||||||
console.log('Upstash Redis client created successfully');
|
console.log('Upstash Redis client created successfully');
|
||||||
|
|
||||||
(global as any)[globalKey] = client;
|
(global as any)[globalKey] = client;
|
||||||
|
// 同步设置旧的全局键,保持向后兼容
|
||||||
|
(global as any)[legacyKey] = client;
|
||||||
}
|
}
|
||||||
|
|
||||||
return client;
|
return client;
|
||||||
|
|
|
@ -11,11 +11,15 @@ export enum UpdateStatus {
|
||||||
FETCH_FAILED = 'fetch_failed', // 获取失败
|
FETCH_FAILED = 'fetch_failed', // 获取失败
|
||||||
}
|
}
|
||||||
|
|
||||||
// 远程版本检查URL配置
|
// 远程版本检查URL配置(支持环境变量覆盖,并保留 MoonTV 上游作为后备)
|
||||||
|
const ENV_PRIMARY = process.env.NEXT_PUBLIC_VERSION_URL_PRIMARY;
|
||||||
|
const ENV_BACKUP = process.env.NEXT_PUBLIC_VERSION_URL_BACKUP;
|
||||||
const VERSION_CHECK_URLS = [
|
const VERSION_CHECK_URLS = [
|
||||||
|
ENV_PRIMARY,
|
||||||
|
ENV_BACKUP,
|
||||||
'https://ghfast.top/raw.githubusercontent.com/senshinya/MoonTV/main/VERSION.txt',
|
'https://ghfast.top/raw.githubusercontent.com/senshinya/MoonTV/main/VERSION.txt',
|
||||||
'https://raw.githubusercontent.com/senshinya/MoonTV/main/VERSION.txt',
|
'https://raw.githubusercontent.com/senshinya/MoonTV/main/VERSION.txt',
|
||||||
];
|
].filter(Boolean) as string[];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 检查是否有新版本可用
|
* 检查是否有新版本可用
|
||||||
|
|
Loading…
Reference in New Issue