first commit
This commit is contained in:
commit
0efaae1715
27 files changed
+1455
No files matched your search
@@ -0,0 +1,25 @@
|
||||
(() => {
|
||||
const $ = (id) => document.getElementById(id);
|
||||
const esc = (value) => String(value ?? '').replace(/[&<>"']/g, (c) => ({'&':'&','<':'<','>':'>','"':'"',"'":'''}[c]));
|
||||
const state = {data:null, view:'overview', install:'apt', search:'', channel:'all', format:'all'};
|
||||
const titles = {overview:'Przegląd',packages:'Paczki',install:'Instalacja',repositories:'Repozytoria'};
|
||||
const fmtDate = (value) => value ? new Intl.DateTimeFormat('pl-PL',{dateStyle:'medium',timeStyle:'short'}).format(new Date(value)) : '—';
|
||||
const fmtSize = (n) => n < 1024 ? `${n} B` : n < 1048576 ? `${(n/1024).toFixed(1)} KiB` : `${(n/1048576).toFixed(1)} MiB`;
|
||||
function toast(text){const t=$('toast');t.textContent=text;t.classList.add('show');setTimeout(()=>t.classList.remove('show'),1600)}
|
||||
function navigate(view){state.view=view;document.querySelectorAll('.view').forEach(x=>x.classList.toggle('active',x.id===view));document.querySelectorAll('.nav').forEach(x=>x.classList.toggle('active',x.dataset.view===view));$('view-title').textContent=titles[view]||view;location.hash=view}
|
||||
function packageRow(p){return `<div class="package-row"><div><div class="pkg-name">${esc(p.name)}</div><div class="muted">${esc(p.version)}</div></div><span class="pill">${esc(p.channel.toUpperCase())}</span><span class="pill">${esc(p.format)}</span><span class="muted">${esc(fmtSize(p.size_bytes))}</span><a class="download" href="${esc(p.download_url)}">Pobierz</a></div>`}
|
||||
function renderOverview(){const d=state.data;if(!d)return;const linux=d.builds.linux||{};const suse=d.builds.suse||{};$('latest-version').textContent=linux.app_version||'—';$('latest-build').textContent=fmtDate(linux.built_at);$('packages-count').textContent=d.summary.packages_count;$('linux-status').textContent=linux.published?'GOTOWE':'BRAK';$('suse-status').textContent=suse.published?'GOTOWE':'BRAK';$('recent-packages').innerHTML=d.packages.slice(0,6).map(packageRow).join('')||'<div class="empty">Brak opublikowanych paczek.</div>'}
|
||||
function renderPackages(){if(!state.data)return;const q=state.search.toLowerCase();const list=state.data.packages.filter(p=>(state.channel==='all'||p.channel===state.channel)&&(state.format==='all'||p.format===state.format)&&(!q||`${p.name} ${p.version} ${p.architecture}`.toLowerCase().includes(q)));$('packages-table').innerHTML=list.map(p=>`<div class="table-row"><div><div class="pkg-name">${esc(p.name)}</div><div class="muted">${esc(p.version)}</div></div><span class="pill">${esc(p.channel.toUpperCase())}</span><span class="pill">${esc(p.format)}</span><span class="muted">${esc(fmtDate(p.built_at))}</span><a class="download" href="${esc(p.download_url)}">Pobierz</a></div>`).join('')||'<div class="empty">Brak wyników.</div>'}
|
||||
function instruction(kind){const d=state.data;const url=d.repository_url,dist=d.apt_distribution,comp=d.apt_component;if(kind==='dnf')return {title:'RHEL / Rocky / Alma / Fedora',desc:'Instalacja przez podpisane repozytorium DNF/YUM.',code:`sudo rpm --import ${url}/repo-key.gpg\n\nsudo tee /etc/yum.repos.d/rustbox.repo >/dev/null <<'REPO'\n[rustbox]\nname=RustBox Repository\nbaseurl=${url}/rpm/$basearch\nenabled=1\ngpgcheck=1\nrepo_gpgcheck=1\ngpgkey=${url}/repo-key.gpg\nREPO\n\nsudo dnf install rustbox`};if(kind==='suse')return {title:'SUSE / openSUSE',desc:'Instalacja przez podpisane repozytorium Zypper.',code:`sudo rpm --import ${url}/repo-key.gpg\nsudo zypper addrepo --refresh --gpgcheck ${url}/suse/x86_64/ rustbox\nsudo zypper refresh rustbox\nsudo zypper install rustbox`};return {title:'Debian / Ubuntu',desc:'Instalacja przez podpisane repozytorium APT.',code:`curl -fsSL ${url}/repo-key.gpg | sudo gpg --dearmor -o /usr/share/keyrings/rustbox.gpg\n\necho "deb [signed-by=/usr/share/keyrings/rustbox.gpg] ${url}/apt ${dist} ${comp}" | sudo tee /etc/apt/sources.list.d/rustbox.list\n\nsudo apt update\nsudo apt install rustbox`}}
|
||||
function renderInstall(){if(!state.data)return;const x=instruction(state.install);$('install-title').textContent=x.title;$('install-desc').textContent=x.desc;$('install-command').textContent=x.code;document.querySelectorAll('[data-install]').forEach(b=>b.classList.toggle('active',b.dataset.install===state.install))}
|
||||
function repoCard(title,url,links){return `<article class="repo-card"><h3>${esc(title)}</h3><a href="${esc(url)}">${esc(url)}</a><div class="repo-links">${links.map(([n,u])=>`<a href="${esc(u)}"><span>${esc(n)}</span></a>`).join('')}</div></article>`}
|
||||
function renderRepositories(){const d=state.data;if(!d)return;const u=d.repository_url,dist=encodeURIComponent(d.apt_distribution);$('repo-cards').innerHTML=repoCard('APT + DNF',u,[['GPG public key',`${u}/repo-key.gpg`],['APT InRelease',`${u}/apt/dists/${dist}/InRelease`],['RPM repomd.xml',`${u}/rpm/x86_64/repodata/repomd.xml`],['Build info',`${u}/LINUX-BUILD-INFO.txt`]])+repoCard('SUSE / Zypper',`${u}/suse/x86_64`,[['RPM repomd.xml',`${u}/suse/x86_64/repodata/repomd.xml`],['Metadata signature',`${u}/suse/x86_64/repodata/repomd.xml.asc`],['Build info',`${u}/SUSE-BUILD-INFO.txt`]]);$('metadata').innerHTML=['linux','suse'].map(ch=>{const b=d.builds[ch]||{};return `<div class="meta-block"><h3>${ch==='linux'?'Linux':'SUSE'}</h3>${[['Wersja',b.app_version],['Wydanie paczki',b.package_release],['Build',fmtDate(b.built_at)],['Commit',b.source_commit?b.source_commit.slice(0,12):'—'],['Rewizja pakowania',b.packaging_revision]].map(([a,v])=>`<div class="meta-row"><span>${esc(a)}</span><strong>${esc(v||'—')}</strong></div>`).join('')}</div>`}).join('')}
|
||||
function renderAll(){renderOverview();renderPackages();renderInstall();renderRepositories()}
|
||||
async function refresh(){const btn=$('refresh');btn.disabled=true;try{const r=await fetch('/api/v1/packages',{cache:'no-store'});if(!r.ok)throw new Error(`HTTP ${r.status}`);state.data=await r.json();renderAll();$('last-sync').textContent=`Ostatnia synchronizacja: ${fmtDate(state.data.generated_at)}`;$('status-dot').classList.add('ok');$('status-text').textContent=state.data.ready?'Repozytorium aktywne':'Oczekiwanie na build'}catch(e){$('status-dot').classList.remove('ok');$('status-text').textContent='Błąd odczytu repozytorium';console.error(e)}finally{btn.disabled=false}}
|
||||
function setTheme(theme){document.documentElement.dataset.theme=theme;localStorage.setItem('rustbox-repo-theme',theme)}
|
||||
document.querySelectorAll('[data-view]').forEach(b=>b.addEventListener('click',()=>navigate(b.dataset.view)));
|
||||
document.querySelectorAll('[data-go]').forEach(b=>b.addEventListener('click',()=>navigate(b.dataset.go)));
|
||||
document.querySelectorAll('[data-install]').forEach(b=>b.addEventListener('click',()=>{state.install=b.dataset.install;renderInstall()}));
|
||||
$('search').addEventListener('input',e=>{state.search=e.target.value;renderPackages()});$('channel').addEventListener('change',e=>{state.channel=e.target.value;renderPackages()});$('format').addEventListener('change',e=>{state.format=e.target.value;renderPackages()});$('refresh').addEventListener('click',refresh);$('copy-install').addEventListener('click',async()=>{try{await navigator.clipboard.writeText($('install-command').textContent);toast('Skopiowano')}catch{toast('Nie udało się skopiować')}});$('theme-toggle').addEventListener('click',()=>setTheme(document.documentElement.dataset.theme==='dark'?'light':'dark'));
|
||||
try{setTheme(localStorage.getItem('rustbox-repo-theme')||'dark')}catch{}navigate(location.hash.slice(1)||'overview');window.addEventListener('hashchange',()=>navigate(location.hash.slice(1)||'overview'));refresh();setInterval(()=>{if(!document.hidden)refresh()},60000);
|
||||
})();
|
||||
Reference in new issue
Block a user