From 8ed7aa4bc18446a327619eb3176d0eb9f68e6d23 Mon Sep 17 00:00:00 2001 From: foxster-mp4 Date: Mon, 17 Jul 2023 19:16:44 -0700 Subject: [PATCH] Refactor --- app.html | 15 ++- apps.html | 15 ++- css/app.css | 8 ++ css/apps.css | 8 ++ css/news.css | 8 ++ css/search.css | 8 ++ css/{shared.css => style.css} | 80 ++++++++++++++++ css/uibanner.css | 69 -------------- index.html | 15 ++- js/app.js | 158 +++++++++++++++++--------------- js/apps.js | 18 +++- js/components/AltStoreBanner.js | 25 +++++ js/components/AppHeader.js | 28 ++++++ js/components/NavigationBar.js | 22 +++++ js/components/NewsItem.js | 25 +++++ js/index.js | 27 ++++-- js/main.js | 109 +++++++++++++--------- js/news.js | 18 +++- js/search.js | 10 ++ js/shared.js | 135 --------------------------- js/utilities.js | 74 +++++++++++++++ news.html | 15 ++- search.html | 13 ++- 23 files changed, 546 insertions(+), 357 deletions(-) rename css/{shared.css => style.css} (82%) delete mode 100644 css/uibanner.css create mode 100644 js/components/AltStoreBanner.js create mode 100644 js/components/AppHeader.js create mode 100644 js/components/NavigationBar.js create mode 100644 js/components/NewsItem.js delete mode 100644 js/shared.js create mode 100644 js/utilities.js diff --git a/app.html b/app.html index 1ef575a..06ceea0 100644 --- a/app.html +++ b/app.html @@ -1,11 +1,18 @@ + + - - + @@ -113,8 +120,6 @@ - - - + \ No newline at end of file diff --git a/apps.html b/apps.html index e29f8b3..27f4bfb 100644 --- a/apps.html +++ b/apps.html @@ -1,11 +1,18 @@ + + - - + @@ -18,8 +25,6 @@
- - - + \ No newline at end of file diff --git a/css/app.css b/css/app.css index 01543e3..2761ec9 100644 --- a/css/app.css +++ b/css/app.css @@ -1,3 +1,11 @@ +/* + app.css + altsource-viewer (https://github.com/therealFoxster/altsource-viewer) + + Copyright (c) 2023 Foxster. + MIT License. +*/ + a { color: var(--app-tint-color) } diff --git a/css/apps.css b/css/apps.css index bd428e6..d84b5d4 100644 --- a/css/apps.css +++ b/css/apps.css @@ -1,3 +1,11 @@ +/* + apps.css + altsource-viewer (https://github.com/therealFoxster/altsource-viewer) + + Copyright (c) 2023 Foxster. + MIT License. +*/ + #main { padding-top: 7rem; } diff --git a/css/news.css b/css/news.css index 6c729f8..b59aa77 100644 --- a/css/news.css +++ b/css/news.css @@ -1,3 +1,11 @@ +/* + news.css + altsource-viewer (https://github.com/therealFoxster/altsource-viewer) + + Copyright (c) 2023 Foxster. + MIT License. +*/ + #main { padding-top: 8rem; } diff --git a/css/search.css b/css/search.css index cf88f87..a64c2dc 100644 --- a/css/search.css +++ b/css/search.css @@ -1,3 +1,11 @@ +/* + search.css + altsource-viewer (https://github.com/therealFoxster/altsource-viewer) + + Copyright (c) 2023 Foxster. + MIT License. +*/ + #main { padding-top: 2rem; } diff --git a/css/shared.css b/css/style.css similarity index 82% rename from css/shared.css rename to css/style.css index d5861c5..9b3b882 100644 --- a/css/shared.css +++ b/css/style.css @@ -1,3 +1,11 @@ +/* + style.css + altsource-viewer (https://github.com/therealFoxster/altsource-viewer) + + Copyright (c) 2023 Foxster. + MIT License. +*/ + @import url("https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.4/font/bootstrap-icons.css"); :root { @@ -421,4 +429,76 @@ a>button { .small.badge { font-size: 8px; +} + +/* uibanner */ + +.uibanner .icon { + max-width: 30px; + border-radius: 7px; + border: 0.75px solid rgba(0, 0, 0, 0.1); +} + +.uibanner { + z-index: 5; + display: flex; + align-items: center; + justify-content: center; + padding-bottom: 1px; + border-bottom: 0.1px solid var(--color-separator); +} + +.uibanner { + background: white; +} + +.uibanner>.icon { + margin-left: 14px; + display: flex; +} + +.uibanner>.content { + min-height: 28px; + width: 100%; + margin-left: 8px; + padding: 8px 16px 8px 0px; + display: flex; + justify-content: space-between; + align-items: center; +} + +.uibanner>.content>.text-container>.title-text { + padding-bottom: 0 !important; + font-weight: 600; + font-size: 12.95px !important; +} + +.uibanner>.content>.text-container>.detail-text { + padding-top: 0 !important; + font-size: 11px !important; + font-weight: 400; + line-height: 12px !important; + opacity: 0.55; +} + +.uibanner>.content button { + min-width: 68px !important; + padding: 5px 13px; + font-size: 15px; + font-weight: 600; + text-transform: uppercase; + border: none; + border-radius: 20px; + color: white; + background-color: rgb(0, 122, 254); + cursor: pointer; +} + +.uibanner>.content a { + margin-left: 6px; + text-decoration: none; + color: unset; + font-weight: 600; + + color: white; } \ No newline at end of file diff --git a/css/uibanner.css b/css/uibanner.css deleted file mode 100644 index 6d0ae8e..0000000 --- a/css/uibanner.css +++ /dev/null @@ -1,69 +0,0 @@ -.uibanner .icon { - max-width: 30px; - border-radius: 7px; - border: 0.75px solid rgba(0, 0, 0, 0.1); -} - -.uibanner { - z-index: 5; - display: flex; - align-items: center; - justify-content: center; - padding-bottom: 1px; - border-bottom: 0.1px solid var(--color-separator); -} - -.uibanner { - background: white; -} - -.uibanner>.icon { - margin-left: 14px; - display: flex; -} - -.uibanner>.content { - min-height: 28px; - width: 100%; - margin-left: 8px; - padding: 8px 16px 8px 0px; - display: flex; - justify-content: space-between; - align-items: center; -} - -.uibanner>.content>.text-container>.title-text { - padding-bottom: 0 !important; - font-weight: 600; - font-size: 12.95px !important; -} - -.uibanner>.content>.text-container>.detail-text { - padding-top: 0 !important; - font-size: 11px !important; - font-weight: 400; - line-height: 12px !important; - opacity: 0.55; -} - -.uibanner>.content button { - min-width: 68px !important; - padding: 5px 13px; - font-size: 15px; - font-weight: 600; - text-transform: uppercase; - border: none; - border-radius: 20px; - color: white; - background-color: rgb(0, 122, 254); - cursor: pointer; -} - -.uibanner>.content a { - margin-left: 6px; - text-decoration: none; - color: unset; - font-weight: 600; - - color: white; -} \ No newline at end of file diff --git a/index.html b/index.html index c73377f..cd3cc27 100644 --- a/index.html +++ b/index.html @@ -1,11 +1,18 @@ + + - - +
@@ -39,8 +46,6 @@
- - - + \ No newline at end of file diff --git a/js/app.js b/js/app.js index 93b5fd3..40b7a76 100644 --- a/js/app.js +++ b/js/app.js @@ -1,3 +1,14 @@ +// +// app.js +// altsource-viewer (https://github.com/therealFoxster/altsource-viewer) +// +// Copyright (c) 2023 Foxster. +// MIT License. +// + +import { urlSearchParams, formatString, sourceURL } from "./utilities.js"; +import { main } from "./main.js"; + if (!urlSearchParams.has('id')) exit(); const bundleId = urlSearchParams.get('id'); @@ -23,7 +34,7 @@ const bundleId = urlSearchParams.get('id'); } })(); -function main(json) { +main((json) => { const app = getAppWithBundleId(bundleId); if (!app) exit(); @@ -74,7 +85,7 @@ function main(json) { `; - this.revealTruncatedText = moreButton => { + window.revealTruncatedText = moreButton => { const textId = moreButton.parentNode.id; const text = document.getElementById(textId); text.style.display = "block"; @@ -125,7 +136,8 @@ function main(json) { // Version size const units = ["B", "KB", "MB", "GB"]; var appSize = app.size, i = 0; - while (appSize > 1024) { i++; + while (appSize > 1024) { + i++; appSize = parseFloat(appSize / 1024).toFixed(1); } versionSizeElement.textContent = `${appSize} ${units[i]}`; @@ -138,82 +150,82 @@ function main(json) { // // Permissions const permissions = document.getElementById("permissions"); - + // If permissions specified if (app.permissions) { // Remove placeholder permission permissions.querySelector(".permission").remove(); - + app.permissions?.forEach(permission => { var permissionType, icon; switch (permission.type) { - // AltStore-supported permissions - 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; - // Additional permissions - case "camera": - permissionType = "Camera" - icon = "camera-fill"; - break; - case "music": - permissionType = "Music Library" - icon = "music-note-list"; - break; - case "location": - permissionType = "Location" - icon = "geo-alt-fill"; - break; - case "microphone": - permissionType = "Microphone" - icon = "mic-fill"; - break; - case "contacts": - permissionType = "Contacts" - icon = "people-fill"; - break; - case "bluetooth": - permissionType = "Bluetooth" - icon = "bluetooth"; - break; - case "faceid": - permissionType = "Face ID" - icon = "person-bounding-box"; - break; - case "network": - permissionType = "Network" - icon = "wifi"; - break; - case "calendar": - case "calendars": - permissionType = "Calendar" - icon = "calendar-date"; - break; - case "reminders": - permissionType = "Reminders" - icon = "list-ul"; - break; - case "siri": - permissionType = "Siri" - icon = "gear-wide-connected"; - break; - case "speech-recognition": - permissionType = "Speech Recognition" - icon = "soundwave"; - break; - default: - permissionType = permission.type.replaceAll("-", " "); - icon = "gear-wide-connected"; - break; + // AltStore-supported permissions + 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; + // Additional permissions + case "camera": + permissionType = "Camera" + icon = "camera-fill"; + break; + case "music": + permissionType = "Music Library" + icon = "music-note-list"; + break; + case "location": + permissionType = "Location" + icon = "geo-alt-fill"; + break; + case "microphone": + permissionType = "Microphone" + icon = "mic-fill"; + break; + case "contacts": + permissionType = "Contacts" + icon = "people-fill"; + break; + case "bluetooth": + permissionType = "Bluetooth" + icon = "bluetooth"; + break; + case "faceid": + permissionType = "Face ID" + icon = "person-bounding-box"; + break; + case "network": + permissionType = "Network" + icon = "wifi"; + break; + case "calendar": + case "calendars": + permissionType = "Calendar" + icon = "calendar-date"; + break; + case "reminders": + permissionType = "Reminders" + icon = "list-ul"; + break; + case "siri": + permissionType = "Siri" + icon = "gear-wide-connected"; + break; + case "speech-recognition": + permissionType = "Speech Recognition" + icon = "soundwave"; + break; + default: + permissionType = permission.type.replaceAll("-", " "); + icon = "gear-wide-connected"; + break; } permissions.insertAdjacentHTML("beforeend", `
@@ -235,7 +247,7 @@ function main(json) { sourceTitle.innerText = json.name; sourceContainer.href = `index.html?source=${sourceURL}`; sourceSubtitle.innerText = json.description ?? "Tap to get started"; -} +}); function exit() { window.location.replace(`index.html?source=${sourceURL}`); diff --git a/js/apps.js b/js/apps.js index b8778b5..f579778 100644 --- a/js/apps.js +++ b/js/apps.js @@ -1,6 +1,18 @@ +// +// apps.js +// altsource-viewer (https://github.com/therealFoxster/altsource-viewer) +// +// Copyright (c) 2023 Foxster. +// MIT License. +// + +import { insertNavigationBar } from "./utilities.js"; +import { AppHeader } from "./components/AppHeader.js"; +import { main } from "./main.js"; + insertNavigationBar("All Apps"); -function main(json) { +main((json) => { // Set tab title document.title = `Apps - ${json.name}`; @@ -13,7 +25,7 @@ function main(json) { let html = `
- ${appHeaderHTML(app) } + ${AppHeader(app)}

${app.subtitle ?? ""}

`; if (app.screenshotURLs) { html += ` @@ -28,4 +40,4 @@ function main(json) { document.getElementById("apps").insertAdjacentHTML("beforeend", html); }); -} \ No newline at end of file +}); \ No newline at end of file diff --git a/js/components/AltStoreBanner.js b/js/components/AltStoreBanner.js new file mode 100644 index 0000000..a7aa2d2 --- /dev/null +++ b/js/components/AltStoreBanner.js @@ -0,0 +1,25 @@ +// +// AltStoreBanner.js +// altsource-viewer (https://github.com/therealFoxster/altsource-viewer) +// +// Copyright (c) 2023 Foxster. +// MIT License. +// + +import { sourceURL } from "../utilities.js"; + +export const AltStoreBanner = (sourceName) => ` +
+ altstore-icon +
+
+

AltStore

+

+ Add ${sourceName ? "\"" + sourceName + "\"" : "this source"} to AltStore to receive app updates +

+
+ + + +
+
`; \ No newline at end of file diff --git a/js/components/AppHeader.js b/js/components/AppHeader.js new file mode 100644 index 0000000..4ab7ef0 --- /dev/null +++ b/js/components/AppHeader.js @@ -0,0 +1,28 @@ +// +// AppHeader.js +// altsource-viewer (https://github.com/therealFoxster/altsource-viewer) +// +// Copyright (c) 2023 Foxster. +// MIT License. +// + +import { sourceURL } from "../utilities.js"; + +export const AppHeader = app => app ? ` +
+
+
+ +
+
+

${app.name}

+

${app.developerName}

+
+ + + +
+
+
+
+
` : undefined; \ No newline at end of file diff --git a/js/components/NavigationBar.js b/js/components/NavigationBar.js new file mode 100644 index 0000000..3c9e8db --- /dev/null +++ b/js/components/NavigationBar.js @@ -0,0 +1,22 @@ +// +// NavigationBar.js +// altsource-viewer (https://github.com/therealFoxster/altsource-viewer) +// +// Copyright (c) 2023 Foxster. +// MIT License. +// + +export const NavigationBar = (title) => ` +`; \ No newline at end of file diff --git a/js/components/NewsItem.js b/js/components/NewsItem.js new file mode 100644 index 0000000..3c3cd76 --- /dev/null +++ b/js/components/NewsItem.js @@ -0,0 +1,25 @@ +// +// NewsItem.js +// altsource-viewer (https://github.com/therealFoxster/altsource-viewer) +// +// Copyright (c) 2023 Foxster. +// MIT License. +// + +import { AppHeader } from "./AppHeader.js"; + +export const NewsItem = (news, minimal = false) => ` +
${news.url ? + "" : ""} +
+
+

${news.title}

+

${news.caption}

+
${news.imageURL && !minimal ? + "
" + + "" + + "
" : ""} +
${news.url ? + "
" : ""} ${news.appID && !minimal ? + AppHeader(getAppWithBundleId(news.appID)) ?? "" : ""} +
`; \ No newline at end of file diff --git a/js/index.js b/js/index.js index c6e6eac..337caad 100644 --- a/js/index.js +++ b/js/index.js @@ -1,4 +1,17 @@ -function main(json) { +// +// index.js +// altsource-viewer (https://github.com/therealFoxster/altsource-viewer) +// +// Copyright (c) 2023 Foxster. +// MIT License. +// + +import { sourceURL, formatString } from "./utilities.js"; +import { NewsItem } from "./components/NewsItem.js"; +import { AppHeader } from "./components/AppHeader.js"; +import { main } from "./main.js"; + +main((json) => { // Set "View All News" link document.querySelector("#news a").href = `news.html?source=${sourceURL}`; // Set "View All Apps" link @@ -17,15 +30,15 @@ function main(json) { (new Date(b.date)).valueOf() - (new Date(a.date)).valueOf()); if (json.news.length == 1) { - document.getElementById("news-items").insertAdjacentHTML("beforeend", newsItemHTML(json.news[0], true)); + document.getElementById("news-items").insertAdjacentHTML("beforeend", NewsItem(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)); + document.getElementById("news-items").insertAdjacentHTML("beforeend", NewsItem(json.news[i], true)); } else document.getElementById("news").remove(); // 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; @@ -39,7 +52,7 @@ function main(json) { // 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)); + document.getElementById("apps").insertAdjacentHTML("beforeend", AppHeader(app)); count++; }); @@ -51,6 +64,6 @@ function main(json) {

${description}

- `); + `); else document.getElementById("about").remove(); -} \ No newline at end of file +}); \ No newline at end of file diff --git a/js/main.js b/js/main.js index 68663b5..46e3863 100644 --- a/js/main.js +++ b/js/main.js @@ -1,54 +1,75 @@ -(function () { - // If no source - if (!urlSearchParams.has('source')) - search(); - // If source is not a valid HTTP URL - else if (!isValidHTTPURL(sourceURL)) { - alert("Invalid HTTP URL."); - search(); - } -})(); +// +// main.js +// altsource-viewer (https://github.com/therealFoxster/altsource-viewer) +// +// Copyright (c) 2023 Foxster. +// MIT License. +// -fetch(sourceURL) - .then(response => response.json()) - .then(json => { - // Set tint color - const tintColor = json.tintColor?.replaceAll("#", ""); - if (tintColor) setTintColor(tintColor); +import { urlSearchParams, sourceURL, search, isValidHTTPURL, setTintColor, insertAltStoreBanner, setUpBackButton } from "./utilities.js"; - insertAddToAltStoreBanner(json.name); +export function main(callback) { + (() => { + // If no source + if (!urlSearchParams.has('source')) + search(); + // If source is not a valid HTTP URL + else if (!isValidHTTPURL(sourceURL)) { + alert("Invalid HTTP URL."); + search(); + } - setApps(json.apps); - main(json); - waitForAllImagesToLoad(); - }) - .catch(error => console.error("An error occurred.", error)); + var apps; + window.setApps = array => + apps = array; + window.getAppWithBundleId = bundleId => + apps?.find(app => app.bundleIdentifier == bundleId) ?? undefined; -function waitForAllImagesToLoad() { - const allImages = document.querySelectorAll("img"); - var count = 0; + setUpBackButton(); + })(); - allImages.forEach(image => { - // New img element that won't be rendered to the DOM - var newImage = document.createElement("img"); - // Attach load listener - newImage.addEventListener("load", loaded); - // Set src - newImage.src = image.src; + fetch(sourceURL) + .then(response => response.json()) + .then(json => { + // Set tint color + const tintColor = json.tintColor?.replaceAll("#", ""); + if (tintColor) setTintColor(tintColor); - // Unable to load image - image.addEventListener("error", (event) => { - if (event.target.id == "app-icon") { - event.target.src = "img/generic_app.jpeg"; - } else event.target.remove() - loaded(); + insertAltStoreBanner(json.name); + + setApps(json.apps); + // main(json); + callback(json); + waitForAllImagesToLoad(); + }) + .catch(error => console.error("An error occurred.", error)); + + function waitForAllImagesToLoad() { + const allImages = document.querySelectorAll("img"); + var count = 0; + + allImages.forEach(image => { + // New img element that won't be rendered to the DOM + var newImage = document.createElement("img"); + // Attach load listener + newImage.addEventListener("load", loaded); + // Set src + newImage.src = image.src; + + // Unable to load image + image.addEventListener("error", (event) => { + if (event.target.id == "app-icon") { + event.target.src = "img/generic_app.jpeg"; + } else event.target.remove() + loaded(); + }); }); - }); - function loaded() { - if (++count == allImages.length) { - document.querySelector("body").classList.remove("loading"); - document.getElementById("loading").remove(); + function loaded() { + if (++count == allImages.length) { + document.querySelector("body").classList.remove("loading"); + document.getElementById("loading").remove(); + } } } -} \ No newline at end of file +} diff --git a/js/news.js b/js/news.js index 87ec0df..e0ae2d5 100644 --- a/js/news.js +++ b/js/news.js @@ -1,6 +1,18 @@ +// +// news.js +// altsource-viewer (https://github.com/therealFoxster/altsource-viewer) +// +// Copyright (c) 2023 Foxster. +// MIT License. +// + +import { insertNavigationBar } from "./utilities.js"; +import { NewsItem } from "./components/NewsItem.js"; +import { main } from "./main.js"; + insertNavigationBar("All News"); -function main(json) { +main((json) => { // Set tab title document.title = `News - ${json.name}`; @@ -8,5 +20,5 @@ function main(json) { json.news.sort((a, b) => (new Date(b.date)).valueOf() - (new Date(a.date)).valueOf()); // Create & insert news items - json.news.forEach(news => document.getElementById("news").insertAdjacentHTML("beforeend", newsItemHTML(news))); -} \ No newline at end of file + json.news.forEach(news => document.getElementById("news").insertAdjacentHTML("beforeend", NewsItem(news))); +}); \ No newline at end of file diff --git a/js/search.js b/js/search.js index 015127a..2e45913 100644 --- a/js/search.js +++ b/js/search.js @@ -1,3 +1,13 @@ +// +// search.js +// altsource-viewer (https://github.com/therealFoxster/altsource-viewer) +// +// Copyright (c) 2023 Foxster. +// MIT License. +// + +import { urlSearchParams, sourceURL } from "./utilities.js"; + (function main() { const success = url => window.location.replace(`index.html?source=${url}`); diff --git a/js/shared.js b/js/shared.js deleted file mode 100644 index df357ee..0000000 --- a/js/shared.js +++ /dev/null @@ -1,135 +0,0 @@ -const urlSearchParams = new URLSearchParams(window.location.search); -const sourceURL = urlSearchParams.get('source')?.replaceAll("+", "%2B"); -// 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 insertAddToAltStoreBanner(source) { - document.getElementById("top")?.insertAdjacentHTML("afterbegin", ` -
- altstore-icon -
-
-

AltStore

-

- Add ${source ? "\"" + source + "\"" : "this source"} to AltStore to receive app updates -

-
- - - -
-
`); -} - -function insertNavigationBar(title) { - document.getElementById("top")?.insertAdjacentHTML("beforeend", ` - `); - setUpBackButton(); -} - -// https://stackoverflow.com/a/43467144/19227228 -function isValidHTTPURL(string) { - var url; - try { - url = new URL(string); - } catch (error) { - console.error("An error occurred.", error); - return false; - } - return url.protocol == "http:" || url.protocol == "https:"; -} - -function formatString(string) { - if (!string) return undefined; - - // URLs - const urlArray = string.match(urlRegex); - // const urlSet = [...new Set(urlArray)]; // Converting to set to remove duplicates - var result = ""; - urlArray?.forEach(url => { - string = string.replace(url, `${url}`) - // Remove formatted substring so it won't get formatted again (prevents tag within the href attribute another tag) - let endIndexOfClosingTag = string.indexOf("") + 4; - let formattedSubstring = string.substring(0, endIndexOfClosingTag); - result += formattedSubstring; - string = string.replace(formattedSubstring, ""); - }); - - result += string; - - // New lines - return result.replaceAll("\n", "
"); -} - -function setTintColor(color) { - document.querySelector(':root')?.style.setProperty("--accent-color", `#${color}`); -} - -function setUpBackButton() { - document.getElementById("back")?.addEventListener("click", () => history.back(1)); -} - -function search() { - window.location.replace("search.html"); -} - -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/js/utilities.js b/js/utilities.js new file mode 100644 index 0000000..6ee05aa --- /dev/null +++ b/js/utilities.js @@ -0,0 +1,74 @@ +// +// utilities.js +// altsource-viewer (https://github.com/therealFoxster/altsource-viewer) +// +// Copyright (c) 2023 Foxster. +// MIT License. +// + +import { AltStoreBanner } from "./components/AltStoreBanner.js"; +import { NavigationBar } from "./components/NavigationBar.js"; + +export const urlSearchParams = new URLSearchParams(window.location.search); +export const sourceURL = urlSearchParams.get('source')?.replaceAll("+", "%2B"); +// https://stackoverflow.com/a/8943487 +export const urlRegex = /(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig; + +export function insertAltStoreBanner(sourceName) { + document.getElementById("top")?.insertAdjacentHTML("afterbegin", AltStoreBanner(sourceName)); +} + +export function insertNavigationBar(title) { + document.getElementById("top")?.insertAdjacentHTML("beforeend", NavigationBar(title)); + setUpBackButton(); +} + +// https://stackoverflow.com/a/43467144/19227228 +export function isValidHTTPURL(string) { + var url; + try { + url = new URL(string); + } catch (error) { + console.error("An error occurred.", error); + return false; + } + return url.protocol == "http:" || url.protocol == "https:"; +} + +export function formatString(string) { + if (!string) return undefined; + + // URLs + const urlArray = string.match(urlRegex); + // const urlSet = [...new Set(urlArray)]; // Converting to set to remove duplicates + var result = ""; + urlArray?.forEach(url => { + string = string.replace(url, `${url}`) + // Remove formatted substring so it won't get formatted again (prevents tag within the href attribute another tag) + let endIndexOfClosingTag = string.indexOf("") + 4; + let formattedSubstring = string.substring(0, endIndexOfClosingTag); + result += formattedSubstring; + string = string.replace(formattedSubstring, ""); + }); + + result += string; + + // New lines + return result.replaceAll("\n", "
"); +} + +export function setTintColor(color) { + document.querySelector(':root')?.style.setProperty("--accent-color", `#${color}`); +} + +export function setUpBackButton() { + document.getElementById("back")?.addEventListener("click", () => history.back(1)); +} + +export function search() { + window.location.replace("search.html"); +} + +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 da3168a..ae88805 100644 --- a/news.html +++ b/news.html @@ -1,11 +1,18 @@ + + - - + @@ -18,8 +25,6 @@
- - - + \ No newline at end of file diff --git a/search.html b/search.html index fe8f3c5..73e6a13 100644 --- a/search.html +++ b/search.html @@ -1,10 +1,18 @@ + + - + AltSource Viewer @@ -68,7 +76,6 @@
- - + \ No newline at end of file