Initial commit: Brass & Sigil monorepo
Self-hosted Minecraft modpack distribution + administration system.
- launcher/ Avalonia 12 desktop client; single-file win-x64 publish.
Microsoft auth via XboxAuthNet, manifest+SHA-1 mod sync,
portable install path, sidecar settings.
- server/ brass-sigil-server daemon (.NET 8, linux-x64). Wraps the
MC subprocess, embedded Kestrel admin panel with cookie
auth + rate limiting, RCON bridge, scheduled backups,
BlueMap CLI integration with player markers + skin proxy,
friend-side whitelist request flow, world wipe with seed
selection (keep current / random / custom).
- pack/ pack.lock.json (Modrinth + manual CurseForge entries),
data-only tweak source under tweaks/, build outputs in
overrides/ (gitignored).
- scripts/ Build-Pack / Build-Tweaks / Update-Pack / Check-Updates
plus Deploy-Brass.ps1 unified one-shot deploy with
version-bump pre-flight and daemon-state detection.
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
// Tiny modal helper. Registers a single document-level Esc + backdrop-click
|
||||
// handler so individual modals don't have to. Public API: openModal(id) /
|
||||
// closeModal(id) / closeAllModals().
|
||||
"use strict";
|
||||
|
||||
let bound = false;
|
||||
|
||||
function bindGlobal() {
|
||||
if (bound) return;
|
||||
bound = true;
|
||||
document.addEventListener("keydown", e => {
|
||||
if (e.key === "Escape") closeAllModals();
|
||||
});
|
||||
document.addEventListener("click", e => {
|
||||
// Backdrop click closes the topmost open modal.
|
||||
const backdrop = e.target.closest(".modal-backdrop");
|
||||
if (backdrop) closeModal(backdrop.parentElement.id);
|
||||
const closeBtn = e.target.closest(".modal-close");
|
||||
if (closeBtn) closeModal(closeBtn.closest(".modal").id);
|
||||
});
|
||||
}
|
||||
|
||||
export function openModal(id) {
|
||||
bindGlobal();
|
||||
const m = document.getElementById(id);
|
||||
if (!m) return;
|
||||
m.hidden = false;
|
||||
document.body.classList.add("modal-open");
|
||||
// Focus first input/button for keyboard users.
|
||||
setTimeout(() => {
|
||||
const focusable = m.querySelector("input, button:not(.modal-close), select, textarea");
|
||||
focusable?.focus();
|
||||
}, 50);
|
||||
}
|
||||
|
||||
export function closeModal(id) {
|
||||
const m = document.getElementById(id);
|
||||
if (!m) return;
|
||||
m.hidden = true;
|
||||
if (!document.querySelector(".modal:not([hidden])")) {
|
||||
document.body.classList.remove("modal-open");
|
||||
}
|
||||
}
|
||||
|
||||
export function closeAllModals() {
|
||||
document.querySelectorAll(".modal:not([hidden])").forEach(m => m.hidden = true);
|
||||
document.body.classList.remove("modal-open");
|
||||
}
|
||||
|
||||
/// Wires `data-open-modal="someId"` on any element to opening the modal.
|
||||
export function setupModalTriggers() {
|
||||
bindGlobal();
|
||||
document.addEventListener("click", e => {
|
||||
const trigger = e.target.closest("[data-open-modal]");
|
||||
if (trigger) openModal(trigger.getAttribute("data-open-modal"));
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user