summaryrefslogtreecommitdiffstats
path: root/assets
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-05-14 20:34:00 +0200
committerDanilo M. <danix@danix.xyz>2026-05-14 20:34:00 +0200
commit9fc726e11fd95926363226d9fbac7cd85355368d (patch)
treef7857d6d19424bd5fb15b687ac25991535fef341 /assets
parent3c99e487fca922a3eccd8d101f10bacc72d7679f (diff)
downloaddanixxyz-theme-9fc726e11fd95926363226d9fbac7cd85355368d.tar.gz
danixxyz-theme-9fc726e11fd95926363226d9fbac7cd85355368d.zip
feat: add pkg-list Alpine component for PACKAGES.TXT
Diffstat (limited to 'assets')
-rw-r--r--assets/js/pkg-list.js66
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;
+}