diff --git a/website/app.js b/website/app.js new file mode 100644 index 0000000..4c2dc0f --- /dev/null +++ b/website/app.js @@ -0,0 +1,104 @@ +(function () { + function escapeHtml(str) { + return String(str) + .replace(/&/g, "&") + .replace(//g, ">") + .replace(/"/g, """) + .replace(/'/g, "'"); + } + + function chunk(arr, size) { + var out = []; + for (var i = 0; i < arr.length; i += size) out.push(arr.slice(i, i + size)); + return out; + } + + function renderLinksTable(links, columns) { + columns = columns || 3; + links = Array.isArray(links) ? links : []; + + var rows = chunk(links, columns); + if (rows.length) { + var last = rows[rows.length - 1]; + while (last.length < columns) last.push(null); + } + + var html = ""; + for (var r = 0; r < rows.length; r++) { + html += ""; + for (var c = 0; c < columns; c++) { + var item = rows[r][c]; + if (!item) { + html += ""; + continue; + } + + var href = escapeHtml(item.href || "#"); + var label = escapeHtml(item.label || ""); + var img = escapeHtml(item.image || ""); + var alt = escapeHtml(item.alt || item.label || ""); + + html += + '"; + } + html += ""; + } + html += "
' + + '' + + '' + alt + '' + + "

" + label + "

" + + "
" + + "
"; + return html; + } + + function renderAllSections(containerId, sectionsObj) { + var container = document.getElementById(containerId); + if (!container) return; + + sectionsObj = sectionsObj || {}; + var keys = Object.keys(sectionsObj); + + // If you want a custom order, add an "order" number in links.js and sort here. + // Default: object insertion order. + var html = ""; + + for (var i = 0; i < keys.length; i++) { + var key = keys[i]; + var section = sectionsObj[key]; + + // support BOTH formats: + // 1) new format: { title, links: [...] } + // 2) old format: key: [ ...links... ] + var title, links; + if (Array.isArray(section)) { + title = key; // fallback title + links = section; + } else { + title = section && section.title ? section.title : key; + links = section && Array.isArray(section.links) ? section.links : []; + } + + // Skip empty sections (optional) + if (!links.length) continue; + + html += "

" + escapeHtml(title) + "

"; + html += renderLinksTable(links, 3); + + // divider between sections + if (i !== keys.length - 1) html += "
"; + } + + container.innerHTML = html || "

No sections defined.

"; + } + + window.addEventListener("DOMContentLoaded", function () { + // focus search input + var q = document.getElementById("q"); + if (q) q.focus(); + + renderAllSections("sections", window.LAUNCHPAD_LINKS); + }); + })(); + \ No newline at end of file diff --git a/website/index.html b/website/index.html new file mode 100644 index 0000000..9fbe8f0 --- /dev/null +++ b/website/index.html @@ -0,0 +1,67 @@ + + + + + SumiLaunch + + + + + + +
+

SumiLaunch

+ + +
+ + +
+ +
+ +
+ +
+ +

TIP: Launchpad Shortcut

+ Menu > Add to Home Screen +

Designed for classic BBOS.

+

© 2026 Sumisu

+

Based on LunarProject.org.

+
+ + + + + diff --git a/website/links.js b/website/links.js new file mode 100644 index 0000000..8f4a12b --- /dev/null +++ b/website/links.js @@ -0,0 +1,37 @@ +window.LAUNCHPAD_LINKS = { + anyBrowser: { + title: "Any Browser", + links: [ + { href: "./news/", label: "SumiNews", image: "http://192.168.1.242:8087/images/lunarnews.png", alt: "SumiNews" }, + { href: "./weather/", label: "SumiWeather", image: "http://192.168.1.242:8087/images/weather.png", alt: "SumiWeather" }, + + { href: "https://pb-appstore.netlify.app/", label: "PB - Appstore", image: "https://cdn.bio.link/uploads/profile_pictures/2025-11-19/2lWy5sAQy0Ox3AMMehIBSTWkIzb6vcvi.png", alt: "PB - Appstore" }, + { href: "http://news.ycombinator.com", label: "Hacker News", image: "http://192.168.1.242:8087/images/newsz.png", alt: "Hacker News" }, + + { href: "http://text.npr.org/", label: "NPR", image: "http://192.168.1.242:8087/images/npr.jpg", alt: "NPR" }, + + { href: "http://williamsmobile.co.uk/apps.htm", label: "WM Apps", image: "http://192.168.1.242:8087/images/wm.jpg", alt: "WilliamsMobile" }, + { href: "http://gdir.telae.net/", label: "Gmaps", image: "http://192.168.1.242:8087/images/gmaps.png", alt: "Gmaps" }, + { href: "http://old.reddit.com/", label: "Old Reddit", image: "http://192.168.1.242:8087/images/reddit.png", alt: "Old Reddit" }, + { href: "http://forums.crackberry.com/", label: "CB Forums", image: "http://192.168.1.242:8087/images/cb.png", alt: "CB Forums" }, + + ] + }, + + search: { + title: "Search", + links: [ + { href: "https://html.duckduckgo.com/html/", label: "DuckDuckGo", image: "https://duckduckgo.com/assets/logo_header.v109.svg", alt: "DuckDuckGo" }, + { href: "https://frogfind.sumisu.xyz/", label: "FrogFind! Search", image: "http://frogfind.de/frosch.gif", alt: "FrogFind! Search" }, + { href: "http://wiby.me/", label: "Wiby", image: "http://192.168.1.242:8087/images/wiby.png", alt: "Wiby" }, + ] + }, + + games: { + title: "Games", + links: [ + { href: "./wordle/", label: "Wordle", image: "https://upload.wikimedia.org/wikipedia/commons/c/c5/Wordle_Logo.svg", alt: "Wordle" }, + ] + } + }; + \ No newline at end of file