automatyzacje-comit7
This commit is contained in:
@@ -926,17 +926,23 @@ def tracker_action(profile: dict, torrent_hash: str, action_name: str, payload:
|
|||||||
("d.tracker.insert", (torrent_hash, 0, url)),
|
("d.tracker.insert", (torrent_hash, 0, url)),
|
||||||
("d.tracker.insert", ("", torrent_hash, "", url)),
|
("d.tracker.insert", ("", torrent_hash, "", url)),
|
||||||
])
|
])
|
||||||
if action_name == "edit":
|
if action_name in {"delete", "remove"}:
|
||||||
url = str(payload.get("url") or "").strip()
|
# Note: Deleting trackers is guarded to keep at least one tracker attached to the torrent.
|
||||||
index = int(payload.get("index", -1))
|
index = int(payload.get("index", -1))
|
||||||
if index < 0:
|
if index < 0:
|
||||||
raise ValueError("Invalid tracker index")
|
raise ValueError("Invalid tracker index")
|
||||||
if not url:
|
total = _tracker_int(_safe_tracker_call(c, "d.tracker_size", torrent_hash, 0), 0) or len(torrent_trackers(profile, torrent_hash))
|
||||||
raise ValueError("Missing tracker URL")
|
if total <= 1:
|
||||||
target = _tracker_target(torrent_hash, index)
|
raise ValueError("Cannot delete the last tracker")
|
||||||
|
if index >= total:
|
||||||
|
raise ValueError("Invalid tracker index")
|
||||||
return _call_first(c, [
|
return _call_first(c, [
|
||||||
("t.url.set", (target, url)),
|
("d.tracker.remove", (torrent_hash, index)),
|
||||||
("t.url.set", ("", target, url)),
|
("d.tracker.remove", (torrent_hash, "", index)),
|
||||||
|
("d.tracker.erase", (torrent_hash, index)),
|
||||||
|
("d.tracker.erase", (torrent_hash, "", index)),
|
||||||
|
("d.tracker.delete", (torrent_hash, index)),
|
||||||
|
("d.tracker.delete", (torrent_hash, "", index)),
|
||||||
])
|
])
|
||||||
raise ValueError(f"Unknown tracker action: {action_name}")
|
raise ValueError(f"Unknown tracker action: {action_name}")
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,31 @@
|
|||||||
// Note: Keeps live filter tooltips stable while the pointer is over a filter button.
|
// Note: Keeps live filter tooltips stable while the pointer is over a filter button.
|
||||||
const filterTooltipState = new WeakMap();
|
const filterTooltipState = new WeakMap();
|
||||||
|
|
||||||
function toast(msg, type="secondary") { const h=$('toastHost'); if(!h) return; const el=document.createElement('div'); el.className=`toast-item text-bg-${type}`; el.innerHTML=esc(msg); h.appendChild(el); setTimeout(()=>el.remove(),3500); }
|
const toastGroups = new Map();
|
||||||
|
function toastKey(msg, type){ return `${type}::${String(msg ?? '')}`; }
|
||||||
|
function toast(msg, type="secondary") {
|
||||||
|
// Note: Groups identical toasts fired together, so repeated automation/action events do not flood the UI.
|
||||||
|
const h=$('toastHost');
|
||||||
|
if(!h) return;
|
||||||
|
const text=String(msg ?? '');
|
||||||
|
const key=toastKey(text,type);
|
||||||
|
const existing=toastGroups.get(key);
|
||||||
|
if(existing){
|
||||||
|
existing.count += 1;
|
||||||
|
const badge=existing.el.querySelector('.toast-count');
|
||||||
|
if(badge){ badge.textContent=`×${existing.count}`; badge.classList.remove('d-none'); }
|
||||||
|
clearTimeout(existing.timer);
|
||||||
|
existing.timer=setTimeout(()=>{ existing.el.remove(); toastGroups.delete(key); },3500);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const el=document.createElement('div');
|
||||||
|
el.className=`toast-item text-bg-${type}`;
|
||||||
|
el.innerHTML=`<span class="toast-message">${esc(text)}</span><span class="toast-count d-none">×1</span>`;
|
||||||
|
h.appendChild(el);
|
||||||
|
const entry={el,count:1,timer:null};
|
||||||
|
entry.timer=setTimeout(()=>{ el.remove(); toastGroups.delete(key); },3500);
|
||||||
|
toastGroups.set(key,entry);
|
||||||
|
}
|
||||||
function setBusy(on){ pendingBusy += on ? 1 : -1; if(pendingBusy<0) pendingBusy=0; $('globalLoader')?.classList.toggle('d-none', pendingBusy===0); $('busyBadge')?.classList.toggle('d-none', pendingBusy===0); }
|
function setBusy(on){ pendingBusy += on ? 1 : -1; if(pendingBusy<0) pendingBusy=0; $('globalLoader')?.classList.toggle('d-none', pendingBusy===0); $('busyBadge')?.classList.toggle('d-none', pendingBusy===0); }
|
||||||
function setInitialLoader(title, text){ if(initialLoaderDone) return; if($('initialLoaderTitle') && title) $('initialLoaderTitle').textContent=title; if($('initialLoaderText') && text) $('initialLoaderText').textContent=text; }
|
function setInitialLoader(title, text){ if(initialLoaderDone) return; if($('initialLoaderTitle') && title) $('initialLoaderTitle').textContent=title; if($('initialLoaderText') && text) $('initialLoaderText').textContent=text; }
|
||||||
function hideInitialLoader(){ if(initialLoaderDone) return; initialLoaderDone=true; $('initialLoader')?.classList.add('is-hidden'); }
|
function hideInitialLoader(){ if(initialLoaderDone) return; initialLoaderDone=true; $('initialLoader')?.classList.add('is-hidden'); }
|
||||||
@@ -274,14 +298,17 @@
|
|||||||
function fmtTs(value){ const n=Number(value||0); if(!n) return '-'; try{return new Date(n*1000).toLocaleString();}catch(e){return String(n);} }
|
function fmtTs(value){ const n=Number(value||0); if(!n) return '-'; try{return new Date(n*1000).toLocaleString();}catch(e){return String(n);} }
|
||||||
function trackerSeedsPeers(t){ const hasScrape = t.seeds !== null || t.peers !== null; return hasScrape ? `${t.seeds ?? "-"} / ${t.peers ?? "-"}` : "-"; }
|
function trackerSeedsPeers(t){ const hasScrape = t.seeds !== null || t.peers !== null; return hasScrape ? `${t.seeds ?? "-"} / ${t.peers ?? "-"}` : "-"; }
|
||||||
function renderTrackers(trackers){
|
function renderTrackers(trackers){
|
||||||
|
// Note: Tracker URL editing is intentionally replaced by safe deletion; adding trackers remains unchanged.
|
||||||
const pane=$('detailPane');
|
const pane=$('detailPane');
|
||||||
const rows=(trackers||[]).map(t=>{
|
const list=trackers||[];
|
||||||
|
const canDelete=list.length>1;
|
||||||
|
const rows=list.map(t=>{
|
||||||
const idx=esc(t.index), url=esc(t.url);
|
const idx=esc(t.index), url=esc(t.url);
|
||||||
return [`<span class="text-muted">#${idx}</span>`, `<div class="tracker-url-view" data-tracker-index="${idx}"><span class="tracker-url-text">${url || '<span class="text-muted">-</span>'}</span></div><div class="tracker-url-edit d-none" data-tracker-index="${idx}"><input class="form-control form-control-sm tracker-url" data-tracker-index="${idx}" value="${url}"></div>`, t.enabled?'yes':'no', esc(trackerSeedsPeers(t)), esc(t.downloaded ?? '-'), fmtTs(t.last_announce), `<div class="tracker-actions"><button class="btn btn-xs btn-outline-secondary tracker-edit-start" data-index="${idx}"><i class="fa-solid fa-pen"></i> Edit</button><button class="btn btn-xs btn-outline-primary tracker-edit-save d-none" data-index="${idx}"><i class="fa-solid fa-floppy-disk"></i> Save</button><button class="btn btn-xs btn-outline-secondary tracker-edit-cancel d-none" data-index="${idx}"><i class="fa-solid fa-xmark"></i> Cancel</button></div>`];
|
const deleteDisabled=canDelete ? '' : ' disabled title="At least one tracker must remain"';
|
||||||
|
return [`<span class="text-muted">#${idx}</span>`, `<span class="tracker-url-text">${url || '<span class="text-muted">-</span>'}</span>`, t.enabled?'yes':'no', esc(trackerSeedsPeers(t)), esc(t.downloaded ?? '-'), fmtTs(t.last_announce), `<div class="tracker-actions"><button class="btn btn-xs btn-outline-danger tracker-delete" data-index="${idx}"${deleteDisabled}><i class="fa-solid fa-trash"></i> Delete</button></div>`];
|
||||||
});
|
});
|
||||||
pane.innerHTML=`<div class="tracker-toolbar"><div class="input-group input-group-sm"><input id="trackerAddUrl" class="form-control" placeholder="https://tracker.example/announce"><button id="trackerAddBtn" class="btn btn-outline-primary"><i class="fa-solid fa-plus"></i> Add tracker</button></div><button id="trackerReannounceBtn" class="btn btn-sm btn-outline-primary"><i class="fa-solid fa-bullhorn"></i> Reannounce</button></div>${table(['#','URL','On','Seeds / Peers','Done','Last announce','Actions'], rows.length?rows:[[ '<span class="text-muted">-</span>','<span class="text-muted">No trackers.</span>','','','','','' ]])}`;
|
pane.innerHTML=`<div class="tracker-toolbar"><div class="input-group input-group-sm"><input id="trackerAddUrl" class="form-control tracker-add-input" placeholder="https://tracker.example/announce"><button id="trackerAddBtn" class="btn btn-outline-primary"><i class="fa-solid fa-plus"></i> Add tracker</button></div><button id="trackerReannounceBtn" class="btn btn-sm btn-outline-primary"><i class="fa-solid fa-bullhorn"></i> Reannounce</button></div>${table(['#','URL','On','Seeds / Peers','Done','Last announce','Actions'], rows.length?rows:[[ '<span class="text-muted">-</span>','<span class="text-muted">No trackers.</span>','','','','','' ]])}`;
|
||||||
}
|
}
|
||||||
function setTrackerEdit(index,on){ const sel=String(index); document.querySelector(`.tracker-url-view[data-tracker-index="${CSS.escape(sel)}"]`)?.classList.toggle('d-none', on); document.querySelector(`.tracker-url-edit[data-tracker-index="${CSS.escape(sel)}"]`)?.classList.toggle('d-none', !on); document.querySelector(`.tracker-edit-start[data-index="${CSS.escape(sel)}"]`)?.classList.toggle('d-none', on); document.querySelector(`.tracker-edit-save[data-index="${CSS.escape(sel)}"]`)?.classList.toggle('d-none', !on); document.querySelector(`.tracker-edit-cancel[data-index="${CSS.escape(sel)}"]`)?.classList.toggle('d-none', !on); }
|
|
||||||
async function trackerAction(action,payload={}){
|
async function trackerAction(action,payload={}){
|
||||||
if(!selectedHash) return toast('No torrent selected','warning');
|
if(!selectedHash) return toast('No torrent selected','warning');
|
||||||
setBusy(true);
|
setBusy(true);
|
||||||
@@ -870,7 +897,7 @@
|
|||||||
function awaitMaybeRun(action){ runAction(action).catch?.(()=>{}); }
|
function awaitMaybeRun(action){ runAction(action).catch?.(()=>{}); }
|
||||||
document.addEventListener('click',e=>{ const ctx=$('ctxMenu'); if(!e.target.closest('#ctxMenu')) ctx.style.display='none'; const mobileFilter=e.target.closest('#mobileFilterBar .mobile-filter'); if(mobileFilter){ document.querySelectorAll('.filter').forEach(x=>x.classList.remove('active')); document.querySelectorAll('.filter').forEach(x=>{ if(x.dataset.filter===mobileFilter.dataset.filter) x.classList.add('active'); }); activeFilter=mobileFilter.dataset.filter; if($('tableWrap'))$('tableWrap').scrollTop=0; if($('mobileList'))$('mobileList').scrollTop=0; scheduleRender(true); return; } const mobileSelectAll=e.target.closest('#mobileSelectAll'); if(mobileSelectAll){ const all=visibleRows.length>0 && visibleRows.every(t=>selected.has(t.hash)); if(all) visibleRows.forEach(t=>selected.delete(t.hash)); else visibleRows.forEach(t=>selected.add(t.hash)); if(selected.size===0){selectedHash=null;lastSelectedHash=null;} else {selectedHash=[...selected][selected.size-1];lastSelectedHash=selectedHash;} scheduleRender(true); return; } const mobileClear=e.target.closest('#mobileClearSelection'); if(mobileClear){ selected.clear(); selectedHash=null; lastSelectedHash=null; scheduleRender(true); return; } const mobileAct=e.target.closest('.mobile-card [data-action]'); if(mobileAct){ const card0=mobileAct.closest('.mobile-card'); selected.clear(); selected.add(card0.dataset.hash); selectedHash=card0.dataset.hash; awaitMaybeRun(mobileAct.dataset.action); scheduleRender(true); return; } const card=e.target.closest('.mobile-card'); const tr=e.target.closest('tr[data-hash]'); const row=tr||card; if(row){ const h=row.dataset.hash; const additive=e.ctrlKey||e.metaKey; if(e.shiftKey){ setSelectionRange(h, additive); } else if(e.target.classList.contains('row-check')){ e.target.checked?selected.add(h):selected.delete(h); lastSelectedHash=h; selectedHash=h; } else { selectedHash=h; if(!additive)selected.clear(); selected.add(h); lastSelectedHash=h; loadDetails(activeTab()); } scheduleRender(true); } const copy=e.target.closest('[data-copy]'); if(copy) copySelected(copy.dataset.copy); const smartEx=e.target.closest('#smartExcludeCtx'); if(smartEx){ selectedHashes().forEach(h=>post('/api/smart-queue/exclusion',{hash:h,excluded:true,reason:'manual'}).catch(()=>{})); toast('Smart Queue exception saved','success'); loadSmartQueue().catch(()=>{}); } const act=e.target.closest('.torrent-action,[data-action]'); if(act&&act.dataset.action&&!act.closest('#detailTabs')&&!act.closest('.mobile-card')) runAction(act.dataset.action); });
|
document.addEventListener('click',e=>{ const ctx=$('ctxMenu'); if(!e.target.closest('#ctxMenu')) ctx.style.display='none'; const mobileFilter=e.target.closest('#mobileFilterBar .mobile-filter'); if(mobileFilter){ document.querySelectorAll('.filter').forEach(x=>x.classList.remove('active')); document.querySelectorAll('.filter').forEach(x=>{ if(x.dataset.filter===mobileFilter.dataset.filter) x.classList.add('active'); }); activeFilter=mobileFilter.dataset.filter; if($('tableWrap'))$('tableWrap').scrollTop=0; if($('mobileList'))$('mobileList').scrollTop=0; scheduleRender(true); return; } const mobileSelectAll=e.target.closest('#mobileSelectAll'); if(mobileSelectAll){ const all=visibleRows.length>0 && visibleRows.every(t=>selected.has(t.hash)); if(all) visibleRows.forEach(t=>selected.delete(t.hash)); else visibleRows.forEach(t=>selected.add(t.hash)); if(selected.size===0){selectedHash=null;lastSelectedHash=null;} else {selectedHash=[...selected][selected.size-1];lastSelectedHash=selectedHash;} scheduleRender(true); return; } const mobileClear=e.target.closest('#mobileClearSelection'); if(mobileClear){ selected.clear(); selectedHash=null; lastSelectedHash=null; scheduleRender(true); return; } const mobileAct=e.target.closest('.mobile-card [data-action]'); if(mobileAct){ const card0=mobileAct.closest('.mobile-card'); selected.clear(); selected.add(card0.dataset.hash); selectedHash=card0.dataset.hash; awaitMaybeRun(mobileAct.dataset.action); scheduleRender(true); return; } const card=e.target.closest('.mobile-card'); const tr=e.target.closest('tr[data-hash]'); const row=tr||card; if(row){ const h=row.dataset.hash; const additive=e.ctrlKey||e.metaKey; if(e.shiftKey){ setSelectionRange(h, additive); } else if(e.target.classList.contains('row-check')){ e.target.checked?selected.add(h):selected.delete(h); lastSelectedHash=h; selectedHash=h; } else { selectedHash=h; if(!additive)selected.clear(); selected.add(h); lastSelectedHash=h; loadDetails(activeTab()); } scheduleRender(true); } const copy=e.target.closest('[data-copy]'); if(copy) copySelected(copy.dataset.copy); const smartEx=e.target.closest('#smartExcludeCtx'); if(smartEx){ selectedHashes().forEach(h=>post('/api/smart-queue/exclusion',{hash:h,excluded:true,reason:'manual'}).catch(()=>{})); toast('Smart Queue exception saved','success'); loadSmartQueue().catch(()=>{}); } const act=e.target.closest('.torrent-action,[data-action]'); if(act&&act.dataset.action&&!act.closest('#detailTabs')&&!act.closest('.mobile-card')) runAction(act.dataset.action); });
|
||||||
document.addEventListener('contextmenu',e=>{ const tr=e.target.closest('tr[data-hash],.mobile-card'); if(!tr)return; e.preventDefault(); selectedHash=tr.dataset.hash; if(!selected.has(selectedHash)){selected.clear();selected.add(selectedHash);scheduleRender(true);} const m=$('ctxMenu'); m.style.left=`${e.pageX}px`; m.style.top=`${e.pageY}px`; m.style.display='block'; });
|
document.addEventListener('contextmenu',e=>{ const tr=e.target.closest('tr[data-hash],.mobile-card'); if(!tr)return; e.preventDefault(); selectedHash=tr.dataset.hash; if(!selected.has(selectedHash)){selected.clear();selected.add(selectedHash);scheduleRender(true);} const m=$('ctxMenu'); m.style.left=`${e.pageX}px`; m.style.top=`${e.pageY}px`; m.style.display='block'; });
|
||||||
document.querySelectorAll('.torrent-table thead th[data-sort]').forEach(th=>th.addEventListener('click',()=>{ const key=th.dataset.sort; if(sortState.key===key) sortState.dir*=-1; else sortState={key,dir:1}; scheduleRender(true); })); $('tableWrap')?.addEventListener('scroll',()=>scheduleRender(false),{passive:true}); $('selectAll')?.addEventListener('change',e=>{selected.clear(); if(e.target.checked)visibleRows.forEach(t=>selected.add(t.hash)); scheduleRender(true);}); $('searchBox')?.addEventListener('input',()=>{if($('tableWrap'))$('tableWrap').scrollTop=0;scheduleRender(true);}); document.querySelectorAll('.filter').forEach(b=>b.addEventListener('click',()=>{document.querySelectorAll('.filter').forEach(x=>x.classList.remove('active')); b.classList.add('active'); activeFilter=b.dataset.filter; if($('tableWrap'))$('tableWrap').scrollTop=0; scheduleRender(true);})); document.querySelectorAll('#detailTabs .nav-link').forEach(b=>b.addEventListener('click',()=>{document.querySelectorAll('#detailTabs .nav-link').forEach(x=>x.classList.remove('active')); b.classList.add('active'); loadDetails(b.dataset.tab);})); document.addEventListener('change',e=>{ const sel=e.target.closest('.file-priority'); if(sel){ setFilePriorities([{index:Number(sel.dataset.index),priority:Number(sel.value)}]); return; } if(e.target && e.target.id==='fileSelectAll'){ document.querySelectorAll('#detailPane .file-check').forEach(cb=>cb.checked=e.target.checked); } }); document.addEventListener('click',e=>{ const bulk=e.target.closest('.file-priority-bulk'); if(!bulk) return; const priority=Number(bulk.dataset.priority); const checked=[...document.querySelectorAll('#detailPane .file-check:checked')].map(cb=>({index:Number(cb.dataset.index),priority})); if(!checked.length) return toast('No files selected','warning'); setFilePriorities(checked); }); document.addEventListener('click',e=>{ const add=e.target.closest('#trackerAddBtn'); if(add){ const url=$('trackerAddUrl')?.value||''; trackerAction('add',{url}); return; } const editStart=e.target.closest('.tracker-edit-start'); if(editStart){ setTrackerEdit(editStart.dataset.index,true); return; } const cancel=e.target.closest('.tracker-edit-cancel'); if(cancel){ setTrackerEdit(cancel.dataset.index,false); return; } const save=e.target.closest('.tracker-edit-save'); if(save){ const input=document.querySelector(`.tracker-url[data-tracker-index="${CSS.escape(String(save.dataset.index))}"]`); trackerAction('edit',{index:Number(save.dataset.index),url:input?.value||''}); return; } const rea=e.target.closest('#trackerReannounceBtn'); if(rea) trackerAction('reannounce',{}); }); $('appStatusRefreshBtn')?.addEventListener('click',loadAppStatus); $('portCheckEnabled')?.addEventListener('change',savePortCheckPref); $('portCheckNowBtn')?.addEventListener('click',()=>loadPortCheck(true)); $('bootstrapThemeSelect')?.addEventListener('change',saveAppearancePreferences); $('fontFamilySelect')?.addEventListener('change',saveAppearancePreferences); $('saveFooterPrefsBtn')?.addEventListener('click',saveFooterPreferences);
|
document.querySelectorAll('.torrent-table thead th[data-sort]').forEach(th=>th.addEventListener('click',()=>{ const key=th.dataset.sort; if(sortState.key===key) sortState.dir*=-1; else sortState={key,dir:1}; scheduleRender(true); })); $('tableWrap')?.addEventListener('scroll',()=>scheduleRender(false),{passive:true}); $('selectAll')?.addEventListener('change',e=>{selected.clear(); if(e.target.checked)visibleRows.forEach(t=>selected.add(t.hash)); scheduleRender(true);}); $('searchBox')?.addEventListener('input',()=>{if($('tableWrap'))$('tableWrap').scrollTop=0;scheduleRender(true);}); document.querySelectorAll('.filter').forEach(b=>b.addEventListener('click',()=>{document.querySelectorAll('.filter').forEach(x=>x.classList.remove('active')); b.classList.add('active'); activeFilter=b.dataset.filter; if($('tableWrap'))$('tableWrap').scrollTop=0; scheduleRender(true);})); document.querySelectorAll('#detailTabs .nav-link').forEach(b=>b.addEventListener('click',()=>{document.querySelectorAll('#detailTabs .nav-link').forEach(x=>x.classList.remove('active')); b.classList.add('active'); loadDetails(b.dataset.tab);})); document.addEventListener('change',e=>{ const sel=e.target.closest('.file-priority'); if(sel){ setFilePriorities([{index:Number(sel.dataset.index),priority:Number(sel.value)}]); return; } if(e.target && e.target.id==='fileSelectAll'){ document.querySelectorAll('#detailPane .file-check').forEach(cb=>cb.checked=e.target.checked); } }); document.addEventListener('click',e=>{ const bulk=e.target.closest('.file-priority-bulk'); if(!bulk) return; const priority=Number(bulk.dataset.priority); const checked=[...document.querySelectorAll('#detailPane .file-check:checked')].map(cb=>({index:Number(cb.dataset.index),priority})); if(!checked.length) return toast('No files selected','warning'); setFilePriorities(checked); }); document.addEventListener('click',e=>{ const add=e.target.closest('#trackerAddBtn'); if(add){ const url=$('trackerAddUrl')?.value||''; trackerAction('add',{url}); return; } const del=e.target.closest('.tracker-delete'); if(del && !del.disabled){ trackerAction('delete',{index:Number(del.dataset.index)}); return; } const rea=e.target.closest('#trackerReannounceBtn'); if(rea) trackerAction('reannounce',{}); }); $('appStatusRefreshBtn')?.addEventListener('click',loadAppStatus); $('portCheckEnabled')?.addEventListener('change',savePortCheckPref); $('portCheckNowBtn')?.addEventListener('click',()=>loadPortCheck(true)); $('bootstrapThemeSelect')?.addEventListener('change',saveAppearancePreferences); $('fontFamilySelect')?.addEventListener('change',saveAppearancePreferences); $('saveFooterPrefsBtn')?.addEventListener('click',saveFooterPreferences);
|
||||||
document.addEventListener('keydown',e=>{ const tag=(e.target?.tagName||'').toLowerCase(); const editable=tag==='input'||tag==='textarea'||tag==='select'||e.target?.isContentEditable; if(editable){ if(e.key==='Enter' && e.target?.id==='labelInput'){ e.preventDefault(); $('addLabelToSelectionBtn')?.click(); } return; } if((e.ctrlKey||e.metaKey)&&e.key.toLowerCase()==='a'){e.preventDefault();selected.clear();visibleRows.forEach(t=>selected.add(t.hash));scheduleRender(true);} if((e.ctrlKey||e.metaKey)&&e.key.toLowerCase()==='i'){e.preventDefault();visibleRows.forEach(t=>selected.has(t.hash)?selected.delete(t.hash):selected.add(t.hash));scheduleRender(true);} if((e.ctrlKey||e.metaKey)&&e.key.toLowerCase()==='o'){e.preventDefault();new bootstrap.Modal($('addModal')).show();} if(e.key==='Escape'){selected.clear();scheduleRender(true);} if(e.key==='Delete') new bootstrap.Modal($('removeModal')).show(); if(e.key===' ') {e.preventDefault();runAction('start');} if(e.key.toLowerCase()==='p')runAction('pause'); if(e.key.toLowerCase()==='s')runAction('stop'); if(e.key.toLowerCase()==='r')runAction('resume'); if(e.key.toLowerCase()==='m')runAction('move'); });
|
document.addEventListener('keydown',e=>{ const tag=(e.target?.tagName||'').toLowerCase(); const editable=tag==='input'||tag==='textarea'||tag==='select'||e.target?.isContentEditable; if(editable){ if(e.key==='Enter' && e.target?.id==='labelInput'){ e.preventDefault(); $('addLabelToSelectionBtn')?.click(); } return; } if((e.ctrlKey||e.metaKey)&&e.key.toLowerCase()==='a'){e.preventDefault();selected.clear();visibleRows.forEach(t=>selected.add(t.hash));scheduleRender(true);} if((e.ctrlKey||e.metaKey)&&e.key.toLowerCase()==='i'){e.preventDefault();visibleRows.forEach(t=>selected.has(t.hash)?selected.delete(t.hash):selected.add(t.hash));scheduleRender(true);} if((e.ctrlKey||e.metaKey)&&e.key.toLowerCase()==='o'){e.preventDefault();new bootstrap.Modal($('addModal')).show();} if(e.key==='Escape'){selected.clear();scheduleRender(true);} if(e.key==='Delete') new bootstrap.Modal($('removeModal')).show(); if(e.key===' ') {e.preventDefault();runAction('start');} if(e.key.toLowerCase()==='p')runAction('pause'); if(e.key.toLowerCase()==='s')runAction('stop'); if(e.key.toLowerCase()==='r')runAction('resume'); if(e.key.toLowerCase()==='m')runAction('move'); });
|
||||||
$('removeModal')?.addEventListener('show.bs.modal',()=>{$('removeCount').textContent=selected.size;$('removeData').checked=true;}); $('confirmRemoveBtn')?.addEventListener('click',async()=>{await runAction('remove',{remove_data:$('removeData').checked});bootstrap.Modal.getInstance($('removeModal'))?.hide();});
|
$('removeModal')?.addEventListener('show.bs.modal',()=>{$('removeCount').textContent=selected.size;$('removeData').checked=true;}); $('confirmRemoveBtn')?.addEventListener('click',async()=>{await runAction('remove',{remove_data:$('removeData').checked});bootstrap.Modal.getInstance($('removeModal'))?.hide();});
|
||||||
$('addModal')?.addEventListener('show.bs.modal',()=>applyDefaultDownloadPath(true));
|
$('addModal')?.addEventListener('show.bs.modal',()=>applyDefaultDownloadPath(true));
|
||||||
|
|||||||
@@ -564,10 +564,27 @@ body {
|
|||||||
gap: 0.4rem;
|
gap: 0.4rem;
|
||||||
}
|
}
|
||||||
.toast-item {
|
.toast-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.45rem;
|
||||||
|
max-width: 360px;
|
||||||
padding: 0.45rem 0.65rem;
|
padding: 0.45rem 0.65rem;
|
||||||
border-radius: 0.55rem;
|
border-radius: 0.55rem;
|
||||||
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.28);
|
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.28);
|
||||||
max-width: 360px;
|
}
|
||||||
|
|
||||||
|
.toast-message {
|
||||||
|
min-width: 0;
|
||||||
|
overflow-wrap: anywhere;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toast-count {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
padding: 0.05rem 0.35rem;
|
||||||
|
border-radius: 999px;
|
||||||
|
background: rgba(255, 255, 255, 0.22);
|
||||||
|
font-size: 0.78rem;
|
||||||
|
font-weight: 700;
|
||||||
}
|
}
|
||||||
@media (max-width: 1100px) {
|
@media (max-width: 1100px) {
|
||||||
:root {
|
:root {
|
||||||
@@ -1630,7 +1647,7 @@ body.mobile-mode .mobile-filter-bar {
|
|||||||
margin-bottom: 0.55rem;
|
margin-bottom: 0.55rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tracker-url {
|
.tracker-add-input {
|
||||||
min-width: 240px;
|
min-width: 240px;
|
||||||
max-width: 520px;
|
max-width: 520px;
|
||||||
}
|
}
|
||||||
@@ -1742,7 +1759,7 @@ body.mobile-mode .mobile-filter-bar {
|
|||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tracker-url {
|
.tracker-add-input {
|
||||||
min-width: 160px;
|
min-width: 160px;
|
||||||
max-width: 230px;
|
max-width: 230px;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user