feat(releases): channel options in version dropdown, drop chip pills
Restructures the version picker on the releases page so channel
mirrors are first-class, selectable options:
Channels (mutable URLs)
stable — currently v0.0.8 ← default selection
beta — tracks stable
alpha — tracks stable
Pinned versions (immutable URLs)
v0.0.8
v0.0.2
v0.0.1
Picking "stable" now rewires every download link on the page to the
*_stable.html (HTML tools) or zddc-server_stable_<plat> (binary)
channel-mirror URL — the kind a user wants to copy + bookmark for a
"latest stable" reference. Same for beta and alpha. Picking a pinned
vX.Y.Z still rewires to immutable per-version URLs.
Removed the separate "Or pick a channel" chip-pill row that previously
sat under the picker. The dropdown is now the single control; chips
duplicated functionality and added visual noise. The .channel-chips
CSS rules in website/css/style.css come out with them.
Static defaults (without JS) now use the stable channel mirror URLs
too, so both copy-from-source and JS-rewire produce the same outcome
for users who want stable. The page works end-to-end with JS off.
Embedded snapshots refreshed.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
8c2e65e4a2
commit
d688e20dad
10 changed files with 124 additions and 219 deletions
154
build.sh
154
build.sh
|
|
@ -331,52 +331,45 @@ build_releases_index() {
|
|||
<select id="version-picker">
|
||||
HEAD
|
||||
|
||||
# Stable versions, latest first
|
||||
_first=1
|
||||
printf '%s\n' "$_all_versions" | while read -r _v; do
|
||||
[ -n "$_v" ] || continue
|
||||
_label="v${_v}"
|
||||
if [ "$_first" = "1" ]; then
|
||||
_label="${_label} (current stable)"
|
||||
_first=0
|
||||
fi
|
||||
printf ' <option value="v%s"%s>%s</option>\n' "$_v" "$( [ "$_v" = "$_latest" ] && printf ' selected' )" "$_label"
|
||||
done
|
||||
|
||||
# Pre-release channels — always shown, so the alpha/beta URLs are
|
||||
# discoverable without knowing the URL pattern. Label tells the
|
||||
# truth about the current state: "active dev" when the channel has
|
||||
# its own bytes, "tracks stable" when it's just a cascade symlink.
|
||||
printf ' <optgroup label="Pre-release channels">\n'
|
||||
# Channels — selectable directly so users can copy the channel-
|
||||
# mirror URLs (e.g. archive_stable.html) for bookmarks. stable is
|
||||
# the default. The label tells the truth about the channel's
|
||||
# current state: when stable is set, show which version it points
|
||||
# at; when alpha/beta is just a symlink to stable, mark as
|
||||
# "tracks stable" so picking it isn't surprising.
|
||||
printf ' <optgroup label="Channels (mutable URLs)">\n'
|
||||
if [ -n "$_latest" ] && [ "$_latest" != "0.0.0" ]; then
|
||||
printf ' <option value="stable" selected>stable — currently v%s</option>\n' "$_latest"
|
||||
else
|
||||
printf ' <option value="stable" selected>stable</option>\n'
|
||||
fi
|
||||
if [ "$_beta_active" = "1" ]; then
|
||||
printf ' <option value="beta">beta — general testing</option>\n'
|
||||
else
|
||||
printf ' <option value="beta">beta — currently tracks stable</option>\n'
|
||||
printf ' <option value="beta">beta — tracks stable</option>\n'
|
||||
fi
|
||||
if [ "$_alpha_active" = "1" ]; then
|
||||
printf ' <option value="alpha">alpha — active dev</option>\n'
|
||||
else
|
||||
printf ' <option value="alpha">alpha — currently tracks stable</option>\n'
|
||||
printf ' <option value="alpha">alpha — tracks stable</option>\n'
|
||||
fi
|
||||
printf ' </optgroup>\n'
|
||||
|
||||
# Pinned per-version, latest first. These are the immutable URLs
|
||||
# for reproducibility. No "(current stable)" suffix because the
|
||||
# stable channel above already covers that.
|
||||
printf ' <optgroup label="Pinned versions (immutable URLs)">\n'
|
||||
printf '%s\n' "$_all_versions" | while read -r _v; do
|
||||
[ -n "$_v" ] || continue
|
||||
printf ' <option value="v%s">v%s</option>\n' "$_v" "$_v"
|
||||
done
|
||||
printf ' </optgroup>\n'
|
||||
|
||||
cat <<'PICKER_END'
|
||||
</select>
|
||||
<span class="picker-hint">Changes every download link below.</span>
|
||||
</div>
|
||||
|
||||
<!-- Channel quick-pick chips — visible at-a-glance entry points to
|
||||
alpha and beta even when they cascade to stable. Clicking drives
|
||||
the version picker (rewires the page) rather than navigating
|
||||
away. The chip is always live; the cascade rule keeps the URLs
|
||||
it represents permanently resolvable. -->
|
||||
<div class="channel-chips" role="group" aria-label="Channel quick pick">
|
||||
<span class="channel-chips-label">Or pick a channel:</span>
|
||||
<button type="button" class="channel-chip is-current" data-channel="stable">stable</button>
|
||||
<button type="button" class="channel-chip" data-channel="beta">beta</button>
|
||||
<button type="button" class="channel-chip" data-channel="alpha">alpha</button>
|
||||
</div>
|
||||
|
||||
<!-- ───────────── Path A — Self-host the server ───────────── -->
|
||||
<section class="card" style="background: var(--color-bg-subtle); border: 1px solid var(--color-border); border-radius: var(--radius-md); padding: var(--spacing-lg) var(--spacing-xl); margin-top: var(--spacing-lg);">
|
||||
<h2 style="margin-top:0;">Path A — Self-host the server</h2>
|
||||
|
|
@ -392,15 +385,19 @@ PICKER_END
|
|||
fi
|
||||
|
||||
if [ "$_zs_published" = "1" ]; then
|
||||
# Default href is the channel-mirror URL (zddc-server_stable_<plat>)
|
||||
# because "stable" is the dropdown's selected option. Picking a
|
||||
# pinned version from the dropdown rewrites these to the
|
||||
# immutable per-version URL via the IIFE.
|
||||
printf ' <a class="dl-primary"\n'
|
||||
printf ' data-tool="zddc-server"\n'
|
||||
printf ' data-platform="linux-amd64"\n'
|
||||
printf ' href="zddc-server_v%s_linux-amd64"\n' "$_latest"
|
||||
printf ' href="zddc-server_stable_linux-amd64"\n'
|
||||
printf ' id="dl-primary-binary">\n'
|
||||
printf ' <span class="dl-icon">⬇</span>\n'
|
||||
printf ' <span>Download <span id="dl-primary-platlabel">for Linux (x86_64)</span></span>\n'
|
||||
printf ' </a>\n'
|
||||
printf ' <span class="dl-primary-meta" id="dl-primary-meta">zddc-server_v%s_linux-amd64</span>\n' "$_latest"
|
||||
printf ' <span class="dl-primary-meta" id="dl-primary-meta">zddc-server_stable_linux-amd64</span>\n'
|
||||
|
||||
printf ' <div class="dl-secondary-row" id="dl-others">\n'
|
||||
printf ' <span>Other platforms:</span>\n'
|
||||
|
|
@ -412,8 +409,8 @@ PICKER_END
|
|||
_label="${_entry#*|}"
|
||||
_suffix=""
|
||||
case "$_plat" in *windows*) _suffix=".exe" ;; esac
|
||||
printf ' <a data-tool="zddc-server" data-platform="%s" href="zddc-server_v%s_%s%s">%s</a>\n' \
|
||||
"$_plat" "$_latest" "$_plat" "$_suffix" "$_label"
|
||||
printf ' <a data-tool="zddc-server" data-platform="%s" href="zddc-server_stable_%s%s">%s</a>\n' \
|
||||
"$_plat" "$_plat" "$_suffix" "$_label"
|
||||
done
|
||||
printf ' </div>\n'
|
||||
|
||||
|
|
@ -453,7 +450,9 @@ PATH_B_OPEN
|
|||
_rest="${_entry#*|}"
|
||||
_name="${_rest%%|*}"
|
||||
_desc="${_rest#*|}"
|
||||
printf ' <a class="tool-card" data-tool="%s" href="%s_v%s.html">\n' "$_t" "$_t" "$_latest"
|
||||
# Default href is the stable-channel mirror; the dropdown
|
||||
# rewires these per selection.
|
||||
printf ' <a class="tool-card" data-tool="%s" href="%s_stable.html">\n' "$_t" "$_t"
|
||||
printf ' <span class="tool-card__title">%s</span>\n' "$_name"
|
||||
printf ' <span class="tool-card__desc">%s</span>\n' "$_desc"
|
||||
printf ' <span class="tool-card__link">Download →</span>\n'
|
||||
|
|
@ -546,90 +545,65 @@ PIN_MID
|
|||
var primaryMeta = document.getElementById('dl-primary-meta');
|
||||
var others = document.getElementById('dl-others');
|
||||
|
||||
function platBinaryName(version, plat) {
|
||||
var suf = (plat.indexOf('windows') === 0) ? '.exe' : '';
|
||||
return 'zddc-server_' + version + '_' + plat + suf;
|
||||
function isChannel(v) {
|
||||
return v === 'stable' || v === 'beta' || v === 'alpha';
|
||||
}
|
||||
function htmlAssetName(tool, version) {
|
||||
return tool + '_' + version + '.html';
|
||||
function platBinaryName(slug, plat) {
|
||||
// slug is a channel name ("stable") or a pinned version ("v0.0.8").
|
||||
// The on-disk name uses the slug as-is in both cases since the
|
||||
// channel-mirror filenames are zddc-server_<channel>_<plat> and
|
||||
// per-version are zddc-server_v<X.Y.Z>_<plat>.
|
||||
var suf = (plat.indexOf('windows') === 0) ? '.exe' : '';
|
||||
return 'zddc-server_' + slug + '_' + plat + suf;
|
||||
}
|
||||
function htmlAssetName(tool, slug) {
|
||||
return tool + '_' + slug + '.html';
|
||||
}
|
||||
|
||||
// Update the primary button to the detected platform (if different
|
||||
// from default). Hide the matching link in the secondary row to
|
||||
// avoid duplication.
|
||||
// Promote the detected platform to the primary CTA. The secondary
|
||||
// row keeps all four; the matching one is hidden to avoid showing
|
||||
// the same download twice.
|
||||
if (primary) {
|
||||
var initialVer = primary.getAttribute('href').match(/_v[\d.]+_/);
|
||||
initialVer = initialVer ? initialVer[0].slice(2, -1) : null;
|
||||
primary.dataset.platform = detected;
|
||||
if (initialVer) {
|
||||
primary.href = platBinaryName('v' + initialVer, detected);
|
||||
if (primaryMeta) primaryMeta.textContent = platBinaryName('v' + initialVer, detected);
|
||||
}
|
||||
if (primaryLabel) primaryLabel.textContent = 'for ' + platLabel;
|
||||
}
|
||||
|
||||
// Hide the duplicate in "Other platforms" row.
|
||||
if (others) {
|
||||
others.querySelectorAll('a[data-platform="' + detected + '"]').forEach(function(a) {
|
||||
a.style.display = 'none';
|
||||
});
|
||||
}
|
||||
|
||||
// Wire the version picker + channel chips. Both drive the same
|
||||
// rewire function. Selecting a per-version stable from the picker
|
||||
// also updates the chip set: stable becomes active, beta/alpha lose
|
||||
// their is-current marker.
|
||||
// Single source of truth: the dropdown's current value drives every
|
||||
// download link's href. Static markup ships with the stable-channel
|
||||
// mirror (`<tool>_stable.html`, `zddc-server_stable_<plat>`) so the
|
||||
// page works fully without JS — the JS just keeps things in sync
|
||||
// when the user picks a different channel or pins a version.
|
||||
var picker = document.getElementById('version-picker');
|
||||
if (!picker) return;
|
||||
var chips = document.querySelectorAll('.channel-chip');
|
||||
|
||||
function rewire(v) {
|
||||
// v is "vX.Y.Z" or "alpha" / "beta"
|
||||
function rewire(slug) {
|
||||
// slug ∈ {"stable", "beta", "alpha"} | "v<X.Y.Z>". Every link with
|
||||
// a data-tool attribute is a download URL the dropdown owns.
|
||||
document.querySelectorAll('[data-tool]').forEach(function(a) {
|
||||
var tool = a.dataset.tool;
|
||||
var plat = a.dataset.platform || '';
|
||||
if (tool === 'zddc-server') {
|
||||
if (plat) {
|
||||
a.href = (v === 'alpha' || v === 'beta')
|
||||
? 'zddc-server_' + v + '_' + plat + (plat.indexOf('windows') === 0 ? '.exe' : '')
|
||||
: platBinaryName(v, plat);
|
||||
} else {
|
||||
a.href = 'zddc-server_' + v + '.html';
|
||||
}
|
||||
a.href = plat ? platBinaryName(slug, plat) : ('zddc-server_' + slug + '.html');
|
||||
} else {
|
||||
a.href = htmlAssetName(tool, v);
|
||||
a.href = htmlAssetName(tool, slug);
|
||||
}
|
||||
});
|
||||
if (primary && primaryMeta) {
|
||||
primaryMeta.textContent = primary.getAttribute('href');
|
||||
}
|
||||
// Reflect channel-vs-version in the chip group. Per-version stable
|
||||
// selections highlight the "stable" chip (since per-version files
|
||||
// are stable releases).
|
||||
var channel = (v === 'alpha' || v === 'beta') ? v : 'stable';
|
||||
chips.forEach(function(c) {
|
||||
c.classList.toggle('is-current', c.dataset.channel === channel);
|
||||
});
|
||||
}
|
||||
|
||||
picker.addEventListener('change', function() { rewire(picker.value); });
|
||||
|
||||
// Channel chips: clicking sets the picker's value to the channel
|
||||
// (or to the latest stable when stable is clicked) and fires a
|
||||
// change event so rewire() runs through the existing flow.
|
||||
chips.forEach(function(c) {
|
||||
c.addEventListener('click', function() {
|
||||
var ch = c.dataset.channel;
|
||||
if (ch === 'stable') {
|
||||
// Latest stable is the first non-channel <option> in the picker.
|
||||
var firstStable = picker.querySelector('option[value^="v"]');
|
||||
if (firstStable) picker.value = firstStable.value;
|
||||
} else {
|
||||
picker.value = ch;
|
||||
}
|
||||
rewire(picker.value);
|
||||
});
|
||||
});
|
||||
// Run rewire once on load to apply the platform-detection result
|
||||
// (the static href for the primary button is for linux-amd64; on a
|
||||
// non-linux client, that needs to flip to the detected platform).
|
||||
rewire(picker.value);
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
|
|
|
|||
2
mdedit/dist/mdedit.html
vendored
2
mdedit/dist/mdedit.html
vendored
|
|
@ -1774,7 +1774,7 @@ body.help-open .app-header {
|
|||
</svg>
|
||||
<div class="header-title-group">
|
||||
<span class="app-header__title">ZDDC Markdown</span>
|
||||
<span class="build-timestamp"><span style="color:red;font-weight:bold">v0.0.9-alpha · 2026-05-02 02:07:03 · 17b0a4d-dirty</span></span>
|
||||
<span class="build-timestamp"><span style="color:red;font-weight:bold">v0.0.9-alpha · 2026-05-02 02:15:56 · 8c2e65e-dirty</span></span>
|
||||
</div>
|
||||
<button id="select-directory" class="btn btn-primary" title="Select a Directory">Select Directory</button>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1231,41 +1231,6 @@ html[data-theme="light"] {
|
|||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
/* Channel quick-pick chips next to the version picker. Visible at-a-
|
||||
glance entry points to alpha and beta channels even when those
|
||||
currently cascade to stable — discoverability matters more than
|
||||
minimalism here. Clicking drives the version picker. */
|
||||
.channel-chips {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
gap: var(--spacing-sm);
|
||||
margin: 0 0 var(--spacing-lg);
|
||||
font-size: 0.92rem;
|
||||
}
|
||||
.channel-chips-label { color: var(--color-text-muted); margin-right: var(--spacing-xs); }
|
||||
.channel-chip {
|
||||
font: inherit;
|
||||
padding: 0.25rem 0.75rem;
|
||||
background: var(--color-bg);
|
||||
color: var(--color-text);
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: 999px;
|
||||
cursor: pointer;
|
||||
transition: background 0.12s, border-color 0.12s, color 0.12s;
|
||||
}
|
||||
.channel-chip:hover { background: var(--color-accent-soft); border-color: var(--color-accent); color: var(--color-accent); }
|
||||
.channel-chip.is-current {
|
||||
background: var(--color-accent);
|
||||
color: #fff;
|
||||
border-color: var(--color-accent);
|
||||
font-weight: 600;
|
||||
}
|
||||
.channel-chip[data-channel="alpha"]:not(.is-current),
|
||||
.channel-chip[data-channel="beta"]:not(.is-current) {
|
||||
color: var(--color-text-muted);
|
||||
}
|
||||
|
||||
/* Channel explainer (bottom of the page) */
|
||||
.channel-explainer { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--spacing-md); margin-top: var(--spacing-md); }
|
||||
.channel-explainer > div {
|
||||
|
|
|
|||
|
|
@ -44,29 +44,20 @@
|
|||
<div class="version-picker-bar">
|
||||
<label for="version-picker">Showing</label>
|
||||
<select id="version-picker">
|
||||
<option value="v0.0.8" selected>v0.0.8 (current stable)</option>
|
||||
<option value="v0.0.2">v0.0.2</option>
|
||||
<option value="v0.0.1">v0.0.1</option>
|
||||
<optgroup label="Pre-release channels">
|
||||
<option value="beta">beta — currently tracks stable</option>
|
||||
<option value="alpha">alpha — currently tracks stable</option>
|
||||
<optgroup label="Channels (mutable URLs)">
|
||||
<option value="stable" selected>stable — currently v0.0.8</option>
|
||||
<option value="beta">beta — tracks stable</option>
|
||||
<option value="alpha">alpha — tracks stable</option>
|
||||
</optgroup>
|
||||
<optgroup label="Pinned versions (immutable URLs)">
|
||||
<option value="v0.0.8">v0.0.8</option>
|
||||
<option value="v0.0.2">v0.0.2</option>
|
||||
<option value="v0.0.1">v0.0.1</option>
|
||||
</optgroup>
|
||||
</select>
|
||||
<span class="picker-hint">Changes every download link below.</span>
|
||||
</div>
|
||||
|
||||
<!-- Channel quick-pick chips — visible at-a-glance entry points to
|
||||
alpha and beta even when they cascade to stable. Clicking drives
|
||||
the version picker (rewires the page) rather than navigating
|
||||
away. The chip is always live; the cascade rule keeps the URLs
|
||||
it represents permanently resolvable. -->
|
||||
<div class="channel-chips" role="group" aria-label="Channel quick pick">
|
||||
<span class="channel-chips-label">Or pick a channel:</span>
|
||||
<button type="button" class="channel-chip is-current" data-channel="stable">stable</button>
|
||||
<button type="button" class="channel-chip" data-channel="beta">beta</button>
|
||||
<button type="button" class="channel-chip" data-channel="alpha">alpha</button>
|
||||
</div>
|
||||
|
||||
<!-- ───────────── Path A — Self-host the server ───────────── -->
|
||||
<section class="card" style="background: var(--color-bg-subtle); border: 1px solid var(--color-border); border-radius: var(--radius-md); padding: var(--spacing-lg) var(--spacing-xl); margin-top: var(--spacing-lg);">
|
||||
<h2 style="margin-top:0;">Path A — Self-host the server</h2>
|
||||
|
|
@ -74,18 +65,18 @@
|
|||
<a class="dl-primary"
|
||||
data-tool="zddc-server"
|
||||
data-platform="linux-amd64"
|
||||
href="zddc-server_v0.0.8_linux-amd64"
|
||||
href="zddc-server_stable_linux-amd64"
|
||||
id="dl-primary-binary">
|
||||
<span class="dl-icon">⬇</span>
|
||||
<span>Download <span id="dl-primary-platlabel">for Linux (x86_64)</span></span>
|
||||
</a>
|
||||
<span class="dl-primary-meta" id="dl-primary-meta">zddc-server_v0.0.8_linux-amd64</span>
|
||||
<span class="dl-primary-meta" id="dl-primary-meta">zddc-server_stable_linux-amd64</span>
|
||||
<div class="dl-secondary-row" id="dl-others">
|
||||
<span>Other platforms:</span>
|
||||
<a data-tool="zddc-server" data-platform="linux-amd64" href="zddc-server_v0.0.8_linux-amd64">Linux (x86_64)</a>
|
||||
<a data-tool="zddc-server" data-platform="darwin-amd64" href="zddc-server_v0.0.8_darwin-amd64">macOS (Intel)</a>
|
||||
<a data-tool="zddc-server" data-platform="darwin-arm64" href="zddc-server_v0.0.8_darwin-arm64">macOS (Apple Silicon)</a>
|
||||
<a data-tool="zddc-server" data-platform="windows-amd64" href="zddc-server_v0.0.8_windows-amd64.exe">Windows (x86_64)</a>
|
||||
<a data-tool="zddc-server" data-platform="linux-amd64" href="zddc-server_stable_linux-amd64">Linux (x86_64)</a>
|
||||
<a data-tool="zddc-server" data-platform="darwin-amd64" href="zddc-server_stable_darwin-amd64">macOS (Intel)</a>
|
||||
<a data-tool="zddc-server" data-platform="darwin-arm64" href="zddc-server_stable_darwin-arm64">macOS (Apple Silicon)</a>
|
||||
<a data-tool="zddc-server" data-platform="windows-amd64" href="zddc-server_stable_windows-amd64.exe">Windows (x86_64)</a>
|
||||
</div>
|
||||
<p style="margin-top: var(--spacing-md); font-size: 0.92rem; color: var(--color-text-muted);">
|
||||
After download: <code>chmod +x</code> the file, set <code>ZDDC_ROOT=/path/to/archive</code>, run.
|
||||
|
|
@ -98,27 +89,27 @@
|
|||
<h2 style="margin-top:0;">Path B — Standalone tools</h2>
|
||||
<p>Every tool is a single self-contained HTML file. <strong>Open it locally and point it at a folder on your disk</strong> — no install, no server, no account. Same on-disk layout the server uses. Use one tool, use all five, mix and match — there is no orchestration to set up.</p>
|
||||
<div class="grid-4" style="margin-top: var(--spacing-md);">
|
||||
<a class="tool-card" data-tool="archive" href="archive_v0.0.8.html">
|
||||
<a class="tool-card" data-tool="archive" href="archive_stable.html">
|
||||
<span class="tool-card__title">Archive Browser</span>
|
||||
<span class="tool-card__desc">Browse and download from a ZDDC archive.</span>
|
||||
<span class="tool-card__link">Download →</span>
|
||||
</a>
|
||||
<a class="tool-card" data-tool="transmittal" href="transmittal_v0.0.8.html">
|
||||
<a class="tool-card" data-tool="transmittal" href="transmittal_stable.html">
|
||||
<span class="tool-card__title">Transmittal Creator</span>
|
||||
<span class="tool-card__desc">Build, sign, and verify transmittal packages.</span>
|
||||
<span class="tool-card__link">Download →</span>
|
||||
</a>
|
||||
<a class="tool-card" data-tool="classifier" href="classifier_v0.0.8.html">
|
||||
<a class="tool-card" data-tool="classifier" href="classifier_stable.html">
|
||||
<span class="tool-card__title">Classifier</span>
|
||||
<span class="tool-card__desc">Rename loose files to ZDDC convention.</span>
|
||||
<span class="tool-card__link">Download →</span>
|
||||
</a>
|
||||
<a class="tool-card" data-tool="mdedit" href="mdedit_v0.0.8.html">
|
||||
<a class="tool-card" data-tool="mdedit" href="mdedit_stable.html">
|
||||
<span class="tool-card__title">Markdown Editor</span>
|
||||
<span class="tool-card__desc">Edit project markdown files in place.</span>
|
||||
<span class="tool-card__link">Download →</span>
|
||||
</a>
|
||||
<a class="tool-card" data-tool="landing" href="landing_v0.0.8.html">
|
||||
<a class="tool-card" data-tool="landing" href="landing_stable.html">
|
||||
<span class="tool-card__title">Landing</span>
|
||||
<span class="tool-card__desc">Project picker for multi-project servers.</span>
|
||||
<span class="tool-card__link">Download →</span>
|
||||
|
|
@ -203,90 +194,65 @@ apps:
|
|||
var primaryMeta = document.getElementById('dl-primary-meta');
|
||||
var others = document.getElementById('dl-others');
|
||||
|
||||
function platBinaryName(version, plat) {
|
||||
var suf = (plat.indexOf('windows') === 0) ? '.exe' : '';
|
||||
return 'zddc-server_' + version + '_' + plat + suf;
|
||||
function isChannel(v) {
|
||||
return v === 'stable' || v === 'beta' || v === 'alpha';
|
||||
}
|
||||
function htmlAssetName(tool, version) {
|
||||
return tool + '_' + version + '.html';
|
||||
function platBinaryName(slug, plat) {
|
||||
// slug is a channel name ("stable") or a pinned version ("v0.0.8").
|
||||
// The on-disk name uses the slug as-is in both cases since the
|
||||
// channel-mirror filenames are zddc-server_<channel>_<plat> and
|
||||
// per-version are zddc-server_v<X.Y.Z>_<plat>.
|
||||
var suf = (plat.indexOf('windows') === 0) ? '.exe' : '';
|
||||
return 'zddc-server_' + slug + '_' + plat + suf;
|
||||
}
|
||||
function htmlAssetName(tool, slug) {
|
||||
return tool + '_' + slug + '.html';
|
||||
}
|
||||
|
||||
// Update the primary button to the detected platform (if different
|
||||
// from default). Hide the matching link in the secondary row to
|
||||
// avoid duplication.
|
||||
// Promote the detected platform to the primary CTA. The secondary
|
||||
// row keeps all four; the matching one is hidden to avoid showing
|
||||
// the same download twice.
|
||||
if (primary) {
|
||||
var initialVer = primary.getAttribute('href').match(/_v[\d.]+_/);
|
||||
initialVer = initialVer ? initialVer[0].slice(2, -1) : null;
|
||||
primary.dataset.platform = detected;
|
||||
if (initialVer) {
|
||||
primary.href = platBinaryName('v' + initialVer, detected);
|
||||
if (primaryMeta) primaryMeta.textContent = platBinaryName('v' + initialVer, detected);
|
||||
}
|
||||
if (primaryLabel) primaryLabel.textContent = 'for ' + platLabel;
|
||||
}
|
||||
|
||||
// Hide the duplicate in "Other platforms" row.
|
||||
if (others) {
|
||||
others.querySelectorAll('a[data-platform="' + detected + '"]').forEach(function(a) {
|
||||
a.style.display = 'none';
|
||||
});
|
||||
}
|
||||
|
||||
// Wire the version picker + channel chips. Both drive the same
|
||||
// rewire function. Selecting a per-version stable from the picker
|
||||
// also updates the chip set: stable becomes active, beta/alpha lose
|
||||
// their is-current marker.
|
||||
// Single source of truth: the dropdown's current value drives every
|
||||
// download link's href. Static markup ships with the stable-channel
|
||||
// mirror (`<tool>_stable.html`, `zddc-server_stable_<plat>`) so the
|
||||
// page works fully without JS — the JS just keeps things in sync
|
||||
// when the user picks a different channel or pins a version.
|
||||
var picker = document.getElementById('version-picker');
|
||||
if (!picker) return;
|
||||
var chips = document.querySelectorAll('.channel-chip');
|
||||
|
||||
function rewire(v) {
|
||||
// v is "vX.Y.Z" or "alpha" / "beta"
|
||||
function rewire(slug) {
|
||||
// slug ∈ {"stable", "beta", "alpha"} | "v<X.Y.Z>". Every link with
|
||||
// a data-tool attribute is a download URL the dropdown owns.
|
||||
document.querySelectorAll('[data-tool]').forEach(function(a) {
|
||||
var tool = a.dataset.tool;
|
||||
var plat = a.dataset.platform || '';
|
||||
if (tool === 'zddc-server') {
|
||||
if (plat) {
|
||||
a.href = (v === 'alpha' || v === 'beta')
|
||||
? 'zddc-server_' + v + '_' + plat + (plat.indexOf('windows') === 0 ? '.exe' : '')
|
||||
: platBinaryName(v, plat);
|
||||
} else {
|
||||
a.href = 'zddc-server_' + v + '.html';
|
||||
}
|
||||
a.href = plat ? platBinaryName(slug, plat) : ('zddc-server_' + slug + '.html');
|
||||
} else {
|
||||
a.href = htmlAssetName(tool, v);
|
||||
a.href = htmlAssetName(tool, slug);
|
||||
}
|
||||
});
|
||||
if (primary && primaryMeta) {
|
||||
primaryMeta.textContent = primary.getAttribute('href');
|
||||
}
|
||||
// Reflect channel-vs-version in the chip group. Per-version stable
|
||||
// selections highlight the "stable" chip (since per-version files
|
||||
// are stable releases).
|
||||
var channel = (v === 'alpha' || v === 'beta') ? v : 'stable';
|
||||
chips.forEach(function(c) {
|
||||
c.classList.toggle('is-current', c.dataset.channel === channel);
|
||||
});
|
||||
}
|
||||
|
||||
picker.addEventListener('change', function() { rewire(picker.value); });
|
||||
|
||||
// Channel chips: clicking sets the picker's value to the channel
|
||||
// (or to the latest stable when stable is clicked) and fires a
|
||||
// change event so rewire() runs through the existing flow.
|
||||
chips.forEach(function(c) {
|
||||
c.addEventListener('click', function() {
|
||||
var ch = c.dataset.channel;
|
||||
if (ch === 'stable') {
|
||||
// Latest stable is the first non-channel <option> in the picker.
|
||||
var firstStable = picker.querySelector('option[value^="v"]');
|
||||
if (firstStable) picker.value = firstStable.value;
|
||||
} else {
|
||||
picker.value = ch;
|
||||
}
|
||||
rewire(picker.value);
|
||||
});
|
||||
});
|
||||
// Run rewire once on load to apply the platform-detection result
|
||||
// (the static href for the primary button is for linux-amd64; on a
|
||||
// non-linux client, that needs to flip to the detected platform).
|
||||
rewire(picker.value);
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
|
|
|
|||
|
|
@ -2113,7 +2113,7 @@ td[data-field="trackingNumber"] {
|
|||
</svg>
|
||||
<div class="header-title-group">
|
||||
<span class="app-header__title">ZDDC Archive</span>
|
||||
<span class="build-timestamp"><span style="color:red;font-weight:bold">v0.0.9-alpha · 2026-05-02 02:07:03 · 17b0a4d-dirty</span></span>
|
||||
<span class="build-timestamp"><span style="color:red;font-weight:bold">v0.0.9-alpha · 2026-05-02 02:15:56 · 8c2e65e-dirty</span></span>
|
||||
</div>
|
||||
<button id="addDirectoryBtn" class="btn btn-primary">Add Local Directory</button>
|
||||
<button id="refreshHeaderBtn" class="btn btn-secondary hidden" title="Refresh Data" style="font-size:1.1rem;">⟳</button>
|
||||
|
|
|
|||
|
|
@ -1376,7 +1376,7 @@ body.help-open .app-header {
|
|||
</svg>
|
||||
<div class="header-title-group">
|
||||
<span class="app-header__title">ZDDC Classifier</span>
|
||||
<span class="build-timestamp"><span style="color:red;font-weight:bold">v0.0.9-alpha · 2026-05-02 02:07:03 · 17b0a4d-dirty</span></span>
|
||||
<span class="build-timestamp"><span style="color:red;font-weight:bold">v0.0.9-alpha · 2026-05-02 02:15:56 · 8c2e65e-dirty</span></span>
|
||||
</div>
|
||||
<button id="selectDirectoryBtn" class="btn btn-primary">Select Directory</button>
|
||||
<button id="refreshBtn" class="btn btn-secondary hidden" title="Refresh and rescan directory">Refresh</button>
|
||||
|
|
|
|||
|
|
@ -866,7 +866,7 @@ body {
|
|||
</g>
|
||||
</svg>
|
||||
<span class="app-header__title">ZDDC Archive</span>
|
||||
<span class="build-timestamp"><span style="color:red;font-weight:bold">v0.0.9-alpha · 2026-05-02 02:07:03 · 17b0a4d-dirty</span></span>
|
||||
<span class="build-timestamp"><span style="color:red;font-weight:bold">v0.0.9-alpha · 2026-05-02 02:15:56 · 8c2e65e-dirty</span></span>
|
||||
</div>
|
||||
<div class="header-right">
|
||||
<button id="theme-btn" class="btn btn-secondary" title="Theme: auto (follows OS)" aria-label="Theme: auto (follows OS)">◐</button>
|
||||
|
|
|
|||
|
|
@ -1774,7 +1774,7 @@ body.help-open .app-header {
|
|||
</svg>
|
||||
<div class="header-title-group">
|
||||
<span class="app-header__title">ZDDC Markdown</span>
|
||||
<span class="build-timestamp"><span style="color:red;font-weight:bold">v0.0.9-alpha · 2026-05-02 02:07:03 · 17b0a4d-dirty</span></span>
|
||||
<span class="build-timestamp"><span style="color:red;font-weight:bold">v0.0.9-alpha · 2026-05-02 02:15:56 · 8c2e65e-dirty</span></span>
|
||||
</div>
|
||||
<button id="select-directory" class="btn btn-primary" title="Select a Directory">Select Directory</button>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -2210,7 +2210,7 @@ dialog.modal--narrow {
|
|||
</svg>
|
||||
<div class="header-title-group">
|
||||
<span class="app-header__title">ZDDC Transmittal</span>
|
||||
<span class="build-timestamp"><span style="color:red;font-weight:bold">v0.0.9-alpha · 2026-05-02 02:07:03 · 17b0a4d-dirty</span></span>
|
||||
<span class="build-timestamp"><span style="color:red;font-weight:bold">v0.0.9-alpha · 2026-05-02 02:15:56 · 8c2e65e-dirty</span></span>
|
||||
</div>
|
||||
<div class="app-header__spacer"></div>
|
||||
<div class="app-header__icons">
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# Generated by build.sh — do not edit. One <app>=<build label> per line.
|
||||
archive=v0.0.9-alpha · 2026-05-02 02:07:03 · 17b0a4d-dirty
|
||||
transmittal=v0.0.9-alpha · 2026-05-02 02:07:03 · 17b0a4d-dirty
|
||||
classifier=v0.0.9-alpha · 2026-05-02 02:07:03 · 17b0a4d-dirty
|
||||
mdedit=v0.0.9-alpha · 2026-05-02 02:07:03 · 17b0a4d-dirty
|
||||
landing=v0.0.9-alpha · 2026-05-02 02:07:03 · 17b0a4d-dirty
|
||||
archive=v0.0.9-alpha · 2026-05-02 02:15:56 · 8c2e65e-dirty
|
||||
transmittal=v0.0.9-alpha · 2026-05-02 02:15:56 · 8c2e65e-dirty
|
||||
classifier=v0.0.9-alpha · 2026-05-02 02:15:56 · 8c2e65e-dirty
|
||||
mdedit=v0.0.9-alpha · 2026-05-02 02:15:56 · 8c2e65e-dirty
|
||||
landing=v0.0.9-alpha · 2026-05-02 02:15:56 · 8c2e65e-dirty
|
||||
|
|
|
|||
Loading…
Reference in a new issue