增加弹幕上限设置
This commit is contained in:
+70
-1
@@ -367,6 +367,7 @@ function PlayPageClient() {
|
|||||||
>([]);
|
>([]);
|
||||||
const [danmakuLoading, setDanmakuLoading] = useState(false);
|
const [danmakuLoading, setDanmakuLoading] = useState(false);
|
||||||
const [danmakuCount, setDanmakuCount] = useState(0);
|
const [danmakuCount, setDanmakuCount] = useState(0);
|
||||||
|
const [danmakuOriginalCount, setDanmakuOriginalCount] = useState(0);
|
||||||
const danmakuPluginRef = useRef<any>(null);
|
const danmakuPluginRef = useRef<any>(null);
|
||||||
const danmakuSettingsRef = useRef(danmakuSettings);
|
const danmakuSettingsRef = useRef(danmakuSettings);
|
||||||
|
|
||||||
@@ -705,6 +706,22 @@ function PlayPageClient() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 应用弹幕数量限制
|
||||||
|
const maxCount = typeof window !== 'undefined' ? parseInt(localStorage.getItem('danmakuMaxCount') || '0', 10) : 0;
|
||||||
|
if (maxCount > 0 && danmakuData.length > maxCount) {
|
||||||
|
const originalCount = danmakuData.length;
|
||||||
|
const step = danmakuData.length / maxCount;
|
||||||
|
const limitedData = [];
|
||||||
|
for (let i = 0; i < maxCount; i++) {
|
||||||
|
limitedData.push(danmakuData[Math.floor(i * step)]);
|
||||||
|
}
|
||||||
|
danmakuData = limitedData;
|
||||||
|
setDanmakuOriginalCount(originalCount);
|
||||||
|
console.log(`弹幕数量限制: 原始 ${originalCount} 条,限制到 ${danmakuData.length} 条`);
|
||||||
|
} else {
|
||||||
|
setDanmakuOriginalCount(0);
|
||||||
|
}
|
||||||
|
|
||||||
// 加载弹幕到插件
|
// 加载弹幕到插件
|
||||||
const currentSettings = danmakuSettingsRef.current;
|
const currentSettings = danmakuSettingsRef.current;
|
||||||
danmakuPluginRef.current.config({
|
danmakuPluginRef.current.config({
|
||||||
@@ -3602,6 +3619,22 @@ function PlayPageClient() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 应用弹幕数量限制
|
||||||
|
const maxCount = typeof window !== 'undefined' ? parseInt(localStorage.getItem('danmakuMaxCount') || '0', 10) : 0;
|
||||||
|
if (maxCount > 0 && danmakuData.length > maxCount) {
|
||||||
|
const originalCount = danmakuData.length;
|
||||||
|
const step = danmakuData.length / maxCount;
|
||||||
|
const limitedData = [];
|
||||||
|
for (let i = 0; i < maxCount; i++) {
|
||||||
|
limitedData.push(danmakuData[Math.floor(i * step)]);
|
||||||
|
}
|
||||||
|
danmakuData = limitedData;
|
||||||
|
setDanmakuOriginalCount(originalCount);
|
||||||
|
console.log(`弹幕数量限制: 原始 ${originalCount} 条,限制到 ${danmakuData.length} 条`);
|
||||||
|
} else {
|
||||||
|
setDanmakuOriginalCount(0);
|
||||||
|
}
|
||||||
|
|
||||||
// 加载弹幕到插件,同时应用当前的弹幕设置
|
// 加载弹幕到插件,同时应用当前的弹幕设置
|
||||||
const currentSettings = danmakuSettingsRef.current;
|
const currentSettings = danmakuSettingsRef.current;
|
||||||
danmakuPluginRef.current.config({
|
danmakuPluginRef.current.config({
|
||||||
@@ -3634,6 +3667,7 @@ function PlayPageClient() {
|
|||||||
episodeTitle: metadata.episodeTitle || '',
|
episodeTitle: metadata.episodeTitle || '',
|
||||||
searchKeyword: metadata.searchKeyword,
|
searchKeyword: metadata.searchKeyword,
|
||||||
danmakuCount: danmakuData.length,
|
danmakuCount: danmakuData.length,
|
||||||
|
danmakuOriginalCount: danmakuOriginalCount > 0 ? danmakuOriginalCount : undefined,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3801,6 +3835,22 @@ function PlayPageClient() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 应用弹幕数量限制
|
||||||
|
const maxCount = typeof window !== 'undefined' ? parseInt(localStorage.getItem('danmakuMaxCount') || '0', 10) : 0;
|
||||||
|
if (maxCount > 0 && danmakuData.length > maxCount) {
|
||||||
|
const originalCount = danmakuData.length;
|
||||||
|
const step = danmakuData.length / maxCount;
|
||||||
|
const limitedData = [];
|
||||||
|
for (let i = 0; i < maxCount; i++) {
|
||||||
|
limitedData.push(danmakuData[Math.floor(i * step)]);
|
||||||
|
}
|
||||||
|
danmakuData = limitedData;
|
||||||
|
setDanmakuOriginalCount(originalCount);
|
||||||
|
console.log(`弹幕数量限制: 原始 ${originalCount} 条,限制到 ${danmakuData.length} 条`);
|
||||||
|
} else {
|
||||||
|
setDanmakuOriginalCount(0);
|
||||||
|
}
|
||||||
|
|
||||||
// 加载弹幕到播放器(使用 reset 方法清空,不触发显示/隐藏事件)
|
// 加载弹幕到播放器(使用 reset 方法清空,不触发显示/隐藏事件)
|
||||||
if (danmakuPluginRef.current) {
|
if (danmakuPluginRef.current) {
|
||||||
danmakuPluginRef.current.reset();
|
danmakuPluginRef.current.reset();
|
||||||
@@ -4050,6 +4100,22 @@ function PlayPageClient() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 应用弹幕数量限制
|
||||||
|
const maxCount = typeof window !== 'undefined' ? parseInt(localStorage.getItem('danmakuMaxCount') || '0', 10) : 0;
|
||||||
|
if (maxCount > 0 && danmakuData.length > maxCount) {
|
||||||
|
const originalCount = danmakuData.length;
|
||||||
|
const step = danmakuData.length / maxCount;
|
||||||
|
const limitedData = [];
|
||||||
|
for (let i = 0; i < maxCount; i++) {
|
||||||
|
limitedData.push(danmakuData[Math.floor(i * step)]);
|
||||||
|
}
|
||||||
|
danmakuData = limitedData;
|
||||||
|
setDanmakuOriginalCount(originalCount);
|
||||||
|
console.log(`弹幕数量限制: 原始 ${originalCount} 条,限制到 ${danmakuData.length} 条`);
|
||||||
|
} else {
|
||||||
|
setDanmakuOriginalCount(0);
|
||||||
|
}
|
||||||
|
|
||||||
// 加载弹幕到插件
|
// 加载弹幕到插件
|
||||||
const currentSettings = danmakuSettingsRef.current;
|
const currentSettings = danmakuSettingsRef.current;
|
||||||
danmakuPluginRef.current.config({
|
danmakuPluginRef.current.config({
|
||||||
@@ -7107,7 +7173,10 @@ function PlayPageClient() {
|
|||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
<span className='text-sm font-medium text-green-400'>
|
<span className='text-sm font-medium text-green-400'>
|
||||||
已加载 {danmakuCount} 条弹幕
|
{danmakuOriginalCount > 0
|
||||||
|
? `已加载 ${danmakuCount} 条弹幕(原始 ${danmakuOriginalCount} 条)`
|
||||||
|
: `已加载 ${danmakuCount} 条弹幕`
|
||||||
|
}
|
||||||
</span>
|
</span>
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
|
|||||||
@@ -241,6 +241,7 @@ export default function DanmakuPanel({
|
|||||||
{currentSelection.danmakuCount !== undefined && (
|
{currentSelection.danmakuCount !== undefined && (
|
||||||
<p className='mt-1 text-xs text-gray-500 dark:text-gray-500'>
|
<p className='mt-1 text-xs text-gray-500 dark:text-gray-500'>
|
||||||
弹幕数量: {currentSelection.danmakuCount}
|
弹幕数量: {currentSelection.danmakuCount}
|
||||||
|
{currentSelection.danmakuOriginalCount && ` (原始 ${currentSelection.danmakuOriginalCount} 条)`}
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -114,6 +114,7 @@ export const UserMenu: React.FC = () => {
|
|||||||
const [nextEpisodePreCache, setNextEpisodePreCache] = useState(true);
|
const [nextEpisodePreCache, setNextEpisodePreCache] = useState(true);
|
||||||
const [nextEpisodeDanmakuPreload, setNextEpisodeDanmakuPreload] = useState(true);
|
const [nextEpisodeDanmakuPreload, setNextEpisodeDanmakuPreload] = useState(true);
|
||||||
const [disableAutoLoadDanmaku, setDisableAutoLoadDanmaku] = useState(false);
|
const [disableAutoLoadDanmaku, setDisableAutoLoadDanmaku] = useState(false);
|
||||||
|
const [danmakuMaxCount, setDanmakuMaxCount] = useState(0);
|
||||||
const [searchTraditionalToSimplified, setSearchTraditionalToSimplified] = useState(false);
|
const [searchTraditionalToSimplified, setSearchTraditionalToSimplified] = useState(false);
|
||||||
|
|
||||||
// 邮件通知设置
|
// 邮件通知设置
|
||||||
@@ -409,6 +410,19 @@ export const UserMenu: React.FC = () => {
|
|||||||
setDisableAutoLoadDanmaku(savedDisableAutoLoadDanmaku === 'true');
|
setDisableAutoLoadDanmaku(savedDisableAutoLoadDanmaku === 'true');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const savedDanmakuMaxCount = localStorage.getItem('danmakuMaxCount');
|
||||||
|
if (savedDanmakuMaxCount !== null) {
|
||||||
|
const value = parseInt(savedDanmakuMaxCount, 10);
|
||||||
|
// 兼容旧版本的0-4映射值
|
||||||
|
if (value <= 4) {
|
||||||
|
const mappedValue = value === 0 ? 0 : value === 1 ? 1000 : value === 2 ? 3000 : value === 3 ? 5000 : 10000;
|
||||||
|
setDanmakuMaxCount(mappedValue);
|
||||||
|
localStorage.setItem('danmakuMaxCount', String(mappedValue));
|
||||||
|
} else {
|
||||||
|
setDanmakuMaxCount(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 加载首页模块配置
|
// 加载首页模块配置
|
||||||
const savedHomeModules = localStorage.getItem('homeModules');
|
const savedHomeModules = localStorage.getItem('homeModules');
|
||||||
if (savedHomeModules !== null) {
|
if (savedHomeModules !== null) {
|
||||||
@@ -772,6 +786,13 @@ export const UserMenu: React.FC = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleDanmakuMaxCountChange = (value: number) => {
|
||||||
|
setDanmakuMaxCount(value);
|
||||||
|
if (typeof window !== 'undefined') {
|
||||||
|
localStorage.setItem('danmakuMaxCount', String(value));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const handleSearchTraditionalToSimplifiedToggle = (value: boolean) => {
|
const handleSearchTraditionalToSimplifiedToggle = (value: boolean) => {
|
||||||
setSearchTraditionalToSimplified(value);
|
setSearchTraditionalToSimplified(value);
|
||||||
if (typeof window !== 'undefined') {
|
if (typeof window !== 'undefined') {
|
||||||
@@ -891,6 +912,7 @@ export const UserMenu: React.FC = () => {
|
|||||||
localStorage.setItem('nextEpisodePreCache', 'true');
|
localStorage.setItem('nextEpisodePreCache', 'true');
|
||||||
localStorage.setItem('nextEpisodeDanmakuPreload', 'true');
|
localStorage.setItem('nextEpisodeDanmakuPreload', 'true');
|
||||||
localStorage.setItem('disableAutoLoadDanmaku', 'false');
|
localStorage.setItem('disableAutoLoadDanmaku', 'false');
|
||||||
|
localStorage.setItem('danmakuMaxCount', '0');
|
||||||
localStorage.setItem('homeModules', JSON.stringify(defaultHomeModules));
|
localStorage.setItem('homeModules', JSON.stringify(defaultHomeModules));
|
||||||
localStorage.setItem('searchTraditionalToSimplified', 'false');
|
localStorage.setItem('searchTraditionalToSimplified', 'false');
|
||||||
window.dispatchEvent(new CustomEvent('homeModulesUpdated'));
|
window.dispatchEvent(new CustomEvent('homeModulesUpdated'));
|
||||||
@@ -1879,6 +1901,65 @@ export const UserMenu: React.FC = () => {
|
|||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* 弹幕加载上限 */}
|
||||||
|
<div className='space-y-2'>
|
||||||
|
<div className='flex items-center justify-between'>
|
||||||
|
<span className='text-xs text-gray-600 dark:text-gray-400'>
|
||||||
|
弹幕加载上限
|
||||||
|
</span>
|
||||||
|
<span className='text-xs font-medium text-gray-700 dark:text-gray-300'>
|
||||||
|
{danmakuMaxCount === 0 ? '无上限' : `${danmakuMaxCount} 条`}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div className='flex items-center gap-2'>
|
||||||
|
<input
|
||||||
|
type='range'
|
||||||
|
min='0'
|
||||||
|
max='10000'
|
||||||
|
step='100'
|
||||||
|
value={danmakuMaxCount}
|
||||||
|
onChange={(e) => handleDanmakuMaxCountChange(parseInt(e.target.value))}
|
||||||
|
className='flex-1 h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer dark:bg-gray-700'
|
||||||
|
style={{
|
||||||
|
background: `linear-gradient(to right, #10b981 0%, #10b981 ${(danmakuMaxCount / 10000) * 100}%, #e5e7eb ${(danmakuMaxCount / 10000) * 100}%, #e5e7eb 100%)`
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className='relative text-xs text-gray-500 dark:text-gray-400' style={{ height: '24px' }}>
|
||||||
|
<button
|
||||||
|
onClick={() => handleDanmakuMaxCountChange(0)}
|
||||||
|
className={`absolute px-2 py-0.5 rounded ${danmakuMaxCount === 0 ? 'bg-green-500 text-white' : 'hover:bg-gray-200 dark:hover:bg-gray-700'}`}
|
||||||
|
style={{ left: '0%', transform: 'translateX(0%)' }}
|
||||||
|
>
|
||||||
|
无上限
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={() => handleDanmakuMaxCountChange(3000)}
|
||||||
|
className={`absolute px-2 py-0.5 rounded ${danmakuMaxCount === 3000 ? 'bg-green-500 text-white' : 'hover:bg-gray-200 dark:hover:bg-gray-700'}`}
|
||||||
|
style={{ left: '30%', transform: 'translateX(-50%)' }}
|
||||||
|
>
|
||||||
|
3000
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={() => handleDanmakuMaxCountChange(5000)}
|
||||||
|
className={`absolute px-2 py-0.5 rounded ${danmakuMaxCount === 5000 ? 'bg-green-500 text-white' : 'hover:bg-gray-200 dark:hover:bg-gray-700'}`}
|
||||||
|
style={{ left: '50%', transform: 'translateX(-50%)' }}
|
||||||
|
>
|
||||||
|
5000
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={() => handleDanmakuMaxCountChange(10000)}
|
||||||
|
className={`absolute px-2 py-0.5 rounded ${danmakuMaxCount === 10000 ? 'bg-green-500 text-white' : 'hover:bg-gray-200 dark:hover:bg-gray-700'}`}
|
||||||
|
style={{ left: '100%', transform: 'translateX(-100%)' }}
|
||||||
|
>
|
||||||
|
10000
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<p className='text-xs text-gray-500 dark:text-gray-400 mt-1'>
|
||||||
|
限制加载的弹幕数量,减少性能消耗
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
{/* 清除弹幕缓存 */}
|
{/* 清除弹幕缓存 */}
|
||||||
<div className='space-y-3'>
|
<div className='space-y-3'>
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ export interface DanmakuSettings {
|
|||||||
filterRules: string[]; // 过滤规则(正则表达式)
|
filterRules: string[]; // 过滤规则(正则表达式)
|
||||||
unlimited: boolean; // 无限弹幕
|
unlimited: boolean; // 无限弹幕
|
||||||
synchronousPlayback: boolean; // 同步播放
|
synchronousPlayback: boolean; // 同步播放
|
||||||
|
maxCount?: number; // 弹幕加载上限
|
||||||
}
|
}
|
||||||
|
|
||||||
// 自动匹配请求
|
// 自动匹配请求
|
||||||
@@ -115,4 +116,5 @@ export interface DanmakuSelection {
|
|||||||
episodeTitle: string;
|
episodeTitle: string;
|
||||||
searchKeyword?: string; // 用户搜索时使用的关键词
|
searchKeyword?: string; // 用户搜索时使用的关键词
|
||||||
danmakuCount?: number; // 弹幕数量
|
danmakuCount?: number; // 弹幕数量
|
||||||
|
danmakuOriginalCount?: number; // 原始弹幕数量
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user