From c4d9245c382f125c47434631fd9d558d95c5fd0c Mon Sep 17 00:00:00 2001 From: Adam Scott Date: Thu, 25 Jul 2024 15:33:40 -0400 Subject: [PATCH] Only show download for the current OS --- _includes/articles/download_card.html | 6 +- assets/css/releases/4.3.scss | 17 ++++ .../modules/detect-browser/detect-browser.js | 85 +++++++++++++++++++ assets/js/releases/4.3.mjs | 28 ++++++ 4 files changed, 133 insertions(+), 3 deletions(-) create mode 100644 assets/js/modules/detect-browser/detect-browser.js diff --git a/_includes/articles/download_card.html b/_includes/articles/download_card.html index 1e4fbca442..64b6c6c855 100644 --- a/_includes/articles/download_card.html +++ b/_includes/articles/download_card.html @@ -26,12 +26,12 @@ {% if primary[0] == "linux" or primary[0] == "macos" or primary[0] == "windows" %} {% assign platform_info = site.data.download_platforms | find: "name", primary[1] %} -
+
{{ platform_info.title }} {{ platform_info.title }}
- +
Standard
@@ -42,7 +42,7 @@
{% else %} {% assign has_mono = true %} -
+
.NET
diff --git a/assets/css/releases/4.3.scss b/assets/css/releases/4.3.scss index d76d98e353..cb82c2b91f 100644 --- a/assets/css/releases/4.3.scss +++ b/assets/css/releases/4.3.scss @@ -147,6 +147,9 @@ $donate-robot-size: 500px; height: min-content; border: none; color: black; + @media (prefers-color-scheme: dark) { + color: white; + } margin: var(--card-padding); @@ -177,6 +180,11 @@ $donate-robot-size: 500px; @include is-mobile() { width: 100%; } + + .download-platform, + .btn-download-primary { + display: none; + } } } @@ -184,6 +192,11 @@ $donate-robot-size: 500px; .download-platform { & > img { margin-right: var(--download-gap); + @media (prefers-color-scheme: dark) { + filter: + contrast(0%) + brightness(200%); + } } display: flex; @@ -197,6 +210,10 @@ $donate-robot-size: 500px; .card-download-other { color: black; + @media (prefers-color-scheme: dark) { + color: white; + } + text-decoration: none; &:hover { text-decoration: underline; diff --git a/assets/js/modules/detect-browser/detect-browser.js b/assets/js/modules/detect-browser/detect-browser.js new file mode 100644 index 0000000000..cee567e4ee --- /dev/null +++ b/assets/js/modules/detect-browser/detect-browser.js @@ -0,0 +1,85 @@ +// https://github.com/julienetie/detect-browser + +const navigatorErrorMessage = 'Could not find `userAgent` or `userAgentData` window.navigator properties to set `os`, `browser` and `version`' +const removeExcessMozillaAndVersion = /^mozilla\/\d\.\d\W/ +const browserPattern = /(\w+)\/(\d+\.\d+(?:\.\d+)?(?:\.\d+)?)/g +const engineAndVersionPattern = /^(ver|cri|gec)/ +const brandList = ['chrome', 'opera', 'safari', 'edge', 'firefox'] +const unknown = 'Unknown' +const empty = '' +const { isArray } = Array +let userAgentData = window.navigator.userAgentData +let userAgent = window.navigator.userAgent + +const mobiles = { + iphone: /iphone/, + ipad: /ipad|macintosh/, + android: /android/ +} + +const desktops = { + windows: /win/, + mac: /macintosh/, + linux: /linux/ +} + +const detectPlatform = (customUserAgent, customUserAgentData) => { + // Use a provided UA string instead of the browser's UA + userAgent = typeof customUserAgent === 'string' ? customUserAgent : userAgent + + // Use a provided UA data string instead of the browser's UA data + userAgentData = typeof customUserAgentData === 'string' ? customUserAgentData : userAgentData + + if (userAgent) { + const ua = userAgent.toLowerCase().replace(removeExcessMozillaAndVersion, empty) + + // Determine the operating system. + const mobileOS = Object.keys(mobiles).find(os => mobiles[os].test(ua) && window.navigator.maxTouchPoints >= 1) + const desktopOS = Object.keys(desktops).find(os => desktops[os].test(ua)) + const os = mobileOS || desktopOS + + // Extract browser and version information. + const browserTest = ua.match(browserPattern) + const versionRegex = /version\/(\d+(\.\d+)*)/ + const safariVersion = ua.match(versionRegex) + const saVesion = isArray(safariVersion) ? safariVersion[1] : null + const browserOffset = browserTest && (browserTest.length > 2 && !(engineAndVersionPattern.test(browserTest[1])) ? 1 : 0) + const browserResult = browserTest && browserTest[browserTest.length - 1 - (browserOffset || 0)].split('/') + const browser = browserResult && browserResult[0] + const version = saVesion ? saVesion : browserResult && browserResult[1] + + return { os, browser, version } + } else if (userAgentData) { + const os = userAgentData.platform.toLowerCase() + let platformData + + // Extract platform brand and version information. + for (const agentBrand of userAgentData.brands) { + const agentBrandEntry = agentBrand.brand.toLowerCase() + const foundBrand = brandList.find(brand => { //eslint-disable-line + if (agentBrandEntry.includes(brand)) { + return brand + } + }) + if (foundBrand) { + platformData = { browser: foundBrand, version: agentBrand.version } + break + } + } + const brandVersionData = platformData || { browser: unknown, version: unknown } + return { os, ...brandVersionData } + } else { + // Log error message if there's a problem. + console + .error(navigatorErrorMessage) + + return { + // Ignore the VSCode strikethough. Disable linting line if necessary. This is just a fallback + os: navigator.platform || unknown, + browser: unknown, + version: unknown + } + } +} + +export default detectPlatform diff --git a/assets/js/releases/4.3.mjs b/assets/js/releases/4.3.mjs index d98824b36a..936ac8d897 100644 --- a/assets/js/releases/4.3.mjs +++ b/assets/js/releases/4.3.mjs @@ -1,6 +1,7 @@ // GSAP for animations. import { gsap } from "../modules/gsap@3.12.5/index.js" import { ScrollTrigger } from "../modules/gsap@3.12.5/ScrollTrigger.js" +import detectPlatform from "../modules/detect-browser/detect-browser.js" gsap.registerPlugin(ScrollTrigger); @@ -59,3 +60,30 @@ for (const element of elements) { duration: 0.2 }); } + +// Hide downloads that aren't for the user's platform. +const platformData = detectPlatform(navigator.userAgent, navigator.userAgentData); +let platformName = "windows"; +switch (platformData.os) { + case "mac": { + platformName = "macos"; + } break; + + case "linux": { + platformName = "linux"; + } break; + + case "windows": + default: + break; +} +const cardDownloadPlatformsElement = document.querySelector(".card-download-platforms"); +if (cardDownloadPlatformsElement != null) { + for (const child of Array.from(cardDownloadPlatformsElement.childNodes)) { + if (child instanceof HTMLElement) { + if (child.classList.contains(`platform-${platformName}`)) { + child.style.display = "flex"; + } + } + } +}