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:
@@ -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,
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user