初始提交:短剧库源码(含转码优化 ultrafast)

This commit is contained in:
yvan
2026-09-17 19:09:08 +08:00
commit 07dc0f1059
247 changed files with 43242 additions and 0 deletions
+65
View File
@@ -0,0 +1,65 @@
import { $, element, empty, button, setMessage, api, post, valueText, firstNonEmpty, dramaTitle, watchLabel, historySuffix, normalizeSource, sourceKey, sourceLabel, categoryName, episodeCount, coverURL, tagsText, dramaSearchText, rebuildOptions, number, formatBytes, formatTime, statusText, releaseText, phaseText, progressText, progressBar, episodeLabel, groupStats } from './ui-core.js';
import { createPlaybackSettings } from './playback-settings.js';
export function createSettings(app) {
let config = {};
function refreshConfigFields(){ $('downloadLocation').textContent=config.outputDir||'尚未设置';$('downloadLocation').title=config.outputDir||''; $('downloadDirectory').value=config.outputDirSetting||config.outputDir||'./短剧下载';$('downloadDirectoryHint').textContent=(config.restartRequired?'已保存新目录,重启后生效。':'')+'选择程序所在电脑的文件夹,或输入相对/绝对路径。重启后新合集使用新目录,原任务和文件保留。';$('downloadConcurrency').value=config.concurrency||2;$('requestConcurrency').value=config.requestConcurrency||2;$('requestInterval').value=config.requestIntervalMs||500;$('proxyMode').value=config.proxyMode||'auto';$('proxyURL').value=config.proxyURL||'';$('proxyUsername').value='';$('proxyPassword').value='';$('proxyPassword').placeholder=config.proxyHasAuth?'已保存,留空保留认证':'';updateProxyFields();$('configText').textContent='当前输出:'+(config.outputDir||'')+' · 下载并发 '+(config.concurrency||2)+' · '+(config.network||'')+' · FFmpeg '+(config.ffmpeg||''); }
function updateProxyFields(){const disabled=$('proxyMode').value!=='manual';for(const name of ['proxyURL','proxyUsername','proxyPassword'])$(name).disabled=disabled;}
async function loadConfig(){try{config=await api('/api/ui/config');refreshConfigFields();}catch(error){$('configText').textContent='配置读取失败:'+error.message;}}
async function saveSettings(){
const settings={outputDir:$('downloadDirectory').value.trim(),concurrency:number($('downloadConcurrency').value),requestConcurrency:number($('requestConcurrency').value),requestIntervalMs:number($('requestInterval').value)};
try{
const mode=$('proxyMode').value;if(mode!=='manual')settings.proxyURL=mode;else{const raw=$('proxyURL').value.trim();const username=$('proxyUsername').value;const password=$('proxyPassword').value;if(!(config.proxyHasAuth&&config.proxyMode==='manual'&&raw===config.proxyURL&&!username&&!password)){const endpoint=new URL(raw);if(!['http:','https:','socks5:','socks5h:'].includes(endpoint.protocol))throw new Error('仅支持 HTTP/HTTPS/SOCKS5 代理');if(username||password){endpoint.username=username;endpoint.password=password;}settings.proxyURL=endpoint.toString();}}
$('saveSettingsBtn').disabled=true;config=await post('/api/ui/config',settings);refreshConfigFields();$('settingsStatus').textContent=config.restartRequired?'设置已保存;下载目录重启后生效,当前任务保持原路径':'设置已保存并应用';
}catch(error){$('settingsStatus').textContent='保存失败:'+error.message;}finally{$('saveSettingsBtn').disabled=false;}
}
async function checkNetwork(){ $('checkNetworkBtn').disabled=true;$('settingsStatus').textContent='正在检测已保存的网络配置、各站入口和黄果实际媒体,最多约一分钟…';try{const result=await post('/api/ui/network/check',{});$('settingsStatus').textContent=(result.data||[]).map(item=>item.name+':'+(item.error||[item.status?'HTTP '+item.status:'',item.detail||''].filter(Boolean).join(' · '))).join(';');}catch(error){$('settingsStatus').textContent='检测失败:'+error.message;}finally{$('checkNetworkBtn').disabled=false;} }
async function chooseDownloadDirectory(){const button=$('browseDirectoryBtn');if(button.disabled)return;button.disabled=true;$('settingsStatus').textContent='请在系统窗口中选择下载文件夹…';try{const result=await post('/api/ui/directory/pick',{initialPath:$('downloadDirectory').value});if(result.canceled){$('settingsStatus').textContent='已取消选择,原目录未修改';return;}$('downloadDirectory').value=result.selectionPath||result.path;$('settingsStatus').textContent='已选择文件夹,请点击“保存并应用”';}catch(error){$('settingsStatus').textContent='选择文件夹失败:'+error.message;}finally{button.disabled=false;}}
async function importLegacyRecords() {
const control = $('legacyImportBtn');
control.disabled = true;
$('viewerImportStatus').textContent = '正在接回旧版记录…';
try {
await post('/api/ui/viewer/legacy', {code: $('legacyImportCode').value.trim()});
$('legacyImportCode').value = '';
$('legacyImportSection').hidden = true;
app.viewer.legacyAvailable = false;
await Promise.all([window.JukuHistory.refresh(), app.following.refresh()]);
$('viewerImportStatus').textContent = app.viewer?.account ? '旧版记录已接入当前账号,原始文件仍保留。' : '旧版记录已接回当前浏览器,原始文件仍保留。';
} catch (error) {
$('viewerImportStatus').textContent = error.message;
} finally {
control.disabled = false;
}
}
function init() {
const admin = Boolean(app.viewer?.account?.admin && !app.viewer.account.requirePasswordChange);
$('serverSettings').hidden = !admin;
$('serverSettingsNotice').hidden = admin;
$('downloadLocationBtn').hidden = !admin;
if (!admin) $('downloadLocation').textContent = '服务端下载目录';
$('legacyImportSection').hidden = !app.viewer?.legacyAvailable;
$('viewerImportStatus').textContent = app.viewer?.legacyError || '';
$('legacyImportBtn').addEventListener('click', importLegacyRecords);
$('browseDirectoryBtn').addEventListener('click', chooseDownloadDirectory);
$('proxyMode').addEventListener('change', updateProxyFields);
$('saveSettingsBtn').addEventListener('click', saveSettings);
$('checkNetworkBtn').addEventListener('click', checkNetwork);
$('openSettingsBtn').addEventListener('click', () => window.JukuDialogs.open('settingsPanel'));
$('closeSettingsBtn').addEventListener('click', () => $('settingsPanel').close());
$('themeSelect').value = window.JukuTheme.get();
$('themeSelect').addEventListener('change', () => window.JukuTheme.set($('themeSelect').value));
document.addEventListener('themechange', event => {$('themeSelect').value = event.detail;});
return admin ? Promise.all([loadConfig(), createPlaybackSettings().init()]) : Promise.resolve();
}
return {init, config: () => config};
}