记住弹幕开关状态
This commit is contained in:
+59
-36
@@ -35,6 +35,8 @@ import {
|
|||||||
searchAnime,
|
searchAnime,
|
||||||
initDanmakuModule,
|
initDanmakuModule,
|
||||||
getDanmakuFromCache,
|
getDanmakuFromCache,
|
||||||
|
saveDanmakuDisplayState,
|
||||||
|
loadDanmakuDisplayState,
|
||||||
} from '@/lib/danmaku/api';
|
} from '@/lib/danmaku/api';
|
||||||
import {
|
import {
|
||||||
getDanmakuSourceIndex,
|
getDanmakuSourceIndex,
|
||||||
@@ -347,6 +349,14 @@ function PlayPageClient() {
|
|||||||
const danmakuPluginRef = useRef<any>(null);
|
const danmakuPluginRef = useRef<any>(null);
|
||||||
const danmakuSettingsRef = useRef(danmakuSettings);
|
const danmakuSettingsRef = useRef(danmakuSettings);
|
||||||
|
|
||||||
|
// 弹幕显示状态的 ref,初始化时从 localStorage 读取
|
||||||
|
const danmakuDisplayStateRef = useRef<boolean>(
|
||||||
|
(() => {
|
||||||
|
const saved = loadDanmakuDisplayState();
|
||||||
|
return saved !== false; // null 或 true 都返回 true
|
||||||
|
})()
|
||||||
|
);
|
||||||
|
|
||||||
// 弹幕热力图完全禁用开关(默认不禁用,即启用热力图功能)
|
// 弹幕热力图完全禁用开关(默认不禁用,即启用热力图功能)
|
||||||
const [danmakuHeatmapDisabled, setDanmakuHeatmapDisabled] = useState<boolean>(() => {
|
const [danmakuHeatmapDisabled, setDanmakuHeatmapDisabled] = useState<boolean>(() => {
|
||||||
if (typeof window !== 'undefined') {
|
if (typeof window !== 'undefined') {
|
||||||
@@ -564,11 +574,9 @@ function PlayPageClient() {
|
|||||||
|
|
||||||
console.log(`[弹幕] 剧集切换到第 ${currentEpisodeIndex + 1} 集,自动加载弹幕`);
|
console.log(`[弹幕] 剧集切换到第 ${currentEpisodeIndex + 1} 集,自动加载弹幕`);
|
||||||
|
|
||||||
// 立即清空当前弹幕
|
// 立即清空当前弹幕(使用 reset 方法,不触发显示/隐藏事件)
|
||||||
if (danmakuPluginRef.current) {
|
if (danmakuPluginRef.current) {
|
||||||
danmakuPluginRef.current.hide();
|
danmakuPluginRef.current.reset();
|
||||||
danmakuPluginRef.current.config({ danmuku: [] });
|
|
||||||
danmakuPluginRef.current.load();
|
|
||||||
setDanmakuCount(0);
|
setDanmakuCount(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -642,11 +650,12 @@ function PlayPageClient() {
|
|||||||
});
|
});
|
||||||
danmakuPluginRef.current.load();
|
danmakuPluginRef.current.load();
|
||||||
|
|
||||||
// 根据设置显示或隐藏弹幕
|
// 根据保存的显示状态来决定显示或隐藏弹幕
|
||||||
if (currentSettings.enabled) {
|
const savedDisplayState = loadDanmakuDisplayState();
|
||||||
danmakuPluginRef.current.show();
|
if (savedDisplayState === false) {
|
||||||
} else {
|
|
||||||
danmakuPluginRef.current.hide();
|
danmakuPluginRef.current.hide();
|
||||||
|
} else {
|
||||||
|
danmakuPluginRef.current.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
setDanmakuCount(danmakuData.length);
|
setDanmakuCount(danmakuData.length);
|
||||||
@@ -1580,6 +1589,12 @@ function PlayPageClient() {
|
|||||||
|
|
||||||
if (artPlayerRef.current) {
|
if (artPlayerRef.current) {
|
||||||
try {
|
try {
|
||||||
|
// 在销毁前先移除弹幕显示/隐藏事件监听器,避免 destroy 时触发 hide 事件导致状态被错误保存
|
||||||
|
if (artPlayerRef.current) {
|
||||||
|
artPlayerRef.current.off('artplayerPluginDanmuku:show');
|
||||||
|
artPlayerRef.current.off('artplayerPluginDanmuku:hide');
|
||||||
|
}
|
||||||
|
|
||||||
// 在销毁前从弹幕插件读取最新配置并保存
|
// 在销毁前从弹幕插件读取最新配置并保存
|
||||||
if (danmakuPluginRef.current?.option && artPlayerRef.current.storage) {
|
if (danmakuPluginRef.current?.option && artPlayerRef.current.storage) {
|
||||||
// 获取当前弹幕设置的快照,避免循环引用
|
// 获取当前弹幕设置的快照,避免循环引用
|
||||||
@@ -2970,12 +2985,8 @@ function PlayPageClient() {
|
|||||||
setDanmakuLoading(true);
|
setDanmakuLoading(true);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 先清空当前弹幕并隐藏
|
// 先清空当前弹幕(使用 reset 方法,不触发显示/隐藏事件)
|
||||||
danmakuPluginRef.current.hide();
|
danmakuPluginRef.current.reset();
|
||||||
danmakuPluginRef.current.config({
|
|
||||||
danmuku: [],
|
|
||||||
});
|
|
||||||
danmakuPluginRef.current.load();
|
|
||||||
|
|
||||||
// 获取弹幕数据(使用 title + episodeIndex 缓存)
|
// 获取弹幕数据(使用 title + episodeIndex 缓存)
|
||||||
const title = videoTitleRef.current;
|
const title = videoTitleRef.current;
|
||||||
@@ -3039,11 +3050,12 @@ function PlayPageClient() {
|
|||||||
});
|
});
|
||||||
danmakuPluginRef.current.load();
|
danmakuPluginRef.current.load();
|
||||||
|
|
||||||
// 根据设置显示或隐藏弹幕
|
// 根据保存的显示状态来决定显示或隐藏弹幕
|
||||||
if (currentSettings.enabled) {
|
const savedDisplayState = loadDanmakuDisplayState();
|
||||||
danmakuPluginRef.current.show();
|
if (savedDisplayState === false) {
|
||||||
} else {
|
|
||||||
danmakuPluginRef.current.hide();
|
danmakuPluginRef.current.hide();
|
||||||
|
} else {
|
||||||
|
danmakuPluginRef.current.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
setDanmakuCount(danmakuData.length);
|
setDanmakuCount(danmakuData.length);
|
||||||
@@ -3095,11 +3107,9 @@ function PlayPageClient() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 加载弹幕到播放器
|
// 加载弹幕到播放器(使用 reset 方法清空,不触发显示/隐藏事件)
|
||||||
if (danmakuPluginRef.current) {
|
if (danmakuPluginRef.current) {
|
||||||
danmakuPluginRef.current.hide();
|
danmakuPluginRef.current.reset();
|
||||||
danmakuPluginRef.current.config({ danmuku: [] });
|
|
||||||
danmakuPluginRef.current.load();
|
|
||||||
|
|
||||||
const currentSettings = danmakuSettingsRef.current;
|
const currentSettings = danmakuSettingsRef.current;
|
||||||
danmakuPluginRef.current.config({
|
danmakuPluginRef.current.config({
|
||||||
@@ -3112,10 +3122,12 @@ function PlayPageClient() {
|
|||||||
});
|
});
|
||||||
danmakuPluginRef.current.load();
|
danmakuPluginRef.current.load();
|
||||||
|
|
||||||
if (currentSettings.enabled) {
|
// 根据保存的显示状态来决定显示或隐藏弹幕
|
||||||
danmakuPluginRef.current.show();
|
const savedDisplayState = loadDanmakuDisplayState();
|
||||||
} else {
|
if (savedDisplayState === false) {
|
||||||
danmakuPluginRef.current.hide();
|
danmakuPluginRef.current.hide();
|
||||||
|
} else {
|
||||||
|
danmakuPluginRef.current.show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3342,11 +3354,12 @@ function PlayPageClient() {
|
|||||||
});
|
});
|
||||||
danmakuPluginRef.current.load();
|
danmakuPluginRef.current.load();
|
||||||
|
|
||||||
// 根据设置显示或隐藏弹幕
|
// 根据保存的显示状态来决定显示或隐藏弹幕
|
||||||
if (currentSettings.enabled) {
|
const savedDisplayState = loadDanmakuDisplayState();
|
||||||
danmakuPluginRef.current.show();
|
if (savedDisplayState === false) {
|
||||||
} else {
|
|
||||||
danmakuPluginRef.current.hide();
|
danmakuPluginRef.current.hide();
|
||||||
|
} else {
|
||||||
|
danmakuPluginRef.current.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
setDanmakuCount(danmakuData.length);
|
setDanmakuCount(danmakuData.length);
|
||||||
@@ -4027,6 +4040,8 @@ function PlayPageClient() {
|
|||||||
heatmap: false, // 禁用 artplayer 自带热力图,使用自定义热力图
|
heatmap: false, // 禁用 artplayer 自带热力图,使用自定义热力图
|
||||||
// 主题
|
// 主题
|
||||||
theme: 'dark',
|
theme: 'dark',
|
||||||
|
// 根据保存的显示状态设置初始可见性
|
||||||
|
visible: danmakuDisplayStateRef.current,
|
||||||
filter: (danmu: any) => {
|
filter: (danmu: any) => {
|
||||||
// 应用过滤规则
|
// 应用过滤规则
|
||||||
const filterConfig = danmakuFilterConfigRef.current;
|
const filterConfig = danmakuFilterConfigRef.current;
|
||||||
@@ -4981,15 +4996,23 @@ function PlayPageClient() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// 根据设置显示或隐藏弹幕
|
|
||||||
if (danmakuSettingsRef.current.enabled) {
|
|
||||||
danmakuPluginRef.current.show();
|
|
||||||
} else {
|
|
||||||
danmakuPluginRef.current.hide();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 自动搜索并加载弹幕
|
// 自动搜索并加载弹幕
|
||||||
await autoSearchDanmaku();
|
await autoSearchDanmaku();
|
||||||
|
|
||||||
|
|
||||||
|
if (artPlayerRef.current) {
|
||||||
|
// 监听弹幕显示/隐藏事件,保存开关状态到 localStorage
|
||||||
|
artPlayerRef.current.on('artplayerPluginDanmuku:show', () => {
|
||||||
|
danmakuDisplayStateRef.current = true;
|
||||||
|
saveDanmakuDisplayState(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
artPlayerRef.current.on('artplayerPluginDanmuku:hide', () => {
|
||||||
|
danmakuDisplayStateRef.current = false;
|
||||||
|
saveDanmakuDisplayState(false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 播放器就绪后,如果正在播放则请求 Wake Lock
|
// 播放器就绪后,如果正在播放则请求 Wake Lock
|
||||||
|
|||||||
+30
-2
@@ -263,10 +263,13 @@ export function loadDanmakuSettings(): DanmakuSettings {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const saved = localStorage.getItem('danmaku_settings');
|
const saved = localStorage.getItem('danmaku_settings');
|
||||||
|
let settings = DEFAULT_DANMAKU_SETTINGS;
|
||||||
|
|
||||||
if (saved) {
|
if (saved) {
|
||||||
const settings = JSON.parse(saved) as DanmakuSettings;
|
settings = { ...DEFAULT_DANMAKU_SETTINGS, ...JSON.parse(saved) };
|
||||||
return { ...DEFAULT_DANMAKU_SETTINGS, ...settings };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return settings;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('读取弹幕设置失败:', error);
|
console.error('读取弹幕设置失败:', error);
|
||||||
}
|
}
|
||||||
@@ -284,6 +287,31 @@ export function saveDanmakuSettings(settings: DanmakuSettings): void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 保存弹幕显示状态到 localStorage(独立的 key)
|
||||||
|
export function saveDanmakuDisplayState(enabled: boolean): void {
|
||||||
|
if (typeof window === 'undefined') return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
localStorage.setItem('danmaku_display_enabled', String(enabled));
|
||||||
|
} catch (error) {
|
||||||
|
console.error('保存弹幕显示状态失败:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 读取弹幕显示状态
|
||||||
|
export function loadDanmakuDisplayState(): boolean | null {
|
||||||
|
if (typeof window === 'undefined') return null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const saved = localStorage.getItem('danmaku_display_enabled');
|
||||||
|
if (saved === null) return null;
|
||||||
|
return saved === 'true';
|
||||||
|
} catch (error) {
|
||||||
|
console.error('读取弹幕显示状态失败:', error);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 记忆上次选择的弹幕
|
// 记忆上次选择的弹幕
|
||||||
export interface DanmakuMemory {
|
export interface DanmakuMemory {
|
||||||
videoTitle: string;
|
videoTitle: string;
|
||||||
|
|||||||
Reference in New Issue
Block a user