diff --git a/src/pages/about/about.js b/src/pages/about/about.js index 2f431af55..a14cb6992 100644 --- a/src/pages/about/about.js +++ b/src/pages/about/about.js @@ -1,121 +1,312 @@ import "./about.scss"; + import Logo from "components/logo"; import Page from "components/page"; + import Reactive from "html-tag-js/reactive"; + import actionStack from "lib/actionStack"; import config from "lib/config"; + import helpers from "utils/helpers"; + export default function AboutInclude() { + /* + * Create the About page. + */ const $page = Page(strings.about.capitalize()); + + /* + * WebView information is loaded asynchronously, + * so these values are reactive. + */ const webviewVersionName = Reactive("N/A"); const webviewPackageName = Reactive("N/A"); + /* + * Social links are kept in an array so the UI + * can be generated without repeating the same JSX. + */ + const socialLinks = [ + { + name: "Mail", + icon: "gmail", + href: "mailto:apps@foxdebug.com", + }, + { + name: "Twitter", + icon: "twitter", + href: config.TWITTER_URL, + }, + { + name: "Instagram", + icon: "instagram", + href: config.INSTAGRAM_URL, + }, + { + name: "GitHub", + icon: "github", + href: config.GITHUB_URL, + }, + { + name: "Telegram", + icon: "telegram", + href: config.TELEGRAM_URL, + }, + { + name: "Discord", + icon: "discord", + href: config.DISCORD_URL, + }, + ]; + + /* + * Open the Android System WebView page + * on Google Play. + */ + const openWebviewPage = (event) => { + event.preventDefault(); + + const packageName = webviewPackageName.value; + + if (!packageName || packageName === "N/A") { + return; + } + + system.openInBrowser( + `https://play.google.com/store/apps/details?id=${packageName}`, + ); + }; + + /* + * Open an external URL. + * + * Normal web URLs use Acode's browser API. + * mailto links are handled by the Android system. + */ + const openExternalLink = (event) => { + event.preventDefault(); + + const href = event.currentTarget.getAttribute("href"); + + if (!href) { + return; + } + + if (href.startsWith("mailto:")) { + window.location.href = href; + return; + } + + system.openInBrowser(href); + }; + + /* + * Add the About page CSS class. + */ $page.classList.add("about-us"); + + /* + * Build the About page. + */ $page.body = (
- + {/* ============================== + HEADER + ============================== */} -
-

Acode editor

-
- Version {BuildInfo.version} ({BuildInfo.versionCode}) +
+
+
-
- -
- { - e.preventDefault(); - system.openInBrowser( - `https://play.google.com/store/apps/details?id=${webviewPackageName.value}`, - ); - }} - > -
- -
-
- Webview {webviewVersionName} -
{webviewPackageName}
-
-
- -
- -
-
- Official webpage -
{config.BASE_URL}
-
-
- -
- + +
+

Acode editor

+ +
+ Version {BuildInfo.version} + + {BuildInfo.versionCode}
-
- Foxbiz Software Pvt. Ltd. -
{config.FOXBIZ_URL}
+
+ + +
+ {/* ============================== + APPLICATION INFORMATION + ============================== */} + + -
- -
- + - Mail - - -
- +
+ + {/* ============================== + SOCIAL LINKS + ============================== */} + +
); + /* + * Get Android WebView information. + * + * This callback updates the reactive values, + * which automatically updates the UI. + */ system.getWebviewInfo((res) => { webviewPackageName.value = res?.packageName || "N/A"; webviewVersionName.value = res?.versionName || "N/A"; }); + /* + * Add the About page to the action stack. + */ actionStack.push({ id: "about", action: $page.hide, }); + /* + * Remove the About page from the action stack + * when the page is hidden. + */ $page.onhide = function () { actionStack.remove("about"); }; + /* + * Add the page to the application. + */ app.append($page); + + /* + * Show advertisement. + */ helpers.showAd(); } diff --git a/src/pages/about/about.scss b/src/pages/about/about.scss index 8b19263a7..7f6a5f65b 100644 --- a/src/pages/about/about.scss +++ b/src/pages/about/about.scss @@ -1,134 +1,497 @@ #about-page { - padding: 16px; - display: flex; - flex-direction: column; - align-items: center; - gap: 24px; - overflow-y: auto; - - .version-info { - text-align: center; - margin-bottom: 32px; - - .version-title { - font-size: 24px; - font-weight: 600; - margin-bottom: 4px; - } - - .version-number { - color: color-mix(in srgb, var(--primary-text-color) 60%, transparent); - font-size: 14px; - } - } - - .info-section { - width: 100%; - max-width: 400px; - min-height: fit-content; - height: auto; - background: color-mix(in srgb, - var(--popup-background-color) 20%, - transparent); - border-radius: 12px; - overflow: visible; - margin-bottom: 16px; - display: flex; - flex-direction: column; - - .info-item { - display: flex; - align-items: center; - padding: 16px; - color: var(--secondary-text-color); - text-decoration: none; - border-bottom: 1px solid var(--border-color); - transition: background 0.2s ease; - - &:last-child { - border-bottom: none; - } - - &:hover { - background: color-mix(in srgb, - var(--popup-background-color) 40%, - transparent); - } - - .info-item-icon { - width: 24px; - height: 24px; - margin-right: 12px; - display: flex; - align-items: center; - font-size: 24px; - } - - .info-item-text { - flex: 1; - font-size: 15px; - - .info-item-subtext { - color: color-mix(in srgb, var(--primary-text-color) 60%, transparent); - font-size: 13px; - margin-top: 2px; - } - } - } - } - - .social-links { - display: grid; - grid-template-columns: repeat(2, 1fr); - gap: 12px; - width: 100%; - max-width: 400px; - - .social-link { - display: inline-flex; - align-items: center; - padding: 12px; - background: color-mix(in srgb, - var(--popup-background-color) 20%, - transparent); - border-radius: 12px; - color: var(--secondary-text-color); - text-decoration: none; - transition: all 0.2s ease; - - &:hover { - background: color-mix(in srgb, - var(--popup-background-color) 40%, - transparent); - transform: translateY(-1px); - } - - .social-icon { - width: 24px; - height: 24px; - margin-right: 12px; - font-size: 24px; - display: flex; - align-items: center; - } - } - } - - @supports not (gap: 1px) { - > * + * { margin-top: 24px; } - .social-links > * { margin-right: 12px; margin-bottom: 12px; } - } - - .icon { - height: 100%; - width: 100%; - } - - .foxbiz { - background-image: url(./foxbiz.svg); - } - - .discord { - background-image: url(./discord.svg); - } -} \ No newline at end of file + padding: 24px 16px 40px; + display: flex; + flex-direction: column; + align-items: center; + overflow-y: auto; + box-sizing: border-box; + + /* + * Main page content. + * Keeps the About page centered on large screens + * while using the full width on smaller phones. + */ + .about-content { + width: 100%; + max-width: 520px; + } + + /* + * ============================== + * HEADER + * ============================== + */ + + .about-header { + width: 100%; + max-width: 520px; + display: flex; + flex-direction: column; + align-items: center; + margin-bottom: 32px; + text-align: center; + } + + .about-logo { + width: 88px; + height: 88px; + margin-bottom: 18px; + display: flex; + align-items: center; + justify-content: center; + border-radius: 22px; + background: color-mix(in srgb, var(--popup-background-color) 35%, transparent); + box-shadow: 0 8px 24px + color-mix(in srgb, var(--popup-background-color) 35%, transparent); + overflow: hidden; + + /* + * Make sure the Logo component doesn't become + * larger than the container. + */ + > * { + max-width: 64px; + max-height: 64px; + } + } + + .about-title { + h1 { + margin: 0; + color: var(--primary-text-color); + font-size: 26px; + font-weight: 700; + line-height: 1.2; + letter-spacing: -0.3px; + } + } + + .about-version { + margin-top: 7px; + color: color-mix(in srgb, var(--primary-text-color) 60%, transparent); + font-size: 14px; + line-height: 1.4; + } + + .version-separator { + margin: 0 6px; + opacity: 0.6; + } + + /* + * ============================== + * SECTIONS + * ============================== + */ + + .about-section { + width: 100%; + margin-bottom: 28px; + } + + .about-section-title { + display: flex; + align-items: center; + margin: 0 4px 10px; + color: var(--primary-text-color); + font-size: 14px; + font-weight: 600; + letter-spacing: 0.1px; + } + + .about-section-icon { + width: 20px; + height: 20px; + margin-right: 8px; + display: flex; + align-items: center; + justify-content: center; + color: var(--secondary-text-color); + font-size: 17px; + } + + /* + * ============================== + * INFORMATION CARD + * ============================== + */ + + .info-section { + width: 100%; + display: flex; + flex-direction: column; + background: color-mix(in srgb, var(--popup-background-color) 24%, transparent); + border: 1px solid + color-mix(in srgb, var(--border-color) 55%, transparent); + border-radius: 16px; + overflow: hidden; + box-shadow: 0 2px 8px + color-mix(in srgb, var(--popup-background-color) 20%, transparent); + } + + .info-item { + position: relative; + display: flex; + align-items: center; + min-height: 68px; + padding: 12px 14px; + box-sizing: border-box; + color: var(--primary-text-color); + text-decoration: none; + -webkit-tap-highlight-color: transparent; + transition: + background-color 0.15s ease, + transform 0.1s ease; + + &:not(:last-child) { + border-bottom: 1px solid + color-mix(in srgb, var(--border-color) 55%, transparent); + } + + &:hover { + background: color-mix( + in srgb, + var(--popup-background-color) 45%, + transparent + ); + } + + &:active { + background: color-mix( + in srgb, + var(--popup-background-color) 65%, + transparent + ); + transform: scale(0.99); + } + } + + .info-item-icon { + flex: 0 0 42px; + width: 42px; + height: 42px; + margin-right: 12px; + display: flex; + align-items: center; + justify-content: center; + border-radius: 12px; + background: color-mix( + in srgb, + var(--popup-background-color) 45%, + transparent + ); + color: var(--primary-text-color); + font-size: 22px; + overflow: hidden; + + .icon { + width: 24px; + height: 24px; + } + } + + .info-item-text { + min-width: 0; + flex: 1; + display: flex; + flex-direction: column; + overflow: hidden; + } + + .info-item-title { + color: var(--primary-text-color); + font-size: 15px; + font-weight: 500; + line-height: 20px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + + .info-item-subtext { + margin-top: 2px; + color: color-mix(in srgb, var(--primary-text-color) 62%, transparent); + font-size: 12px; + line-height: 17px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + + .info-item-package { + margin-top: 1px; + color: color-mix(in srgb, var(--primary-text-color) 42%, transparent); + font-family: monospace; + font-size: 10px; + line-height: 14px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + + .info-item-arrow { + flex: 0 0 24px; + width: 24px; + height: 24px; + margin-left: 8px; + display: flex; + align-items: center; + justify-content: center; + color: color-mix(in srgb, var(--primary-text-color) 45%, transparent); + font-size: 18px; + + .icon { + width: 18px; + height: 18px; + } + } + + /* + * ============================== + * SOCIAL LINKS + * ============================== + */ + + .social-links { + width: 100%; + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 10px; + } + + .social-link { + min-width: 0; + min-height: 54px; + padding: 10px 11px; + display: flex; + align-items: center; + box-sizing: border-box; + border: 1px solid + color-mix(in srgb, var(--border-color) 45%, transparent); + border-radius: 14px; + background: color-mix( + in srgb, + var(--popup-background-color) 22%, + transparent + ); + color: var(--secondary-text-color); + text-decoration: none; + -webkit-tap-highlight-color: transparent; + transition: + background-color 0.15s ease, + transform 0.1s ease, + border-color 0.15s ease; + + &:hover { + background: color-mix( + in srgb, + var(--popup-background-color) 42%, + transparent + ); + border-color: color-mix( + in srgb, + var(--border-color) 75%, + transparent + ); + } + + &:active { + transform: scale(0.97); + background: color-mix( + in srgb, + var(--popup-background-color) 60%, + transparent + ); + } + } + + .social-icon { + flex: 0 0 34px; + width: 34px; + height: 34px; + margin-right: 9px; + display: flex; + align-items: center; + justify-content: center; + border-radius: 10px; + background: color-mix( + in srgb, + var(--popup-background-color) 42%, + transparent + ); + color: var(--primary-text-color); + font-size: 19px; + + .icon { + width: 20px; + height: 20px; + } + } + + .social-name { + min-width: 0; + flex: 1; + color: var(--secondary-text-color); + font-size: 13px; + font-weight: 500; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + + .social-arrow { + flex: 0 0 18px; + width: 18px; + height: 18px; + margin-left: 5px; + display: flex; + align-items: center; + justify-content: center; + color: color-mix(in srgb, var(--primary-text-color) 38%, transparent); + + .icon { + width: 16px; + height: 16px; + } + } + + /* + * ============================== + * FOOTER + * ============================== + */ + + .about-footer { + width: 100%; + margin-top: 12px; + padding: 24px 16px; + box-sizing: border-box; + text-align: center; + border-top: 1px solid + color-mix(in srgb, var(--border-color) 45%, transparent); + } + + .about-footer-title { + color: var(--primary-text-color); + font-size: 16px; + font-weight: 600; + } + + .about-footer-version { + margin-top: 4px; + color: color-mix(in srgb, var(--primary-text-color) 50%, transparent); + font-size: 12px; + } + + .about-footer-text { + margin-top: 8px; + color: color-mix(in srgb, var(--primary-text-color) 42%, transparent); + font-size: 12px; + } + + /* + * ============================== + * ICONS + * ============================== + */ + + .icon { + display: block; + width: 100%; + height: 100%; + background-repeat: no-repeat; + background-position: center; + background-size: contain; + } + + .foxbiz { + background-image: url(./foxbiz.svg); + } + + .discord { + background-image: url(./discord.svg); + } + + /* + * ============================== + * SMALL PHONES + * ============================== + */ + + @media (max-width: 360px) { + padding-right: 12px; + padding-left: 12px; + + .about-header { + margin-bottom: 24px; + } + + .about-logo { + width: 76px; + height: 76px; + border-radius: 19px; + } + + .about-title h1 { + font-size: 23px; + } + + .info-item { + min-height: 64px; + padding: 10px 11px; + } + + .info-item-icon { + flex-basis: 38px; + width: 38px; + height: 38px; + margin-right: 10px; + } + + .social-links { + gap: 8px; + } + + .social-link { + min-height: 50px; + padding: 8px; + } + + .social-icon { + flex-basis: 30px; + width: 30px; + height: 30px; + margin-right: 7px; + } + } + + /* + * ============================== + * ACCESSIBILITY + * ============================== + */ + + @media (prefers-reduced-motion: reduce) { + .info-item, + .social-link { + transition: none; + } + } + + /* + * ============================== + * OLD BROWSER FALLBACK + * ============================== + */ + + @supports not (gap: 1px) { + .about-section { + margin-bottom: 24px; + } + + .social-link { + margin-right: 8px; + margin-bottom: 8px; + } + } +}