From 660e88e3602deed5571d57ecc95a225bd4ca9f19 Mon Sep 17 00:00:00 2001 From: foxster-mp4 Date: Sun, 30 Apr 2023 00:33:30 -0700 Subject: [PATCH] Refactor --- app.html | 5 +- apps.html | 7 +- css/{main.css => shared.css} | 0 home.html | 8 +- index.html | 3 +- js/app.js | 355 +++++++++++++++++------------------ js/apps.js | 52 +++-- js/home.js | 102 +++++----- js/index.js | 29 +-- js/main.js | 143 +++----------- js/news.js | 22 +-- js/shared.js | 109 +++++++++++ news.html | 7 +- 13 files changed, 409 insertions(+), 433 deletions(-) rename css/{main.css => shared.css} (100%) create mode 100644 js/shared.js diff --git a/app.html b/app.html index b264b0d..a2ea224 100644 --- a/app.html +++ b/app.html @@ -4,9 +4,9 @@ - - + +
@@ -99,6 +99,7 @@
+ diff --git a/apps.html b/apps.html index 26d8537..916008a 100644 --- a/apps.html +++ b/apps.html @@ -4,9 +4,9 @@ - - + +
@@ -18,7 +18,8 @@
- + + \ No newline at end of file diff --git a/css/main.css b/css/shared.css similarity index 100% rename from css/main.css rename to css/shared.css diff --git a/home.html b/home.html index 6d003f2..004e44a 100644 --- a/home.html +++ b/home.html @@ -1,14 +1,12 @@ - + - -
loading @@ -41,8 +39,8 @@
- + + - \ No newline at end of file diff --git a/index.html b/index.html index 963415c..1e7c23a 100644 --- a/index.html +++ b/index.html @@ -4,8 +4,8 @@ + - @@ -56,6 +56,7 @@ + \ No newline at end of file diff --git a/js/app.js b/js/app.js index e9323f2..2d1a3bf 100644 --- a/js/app.js +++ b/js/app.js @@ -1,200 +1,183 @@ +if (!urlSearchParams.has('id')) exit(); const bundleId = urlSearchParams.get('id'); -if (!urlSearchParams.has('id') || !bundleId) nope(); -// Hide/show navigation bar title & install button -let hidden = false; -window.onscroll = function (e) { - const appName = document.querySelector(".app-header .text>.title"); - const title = document.getElementById("title"); - const button = document.querySelector("#nav-bar .install"); +(function () { + // Hide/show navigation bar title & install button + let hidden = false; + window.onscroll = function (e) { + const appName = document.querySelector(".app-header .text>.title"); + const title = document.getElementById("title"); + const button = document.querySelector("#nav-bar .install"); - if (hidden && appName.getBoundingClientRect().y >= 72) { // App name not visible - hidden = false; - title.classList.add("hidden"); - button.classList.add("hidden"); - button.disaled = true; - } else if (!hidden && appName.getBoundingClientRect().y < 72) { - hidden = true; - title.classList.remove("hidden"); - button.classList.remove("hidden"); - button.disaled = false; + if (hidden && appName.getBoundingClientRect().y >= 72) { // App name not visible + hidden = false; + title.classList.add("hidden"); + button.classList.add("hidden"); + button.disaled = true; + } else if (!hidden && appName.getBoundingClientRect().y < 72) { + hidden = true; + title.classList.remove("hidden"); + button.classList.remove("hidden"); + button.disaled = false; + } } -} +})(); -fetch(sourceURL) - .then(response => response.json()) - .then(json => { - const apps = json.apps.filter(app => app.bundleIdentifier === bundleId); - const app = apps[0]; - if (!app) { - alert(`Unable to find app matching bundle identifier "${bundleId}".\nYou will now be redirected to the home page.`); - nope(); - } +function main(json) { + const app = getAppWithBundleId(bundleId); + if (!app) exit(); - document.title = `${app.name} - ${json.name}`; + // Set tab title + document.title = `${app.name} - ${json.name}`; - const tintColor = `#${app.tintColor}`; + const tintColor = `#${app.tintColor}`; + // Set tint color + if (tintColor) document.querySelector(':root').style.setProperty("--app-tint-color", `${tintColor}`); - if (tintColor) - document.querySelector(':root').style.setProperty("--app-tint-color", `${tintColor}`); + // Tint back button + document.getElementById("back").style.color = tintColor; - // Tint back button - const backButton = document.getElementById("back"); - backButton.style.color = tintColor; - - const installButtons = document.querySelectorAll("a.install"); - installButtons.forEach(button => { - button.href = `altstore://install?url=${app.downloadURL}`; - }); - - const downloadButton = document.getElementById("download"); - downloadButton.href = app.downloadURL; - - // - // Navigation bar - // - const navBar = document.getElementById("nav-bar"); - const navBarIcon = navBar.querySelector("#title>img"); - const navBarTitle = navBar.querySelector("#title>p"); - const navBarInstallButton = navBar.querySelector(".uibutton"); - - navBarTitle.textContent = app.name; - navBarIcon.src = app.iconURL; - navBarInstallButton.style.backgroundColor = `${tintColor}`; - - // - // App header - // - const appHeader = document.querySelector("#main .app-header"); - const appHeaderIcon = appHeader.querySelector("img"); - const appHeaderTitle = appHeader.querySelector(".title"); - const appHeaderSubtitle = appHeader.querySelector(".subtitle"); - const appHeaderInstallButton = appHeader.querySelector(".uibutton"); - const appHeaderBackground = appHeader.querySelector(".background"); - - appHeaderIcon.src = app.iconURL; - appHeaderTitle.textContent = app.name; - appHeaderSubtitle.textContent = app.developerName; - appHeaderInstallButton.style.backgroundColor = tintColor; - appHeaderBackground.style.backgroundColor = tintColor; - - // - // Preview - // - const preview = document.getElementById("preview"); - const previewSubtitle = preview.querySelector("#subtitle"); - const previewScreenshots = preview.querySelector("#screenshots"); - const previewDescription = preview.querySelector("#description"); - - previewSubtitle.textContent = app.subtitle; - app.screenshotURLs.forEach(url => { - previewScreenshots.insertAdjacentHTML("beforeend", ``); - }); - - previewDescription.innerHTML = formatString(app.localizedDescription); - - const more = ` - - - `; - - if (previewDescription.scrollHeight > previewDescription.clientHeight) - previewDescription.insertAdjacentHTML("beforeend", more); - - // - // Version info - // - const versionDate = document.getElementById("version-date"); - const version = document.getElementById("version"); - const versionSize = document.getElementById("version-size"); - const versionDescription = document.getElementById("version-description"); - - // Version date - const versionDateObject = new Date(app.versionDate), - month = versionDateObject.toUTCString().split(" ")[2], - date = versionDateObject.getDate(), - dateString = `${month} ${date}, ${versionDateObject.getFullYear()}`; - const today = new Date(); - const msPerDay = 60 * 60 * 24 * 1000; - const msDifference = today.valueOf() - versionDateObject.valueOf(); - versionDate.textContent = dateString; - if (msDifference <= msPerDay) // Today - versionDate.textContent = "Today"; - else if (msDifference <= msPerDay * 2) // Yesterday - versionDate.textContent = "Yesterday"; - - // Version number - version.textContent = `Version ${app.version}`; - - // Version size - const units = ["B", "KB", "MB", "GB"]; - var appSize = app.size, c = 0; - while (appSize > 1024) { - appSize = parseFloat(appSize / 1024).toFixed(1); - c++; - } - versionSize.textContent = `${appSize} ${units[c]}`; - - // Version description - versionDescription.innerHTML = formatString(app.versionDescription); - if (versionDescription.scrollHeight > versionDescription.clientHeight) - versionDescription.insertAdjacentHTML("beforeend", more); - - // - // Permissions - // - const permissions = document.getElementById("permissions"); - - if (app.permissions) - permissions.querySelector(".permission").remove(); - - app.permissions?.forEach(permission => { - let permissionType = "Unknown", icon = "gear-wide-connected"; - switch (permission.type) { - case "background-audio": - permissionType = "Background Audio"; - // icon = "audio"; - icon = "volume-up-fill"; - break; - case "background-fetch": - permissionType = "Background Fetch"; - // icon = "fetch"; - icon = "arrow-repeat" - break; - case "photos": - permissionType = "Photos" - // icon = "photos"; - icon = "image-fill"; - break; - default: - break; - } - - const html = ` -
- -
-

${permissionType}

-

${permission.usageDescription ?? "No description provided."}

-
-
`; - - permissions.insertAdjacentHTML("beforeend", html); - }); - - waitForAllImagesToLoad(); + // Set up install buttons + document.querySelectorAll("a.install").forEach(button => { + button.href = `altstore://install?url=${app.downloadURL}`; }); -function revealTruncatedText(moreButton) { - const textId = moreButton.parentNode.id; - const text = document.getElementById(textId); - text.style.display = "block"; - text.style.overflow = "auto"; - text.style.webkitLineClamp = "none"; - text.style.lineClamp = "none"; - text.removeChild(moreButton) + // Set up download button + document.getElementById("download").href = app.downloadURL; + + // + // Navigation bar + const navigationBar = document.getElementById("nav-bar"); + // Title + navigationBar.querySelector("#title>p").textContent = app.name; + // App icon + navigationBar.querySelector("#title>img").src = app.iconURL; + // Install button + navigationBar.querySelector(".uibutton").style.backgroundColor = `${tintColor}`; + + // + // App header + const appHeader = document.querySelector("#main .app-header"); + // Icon + appHeader.querySelector("img").src = app.iconURL; + // App name + appHeader.querySelector(".title").textContent = app.name; + // Developer name + appHeader.querySelector(".subtitle").textContent = app.developerName; + // Install button + appHeader.querySelector(".uibutton").style.backgroundColor = tintColor; + // Background + appHeader.querySelector(".background").style.backgroundColor = tintColor; + + const more = ` + + + `; + + this.revealTruncatedText = moreButton => { + const textId = moreButton.parentNode.id; + const text = document.getElementById(textId); + text.style.display = "block"; + text.style.overflow = "auto"; + text.style.webkitLineClamp = "none"; + text.style.lineClamp = "none"; + text.removeChild(moreButton) + } + + // + // Preview + const preview = document.getElementById("preview"); + // Subtitle + preview.querySelector("#subtitle").textContent = app.subtitle; + // Screenshots + app.screenshotURLs.forEach(url => { + preview.querySelector("#screenshots").insertAdjacentHTML("beforeend", ``); + }); + // Description + const previewDescription = preview.querySelector("#description"); + previewDescription.innerHTML = formatString(app.localizedDescription); + if (previewDescription.scrollHeight > previewDescription.clientHeight) + previewDescription.insertAdjacentHTML("beforeend", more); + + // + // Version info + const versionDateElement = document.getElementById("version-date"); + const versionNumberElement = document.getElementById("version"); + const versionSizeElement = document.getElementById("version-size"); + const versionDescriptionElement = document.getElementById("version-description"); + + const versionDate = new Date(app.versionDate), + month = versionDate.toUTCString().split(" ")[2], + date = versionDate.getDate(); + const today = new Date(); + const msPerDay = 60 * 60 * 24 * 1000; + const msDifference = today.valueOf() - versionDate.valueOf(); + + // Version date + versionDateElement.textContent = `${month} ${date}, ${versionDate.getFullYear()}`; + if (msDifference <= msPerDay) + versionDateElement.textContent = "Today"; + else if (msDifference <= msPerDay * 2) + versionDateElement.textContent = "Yesterday"; + + // Version number + versionNumberElement.textContent = `Version ${app.version}`; + + // Version size + const units = ["B", "KB", "MB", "GB"]; + var appSize = app.size, i = 0; + while (appSize > 1024) { i++; + appSize = parseFloat(appSize / 1024).toFixed(1); + } + versionSizeElement.textContent = `${appSize} ${units[i]}`; + + // Version description + versionDescriptionElement.innerHTML = formatString(app.versionDescription); + if (versionDescriptionElement.scrollHeight > versionDescriptionElement.clientHeight) + versionDescriptionElement.insertAdjacentHTML("beforeend", more); + + // + // Permissions + const permissions = document.getElementById("permissions"); + + // If permissions specified + if (app.permissions) + // Remove placeholder permission + permissions.querySelector(".permission").remove(); + else return; + + app.permissions?.forEach(permission => { + var permissionType, icon; + switch (permission.type) { + case "background-audio": + permissionType = "Background Audio"; + icon = "volume-up-fill"; + break; + case "background-fetch": + permissionType = "Background Fetch"; + icon = "arrow-repeat" + break; + case "photos": + permissionType = "Photos" + icon = "image-fill"; + break; + default: + permissionType = permission.type.replaceAll("-", " "); + icon = "gear-wide-connected"; + break; + } + + permissions.insertAdjacentHTML("beforeend", ` +
+ +
+

${permissionType}

+

${permission.usageDescription ?? "No description provided."}

+
+
`); + }); } -function nope() { - window.location.replace("index.html"); +function exit() { + window.location.replace(`home.html?source=${sourceURL}`); } \ No newline at end of file diff --git a/js/apps.js b/js/apps.js index ca9d10e..05795de 100644 --- a/js/apps.js +++ b/js/apps.js @@ -1,37 +1,31 @@ -addNavigationBar("All Apps"); +insertNavigationBar("All Apps"); -fetch(sourceURL) - .then(response => response.json()) - .then(json => { - if (json.tintColor) setTintColor(json.tintColor) +function main(json) { + // Set tab title + document.title = `Apps - ${json.name}`; - document.title = `Apps - ${json.name}`; + // Sort apps in decending order of version date (newest first) + json.apps.sort((a, b) => (new Date(b.versionDate)).valueOf() - (new Date(a.versionDate)).valueOf()); - json.apps.sort((a, b) => (new Date(b.versionDate)).valueOf() - (new Date(a.versionDate)).valueOf()); - json.apps.forEach(app => { - if (app.beta) return; // Ignore beta apps + // Create & insert app items + json.apps.forEach(app => { + if (app.beta) return; // Ignore beta apps - const urls = app.screenshotURLs; - - let html = ` -
`; - html += - appHeaderHTML(app); + let html = ` +
+ ${appHeaderHTML(app) } +

${app.subtitle ?? ""}

`; + if (app.screenshotURLs) { html += ` -

${app.subtitle ?? ""}

`; - if (urls) { - html += ` -
`; - for (let i = 0; i < urls.length, i < 2; i++) html += ` - `; - html += ` -
`; - } +
`; + for (let i = 0; i < app.screenshotURLs.length, i < 2; i++) html += ` + `; html += `
`; + } + html += ` +
`; - document.getElementById("apps").insertAdjacentHTML("beforeend", html); - }); - - waitForAllImagesToLoad(); - }); \ No newline at end of file + document.getElementById("apps").insertAdjacentHTML("beforeend", html); + }); +} \ No newline at end of file diff --git a/js/home.js b/js/home.js index 2dbd6ac..7f67bfb 100644 --- a/js/home.js +++ b/js/home.js @@ -1,64 +1,56 @@ -fetch(sourceURL) - .then(response => response.json()) - .then(json => { - document.querySelector("#news a").href = `news.html?source=${sourceURL}`; - document.querySelector("#apps a").href = `apps.html?source=${sourceURL}`; +function main(json) { + // Set "View All News" link + document.querySelector("#news a").href = `news.html?source=${sourceURL}`; + // Set "View All Apps" link + document.querySelector("#apps a").href = `apps.html?source=${sourceURL}`; - if (json.tintColor) setTintColor(json.tintColor) + // Set tab title + document.title = json.name; + // Set page title + document.getElementById("title").innerText = json.name; - document.title = json.name; - document.getElementById("title").innerText = json.name; + // + // News + if (json.news && json.news.length >= 1) { + // Sort news in decending order of date (latest first) + json.news.sort((a, b) => // If b < a + (new Date(b.date)).valueOf() - (new Date(a.date)).valueOf()); - // Sort apps in descending order - json.apps.sort((a, b) => { - // If b < a - return (new Date(b.versionDate)).valueOf() - (new Date(a.versionDate)).valueOf(); - }); + if (json.news.length == 1) { + document.getElementById("news-items").insertAdjacentHTML("beforeend", newsItemHTML(json.news[0], true)); + document.getElementById("news-items").classList.add("one"); + } else for (let i = 0; i < 5 && i < json.news.length; i++) + document.getElementById("news-items").insertAdjacentHTML("beforeend", newsItemHTML(json.news[i], true)); + } else document.getElementById("news").remove(); - if (json.news && json.news.length >= 1) { - // Sort news in decending order (latest first) - json.news.sort((a, b) => (new Date(b.date)).valueOf() - (new Date(a.date)).valueOf()); + // Sort apps in descending order of version date + json.apps.sort((a, b) => (new Date(b.versionDate)).valueOf() - (new Date(a.versionDate)).valueOf()); + + // + // Featured apps + let count = 1; + json.apps.forEach(app => { + // Max: 3 featured apps if not specified + if (count > 3) return; - // News - if (json.news.length == 1) { - document.getElementById("news-items").insertAdjacentHTML("beforeend", newsItemHTML(json.news[0], json.apps, true)); - document.getElementById("news-items").classList.add("one"); - } else if (json.news.length > 1) { - for (let i = 0; i < 5 && i < json.news.length; i++) { - document.getElementById("news-items").insertAdjacentHTML("beforeend", newsItemHTML(json.news[i], json.apps, true)); - } - } - } else { - document.getElementById("news").remove(); - } + // Ignore beta apps + if (app.beta) return; - // Apps - let count = 1; - json.apps.forEach(app => { - // Max: 3 featured apps if not specified - if (count > 3) return; + // If there are featured apps, ignore non-featured apps + if (json.featuredApps && !json.featuredApps.includes(app.bundleIdentifier)) return; - // Ignore beta apps - if (app.beta) return; + document.getElementById("apps").insertAdjacentHTML("beforeend", appHeaderHTML(app)); - // If there are featured apps, ignore non-featured apps - if (json.featuredApps && !json.featuredApps.includes(app.bundleIdentifier)) return; - - document.getElementById("apps").insertAdjacentHTML("beforeend", appHeaderHTML(app)); - - count++; - }); - - var description = formatString(json.description); - if (description) { - document.getElementById("about").insertAdjacentHTML("beforeend", ` -
-

${description}

-
- `); - } else { - document.getElementById("about").remove(); - } - - waitForAllImagesToLoad(); + count++; }); + + // + // About + var description = formatString(json.description); + if (description) document.getElementById("about").insertAdjacentHTML("beforeend", ` +
+

${description}

+
+ `); + else document.getElementById("about").remove(); +} \ No newline at end of file diff --git a/js/index.js b/js/index.js index 32338d4..ecc16dd 100644 --- a/js/index.js +++ b/js/index.js @@ -1,16 +1,17 @@ -const textField = document.querySelector("input"); +(function main() { + // If source specified, go straight to home page + if (urlSearchParams.has('source') && sourceURL.match(urlRegex)) + window.location.replace(`home.html?source=${sourceURL}`); -textField.addEventListener("keypress", function (event) { - // If the user presses the "Enter" key on the keyboard - if (event.key === "Enter") { - event.preventDefault(); + const textField = document.querySelector("input"); + textField.addEventListener("keypress", function (event) { + if (event.key === "Enter") { + event.preventDefault(); - const url = textField.value; - const urlRegex = /(https?:\/\/[^ ]*)/g; - - if (!url.match(urlRegex)) - alert("Invalid URL."); - else - window.location.replace(`home.html?source=${url}`); - } -}); \ No newline at end of file + const url = textField.value; + if (!url.match(urlRegex)) + alert("Invalid URL."); + else window.location.replace(`home.html?source=${url}`); + } + }); +})(); \ No newline at end of file diff --git a/js/main.js b/js/main.js index 44c2963..71cdcdf 100644 --- a/js/main.js +++ b/js/main.js @@ -1,50 +1,23 @@ -const urlSearchParams = new URLSearchParams(window.location.search); -const sourceURL = urlSearchParams.get('source'); +(function () { + // If no source or source is not a URL + if (!urlSearchParams.has('source') || !sourceURL.match(urlRegex)) + window.location.replace("index.html"); + insertAddToAltStoreBanner(); +})() -// If no source -if (!urlSearchParams.has('source') || !sourceURL) { - alert(`No source provided.`); - window.location.replace("index.html"); -} +fetch(sourceURL, { + cache: "force-cache" +}) + .then(response => response.json()) + .then(json => { + // Set tint color + if (json.tintColor) setTintColor(json.tintColor); -const urlRegex = /(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig; // https://stackoverflow.com/a/8943487 -function formatString(string) { - if (!string) return undefined; - - // URLs - const urlArray = string.match(urlRegex); - const urlSet = [...new Set(urlArray)]; // Converting to set to remove duplicates - urlSet.forEach(url => string = string.replaceAll(url, `${url}`)); - - // New lines - return string.replaceAll("\n", "
"); -} - -// If source is not a URL -if (!sourceURL.match(urlRegex)) { - alert("Invalid URL."); - window.location.replace("index.html"); -} - -// Back button -document.getElementById("back")?.addEventListener("click", () => history.back(1)); - -// Add to AltStore banner -document.getElementById("top")?.insertAdjacentHTML("afterbegin", ` -
- altstore-icon -
-
-

AltStore

-

- Add this source to AltStore to receive app updates (requires AltStore beta) -

-
- - - -
-
`); + setApps(json.apps); + main(json); + waitForAllImagesToLoad(); + }) + .catch(error => console.error("An error occurred.", error)); function waitForAllImagesToLoad() { const allImages = document.querySelectorAll("img"); @@ -54,89 +27,15 @@ function waitForAllImagesToLoad() { // New img element that won't be rendered to the DOM var newImage = document.createElement("img"); // Attach load listener - newImage.addEventListener("load", imageLoaded); + newImage.addEventListener("load", loaded); // Set src newImage.src = image.src; - }) + }); - function imageLoaded() { + function loaded() { if (++count == allImages.length) { document.querySelector("body").classList.remove("loading"); document.getElementById("loading").remove(); } } -} - -function setTintColor(color) { - document.querySelector(':root').style.setProperty("--accent-color", `#${color}`); -} - -function addNavigationBar(title) { - document.getElementById("top").insertAdjacentHTML("beforeend", ` - `); - document.getElementById("back")?.addEventListener("click", () => history.back(1)); -} - -function newsItemHTML(news, apps, minimal) { - let html = ` -
`; - - if (news.url) html += ` - `; - html += ` -
-
-

${news.title}

-

${news.caption}

-
`; - if (news.imageURL && !minimal) html += ` -
- -
`; - html += ` -
`; - if (news.url) html += - "
"; - - if (news.appID && !minimal) { - const app = apps.find(app => app.bundleIdentifier == news.appID); - if (app) html += appHeaderHTML(app); - } - - html += "
"; - - return html; -} - -function appHeaderHTML(app) { - return ` -
-
-
- -
-
-

${app.name}

-

${app.developerName}

-
- - - -
-
-
-
-
`; } \ No newline at end of file diff --git a/js/news.js b/js/news.js index fb3462b..c27bd7e 100644 --- a/js/news.js +++ b/js/news.js @@ -1,16 +1,12 @@ -addNavigationBar("All News"); +insertNavigationBar("All News"); -fetch(sourceURL) - .then(response => response.json()) - .then(json => { - if (json.tintColor) setTintColor(json.tintColor) +function main(json) { + // Set tab title + document.title = `News - ${json.name}`; - document.title = `News - ${json.name}`; + // Sort news by latest + json.news.sort((a, b) => (new Date(b.date)).valueOf() - (new Date(a.date)).valueOf()); - json.news.sort((a, b) => (new Date(b.date)).valueOf() - (new Date(a.date)).valueOf()); - json.news.forEach(news => - document.getElementById("news").insertAdjacentHTML("beforeend", newsItemHTML(news, json.apps)) - ); - - waitForAllImagesToLoad(); - }); \ No newline at end of file + // Create & insert news items + json.news.forEach(news => document.getElementById("news").insertAdjacentHTML("beforeend", newsItemHTML(news))); +} \ No newline at end of file diff --git a/js/shared.js b/js/shared.js new file mode 100644 index 0000000..a226e04 --- /dev/null +++ b/js/shared.js @@ -0,0 +1,109 @@ +const urlSearchParams = new URLSearchParams(window.location.search); +const sourceURL = urlSearchParams.get('source'); +// https://stackoverflow.com/a/8943487 +const urlRegex = /(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig; + +(function (global) { + var apps; + global.setApps = array => + apps = array; + global.getAppWithBundleId = bundleId => + apps?.find(app => app.bundleIdentifier == bundleId) ?? undefined; + + setUpBackButton(); +})(this); + +const newsItemHTML = (news, minimal = false) => ` +
${news.url ? + "" : ""} +
+
+

${news.title}

+

${news.caption}

+
${news.imageURL && !minimal ? + "
" + + "" + + "
" : ""} +
${news.url ? + "
" : ""} ${news.appID && !minimal ? + appHeaderHTML(getAppWithBundleId(news.appID)) ?? "" : ""} +
`; + +const appHeaderHTML = app => app ? ` +
+
+
+ +
+
+

${app.name}

+

${app.developerName}

+
+ + + +
+
+
+
+
` : undefined; + +function formatString(string) { + if (!string) return undefined; + + // URLs + const urlArray = string.match(urlRegex); + const urlSet = [...new Set(urlArray)]; // Converting to set to remove duplicates + urlSet.forEach(url => string = string.replaceAll(url, `${url}`)); + + // New lines + return string.replaceAll("\n", "
"); +} + +function insertAddToAltStoreBanner() { + document.getElementById("top")?.insertAdjacentHTML("afterbegin", ` +
+ altstore-icon +
+
+

AltStore

+

+ Add this source to AltStore to receive app updates (requires AltStore beta) +

+
+ + + +
+
`); +} + +function insertNavigationBar(title) { + document.getElementById("top")?.insertAdjacentHTML("beforeend", ` + `); + setUpBackButton(); +} + +function setTintColor(color) { + document.querySelector(':root')?.style.setProperty("--accent-color", `#${color}`); +} + +function setUpBackButton() { + document.getElementById("back")?.addEventListener("click", () => history.back(1)); +} + +const $ = selector => selector.startsWith("#") && !selector.includes(".") && !selector.includes(" ") + ? document.getElementById(selector.substring(1)) + : document.querySelectorAll(selector); \ No newline at end of file diff --git a/news.html b/news.html index d2c2903..6158f99 100644 --- a/news.html +++ b/news.html @@ -4,9 +4,9 @@ - - + +
@@ -18,7 +18,8 @@
- + + \ No newline at end of file