Add mode READMEs and move Bigscreen app

Add comprehensive READMEs for Bigscreen and Desktop modes, and relocate the Tauri frontend prototype into a new Bigscreen/ subdirectory. This moves package.json/package-lock, src, src-tauri, assets, views, styles and related files into Bigscreen/ to separate the controller-first shell from top-level docs. Update the root README.md to reframe the project as "NebulaOS", describe Bigscreen/Desktop modes, the vision, tech stack and development notes. This reorganizes the repo layout for clearer mode separation and documentation.
This commit is contained in:
Andrew Zambazos
2026-05-21 20:11:18 +12:00
parent b141c0a058
commit f0d2926872
87 changed files with 974 additions and 322 deletions
+152
View File
@@ -0,0 +1,152 @@
const PANEL_COPY = {
search: {
title: "Search",
description: "Search games, apps, and settings across NebulaOS.",
placeholder: "Search NebulaOS…",
},
notifications: {
title: "Notifications",
description: "System alerts and download updates will appear here.",
},
downloads: {
title: "Downloads",
description: "Active and completed downloads will be listed here.",
},
controller: {
title: "Controller Settings",
description: "Map buttons, adjust dead zones, and test input.",
},
};
export const createGuidePanelOverlay = ({ mountRoot }) => {
let openState = false;
let activePanel = null;
let onClose = null;
let overlay = null;
const renderMarkup = () => {
mountRoot.insertAdjacentHTML(
"beforeend",
`
<section class="guide-panel-overlay" data-guide-panel-overlay hidden aria-label="Guide panel">
<div class="guide-panel-sheet panel" role="dialog" aria-modal="true">
<header class="guide-panel-sheet-head">
<h2 class="guide-panel-sheet-title" data-panel-title>Panel</h2>
<p class="muted guide-panel-sheet-desc" data-panel-desc></p>
</header>
<div class="guide-panel-sheet-body" data-panel-body></div>
<button
type="button"
class="focusable guide-panel-close"
data-focusable="true"
data-row="0"
data-col="0"
data-action="close"
data-focus-key="guide-panel-close"
>Close</button>
</div>
</section>
`,
);
overlay = mountRoot.querySelector("[data-guide-panel-overlay]");
};
const getBodyHtml = (panelId) => {
const copy = PANEL_COPY[panelId];
if (!copy) {
return `<p class="muted">This panel is not available yet.</p>`;
}
if (panelId === "search") {
return `
<label class="guide-panel-search-label">
<span class="sr-only">Search query</span>
<input
type="search"
class="guide-panel-search-input"
placeholder="${copy.placeholder}"
data-panel-search
autocomplete="off"
/>
</label>
<p class="muted guide-panel-hint">Results will appear here. (Placeholder)</p>
`;
}
return `
<div class="guide-panel-placeholder-card">
<p class="guide-panel-placeholder-title">${copy.title}</p>
<p class="muted">${copy.description}</p>
<p class="guide-panel-placeholder-note">Connected to guide quick actions · stub UI</p>
</div>
`;
};
const close = () => {
openState = false;
activePanel = null;
if (overlay) {
overlay.hidden = true;
}
onClose?.();
onClose = null;
};
const bindOverlayEvents = () => {
overlay?.addEventListener("click", (event) => {
if (event.target === overlay) {
close();
}
});
overlay?.querySelector(".guide-panel-close")?.addEventListener("click", () => close());
};
const open = (panelId, options = {}) => {
if (!overlay) {
renderMarkup();
bindOverlayEvents();
}
const copy = PANEL_COPY[panelId] ?? { title: "Panel", description: "" };
overlay.querySelector("[data-panel-title]").textContent = copy.title;
overlay.querySelector("[data-panel-desc]").textContent = copy.description ?? "";
overlay.querySelector("[data-panel-body]").innerHTML = getBodyHtml(panelId);
openState = true;
activePanel = panelId;
onClose = options.onClose ?? null;
overlay.hidden = false;
const closeBtn = overlay.querySelector("[data-guide-panel-close], .guide-panel-close");
closeBtn?.focus({ preventScroll: true });
closeBtn?.classList.add("is-focused");
console.log(`[GuidePanel] Opened: ${panelId}`);
};
const handleAction = (action) => {
if (!openState) {
return false;
}
if (action === "accept") {
close();
return true;
}
if (action === "back" || action === "menu") {
close();
return true;
}
return true;
};
return {
open,
close,
isOpen: () => openState,
getActivePanel: () => activePanel,
handleAction,
};
};