~avery/protondb-indicator

0706a9911a3ea023b6924fa8299d0724147f898d — Avery 1 year, 5 months ago
Initial commit
8 files changed, 469 insertions(+), 0 deletions(-)

A .gitignore
A .prettierrc.json
A dom-chef-shim.js
A package.json
A plugin.toml
A src/index.tsx
A tsconfig.json
A yarn.lock
A  => .gitignore +132 -0
@@ 1,132 @@
# https://github.com/github/gitignore/blob/d0b80a469983a7beece8fa1f5c48a8242318b531/Node.gitignore

# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
.pnpm-debug.log*

# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage
*.lcov

# nyc test coverage
.nyc_output

# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# Bower dependency directory (https://bower.io/)
bower_components

# node-waf configuration
.lock-wscript

# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release

# Dependency directories
node_modules/
jspm_packages/

# Snowpack dependency directory (https://snowpack.dev/)
web_modules/

# TypeScript cache
*.tsbuildinfo

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Optional stylelint cache
.stylelintcache

# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# Yarn Integrity file
.yarn-integrity

# dotenv environment variable files
.env
.env.development.local
.env.test.local
.env.production.local
.env.local

# parcel-bundler cache (https://parceljs.org/)
.cache
.parcel-cache

# Next.js build output
.next
out

# Nuxt.js build / generate output
.nuxt
dist

# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and not Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public

# vuepress build output
.vuepress/dist

# vuepress v2.x temp and cache directory
.temp
.cache

# Docusaurus cache and generated files
.docusaurus

# Serverless directories
.serverless/

# FuseBox cache
.fusebox/

# DynamoDB Local files
.dynamodb/

# TernJS port file
.tern-port

# Stores VSCode versions used for testing VSCode extensions
.vscode-test

# yarn v2
.yarn/cache
.yarn/unplugged
.yarn/build-state.yml
.yarn/install-state.gz
.pnp.*

A  => .prettierrc.json +3 -0
@@ 1,3 @@
{
	"singleQuote": true
}
\ No newline at end of file

A  => dom-chef-shim.js +2 -0
@@ 1,2 @@
import { h } from 'dom-chef';
export { h };
\ No newline at end of file

A  => package.json +20 -0
@@ 1,20 @@
{
  "name": "protondb-indicator",
  "version": "0.1.0",
  "main": "dist/index.jsx",
  "author": "Avery <avery@avery.cafe> (https://avery.cafe)",
  "license": "GPL-3.0",
  "scripts": {
    "format": "prettier src --write",
    "build": "esbuild src/index.tsx --bundle --format=esm --jsx-factory=h --jsx-fragment=DocumentFragment --inject:./dom-chef-shim.js --outfile=dist/index.js"
  },
  "dependencies": {
    "dom-chef": "^5.1.0"
  },
  "devDependencies": {
    "esbuild": "^0.14.30",
    "prettier": "^2.6.2",
    "prettier-plugin-organize-imports": "^2.3.4",
    "typescript": "^4.6.3"
  }
}

A  => plugin.toml +17 -0
@@ 1,17 @@
name = "ProtonDB Indicator"
link = "https://git.sr.ht/~avery/protondb-plugin"
source = "https://git.sr.ht/~avery/protondb-plugin"

[author]
name = "Avery"
link = "https://avery.cafe"

[entrypoints]

	[entrypoints.desktop]
	library = true
	menu = false

	[entrypoints.deck]
	library = true
	menu = false
\ No newline at end of file

A  => src/index.tsx +101 -0
@@ 1,101 @@
// TODO: Import SMM types package
type SMM = any;

// TODO: these are from main code
const deleteAll = (selector: string) =>
  document.querySelectorAll(selector).forEach((node) => node.remove());

class NetworkGetError extends Error {
  readonly status: number;
  constructor(status: number) {
    super(`Get returned error status code: ${status}`);
    this.status = status;
  }
}

const SHARED_SELECTORS = {
  appDetails: '[class*=appdetails_Container]',
  appDetailsHeader: '[class^="sharedappdetailsheader_TopCapsule"]',
  appDetailsName: 'span[class^=appdetailsplaysection_PlayBarGameName]',
};
// ==============================

enum TierColours {
  pending = '#6a6a6a',
  borked = '#ff0000',
  bronze = '#cd7f32',
  silver = '#a6a6a6',
  gold = '#cfb53b',
  platinum = '#b4c7dc',
}

type TierRes = { tier: keyof typeof TierColours };

const getTierUrl = (appId: string) =>
  `https://www.protondb.com/api/v1/reports/summaries/${appId}.json`;

export const load = (smm: SMM) => {
  const protonDbCache: Record<string, any> = {};

  smm.addEventListener('switchToAppDetails', async (event: any) => {
    deleteAll('[data-smm-protondb]');

    const { appId, appName } = event.detail;
    let data: TierRes = protonDbCache[appId];
    if (!data) {
      try {
        // data = await smm.Network.get<TierRes>(getTierUrl(appId));
        data = await smm.Network.get(getTierUrl(appId));
        protonDbCache[appId] = data;
      } catch (err) {
        if (err instanceof NetworkGetError) {
          smm.Toast.addToast(`Error fetching ProtonDB rating for ${appName}`);
          console.info(`Error fetching ProtonDB rating for app ${appId}:`, err.status);
          return;
        }
      }
    }
    const { tier } = data;

    const indicator = (
      <a
        href={`https://www.protondb.com/app/${appId}`}
        style={{
          position: 'absolute',
          top: 24,
          left: 24,
          display: 'flex',
          alignItems: 'center',
          padding: '4px 8px',
          backgroundColor: TierColours[tier],
          color: 'rgba(0, 0, 0, 50%)',
          fontSize: 20,
          textDecoration: 'none',
          borderRadius: 4,
        }}
        data-smm-protondb={true}
      >
        <img
          // TODO: cache this image manually, or check license and include it with plugin
          // (it will be cached by the browser anyways, but it would still be nice to reduce traffic)
          src="https://www.protondb.com/sites/protondb/images/site-logo.svg"
          style={{
            width: 20,
            marginRight: 4,
          }}
        />
        <span>{tier.charAt(0).toUpperCase() + tier.slice(1)}</span>
      </a>
    );

    document
      .querySelector(SHARED_SELECTORS.appDetailsHeader)!
      .appendChild(indicator as unknown as HTMLElement);
  });
};

export const unload = () => {
	document
		.querySelectorAll('[data-smm-protondb]')
		.forEach((node) => node.remove());
};
\ No newline at end of file

A  => tsconfig.json +13 -0
@@ 1,13 @@
{
	"compilerOptions": {
		"target": "ES2020",
		"strict": true,
		"noEmit": true,
		"lib": ["ES2020", "DOM", "DOM.Iterable"],
		"isolatedModules": true,
		"esModuleInterop": true,
		"moduleResolution": "node",
		"jsx": "preserve"
	},
	"include": ["src/**/*"]
}
\ No newline at end of file

A  => yarn.lock +181 -0
@@ 1,181 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1


"@types/prop-types@*":
  version "15.7.5"
  resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.5.tgz#5f19d2b85a98e9558036f6a3cacc8819420f05cf"
  integrity sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==

"@types/react@^17.0.42":
  version "17.0.44"
  resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.44.tgz#c3714bd34dd551ab20b8015d9d0dbec812a51ec7"
  integrity sha512-Ye0nlw09GeMp2Suh8qoOv0odfgCoowfM/9MG6WeRD60Gq9wS90bdkdRtYbRkNhXOpG4H+YXGvj4wOWhAC0LJ1g==
  dependencies:
    "@types/prop-types" "*"
    "@types/scheduler" "*"
    csstype "^3.0.2"

"@types/scheduler@*":
  version "0.16.2"
  resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.2.tgz#1a62f89525723dde24ba1b01b092bf5df8ad4d39"
  integrity sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==

csstype@^3.0.2:
  version "3.0.11"
  resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.11.tgz#d66700c5eacfac1940deb4e3ee5642792d85cd33"
  integrity sha512-sa6P2wJ+CAbgyy4KFssIb/JNMLxFvKF1pCYCSXS8ZMuqZnMsrxqI2E5sPyoTpxoPU/gVZMzr2zjOfg8GIZOMsw==

dom-chef@^5.1.0:
  version "5.1.0"
  resolved "https://registry.yarnpkg.com/dom-chef/-/dom-chef-5.1.0.tgz#96cf01475dc30362f1549e1c05ce26aeeb319e24"
  integrity sha512-zV1cLrO8sl7X5dWTLp6SQM/DzadfXQEgVf+sfXZqGUd709ezeEfpI8n/IgW2O8kt1sfIgZA+Us0lbKSkP4foqQ==
  dependencies:
    "@types/react" "^17.0.42"
    svg-tag-names "^3.0.1"

esbuild-android-64@0.14.30:
  version "0.14.30"
  resolved "https://registry.yarnpkg.com/esbuild-android-64/-/esbuild-android-64-0.14.30.tgz#9efcdb3d826b9c67705a0c518d361ab44ae4cc5b"
  integrity sha512-vdJ7t8A8msPfKpYUGUV/KaTQRiZ0vDa2XSTlzXVkGGVHLKPeb85PBUtYJcEgw3htW3IdX5i1t1IMdQCwJJgNAg==

esbuild-android-arm64@0.14.30:
  version "0.14.30"
  resolved "https://registry.yarnpkg.com/esbuild-android-arm64/-/esbuild-android-arm64-0.14.30.tgz#7b90fa7578b94da047e0bf3da477cb5775b58664"
  integrity sha512-BdgGfxeA5hBQNErLr7BWJUA8xjflEfyaARICy8e0OJYNSAwDbEzOf8LyiKWSrDcgV129mWhi3VpbNQvOIDEHcg==

esbuild-darwin-64@0.14.30:
  version "0.14.30"
  resolved "https://registry.yarnpkg.com/esbuild-darwin-64/-/esbuild-darwin-64-0.14.30.tgz#275e40eb100286b868d4cd664e6447b53400f7ff"
  integrity sha512-VRaOXMMrsG5n53pl4qFZQdXy2+E0NoLP/QH3aDUI0+bQP+ZHDmbINKcDy2IX7GVFI9kqPS18iJNAs5a6/G2LZg==

esbuild-darwin-arm64@0.14.30:
  version "0.14.30"
  resolved "https://registry.yarnpkg.com/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.30.tgz#c2b8fe03fb0dcee1d227b226c9c921de71e4d411"
  integrity sha512-qDez+fHMOrO9Oc9qjt/x+sy09RJVh62kik5tVybKRLmezeV4qczM9/sAYY57YN0aWLdHbcCj2YqJUWYJNsgKnw==

esbuild-freebsd-64@0.14.30:
  version "0.14.30"
  resolved "https://registry.yarnpkg.com/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.30.tgz#328bb272ce6cfcae202b6e0a06c240036335cc91"
  integrity sha512-mec1jENcImVVagddZlGWsdAUwBnzR5cgnhzCxv+9fSMxKbx1uZYLLUAnLPp8m/i934zrumR1xGjJ5VoWdPlI2w==

esbuild-freebsd-arm64@0.14.30:
  version "0.14.30"
  resolved "https://registry.yarnpkg.com/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.30.tgz#49ce79fa7d7087a941e27432da46bafb5b35a979"
  integrity sha512-cpjbTs6Iok/AfeB0JgTzyUJTMStC1SQULmany5nHx6S4GTkSgaAHuJzZO0GcVWqghI4e0YL/bjXAhN5Mn6feNw==

esbuild-linux-32@0.14.30:
  version "0.14.30"
  resolved "https://registry.yarnpkg.com/esbuild-linux-32/-/esbuild-linux-32-0.14.30.tgz#c473299f5291130f6d4436808603b529ccbfa785"
  integrity sha512-liIONVT4F2kZmOMwtwASqZ8WkIjb5HHBR9HUffdHiuotSTF3CyZO+EJf+Og+SYYuuVIvt0qHNSFjBA/iSESteQ==

esbuild-linux-64@0.14.30:
  version "0.14.30"
  resolved "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.30.tgz"
  integrity sha512-LUnpzoMpRqFON5En4qEj6NWiyH6a1K+Y2qYNKrCy5qPTjDoG/EWeqMz69n8Uv7pRuvDKl3FNGJ1dufTrA5i0sw==

esbuild-linux-arm64@0.14.30:
  version "0.14.30"
  resolved "https://registry.yarnpkg.com/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.30.tgz#78485a9f49858ea69ced85c3dd0fe58d354f20f8"
  integrity sha512-DHZHn6FK5q/KL0fpNT/0jE38Nnyk2rXxKE9WENi95EXtqfOLPgE8tzjTZQNgpr61R95QX4ymQU26ni3IZk8buQ==

esbuild-linux-arm@0.14.30:
  version "0.14.30"
  resolved "https://registry.yarnpkg.com/esbuild-linux-arm/-/esbuild-linux-arm-0.14.30.tgz#00392bbe04ac687dd6d9849ecee302bc27f984f2"
  integrity sha512-97T+bbXnpqf7mfIG49UR7ZSJFGgvc22byn74qw3Kx2GDCBSQoVFjyWuKOHGXp8nXk3XYrdFF+mQ8yQ7aNsgQvg==

esbuild-linux-mips64le@0.14.30:
  version "0.14.30"
  resolved "https://registry.yarnpkg.com/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.30.tgz#cf48a292037c3a9ca3ca84ec0ae4f47bf1247ab4"
  integrity sha512-fLUzTFZ7uknC0aPTk7/lM7NmaG/9ZqE3SaHEphcaM009SZK/mDOvZugWi1ss6WGNhk13dUrhkfHcc4FSb9hYhg==

esbuild-linux-ppc64le@0.14.30:
  version "0.14.30"
  resolved "https://registry.yarnpkg.com/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.30.tgz#8e448a54e7040829ee9ecfc68dab0f3a039b1cff"
  integrity sha512-2Oudm2WEfj0dNU9bzIl5L/LrsMEmHWsOsYgJJqu8fDyUDgER+J1d33qz3cUdjsJk7gAENayIxDSpsuCszx0w3A==

esbuild-linux-riscv64@0.14.30:
  version "0.14.30"
  resolved "https://registry.yarnpkg.com/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.30.tgz#118af007f21adb00c4362d5eda3f004290f4d0ef"
  integrity sha512-RPMucPW47rV4t2jlelaE948iCRtbZf5RhifxSwzlpM1Mqdyu99MMNK0w4jFreGTmLN+oGomxIOxD6n+2E/XqHw==

esbuild-linux-s390x@0.14.30:
  version "0.14.30"
  resolved "https://registry.yarnpkg.com/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.30.tgz#e0649e26d8791bf6265685842dcef732de59b49b"
  integrity sha512-OZ68r7ok6qO7hdwrwQn2p5jbIRRcUcVaAykB7e0uCA0ODwfeGunILM6phJtq2Oz4dlEEFvd+tSuma3paQKwt+A==

esbuild-netbsd-64@0.14.30:
  version "0.14.30"
  resolved "https://registry.yarnpkg.com/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.30.tgz#7653db21ab4379a1b557f338b040e3493ff5006c"
  integrity sha512-iyejQUKn0TzpPkufq8pSCxOg9NheycQbMbPCmjefTe9wYuUlBt1TcHvdoJnYbQzsAhAh1BNq+s0ycRsIJFZzaQ==

esbuild-openbsd-64@0.14.30:
  version "0.14.30"
  resolved "https://registry.yarnpkg.com/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.30.tgz#3fad1699cb2ca7a060585356e2881df7b3fa5bb1"
  integrity sha512-UyK1MTMcy4j5fH260fsE1o6MVgWNhb62eCK2yCKCRazZv8Nqdc2WiP9ygjWidmEdCDS+A6MuVp9ozk9uoQtQpA==

esbuild-sunos-64@0.14.30:
  version "0.14.30"
  resolved "https://registry.yarnpkg.com/esbuild-sunos-64/-/esbuild-sunos-64-0.14.30.tgz#2306a178dc2362cf32fc182327c21b49b78ca1a3"
  integrity sha512-aQRtRTNKHB4YuG+xXATe5AoRTNY48IJg5vjE8ElxfmjO9+KdX7MHFkTLhlKevCD6rNANtB3qOlSIeAiXTwHNqw==

esbuild-windows-32@0.14.30:
  version "0.14.30"
  resolved "https://registry.yarnpkg.com/esbuild-windows-32/-/esbuild-windows-32-0.14.30.tgz#ea17b2a9468e346734f926a7edd49de3cc81d12f"
  integrity sha512-9/fb1tPtpacMqxAXp3fGHowUDg/l9dVch5hKmCLEZC6PdGljh6h372zMdJwYfH0Bd5CCPT0Wx95uycBLJiqpXA==

esbuild-windows-64@0.14.30:
  version "0.14.30"
  resolved "https://registry.yarnpkg.com/esbuild-windows-64/-/esbuild-windows-64-0.14.30.tgz#266147f1f45974ac61dece10ab32bc916050dcc2"
  integrity sha512-DHgITeUhPAnN9I5O6QBa1GVyPOhiYCn4S4TtQr7sO4+X0LNyqnlmA1M0qmGkUdDC1QQfjI8uQ4G/whdWb2pWIQ==

esbuild-windows-arm64@0.14.30:
  version "0.14.30"
  resolved "https://registry.yarnpkg.com/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.30.tgz#8e5e9c2455bffaf3e1a387eee4841f5c3797b8a8"
  integrity sha512-F1kLyQH7zSgjh5eLxogGZN7C9+KNs9m+s7Q6WZoMmCWT/6j998zlaoECHyM8izJRRfsvw2eZlEa1jO6/IOU1AQ==

esbuild@^0.14.30:
  version "0.14.30"
  resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.14.30.tgz#8bf6501a58f71e622e7485aeada79c764c1affe4"
  integrity sha512-wCecQSBkIjp2xjuXY+wcXS/PpOQo9rFh4NAKPh4Pm9f3fuLcnxkR0rDzA+mYP88FtXIUcXUyYmaIgfrzRl55jA==
  optionalDependencies:
    esbuild-android-64 "0.14.30"
    esbuild-android-arm64 "0.14.30"
    esbuild-darwin-64 "0.14.30"
    esbuild-darwin-arm64 "0.14.30"
    esbuild-freebsd-64 "0.14.30"
    esbuild-freebsd-arm64 "0.14.30"
    esbuild-linux-32 "0.14.30"
    esbuild-linux-64 "0.14.30"
    esbuild-linux-arm "0.14.30"
    esbuild-linux-arm64 "0.14.30"
    esbuild-linux-mips64le "0.14.30"
    esbuild-linux-ppc64le "0.14.30"
    esbuild-linux-riscv64 "0.14.30"
    esbuild-linux-s390x "0.14.30"
    esbuild-netbsd-64 "0.14.30"
    esbuild-openbsd-64 "0.14.30"
    esbuild-sunos-64 "0.14.30"
    esbuild-windows-32 "0.14.30"
    esbuild-windows-64 "0.14.30"
    esbuild-windows-arm64 "0.14.30"

prettier-plugin-organize-imports@^2.3.4:
  version "2.3.4"
  resolved "https://registry.npmjs.org/prettier-plugin-organize-imports/-/prettier-plugin-organize-imports-2.3.4.tgz"
  integrity sha512-R8o23sf5iVL/U71h9SFUdhdOEPsi3nm42FD/oDYIZ2PQa4TNWWuWecxln6jlIQzpZTDMUeO1NicJP6lLn2TtRw==

prettier@^2.6.2:
  version "2.6.2"
  resolved "https://registry.npmjs.org/prettier/-/prettier-2.6.2.tgz"
  integrity sha512-PkUpF+qoXTqhOeWL9fu7As8LXsIUZ1WYaJiY/a7McAQzxjk82OF0tibkFXVCDImZtWxbvojFjerkiLb0/q8mew==

svg-tag-names@^3.0.1:
  version "3.0.1"
  resolved "https://registry.yarnpkg.com/svg-tag-names/-/svg-tag-names-3.0.1.tgz#9a89117c1644104cb798e75f9c3cf18fa8d52231"
  integrity sha512-R5EDS44RQSOwwKIOOUZLKZggMeFL8fDSSZr1hVK5Z0KkyuGVOZfyepBZDkPu/aoL+hSOysxxvAk8uN4yN2LOMQ==

typescript@^4.6.3:
  version "4.6.3"
  resolved "https://registry.npmjs.org/typescript/-/typescript-4.6.3.tgz"
  integrity sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw==