再次优化弹幕加载逻辑
This commit is contained in:
+39
-26
@@ -557,8 +557,14 @@ function PlayPageClient() {
|
|||||||
|
|
||||||
// 监听剧集切换,自动加载对应的弹幕
|
// 监听剧集切换,自动加载对应的弹幕
|
||||||
const lastLoadedEpisodeIndexForDanmakuRef = useRef<number | null>(null);
|
const lastLoadedEpisodeIndexForDanmakuRef = useRef<number | null>(null);
|
||||||
|
const loadingDanmakuEpisodeIdRef = useRef<number | null>(null);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
// 等待初始化完成(播放记录恢复完成)
|
||||||
|
if (loading) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// 检查集数是否有效且是否已改变
|
// 检查集数是否有效且是否已改变
|
||||||
if (currentEpisodeIndex < 0 || !videoTitle) {
|
if (currentEpisodeIndex < 0 || !videoTitle) {
|
||||||
return;
|
return;
|
||||||
@@ -857,7 +863,7 @@ function PlayPageClient() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
loadDanmakuForCurrentEpisode();
|
loadDanmakuForCurrentEpisode();
|
||||||
}, [currentEpisodeIndex, videoTitle]);
|
}, [currentEpisodeIndex, videoTitle, loading]);
|
||||||
|
|
||||||
// 获取豆瓣评分数据
|
// 获取豆瓣评分数据
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -2988,11 +2994,22 @@ function PlayPageClient() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 防止重复加载同一个 episodeId
|
||||||
|
if (loadingDanmakuEpisodeIdRef.current === episodeId) {
|
||||||
|
console.log(`[弹幕加载] 跳过重复加载: episodeId=${episodeId}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
loadingDanmakuEpisodeIdRef.current = episodeId;
|
||||||
setDanmakuLoading(true);
|
setDanmakuLoading(true);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 先清空当前弹幕(使用 reset 方法,不触发显示/隐藏事件)
|
// 先清空当前弹幕(使用 reset 方法,不触发显示/隐藏事件)
|
||||||
danmakuPluginRef.current.reset();
|
danmakuPluginRef.current.reset();
|
||||||
|
// 强制清空屏幕上的弹幕
|
||||||
|
danmakuPluginRef.current.config({ danmuku: [] });
|
||||||
|
danmakuPluginRef.current.load();
|
||||||
|
setDanmakuCount(0);
|
||||||
|
|
||||||
// 获取弹幕数据(使用 title + episodeIndex 缓存)
|
// 获取弹幕数据(使用 title + episodeIndex 缓存)
|
||||||
const title = videoTitleRef.current;
|
const title = videoTitleRef.current;
|
||||||
@@ -3005,6 +3022,7 @@ function PlayPageClient() {
|
|||||||
if (comments.length === 0) {
|
if (comments.length === 0) {
|
||||||
console.warn('未获取到弹幕数据');
|
console.warn('未获取到弹幕数据');
|
||||||
setDanmakuLoading(false);
|
setDanmakuLoading(false);
|
||||||
|
loadingDanmakuEpisodeIdRef.current = null;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3074,6 +3092,7 @@ function PlayPageClient() {
|
|||||||
setDanmakuCount(0);
|
setDanmakuCount(0);
|
||||||
} finally {
|
} finally {
|
||||||
setDanmakuLoading(false);
|
setDanmakuLoading(false);
|
||||||
|
loadingDanmakuEpisodeIdRef.current = null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -3154,41 +3173,34 @@ function PlayPageClient() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// 处理弹幕选择
|
// 处理弹幕选择
|
||||||
const handleDanmakuSelect = async (selection: DanmakuSelection) => {
|
const handleDanmakuSelect = async (selection: DanmakuSelection, isManual: boolean = false) => {
|
||||||
|
console.log(`[弹幕选择] isManual=${isManual}, selection:`, selection);
|
||||||
setCurrentDanmakuSelection(selection);
|
setCurrentDanmakuSelection(selection);
|
||||||
|
|
||||||
// 保存手动选择的剧集 ID 到 sessionStorage
|
// 只有手动选择时才保存到 sessionStorage
|
||||||
const title = videoTitleRef.current;
|
if (isManual) {
|
||||||
const episodeIndex = currentEpisodeIndexRef.current;
|
const title = videoTitleRef.current;
|
||||||
if (title && episodeIndex >= 0) {
|
const episodeIndex = currentEpisodeIndexRef.current;
|
||||||
saveManualDanmakuSelection(title, episodeIndex, selection.episodeId);
|
if (title && episodeIndex >= 0) {
|
||||||
|
saveManualDanmakuSelection(title, episodeIndex, selection.episodeId);
|
||||||
|
|
||||||
// 保存用户手动选择的动漫ID(用于换集时自动匹配)
|
// 保存用户手动选择的动漫ID(用于换集时自动匹配)
|
||||||
saveDanmakuAnimeId(title, selection.animeId);
|
saveDanmakuAnimeId(title, selection.animeId);
|
||||||
|
|
||||||
// 保存搜索关键词(如果有的话)
|
// 保存搜索关键词(如果有的话)
|
||||||
if (selection.searchKeyword) {
|
if (selection.searchKeyword) {
|
||||||
saveDanmakuSearchKeyword(title, selection.searchKeyword);
|
saveDanmakuSearchKeyword(title, selection.searchKeyword);
|
||||||
console.log(`[弹幕记忆] 保存手动搜索关键词: ${selection.searchKeyword}`);
|
console.log(`[弹幕记忆] 保存手动搜索关键词: ${selection.searchKeyword}`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取该动漫的所有剧集列表
|
|
||||||
try {
|
|
||||||
const episodesResult = await getEpisodes(selection.animeId);
|
|
||||||
if (episodesResult.success && episodesResult.bangumi.episodes.length > 0) {
|
|
||||||
setDanmakuEpisodesList(episodesResult.bangumi.episodes);
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error('获取弹幕剧集列表失败:', error);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 加载弹幕
|
// 加载弹幕
|
||||||
await loadDanmaku(selection.episodeId);
|
await loadDanmaku(selection.episodeId);
|
||||||
};
|
};
|
||||||
|
|
||||||
// 处理用户选择弹幕源
|
// 处理用户选择弹幕源
|
||||||
const handleDanmakuSourceSelect = async (selectedAnime: DanmakuAnime, selectedIndex?: number) => {
|
const handleDanmakuSourceSelect = async (selectedAnime: DanmakuAnime, selectedIndex?: number, isManualSearch: boolean = false) => {
|
||||||
setShowDanmakuSourceSelector(false);
|
setShowDanmakuSourceSelector(false);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -3226,7 +3238,8 @@ function PlayPageClient() {
|
|||||||
console.log('用户选择弹幕源:', selection);
|
console.log('用户选择弹幕源:', selection);
|
||||||
|
|
||||||
// 通过统一的 handleDanmakuSelect 处理弹幕加载
|
// 通过统一的 handleDanmakuSelect 处理弹幕加载
|
||||||
await handleDanmakuSelect(selection);
|
// 只有从弹幕面板手动搜索选择时才标记为手动选择
|
||||||
|
await handleDanmakuSelect(selection, isManualSearch);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
console.warn('未找到剧集信息');
|
console.warn('未找到剧集信息');
|
||||||
@@ -6541,7 +6554,7 @@ function PlayPageClient() {
|
|||||||
sourceSearchError={sourceSearchError}
|
sourceSearchError={sourceSearchError}
|
||||||
backgroundSourcesLoading={backgroundSourcesLoading}
|
backgroundSourcesLoading={backgroundSourcesLoading}
|
||||||
precomputedVideoInfo={precomputedVideoInfo}
|
precomputedVideoInfo={precomputedVideoInfo}
|
||||||
onDanmakuSelect={handleDanmakuSelect}
|
onDanmakuSelect={(selection) => handleDanmakuSelect(selection, true)}
|
||||||
currentDanmakuSelection={currentDanmakuSelection}
|
currentDanmakuSelection={currentDanmakuSelection}
|
||||||
onUploadDanmaku={handleUploadDanmaku}
|
onUploadDanmaku={handleUploadDanmaku}
|
||||||
episodeFilterConfig={episodeFilterConfig}
|
episodeFilterConfig={episodeFilterConfig}
|
||||||
|
|||||||
Reference in New Issue
Block a user