'use strict'; Object.assign(MESSAGES.zh,{'source-browser':'从来源选入照片'}); Object.assign(MESSAGES.en,{'source-browser':'Import from source'}); icons['source-browser']='▧'; const sourceBrowser={source:null,filters:{},offset:0,previous:[]}; function openSourceBrowser(sourceId){sourceBrowser.source=sourceId;sourceBrowser.offset=0;sourceBrowser.previous=[];return navigate('source-browser');} views['source-browser']=async function(epoch){ const sources=await api('/api/v1/source-libraries');if(epoch!==state.epoch)return; if(!sources.length)return navigate('gallery'); if(!sources.some(s=>s.id===sourceBrowser.source)){sourceBrowser.source=sources[0].id;sourceBrowser.filters={};sourceBrowser.offset=0;sourceBrowser.previous=[];} const source=sources.find(s=>s.id===sourceBrowser.source),nas=source.kind==='synology-photos',f=sourceBrowser.filters; const input=(name,label,type='text',extra='')=>`
`; $('#main').innerHTML=`

${tr('按批读取照片信息,预览仅在进入可视区域时加载;选入后保存在本地,不会推送设备。','Reads metadata in bounded batches and loads previews on demand. Import stores locally without sending to devices.')}

${input('filename',tr('文件名关键字','Filename keyword'),'search','maxlength="200"')}${input('folder',tr('文件夹关键字','Folder keyword'),'search','maxlength="500"')}${input('min_mb',tr('最小文件大小(MB)','Min file size (MB)'),'number','min="0" step="0.1" max="1000000"')}${input('max_mb',tr('最大文件大小(MB)','Max file size (MB)'),'number','min="0" step="0.1" max="1000000"')}${input('min_width',tr('最小宽度(px)','Min width (px)'),'number','min="0" max="100000"')}${input('max_width',tr('最大宽度(px)','Max width (px)'),'number','min="0" max="100000"')}${input('min_height',tr('最小高度(px)','Min height (px)'),'number','min="0" max="100000"')}${input('max_height',tr('最大高度(px)','Max height (px)'),'number','min="0" max="100000"')}
${input('date_from',tr('开始日期','From date'),'date')}${input('date_to',tr('结束日期(含当天)','Through date (inclusive)'),'date')}

${nas?tr('筛选在当前来源设置范围内进行;日期使用系统时区,入库日期不等同于原文件的创建时间。筛选较少见照片时,可继续下一页检索,页面不会等待全库扫描。','Filters stay within this source. Dates use the system timezone; indexed dates are not original file creation dates. Continue through pages for rare matches without waiting for a full scan.'):tr('此来源使用现有目录接口;高级筛选和快速分页目前支持 Synology Photos。','This provider uses its existing catalog. Advanced filters and fast paging currently support Synology Photos.')}

${tr('正在读取本批照片…','Reading this batch…')}

`; bind('browse-back',()=>{libraryUI.source=source.id;libraryUI.offset=0;return navigate('gallery');}); $('#browse-source').onchange=()=>{sourceBrowser.filters={};return openSourceBrowser($('#browse-source').value);}; $('#source-browser-filters').onsubmit=busy(async e=>{e.preventDefault();const values=Object.fromEntries(new FormData(e.currentTarget));const people=$('#browse-person_id');sourceBrowser.filters={...values,person_name:people.selectedOptions[0]?.textContent||''};sourceBrowser.offset=0;sourceBrowser.previous=[];await navigate();}); $('#source-browser-filters').onreset=e=>{e.preventDefault();sourceBrowser.filters={};sourceBrowser.offset=0;sourceBrowser.previous=[];navigate();}; const params=new URLSearchParams({offset:sourceBrowser.offset,limit:36});for(const [key,value] of Object.entries(f)){if(value!==''&&key!=='person_name'&&!key.endsWith('_mb'))params.set(key,value);}for(const [key,target] of [['min_mb','min_bytes'],['max_mb','max_bytes']])if(f[key]!==undefined&&f[key]!=='')params.set(target,Math.round(Number(f[key])*1024*1024)); if(nas)loadBrowserPeople(source,epoch); let page;try{page=await api('/api/v1/source-libraries/'+encodeURIComponent(source.id)+'/browse?'+params);}catch(error){if(epoch!==state.epoch)return;$('#browse-status').textContent=error.message;$('#browse-gallery').setAttribute('aria-busy','false');return;} if(epoch!==state.epoch)return; $('#browse-status').textContent=tr(`本批找到 ${page.items.length} 张照片${page.paged_provider?`,检查 ${page.scanned} 条记录`:''}。${!page.items.length&&page.next_offset!==null?'可继续下一页检索。':''}`,`${page.items.length} matches in this batch${page.paged_provider?`, ${page.scanned} records checked`:''}.${!page.items.length&&page.next_offset!==null?' Continue to the next batch.':''}`); $('#browse-gallery').innerHTML=page.items.map((item,i)=>`

${esc(item.name)}

${esc(item.folder||item.source_path||'')}${item.width&&item.height?`${item.width} × ${item.height} px · `:''}${item.filesize?`${(item.filesize/1024/1024).toFixed(2)} MB`:''}${item.indexed_time?tr('入库:','Indexed: ')+esc(fmt(new Date(item.indexed_time*1000).toISOString())):''}${item.time?tr('拍摄:','Photo: ')+esc(fmt(new Date(item.time*1000).toISOString())):''}${esc((item.people||[]).map(p=>p.name).filter(Boolean).join('、'))}
`).join('');$('#browse-gallery').setAttribute('aria-busy','false'); $('#browse-next').disabled=page.next_offset===null; bind('browse-prev',()=>{sourceBrowser.offset=sourceBrowser.previous.pop()||0;return navigate();}); bind('browse-next',()=>{if(page.next_offset===null)return;sourceBrowser.previous.push(sourceBrowser.offset);sourceBrowser.offset=page.next_offset;return navigate();}); document.querySelectorAll('[data-browse-preview]').forEach(b=>b.onclick=busy(()=>{const item=page.items[b.dataset.browsePreview];return openImageViewer(item.preview_url,item.name);})); document.querySelectorAll('[data-browse-import]').forEach(b=>b.onclick=busy(async()=>{const item=page.items[b.dataset.browseImport];await api('/api/v1/source-libraries/'+encodeURIComponent(source.id)+'/import',{method:'POST',body:{item_id:item.id}});if(epoch!==state.epoch)return;b.textContent=tr('已选入','Imported');b.disabled=true;libraryUI.offset=0;toast(tr('已保存到来源图库','Saved in source library'));})); hydrateImages(); }; async function loadBrowserPeople(source,epoch){ try{const people=await api('/api/v1/integrations/synology-photos/people?space='+encodeURIComponent(source.people_space||'shared'));if(epoch!==state.epoch)return;$('#browse-person_id').innerHTML=''+people.map(p=>``).join('');}catch(error){if(epoch===state.epoch)$('#browse-people-status').textContent=tr('人物列表暂不可用,可继续浏览照片','People unavailable; photo browsing remains available');} }