diff options
| author | Danilo M. <danix@danix.xyz> | 2026-05-14 20:34:00 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-05-14 20:34:00 +0200 |
| commit | 9fc726e11fd95926363226d9fbac7cd85355368d (patch) | |
| tree | f7857d6d19424bd5fb15b687ac25991535fef341 | |
| parent | 3c99e487fca922a3eccd8d101f10bacc72d7679f (diff) | |
| download | danixxyz-theme-9fc726e11fd95926363226d9fbac7cd85355368d.tar.gz danixxyz-theme-9fc726e11fd95926363226d9fbac7cd85355368d.zip | |
feat: add pkg-list Alpine component for PACKAGES.TXT
| -rw-r--r-- | assets/js/pkg-list.js | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/assets/js/pkg-list.js b/assets/js/pkg-list.js new file mode 100644 index 0000000..953c4ec --- /dev/null +++ b/assets/js/pkg-list.js @@ -0,0 +1,66 @@ +document.addEventListener('alpine:init', () => { + Alpine.data('pkgList', (i18n) => ({ + state: 'loading', // 'loading' | 'loaded' | 'error' + i18n: i18n, + packages: [], + filter: '', + + get filtered() { + if (!this.filter) return this.packages; + const q = this.filter.toLowerCase(); + return this.packages.filter(p => p.name.toLowerCase().includes(q)); + }, + + async init() { + try { + const res = await fetch('https://packages.danix.xyz/PACKAGES.TXT'); + if (!res.ok) throw new Error('HTTP ' + res.status); + const text = await res.text(); + this.packages = parsePkgTxt(text); + this.state = 'loaded'; + } catch (e) { + console.error('pkg-list fetch error:', e); + this.state = 'error'; + } + } + })); +}); + +function parsePkgTxt(text) { + const packages = []; + const nameRe = /^PACKAGE NAME:\s+(.+\.txz)\s*$/m; + const locRe = /^PACKAGE LOCATION:\s+(.+)\s*$/m; + + // Split on blank lines between blocks + const blocks = text.split(/\n{2,}/); + + for (const block of blocks) { + const nameMatch = block.match(nameRe); + const locMatch = block.match(locRe); + if (!nameMatch || !locMatch) continue; + + const filename = nameMatch[1].trim(); + const location = locMatch[1].trim(); // e.g. ./desktop/waybar + + // Parse name and version from filename: name-version-arch-build_tag.txz + // Strategy: version segment starts with a digit after a hyphen + const parts = filename.replace(/\.txz$/, '').split('-'); + let nameEnd = 1; + for (let i = 1; i < parts.length; i++) { + if (/^\d/.test(parts[i])) { nameEnd = i; break; } + } + const name = parts.slice(0, nameEnd).join('-'); + const version = parts[nameEnd] || ''; + + // Derive folder URL: ./desktop/waybar -> https://packages.danix.xyz/desktop/waybar/ + const folder = location.replace(/^\.\//, ''); + const url = 'https://packages.danix.xyz/' + folder + '/'; + const label = folder; // e.g. desktop/waybar + + packages.push({ name, version, url, label }); + } + + // Sort alphabetically by name + packages.sort((a, b) => a.name.localeCompare(b.name)); + return packages; +} |
