mirror of
https://github.com/driftywinds/driftywinds.github.io.git
synced 2025-12-19 11:03:32 +00:00
Update directory structure
This commit is contained in:
36
view/all-apps/all-apps.css
Normal file
36
view/all-apps/all-apps.css
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
all-apps.css
|
||||
altsource-viewer (https://github.com/therealFoxster/altsource-viewer)
|
||||
|
||||
Copyright (c) 2023 Foxster.
|
||||
MIT License.
|
||||
*/
|
||||
|
||||
#main {
|
||||
padding-top: 7rem;
|
||||
}
|
||||
|
||||
#apps .app-container {
|
||||
margin: 1em 1rem 3.25em 1rem;
|
||||
}
|
||||
|
||||
#apps .app-container:last-of-type {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
.screenshots {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
.screenshots:last-of-type {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
.screenshot {
|
||||
max-width: 48%;
|
||||
border-radius: 4px;
|
||||
border: 0.75px solid rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
43
view/all-apps/all-apps.js
Normal file
43
view/all-apps/all-apps.js
Normal file
@@ -0,0 +1,43 @@
|
||||
//
|
||||
// all-apps.js
|
||||
// altsource-viewer (https://github.com/therealFoxster/altsource-viewer)
|
||||
//
|
||||
// Copyright (c) 2023 Foxster.
|
||||
// MIT License.
|
||||
//
|
||||
|
||||
import { insertNavigationBar } from "../../common/modules/utilities.js";
|
||||
import { AppHeader } from "../../common/components/AppHeader.js";
|
||||
import { main } from "../../common/modules/main.js";
|
||||
|
||||
insertNavigationBar("All Apps");
|
||||
|
||||
main((json) => {
|
||||
// Set tab title
|
||||
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());
|
||||
|
||||
// Create & insert app items
|
||||
json.apps.forEach(app => {
|
||||
if (app.beta) return; // Ignore beta apps
|
||||
|
||||
let html = `
|
||||
<div class="app-container">
|
||||
${AppHeader(app, "..")}
|
||||
<p style="text-align: center; font-size: 0.9em;">${app.subtitle ?? ""}</p>`;
|
||||
if (app.screenshotURLs) {
|
||||
html += `
|
||||
<div class="screenshots">`;
|
||||
for (let i = 0; i < app.screenshotURLs.length, i < 2; i++) if (app.screenshotURLs[i]) html += `
|
||||
<img src="${app.screenshotURLs[i]}" class="screenshot">`;
|
||||
html += `
|
||||
</div>`;
|
||||
}
|
||||
html += `
|
||||
</div>`;
|
||||
|
||||
document.getElementById("apps").insertAdjacentHTML("beforeend", html);
|
||||
});
|
||||
});
|
||||
30
view/all-apps/index.html
Normal file
30
view/all-apps/index.html
Normal file
@@ -0,0 +1,30 @@
|
||||
<!--
|
||||
all-apps/index.html
|
||||
altsource-viewer (https://github.com/therealFoxster/altsource-viewer)
|
||||
|
||||
Copyright (c) 2023 Foxster.
|
||||
MIT License.
|
||||
-->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" href="../../common/style.css">
|
||||
<link rel="stylesheet" href="all-apps.css">
|
||||
</head>
|
||||
<body class="loading">
|
||||
<div id="loading">
|
||||
<img src="../../common/assets/img/loading.gif" alt="loading">
|
||||
<p>Loading</p>
|
||||
</div>
|
||||
<!-- Add to AltStore banner & navigation bar -->
|
||||
<div id="top"></div>
|
||||
<div id="main">
|
||||
<div id="apps"></div>
|
||||
</div>
|
||||
<script src="all-apps.js" type="module"></script>
|
||||
</body>
|
||||
</html>
|
||||
248
view/app/app.css
Normal file
248
view/app/app.css
Normal file
@@ -0,0 +1,248 @@
|
||||
/*
|
||||
app.css
|
||||
altsource-viewer (https://github.com/therealFoxster/altsource-viewer)
|
||||
|
||||
Copyright (c) 2023 Foxster.
|
||||
MIT License.
|
||||
*/
|
||||
|
||||
a {
|
||||
color: var(--app-tint-color)
|
||||
}
|
||||
|
||||
/* Main */
|
||||
|
||||
#main {
|
||||
padding: unset;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#main .item {
|
||||
margin-top: 30%;
|
||||
margin-bottom: 0;
|
||||
padding: 1em;
|
||||
}
|
||||
|
||||
#nav-bar #title,
|
||||
#nav-bar .install {
|
||||
transition: opacity 0.25s ease-in-out;
|
||||
}
|
||||
|
||||
#nav-bar #back-container {
|
||||
min-width: 78px;
|
||||
}
|
||||
|
||||
/* IPA install & download */
|
||||
|
||||
.ipa {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.ipa #download {
|
||||
position: absolute;
|
||||
margin-top: 36px; /* 32px button height + 4px gap */
|
||||
font-size: 0.65em;
|
||||
font-weight: 450;
|
||||
}
|
||||
|
||||
/* Preview */
|
||||
|
||||
#preview {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#preview #subtitle {
|
||||
text-align: center;
|
||||
font-size: 0.9em;
|
||||
margin: 0 1em;
|
||||
}
|
||||
|
||||
#preview .header {
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
||||
#preview #screenshots {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
overflow: scroll;
|
||||
padding-right: 1em;
|
||||
}
|
||||
|
||||
#preview #screenshots>img {
|
||||
max-width: 70%;
|
||||
margin-left: 1em;
|
||||
border-radius: 0.5em;
|
||||
border: 0.75px solid rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
#preview #description {
|
||||
margin: 1em;
|
||||
-webkit-line-clamp: 5;
|
||||
line-clamp: 5;
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
word-wrap: break-word
|
||||
}
|
||||
|
||||
/* What's new */
|
||||
|
||||
#whats-new,
|
||||
#permissions,
|
||||
#source {
|
||||
padding: 1em;
|
||||
}
|
||||
|
||||
#whats-new .header,
|
||||
#permissions .header,
|
||||
#source .header {
|
||||
margin: 0.35em 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
#whats-new .header>p {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
#whats-new #version-date {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
#whats-new #version-description {
|
||||
-webkit-line-clamp: 3;
|
||||
line-clamp: 3;
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
word-wrap: break-word
|
||||
}
|
||||
|
||||
/* Permissions */
|
||||
|
||||
#permissions .permission {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
gap: 0.75em;
|
||||
margin: 0.5em 0;
|
||||
}
|
||||
|
||||
#permissions .permission i {
|
||||
font-size: 1.55em;
|
||||
color: var(--app-tint-color);
|
||||
}
|
||||
|
||||
#permissions .permission .title {
|
||||
font-weight: 550;
|
||||
}
|
||||
|
||||
#permissions .permission .description {
|
||||
font-size: 0.9em;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
#permission-containers {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1.75em;
|
||||
margin-top: 1em;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
|
||||
.permission-icon {
|
||||
color: var(--app-tint-color) !important;
|
||||
font-size: 2em;
|
||||
}
|
||||
|
||||
.permission-container {
|
||||
border-radius: 1.5em;
|
||||
padding: 1.25em;
|
||||
box-shadow: 0px 4px 10px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
.permission-container-header {
|
||||
text-align: center;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
|
||||
.permission-container p.description {
|
||||
opacity: 0.5;
|
||||
line-height: 1.5em;
|
||||
}
|
||||
|
||||
.permission-container p {
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
.permission-container b {
|
||||
font-size: 1.25em;
|
||||
}
|
||||
|
||||
.permission-items {
|
||||
margin: 0.5em 0;
|
||||
display: grid;
|
||||
grid-template-columns: 49.25% 49.25%;
|
||||
row-gap: 4px;
|
||||
}
|
||||
|
||||
.permission-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
width: fit-content;
|
||||
font-size: 0.85em;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.permission-item i {
|
||||
font-size: 1.5em !important;
|
||||
}
|
||||
|
||||
/* Source */
|
||||
#source {
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
#source .row {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.15em;
|
||||
/* justify-content: space-between; */
|
||||
/* margin: 1em 0; */
|
||||
}
|
||||
|
||||
#source .container {
|
||||
color: unset;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin: 0.55em 0;
|
||||
}
|
||||
|
||||
#source .row>.row-title {
|
||||
font-size: 1.05em;
|
||||
color: var(--app-tint-color) !important;
|
||||
}
|
||||
|
||||
#source .bi {
|
||||
-webkit-text-stroke: 0.25px;
|
||||
color: var(--app-tint-color);
|
||||
}
|
||||
|
||||
#source .row>.row-subtitle {
|
||||
color: unset;
|
||||
font-size: 0.9em;
|
||||
opacity: 0.5;
|
||||
-webkit-line-clamp: 3;
|
||||
line-clamp: 3;
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
word-wrap: break-word
|
||||
}
|
||||
227
view/app/app.js
Normal file
227
view/app/app.js
Normal file
@@ -0,0 +1,227 @@
|
||||
//
|
||||
// app.js
|
||||
// altsource-viewer (https://github.com/therealFoxster/altsource-viewer)
|
||||
//
|
||||
// Copyright (c) 2023 Foxster.
|
||||
// MIT License.
|
||||
//
|
||||
|
||||
import { urlSearchParams, sourceURL } from "../../common/modules/constants.js";
|
||||
import { formatString, insertSpaceInCamelString, insertSpaceInSnakeString, formatVersionDate, open } from "../../common/modules/utilities.js";
|
||||
import { main } from "../../common/modules/main.js";
|
||||
import { AppPermissionItem } from "../../common/components/AppPermissionItem.js";
|
||||
// import { privacy, entitlements, legacyPermissions } from "../../modules/constants.js";
|
||||
|
||||
// Dynamic imports (https://stackoverflow.com/a/76845572/19227228)
|
||||
const { default: privacy } = await import("../../common/assets/privacy.json", { assert: { type: "json" } })
|
||||
const { default: entitlements } = await import("../../common/assets/entitlements.json", { assert: { type: "json" } })
|
||||
const { default: legacyPermissions } = await import("../../common/assets/legacy-permissions.json", { assert: { type: "json" } })
|
||||
|
||||
const fallbackURL = `../?source=${sourceURL}`;
|
||||
|
||||
if (!urlSearchParams.has('id')) open(fallbackURL);
|
||||
const bundleId = urlSearchParams.get('id');
|
||||
|
||||
(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;
|
||||
}
|
||||
}
|
||||
})();
|
||||
|
||||
main((json) => {
|
||||
const app = getAppWithBundleId(bundleId);
|
||||
if (!app) {
|
||||
open(fallbackURL);
|
||||
return;
|
||||
}
|
||||
|
||||
// If has multiple versions, show the latest one
|
||||
if (app.versions) {
|
||||
const latestVersion = app.versions[0];
|
||||
app.version = latestVersion.version;
|
||||
app.versionDate = latestVersion.date;
|
||||
app.versionDescription = latestVersion.localizedDescription;
|
||||
app.downloadURL = latestVersion.downloadURL;
|
||||
app.size = latestVersion.size;
|
||||
}
|
||||
|
||||
// Set tab title
|
||||
document.title = `${app.name} - ${json.name}`;
|
||||
|
||||
const tintColor = `#${app.tintColor?.replaceAll("#", "")}`;
|
||||
// Set tint color
|
||||
if (tintColor) document.querySelector(':root').style.setProperty("--app-tint-color", `${tintColor}`);
|
||||
|
||||
// Tint back button
|
||||
document.getElementById("back").style.color = tintColor;
|
||||
|
||||
// Set up install buttons
|
||||
document.querySelectorAll("a.install").forEach(button => {
|
||||
button.href = `altstore://install?url=${app.downloadURL}`;
|
||||
});
|
||||
|
||||
// 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 = `
|
||||
<a id="more" onclick="revealTruncatedText(this);">
|
||||
<button style="color: ${tintColor};">more</button>
|
||||
</a>`;
|
||||
|
||||
window.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", `<img src="${url}" alt="" class="screenshot">`);
|
||||
});
|
||||
// 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");
|
||||
|
||||
// Version date
|
||||
versionDateElement.textContent = formatVersionDate(app.versionDate);
|
||||
|
||||
// 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);
|
||||
|
||||
// Version history
|
||||
document.getElementById("version-history").href = `./version-history/?source=${sourceURL}&id=${app.bundleIdentifier}`;
|
||||
|
||||
//
|
||||
// Permissions
|
||||
|
||||
//
|
||||
// Privacy
|
||||
const privacyContainer = document.getElementById("privacy");
|
||||
if (app.appPermissions?.privacy?.length || app.permissions) {
|
||||
privacyContainer.querySelector(".permission-icon").classList = "permission-icon bi-person-fill-lock";
|
||||
privacyContainer.querySelector("b").innerText = "Privacy";
|
||||
privacyContainer.querySelector(".description").innerText = `"${app.name}" may request to access the following:`;
|
||||
}
|
||||
app.appPermissions?.privacy?.forEach(privacyPermission => {
|
||||
const permission = privacy[privacyPermission.name];
|
||||
let name = permission?.name ?? insertSpaceInCamelString(privacyPermission.name),
|
||||
icon;
|
||||
if (permission?.icon) icon = permission.icon;
|
||||
else icon = "gear-wide-connected";
|
||||
privacyContainer.querySelector(".permission-items").insertAdjacentHTML("beforeend",
|
||||
AppPermissionItem(name, icon, privacyPermission?.usageDescription)
|
||||
);
|
||||
});
|
||||
|
||||
//
|
||||
// Legacy permissions
|
||||
if (!app.appPermissions?.privacy) {
|
||||
app.permissions?.forEach(appPermission => {
|
||||
const permission = legacyPermissions[appPermission.type];
|
||||
let name = insertSpaceInSnakeString(appPermission.type),
|
||||
icon;
|
||||
if (permission?.icon) icon = permission.icon;
|
||||
else icon = "gear-wide-connected";
|
||||
privacyContainer.querySelector(".permission-items").insertAdjacentHTML("beforeend",
|
||||
AppPermissionItem(name, icon, appPermission?.usageDescription)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
//
|
||||
// Entitlements
|
||||
const entitlementsContainer = document.getElementById("entitlements");
|
||||
if (!app.appPermissions?.entitlements?.length) entitlementsContainer.remove();
|
||||
app.appPermissions?.entitlements.forEach(entitlementPermission => {
|
||||
const permission = entitlements[entitlementPermission.name];
|
||||
let name = permission?.name ?? insertSpaceInSnakeString(entitlementPermission.name),
|
||||
icon;
|
||||
if (permission?.icon) icon = permission.icon;
|
||||
else icon = "gear-wide-connected";;
|
||||
entitlementsContainer.querySelector(".permission-items").insertAdjacentHTML("beforeend",
|
||||
AppPermissionItem(name, icon, permission?.description)
|
||||
);
|
||||
});
|
||||
|
||||
//
|
||||
// Source info
|
||||
const source = document.getElementById("source");
|
||||
const sourceContainer = source.querySelector(".container");
|
||||
const sourceTitle = source.querySelector(".row-title");
|
||||
const sourceSubtitle = source.querySelector(".row-subtitle");
|
||||
sourceTitle.innerText = json.name;
|
||||
sourceContainer.href = `../../?source=${sourceURL}`;
|
||||
sourceSubtitle.innerText = json.description ?? "Tap to get started";
|
||||
});
|
||||
125
view/app/index.html
Normal file
125
view/app/index.html
Normal file
@@ -0,0 +1,125 @@
|
||||
<!--
|
||||
app/index.html
|
||||
altsource-viewer (https://github.com/therealFoxster/altsource-viewer)
|
||||
|
||||
Copyright (c) 2023 Foxster.
|
||||
MIT License.
|
||||
-->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" href="../../common/style.css">
|
||||
<link rel="stylesheet" href="app.css">
|
||||
</head>
|
||||
<body class="loading">
|
||||
<div id="loading">
|
||||
<img src="../../common/assets/img/loading.gif" alt="loading">
|
||||
<p>Loading</p>
|
||||
</div>
|
||||
<div id="main">
|
||||
<div id="top">
|
||||
<!-- Navigation bar -->
|
||||
<div id="nav-bar">
|
||||
<div id="back-container">
|
||||
<button id="back" type="button">
|
||||
<i class="bi bi-chevron-left"></i>
|
||||
Back
|
||||
</button>
|
||||
</div>
|
||||
<div id="title" class="hidden">
|
||||
<img id="app-icon" src="../../common/assets/img/generic_app.jpeg" alt="generic-app-icon">
|
||||
<p>AltSource</p>
|
||||
</div>
|
||||
<a href="https://example.com" class="install hidden">
|
||||
<button class="uibutton">Free</button>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Content -->
|
||||
<div class="item">
|
||||
<div class="app-header">
|
||||
<div class="content">
|
||||
<img id="app-icon" src="../../common/assets/img/generic_app.jpeg" alt="generic-app-icon">
|
||||
<div class="right">
|
||||
<div class="text">
|
||||
<p class="title">AltSource</p>
|
||||
<p class="subtitle">therealFoxster</p>
|
||||
</div>
|
||||
<div class="ipa">
|
||||
<a href="https://example.com" class="install">
|
||||
<button class="uibutton">Free</button>
|
||||
</a>
|
||||
<a href="http://example.com" id="download">
|
||||
Download IPA
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="background"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="preview" class="section">
|
||||
<p id="subtitle"></p>
|
||||
<div class="header">
|
||||
<h2>Preview</h2>
|
||||
</div>
|
||||
<div id="screenshots"></div>
|
||||
<p id="description"></p>
|
||||
</div>
|
||||
<div id="whats-new" class="section">
|
||||
<div class="header">
|
||||
<h2>What's New</h2>
|
||||
<!-- <p id="version-size">0 KB</p> -->
|
||||
<a id="version-history" style="color: var(--app-tint-color);" href="http://">Version History</a>
|
||||
</div>
|
||||
<div class="header">
|
||||
<p id="version">Version 2.0</p>
|
||||
<p id="version-date">Apr 10, 2023</p>
|
||||
</div>
|
||||
<p id="version-description"></p>
|
||||
</div>
|
||||
<div id="permissions" class="section">
|
||||
<div class="header">
|
||||
<h2>App Permissions</h2>
|
||||
</div>
|
||||
<div id="permission-containers">
|
||||
<div id="privacy" class="permission-container secondary-bg">
|
||||
<div class="permission-container-header">
|
||||
<i class="permission-icon bi-person-fill-check"></i>
|
||||
<p><b>None</b></p>
|
||||
<p class="description">This app's permissions have not been specified by the developer.</p>
|
||||
</div>
|
||||
<div class="permission-items">
|
||||
</div>
|
||||
</div>
|
||||
<div id="entitlements" class="permission-container secondary-bg">
|
||||
<div class="permission-container-header">
|
||||
<i class="permission-icon bi-key-fill"></i>
|
||||
<p><b>Entitlements</b></p>
|
||||
<p class="description">Entitlements are additional permissions that grant access to certain system services, including potentially sensitive information.</p>
|
||||
</div>
|
||||
<div class="permission-items">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="source" class="section">
|
||||
<div class="header">
|
||||
<h2>Discover More On</h2>
|
||||
</div>
|
||||
<a class="container" target="_blank">
|
||||
<div class="row">
|
||||
<p class="row-title"></p>
|
||||
<p class="row-subtitle"></p>
|
||||
</div>
|
||||
<i class="bi bi-arrow-up-right-square"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<script src="app.js" type="module"></script>
|
||||
</body>
|
||||
</html>
|
||||
30
view/app/version-history/index.html
Normal file
30
view/app/version-history/index.html
Normal file
@@ -0,0 +1,30 @@
|
||||
<!--
|
||||
version-history/index.html
|
||||
altsource-viewer (https://github.com/therealFoxster/altsource-viewer)
|
||||
|
||||
Copyright (c) 2023 Foxster.
|
||||
MIT License.
|
||||
-->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" href="../../../common/style.css">
|
||||
<link rel="stylesheet" href="version-history.css">
|
||||
</head>
|
||||
<body class="loading">
|
||||
<div id="loading">
|
||||
<img src="../../../common/assets/img/loading.gif" alt="loading">
|
||||
<p>Loading</p>
|
||||
</div>
|
||||
<!-- Add to AltStore banner & navigation bar -->
|
||||
<div id="top"></div>
|
||||
<div id="main">
|
||||
<div id="versions"></div>
|
||||
</div>
|
||||
<script src="version-history.js" type="module"></script>
|
||||
</body>
|
||||
</html>
|
||||
69
view/app/version-history/version-history.css
Normal file
69
view/app/version-history/version-history.css
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
version-history.css
|
||||
altsource-viewer (https://github.com/therealFoxster/altsource-viewer)
|
||||
|
||||
Copyright (c) 2023 Foxster.
|
||||
MIT License.
|
||||
*/
|
||||
|
||||
#main {
|
||||
padding-top: 8rem;
|
||||
}
|
||||
|
||||
a {
|
||||
color: var(--app-tint-color);
|
||||
}
|
||||
|
||||
#versions {
|
||||
padding: 0 1rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
/* gap: 1em; */
|
||||
}
|
||||
|
||||
.version {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
border-bottom: 0.1px solid var(--color-separator);
|
||||
padding: 1.25em 0;
|
||||
}
|
||||
|
||||
.version:first-of-type {
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.version {
|
||||
border-color: var(--color-separator-dark) !important;
|
||||
}
|
||||
}
|
||||
|
||||
.version-header, .version-options {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
|
||||
.version-options {
|
||||
color: var(--app-tint-color);
|
||||
}
|
||||
|
||||
.version-number {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.version-date {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.version-description {
|
||||
-webkit-line-clamp: 3;
|
||||
line-clamp: 3;
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
word-wrap: break-word;
|
||||
/* line-height: 1.5em; */
|
||||
}
|
||||
66
view/app/version-history/version-history.js
Normal file
66
view/app/version-history/version-history.js
Normal file
@@ -0,0 +1,66 @@
|
||||
//
|
||||
// version-history.js
|
||||
// altsource-viewer (https://github.com/therealFoxster/altsource-viewer)
|
||||
//
|
||||
// Copyright (c) 2023 Foxster.
|
||||
// MIT License.
|
||||
//
|
||||
|
||||
import { urlSearchParams, sourceURL } from "../../../common/modules/constants.js";
|
||||
import { insertNavigationBar, formatVersionDate, formatString, open } from "../../../common/modules/utilities.js";
|
||||
import { main } from "../../../common/modules/main.js";
|
||||
import { MoreButton } from "../../../common/components/MoreButton.js";
|
||||
import { VersionHistoryItem } from "../../../common/components/VersionHistoryItem.js";
|
||||
|
||||
const fallbackURL = `../../?source=${sourceURL}`;
|
||||
|
||||
if (!urlSearchParams.has('id')) open(fallbackURL);
|
||||
const bundleId = urlSearchParams.get('id');
|
||||
|
||||
insertNavigationBar("Version History");
|
||||
|
||||
main(json => {
|
||||
const app = getAppWithBundleId(bundleId);
|
||||
if (!app) {
|
||||
open(fallbackURL);
|
||||
return;
|
||||
}
|
||||
|
||||
// Set tab title
|
||||
document.title = `Version History - ${app.name}`;
|
||||
|
||||
// Set tint color
|
||||
const tintColor = `#${app.tintColor?.replaceAll("#", "")}`;
|
||||
if (tintColor) document.querySelector(':root').style.setProperty("--app-tint-color", `${tintColor}`);
|
||||
document.getElementById("back").style.color = tintColor;
|
||||
|
||||
const versionsContainer = document.getElementById("versions");
|
||||
if (app.versions) {
|
||||
app.versions.forEach((version, i) => {
|
||||
versionsContainer.insertAdjacentHTML("beforeend",
|
||||
VersionHistoryItem(
|
||||
version.version,
|
||||
formatVersionDate(version.date),
|
||||
formatString(version.localizedDescription),
|
||||
version.downloadURL,
|
||||
i
|
||||
)
|
||||
);
|
||||
});
|
||||
} else {
|
||||
versionsContainer.insertAdjacentHTML("beforeend",
|
||||
VersionHistoryItem(
|
||||
app.version,
|
||||
formatVersionDate(app.versionDate),
|
||||
formatString(app.versionDescription),
|
||||
app.downloadURL,
|
||||
0
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
document.querySelectorAll(".version-description").forEach(element => {
|
||||
if (element.scrollHeight > element.clientHeight)
|
||||
element.insertAdjacentHTML("beforeend", MoreButton(tintColor));
|
||||
});
|
||||
}, "../../../");
|
||||
51
view/index.html
Normal file
51
view/index.html
Normal file
@@ -0,0 +1,51 @@
|
||||
<!--
|
||||
view/index.html
|
||||
altsource-viewer (https://github.com/therealFoxster/altsource-viewer)
|
||||
|
||||
Copyright (c) 2023 Foxster.
|
||||
MIT License.
|
||||
-->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" href="../common/style.css">
|
||||
</head>
|
||||
<body class="loading">
|
||||
<div id="loading">
|
||||
<img src="../common/assets/img/loading.gif" alt="loading">
|
||||
<p>Loading</p>
|
||||
</div>
|
||||
<!-- Add to AltStore banner -->
|
||||
<div id="top"></div>
|
||||
<div id="main">
|
||||
<p>AltSource Viewer</p>
|
||||
<div class="header">
|
||||
<h1 id="title">altsource-v2</h1>
|
||||
<a href="../" style="font-size: 0.75em; font-weight: 750;">EDIT</a>
|
||||
</div>
|
||||
<div id="news" class="section">
|
||||
<div class="header">
|
||||
<h2>News</h2>
|
||||
<a href="../">View All</a>
|
||||
</div>
|
||||
<div id="news-items"></div>
|
||||
</div>
|
||||
<div id="apps" class="section">
|
||||
<div class="header">
|
||||
<h2>Featured Apps</h2>
|
||||
<a href="../">View All Apps</a>
|
||||
</div>
|
||||
</div>
|
||||
<div id="about" class="section">
|
||||
<div class="header">
|
||||
<h2>About</h2>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="view.js" type="module"></script>
|
||||
</body>
|
||||
</html>
|
||||
30
view/news/index.html
Normal file
30
view/news/index.html
Normal file
@@ -0,0 +1,30 @@
|
||||
<!--
|
||||
news/index.html
|
||||
altsource-viewer (https://github.com/therealFoxster/altsource-viewer)
|
||||
|
||||
Copyright (c) 2023 Foxster.
|
||||
MIT License.
|
||||
-->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" href="../../common/style.css">
|
||||
<link rel="stylesheet" href="news.css">
|
||||
</head>
|
||||
<body class="loading">
|
||||
<div id="loading">
|
||||
<img src="../../common/assets/img/loading.gif" alt="loading">
|
||||
<p>Loading</p>
|
||||
</div>
|
||||
<!-- Add to AltStore banner & navigation bar -->
|
||||
<div id="top"></div>
|
||||
<div id="main">
|
||||
<div id="news"></div>
|
||||
</div>
|
||||
<script src="news.js" type="module"></script>
|
||||
</body>
|
||||
</html>
|
||||
27
view/news/news.css
Normal file
27
view/news/news.css
Normal file
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
news.css
|
||||
altsource-viewer (https://github.com/therealFoxster/altsource-viewer)
|
||||
|
||||
Copyright (c) 2023 Foxster.
|
||||
MIT License.
|
||||
*/
|
||||
|
||||
#main {
|
||||
padding-top: 8rem;
|
||||
}
|
||||
|
||||
#news {
|
||||
padding: 0 1rem;
|
||||
}
|
||||
|
||||
.news-item-wrapper {
|
||||
margin-bottom: 3em;
|
||||
}
|
||||
|
||||
.news-item-wrapper:last-of-type {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
.news-item-wrapper .item {
|
||||
margin-bottom: 1rem !important;
|
||||
}
|
||||
24
view/news/news.js
Normal file
24
view/news/news.js
Normal file
@@ -0,0 +1,24 @@
|
||||
//
|
||||
// news.js
|
||||
// altsource-viewer (https://github.com/therealFoxster/altsource-viewer)
|
||||
//
|
||||
// Copyright (c) 2023 Foxster.
|
||||
// MIT License.
|
||||
//
|
||||
|
||||
import { insertNavigationBar } from "../../common/modules/utilities.js";
|
||||
import { NewsItem } from "../../common/components/NewsItem.js";
|
||||
import { main } from "../../common/modules/main.js";
|
||||
|
||||
insertNavigationBar("All News");
|
||||
|
||||
main(json => {
|
||||
// Set tab title
|
||||
document.title = `News - ${json.name}`;
|
||||
|
||||
// Sort news by latest
|
||||
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", NewsItem(news)));
|
||||
});
|
||||
70
view/view.js
Normal file
70
view/view.js
Normal file
@@ -0,0 +1,70 @@
|
||||
//
|
||||
// view.js
|
||||
// altsource-viewer (https://github.com/therealFoxster/altsource-viewer)
|
||||
//
|
||||
// Copyright (c) 2023 Foxster.
|
||||
// MIT License.
|
||||
//
|
||||
|
||||
import { sourceURL } from "../common/modules/constants.js";
|
||||
import { formatString } from "../common/modules/utilities.js";
|
||||
import { NewsItem } from "../common/components/NewsItem.js";
|
||||
import { AppHeader } from "../common/components/AppHeader.js";
|
||||
import { main } from "../common/modules/main.js";
|
||||
|
||||
main(json => {
|
||||
// Set "View All News" link
|
||||
document.querySelector("#news a").href = `./news/?source=${sourceURL}`;
|
||||
// Set "View All Apps" link
|
||||
document.querySelector("#apps a").href = `./all-apps/?source=${sourceURL}`;
|
||||
|
||||
// Set tab title
|
||||
document.title = json.name;
|
||||
// Set page title
|
||||
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());
|
||||
|
||||
if (json.news.length == 1) {
|
||||
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", 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;
|
||||
json.apps.forEach(app => {
|
||||
// Max: 5 featured apps if not specified
|
||||
if (count > 5) return;
|
||||
|
||||
// Ignore beta apps
|
||||
if (app.beta) return;
|
||||
|
||||
// If there are featured apps, ignore non-featured apps
|
||||
if (json.featuredApps && !json.featuredApps.includes(app.bundleIdentifier)) return;
|
||||
|
||||
document.getElementById("apps").insertAdjacentHTML("beforeend", AppHeader(app));
|
||||
|
||||
count++;
|
||||
});
|
||||
|
||||
//
|
||||
// About
|
||||
var description = formatString(json.description);
|
||||
if (description) document.getElementById("about").insertAdjacentHTML("beforeend", `
|
||||
<div class="item">
|
||||
<p>${description}</p>
|
||||
</div>
|
||||
`);
|
||||
else document.getElementById("about").remove();
|
||||
}, "../");
|
||||
Reference in New Issue
Block a user