From 4e1f2b3607a9186e6c464fcf5f9e07c6e4daf64f Mon Sep 17 00:00:00 2001 From: Cadence Ember Date: Wed, 22 Dec 2021 00:17:57 +1300 Subject: [PATCH 01/12] Update dependencies --- package-lock.json | 454 +++++++++++++++++++++++++--------------------- package.json | 8 +- 2 files changed, 250 insertions(+), 212 deletions(-) diff --git a/package-lock.json b/package-lock.json index bce45e7..42834df 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,22 +5,21 @@ "requires": true, "dependencies": { "@babel/helper-validator-identifier": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", - "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==" + "version": "7.15.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz", + "integrity": "sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w==" }, "@babel/parser": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.13.tgz", - "integrity": "sha512-z7n7ybOUzaRc3wwqLpAX8UFIXsrVXUJhtNGBwAnLz6d1KUapqyq7ad2La8gZ6CXhHmGAIL32cop8Tst4/PNWLw==" + "version": "7.16.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.16.6.tgz", + "integrity": "sha512-Gr86ujcNuPDnNOY8mi383Hvi8IYrJVJYuf3XcuBM/Dgd+bINn/7tHqsj+tKkoreMbmGsFLsltI/JJd8fOFWGDQ==" }, "@babel/types": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.13.tgz", - "integrity": "sha512-oKrdZTld2im1z8bDwTOQvUbxKwE+854zc16qWZQlcTqMN00pWxHQ4ZeOq0yDMnisOpRykH2/5Qqcrk/OlbAjiQ==", + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.16.0.tgz", + "integrity": "sha512-PJgg/k3SdLsGb3hhisFvtLOw5ts113klrpLuIPtCJIU+BB24fqq6lf8RWqKJEjzqXR9AEH1rIb5XTqwBHB+kQg==", "requires": { - "@babel/helper-validator-identifier": "^7.12.11", - "lodash": "^4.17.19", + "@babel/helper-validator-identifier": "^7.15.7", "to-fast-properties": "^2.0.0" } }, @@ -35,9 +34,9 @@ "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" }, "anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", "requires": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -49,9 +48,9 @@ "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" }, "are-we-there-yet": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", - "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz", + "integrity": "sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g==", "requires": { "delegates": "^1.0.0", "readable-stream": "^2.0.6" @@ -76,18 +75,18 @@ } }, "base64-js": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", - "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==" + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" }, "better-sqlite3": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-7.1.0.tgz", - "integrity": "sha512-FV/snQ8F/kyqhdxsevzbojVtMowDWOfe1A5N3lYu1KJwoho2t7JgITmdlSc7DkOh3Zq65I+ZyeNWXQrkLEDFTg==", + "version": "7.4.5", + "resolved": "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-7.4.5.tgz", + "integrity": "sha512-mybC3dgrtJeHkIRGP36tST7wjBlIMgTRAXhhO4bMpPZ17EG23FZxZeFcwKWy6o8mV1SKQFnQNyeAZlQpGrgheQ==", "requires": { "bindings": "^1.5.0", - "prebuild-install": "^5.3.3", - "tar": "4.4.10" + "prebuild-install": "^7.0.0", + "tar": "^6.1.11" } }, "binary-extensions": { @@ -104,9 +103,9 @@ } }, "bl": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.0.3.tgz", - "integrity": "sha512-fs4G6/Hu4/EE+F75J8DuN/0IpQqNjAdC7aEQv7Qt8MHGUH7Ckv2MwTEEeN9QehD0pfIDkMI1bkHYkKy7xHyKIg==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", "requires": { "buffer": "^5.5.0", "inherits": "^2.0.4", @@ -134,12 +133,12 @@ } }, "buffer": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz", - "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==", + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4" + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" } }, "call-bind": { @@ -160,18 +159,18 @@ } }, "chokidar": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", - "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz", + "integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==", "requires": { - "anymatch": "~3.1.1", + "anymatch": "~3.1.2", "braces": "~3.0.2", - "fsevents": "~2.3.1", - "glob-parent": "~5.1.0", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", - "readdirp": "~3.5.0" + "readdirp": "~3.6.0" } }, "chownr": { @@ -204,16 +203,16 @@ "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==" }, "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" }, "decompress-response": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz", - "integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", "requires": { - "mimic-response": "^2.0.0" + "mimic-response": "^3.1.0" } }, "deep-extend": { @@ -227,9 +226,9 @@ "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" }, "denque": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/denque/-/denque-1.4.1.tgz", - "integrity": "sha512-OfzPuSZKGcgr96rf1oODnfjqBFmr1DVoc/TrItj3Ohe0Ah1C5WX5Baquw/9U9KovnQ88EqmJbD66rKYUQYN1tQ==" + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/denque/-/denque-1.5.1.tgz", + "integrity": "sha512-XwE+iZ4D6ZUB7mfYRMb5wByE8L74HCn30FBN7sWnXksWc1LO1bPDl67pBR9o/kC4z/xSNAwkMYcGgqDV3BE3Hw==" }, "detect-libc": { "version": "1.0.3", @@ -273,17 +272,17 @@ "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" }, "fs-minipass": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", - "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", "requires": { - "minipass": "^2.6.0" + "minipass": "^3.0.0" } }, "fsevents": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.1.tgz", - "integrity": "sha512-YR47Eg4hChJGAB1O3yEAOkGO+rlzutoICGqGo9EZ4lKWokzZRSyIW1QmTzqjtw8MJdj9srP869CuWw/hyzSiBw==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", "optional": true }, "function-bind": { @@ -307,9 +306,9 @@ } }, "get-intrinsic": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.0.tgz", - "integrity": "sha512-M11rgtQp5GZMZzDL7jLTNxbDfurpzuau5uqRWDPvlHjfvg3TdScAZo96GLvhMjImrmR8uAt0FS2RLoMrfWGKlg==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", "requires": { "function-bind": "^1.1.1", "has": "^1.0.3", @@ -322,9 +321,9 @@ "integrity": "sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4=" }, "glob-parent": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", - "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "requires": { "is-glob": "^4.0.1" } @@ -338,9 +337,17 @@ } }, "has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==" + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==" + }, + "has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "requires": { + "has-symbols": "^1.0.2" + } }, "has-unicode": { "version": "2.0.1", @@ -348,9 +355,14 @@ "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" }, "ieee754": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", - "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==" + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + }, + "immutable": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.0.0.tgz", + "integrity": "sha512-zIE9hX70qew5qTUjSS7wi1iwj/l7+m54KWU247nhM3v806UdGj1yDndXj+IOYxxtW9zyLI+xqFNZjTuDaLUqFw==" }, "inherits": { "version": "2.0.4", @@ -358,9 +370,9 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "ini": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" }, "is-binary-path": { "version": "2.1.0", @@ -371,9 +383,9 @@ } }, "is-core-module": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.2.0.tgz", - "integrity": "sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==", + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.0.tgz", + "integrity": "sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw==", "requires": { "has": "^1.0.3" } @@ -401,9 +413,9 @@ } }, "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "requires": { "is-extglob": "^2.1.1" } @@ -419,12 +431,12 @@ "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==" }, "is-regex": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.2.tgz", - "integrity": "sha512-axvdhb5pdhEVThqJzYXwMlVuZwC+FF2DpcOhTS+y/8jVq4trxyPgfcwIxIKiyeuLlSQYKkmUaPQJ8ZE4yNKXDg==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", "requires": { "call-bind": "^1.0.2", - "has-symbols": "^1.0.1" + "has-tostringtag": "^1.0.0" } }, "isarray": { @@ -446,20 +458,23 @@ "promise": "^7.0.1" } }, - "lodash": { - "version": "4.17.20", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", - "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==" + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "requires": { + "yallist": "^4.0.0" + } }, "mime": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.5.0.tgz", - "integrity": "sha512-ft3WayFSFUVBuJj7BMLKAQcSlItKtfjsKDDsii3rqFDAZ7t11zRe8ASw/GlmivGwVUYtwkQrxiGGpL6gFvB0ag==" + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==" }, "mimic-response": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz", - "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==" + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==" }, "minimist": { "version": "1.2.5", @@ -467,20 +482,20 @@ "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" }, "minipass": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", - "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.6.tgz", + "integrity": "sha512-rty5kpw9/z8SX9dmxblFA6edItUmwJgMeYDZRrwlIVN27i8gysGbznJwUggw2V/FVqFSDdWy040ZPS811DYAqQ==", "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" + "yallist": "^4.0.0" } }, "minizlib": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", - "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", "requires": { - "minipass": "^2.9.0" + "minipass": "^3.0.0", + "yallist": "^4.0.0" } }, "mixin-deep": { @@ -489,12 +504,9 @@ "integrity": "sha512-imbHQNRglyaplMmjBLL3V5R6Bfq5oM+ivds3SKgc6oRtzErEnBUUc5No11Z2pilkUvl42gJvi285xTNswcKCMA==" }, "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "requires": { - "minimist": "^1.2.5" - } + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" }, "mkdirp-classic": { "version": "0.5.3", @@ -507,22 +519,20 @@ "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==" }, "node-abi": { - "version": "2.19.1", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.19.1.tgz", - "integrity": "sha512-HbtmIuByq44yhAzK7b9j/FelKlHYISKQn0mtvcBrU5QBkhoCMp5bu8Hv5AI34DcKfOAcJBcOEMwLlwO62FFu9A==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.5.0.tgz", + "integrity": "sha512-LtHvNIBgOy5mO8mPEUtkCW/YCRWYEKshIvqhe1GHHyXEHEB5mgICyYnAcl4qan3uFeRROErKGzatFHPf6kDxWw==", "requires": { - "semver": "^5.4.1" + "semver": "^7.3.5" } }, "node-fetch": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", - "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==" - }, - "noop-logger": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/noop-logger/-/noop-logger-0.1.1.tgz", - "integrity": "sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI=" + "version": "2.6.6", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.6.tgz", + "integrity": "sha512-Z8/6vRlTUChSdIgMa51jxQ4lrw/Jy5SOW10ObaA47/RElsAN2c5Pn8bTgFGWn/ibwzXTE8qwr1Yzx28vsecXEA==", + "requires": { + "whatwg-url": "^5.0.0" + } }, "normalize-path": { "version": "3.0.0", @@ -559,45 +569,43 @@ } }, "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" }, "picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==" + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", + "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==" }, "pinski": { - "version": "git+https://git.sr.ht/~cadence/nodejs-pinski#210be3cfacbd93d44e104698a29abd39494a6271", - "from": "git+https://git.sr.ht/~cadence/nodejs-pinski#210be3cfacbd93d44e104698a29abd39494a6271", + "version": "git+https://git.sr.ht/~cadence/nodejs-pinski#e22095172a061a8271e28272e2e481d541ea6725", + "from": "git+https://git.sr.ht/~cadence/nodejs-pinski#e22095172a061a8271e28272e2e481d541ea6725", "requires": { - "mime": "^2.4.6", - "pug": "^3.0.0", - "sass": "^1.26.10", - "ws": "^7.3.1" + "mime": "^2.5.2", + "pug": "^3.0.2", + "sass": "^1.35.1", + "ws": "^7.4.6" } }, "prebuild-install": { - "version": "5.3.5", - "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-5.3.5.tgz", - "integrity": "sha512-YmMO7dph9CYKi5IR/BzjOJlRzpxGGVo1EsLSUZ0mt/Mq0HWZIHOKHHcHdT69yG54C9m6i45GpItwRHpk0Py7Uw==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.0.0.tgz", + "integrity": "sha512-IvSenf33K7JcgddNz2D5w521EgO+4aMMjFt73Uk9FRzQ7P+QZPKrp7qPsDydsSwjGt3T5xRNnM1bj1zMTD5fTA==", "requires": { "detect-libc": "^1.0.3", "expand-template": "^2.0.3", "github-from-package": "0.0.0", "minimist": "^1.2.3", - "mkdirp": "^0.5.1", + "mkdirp-classic": "^0.5.3", "napi-build-utils": "^1.0.1", - "node-abi": "^2.7.0", - "noop-logger": "^0.1.1", + "node-abi": "^3.3.0", "npmlog": "^4.0.1", "pump": "^3.0.0", "rc": "^1.2.7", - "simple-get": "^3.0.3", + "simple-get": "^4.0.0", "tar-fs": "^2.0.0", - "tunnel-agent": "^0.6.0", - "which-pm-runs": "^1.0.0" + "tunnel-agent": "^0.6.0" } }, "process-nextick-args": { @@ -614,17 +622,17 @@ } }, "pug": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pug/-/pug-3.0.0.tgz", - "integrity": "sha512-inmsJyFBSHZaiGLaguoFgJGViX0If6AcfcElimvwj9perqjDpUpw79UIEDZbWFmoGVidh08aoE+e8tVkjVJPCw==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/pug/-/pug-3.0.2.tgz", + "integrity": "sha512-bp0I/hiK1D1vChHh6EfDxtndHji55XP/ZJKwsRqrz6lRia6ZC2OZbdAymlxdVFwd1L70ebrVJw4/eZ79skrIaw==", "requires": { - "pug-code-gen": "^3.0.0", + "pug-code-gen": "^3.0.2", "pug-filters": "^4.0.0", - "pug-lexer": "^5.0.0", + "pug-lexer": "^5.0.1", "pug-linker": "^4.0.0", "pug-load": "^3.0.0", "pug-parser": "^6.0.0", - "pug-runtime": "^3.0.0", + "pug-runtime": "^3.0.1", "pug-strip-comments": "^2.0.0" } }, @@ -639,9 +647,9 @@ } }, "pug-code-gen": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/pug-code-gen/-/pug-code-gen-3.0.1.tgz", - "integrity": "sha512-xJIGvmXTQlkJllq6hqxxjRWcay2F9CU69TuAuiVZgHK0afOhG5txrQOcZyaPHBvSWCU/QQOqEp5XCH94rRZpBQ==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/pug-code-gen/-/pug-code-gen-3.0.2.tgz", + "integrity": "sha512-nJMhW16MbiGRiyR4miDTQMRWDgKplnHyeLvioEJYbk1RsPI3FuA3saEP8uwnTb2nTJEKBU90NFVWJBk4OU5qyg==", "requires": { "constantinople": "^4.0.1", "doctypes": "^1.1.0", @@ -671,9 +679,9 @@ } }, "pug-lexer": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/pug-lexer/-/pug-lexer-5.0.0.tgz", - "integrity": "sha512-52xMk8nNpuyQ/M2wjZBN5gXQLIylaGkAoTk5Y1pBhVqaopaoj8Z0iVzpbFZAqitL4RHNVDZRnJDsqEYe99Ti0A==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/pug-lexer/-/pug-lexer-5.0.1.tgz", + "integrity": "sha512-0I6C62+keXlZPZkOJeVam9aBLVP2EnbeDw3An+k0/QlqdwH6rv8284nko14Na7c0TtqtogfWXcRoFE4O4Ff20w==", "requires": { "character-parser": "^2.2.0", "is-expression": "^4.0.0", @@ -708,9 +716,9 @@ } }, "pug-runtime": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pug-runtime/-/pug-runtime-3.0.0.tgz", - "integrity": "sha512-GoEPcmQNnaTsePEdVA05bDpY+Op5VLHKayg08AQiqJBWU/yIaywEYv7TetC5dEQS3fzBBoyb2InDcZEg3mPTIA==" + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/pug-runtime/-/pug-runtime-3.0.1.tgz", + "integrity": "sha512-L50zbvrQ35TkpHwv0G6aLSuueDRwc/97XdY8kL3tOT0FmhgG7UypU3VztfV/LATAvmUfYi4wNxSajhSAeNN+Kg==" }, "pug-strip-comments": { "version": "2.0.0", @@ -760,19 +768,19 @@ } }, "readdirp": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", - "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "requires": { "picomatch": "^2.2.1" } }, "resolve": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz", - "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==", + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", + "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", "requires": { - "is-core-module": "^2.1.0", + "is-core-module": "^2.2.0", "path-parse": "^1.0.6" } }, @@ -782,17 +790,22 @@ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, "sass": { - "version": "1.32.6", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.32.6.tgz", - "integrity": "sha512-1bcDHDcSqeFtMr0JXI3xc/CXX6c4p0wHHivJdru8W7waM7a1WjKMm4m/Z5sY7CbVw4Whi2Chpcw6DFfSWwGLzQ==", + "version": "1.45.1", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.45.1.tgz", + "integrity": "sha512-pwPRiq29UR0o4X3fiQyCtrESldXvUQAAE0QmcJTpsI4kuHHcLzZ54M1oNBVIXybQv8QF2zfkpFcTxp8ta97dUA==", "requires": { - "chokidar": ">=2.0.0 <4.0.0" + "chokidar": ">=3.0.0 <4.0.0", + "immutable": "^4.0.0", + "source-map-js": ">=0.6.2 <2.0.0" } }, "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "requires": { + "lru-cache": "^6.0.0" + } }, "set-blocking": { "version": "2.0.0", @@ -800,9 +813,9 @@ "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" }, "signal-exit": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", - "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==" + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.6.tgz", + "integrity": "sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ==" }, "simple-concat": { "version": "1.0.1", @@ -810,15 +823,20 @@ "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==" }, "simple-get": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.0.tgz", - "integrity": "sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.0.tgz", + "integrity": "sha512-ZalZGexYr3TA0SwySsr5HlgOOinS4Jsa8YB2GJ6lUNAazyAu4KG/VmzMTwAt2YVXzzVj8QmefmAonZIK2BSGcQ==", "requires": { - "decompress-response": "^4.2.0", + "decompress-response": "^6.0.0", "once": "^1.3.1", "simple-concat": "^1.0.0" } }, + "source-map-js": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.1.tgz", + "integrity": "sha512-4+TN2b3tqOCd/kaGRJ/sTYA0tR0mdXx26ipdolxcwtJVqEnqNYvlCAt1q3ypy4QMlYus+Zh34RNtYLoq2oQ4IA==" + }, "string-width": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", @@ -851,36 +869,42 @@ "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" }, "tar": { - "version": "4.4.10", - "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.10.tgz", - "integrity": "sha512-g2SVs5QIxvo6OLp0GudTqEf05maawKUxXru104iaayWA09551tFCTI8f1Asb4lPfkBr91k07iL4c11XO3/b0tA==", + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz", + "integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==", "requires": { - "chownr": "^1.1.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.3.5", - "minizlib": "^1.2.1", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.2", - "yallist": "^3.0.3" + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^3.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "dependencies": { + "chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==" + } } }, "tar-fs": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.0.tgz", - "integrity": "sha512-9uW5iDvrIMCVpvasdFHW0wJPez0K4JnMZtsuIeDI7HyMGJNxmDZDOCQROr7lXyS+iL/QMpj07qcjGYTSdRFXUg==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", "requires": { "chownr": "^1.1.1", "mkdirp-classic": "^0.5.2", "pump": "^3.0.0", - "tar-stream": "^2.0.0" + "tar-stream": "^2.1.4" } }, "tar-stream": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.3.tgz", - "integrity": "sha512-Z9yri56Dih8IaK8gncVPx4Wqt86NDmQTSh49XLZgjWpGZL9GK9HKParS2scqHCC4w6X9Gh2jwaU45V47XTKwVA==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", "requires": { - "bl": "^4.0.1", + "bl": "^4.0.3", "end-of-stream": "^1.4.1", "fs-constants": "^1.0.0", "inherits": "^2.0.3", @@ -917,6 +941,11 @@ "resolved": "https://registry.npmjs.org/token-stream/-/token-stream-1.0.0.tgz", "integrity": "sha1-zCAOqyYT9BZtJ/+a/HylbUnfbrQ=" }, + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" + }, "tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", @@ -935,17 +964,26 @@ "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz", "integrity": "sha1-YU9/v42AHwu18GYfWy9XhXUOTwk=" }, - "which-pm-runs": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz", - "integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=" + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" + }, + "whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", + "requires": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } }, "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", + "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", "requires": { - "string-width": "^1.0.2 || 2" + "string-width": "^1.0.2 || 2 || 3 || 4" } }, "with": { @@ -965,14 +1003,14 @@ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, "ws": { - "version": "7.4.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.3.tgz", - "integrity": "sha512-hr6vCR76GsossIRsr8OLR9acVVm1jyfEWvhbNjtgPOrfvAlKzvyeg/P6r8RuDjRyrcQoPQT7K0DGEPc7Ae6jzA==" + "version": "7.5.6", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.6.tgz", + "integrity": "sha512-6GLgCqo2cy2A2rjCNFlxQS6ZljG/coZfZXclldI8FB/1G3CCI36Zd8xy2HrFVACi8tfk5XrgLQEk+P0Tnz9UcA==" }, "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" } } } diff --git a/package.json b/package.json index 8955288..e3b697a 100644 --- a/package.json +++ b/package.json @@ -10,11 +10,11 @@ "author": "", "license": "AGPL-3.0", "dependencies": { - "better-sqlite3": "^7.1.0", + "better-sqlite3": "^7.4.5", "cookie": "^0.4.1", - "denque": "^1.4.1", + "denque": "^1.5.1", "mixin-deep": "^2.0.1", - "node-fetch": "^2.6.0", - "pinski": "git+https://git.sr.ht/~cadence/nodejs-pinski#210be3cfacbd93d44e104698a29abd39494a6271" + "node-fetch": "^2.6.6", + "pinski": "git+https://git.sr.ht/~cadence/nodejs-pinski#e22095172a061a8271e28272e2e481d541ea6725" } } From 0d23d66700a146643b3dc85b714d76c119da4fd8 Mon Sep 17 00:00:00 2001 From: Cadence Ember Date: Tue, 28 Dec 2021 16:32:11 +1300 Subject: [PATCH 02/12] Add theme support, light theme, and edgeless light --- api/channels.js | 2 +- api/filters.js | 15 ++++--- api/pages.js | 25 +++++++++-- api/search.js | 2 +- api/video.js | 8 ++-- ...down-wide.svg => arrow-down-wide-dark.svg} | 0 html/static/images/arrow-down-wide-light.svg | 1 + html/static/images/settings.svg | 2 +- html/static/images/subscriptions.svg | 2 +- pug/includes/layout.pug | 11 ++--- pug/settings.pug | 10 +++++ pug/subscriptions.pug | 4 +- pug/video.pug | 1 + sass/dark.sass | 9 ++++ sass/edgeless-light.sass | 4 ++ sass/includes/{base.sass => _base.sass} | 33 ++++++++------ sass/includes/{buttons.sass => _buttons.sass} | 26 ++++++----- ...-think-page.sass => _cant-think-page.sass} | 10 +++-- .../{channel-page.sass => _channel-page.sass} | 17 ++++--- .../{filters-page.sass => _filters-page.sass} | 20 +++++---- sass/includes/{footer.sass => _footer.sass} | 7 ++- sass/includes/{forms.sass => _forms.sass} | 39 ++++++++-------- .../{home-page.sass => _home-page.sass} | 8 ++-- ...licenses-page.sass => _licenses-page.sass} | 2 + sass/includes/_main.sass | 32 +++++++++++++ sass/includes/{nav.sass => _nav.sass} | 27 ++++++----- .../{privacy-page.sass => _privacy-page.sass} | 2 + .../{search-page.sass => _search-page.sass} | 6 ++- ...settings-page.sass => _settings-page.sass} | 11 +++-- ...ons-page.sass => _subscriptions-page.sass} | 10 +++-- sass/includes/_takedown-page.sass | 16 +++++++ ...o-list-item.sass => _video-list-item.sass} | 33 +++++++------- .../{video-page.sass => _video-page.sass} | 45 ++++++++++++------- sass/includes/colors.sass | 17 ------- sass/includes/takedown-page.sass | 14 ------ sass/light.sass | 2 + sass/main.sass | 30 ------------- sass/theme-modules/_edgeless.sass | 27 +++++++++++ sass/themes/_dark.scss | 38 ++++++++++++++++ sass/themes/_edgeless-light.scss | 8 ++++ sass/themes/_light.scss | 38 ++++++++++++++++ server.js | 12 ++--- utils/constants.js | 4 ++ utils/icon-loader.js | 8 ++++ utils/upgradedb.js | 7 ++- 45 files changed, 433 insertions(+), 212 deletions(-) rename html/static/images/{arrow-down-wide.svg => arrow-down-wide-dark.svg} (100%) create mode 100644 html/static/images/arrow-down-wide-light.svg create mode 100644 sass/dark.sass create mode 100644 sass/edgeless-light.sass rename sass/includes/{base.sass => _base.sass} (55%) rename sass/includes/{buttons.sass => _buttons.sass} (66%) rename sass/includes/{cant-think-page.sass => _cant-think-page.sass} (88%) rename sass/includes/{channel-page.sass => _channel-page.sass} (77%) rename sass/includes/{filters-page.sass => _filters-page.sass} (64%) rename sass/includes/{footer.sass => _footer.sass} (76%) rename sass/includes/{forms.sass => _forms.sass} (75%) rename sass/includes/{home-page.sass => _home-page.sass} (80%) rename sass/includes/{licenses-page.sass => _licenses-page.sass} (71%) create mode 100644 sass/includes/_main.sass rename sass/includes/{nav.sass => _nav.sass} (52%) rename sass/includes/{privacy-page.sass => _privacy-page.sass} (69%) rename sass/includes/{search-page.sass => _search-page.sass} (63%) rename sass/includes/{settings-page.sass => _settings-page.sass} (77%) rename sass/includes/{subscriptions-page.sass => _subscriptions-page.sass} (83%) create mode 100644 sass/includes/_takedown-page.sass rename sass/includes/{video-list-item.sass => _video-list-item.sass} (84%) rename sass/includes/{video-page.sass => _video-page.sass} (77%) delete mode 100644 sass/includes/colors.sass delete mode 100644 sass/includes/takedown-page.sass create mode 100644 sass/light.sass delete mode 100644 sass/main.sass create mode 100644 sass/theme-modules/_edgeless.sass create mode 100644 sass/themes/_dark.scss create mode 100644 sass/themes/_edgeless-light.scss create mode 100644 sass/themes/_light.scss create mode 100644 utils/icon-loader.js diff --git a/api/channels.js b/api/channels.js index 4751d5a..de9bc2c 100644 --- a/api/channels.js +++ b/api/channels.js @@ -24,7 +24,7 @@ module.exports = [ video.watched = watchedVideos.includes(video.videoId) }) } - return render(200, "pug/channel.pug", {url, data, subscribed, instanceOrigin}) + return render(200, "pug/channel.pug", {settings, url, data, subscribed, instanceOrigin}) } } ] diff --git a/api/filters.js b/api/filters.js index 189af7b..0563a60 100644 --- a/api/filters.js +++ b/api/filters.js @@ -9,8 +9,7 @@ const {Matcher, PatternCompileError} = require("../utils/matcher") const filterMaxLength = 160 const regexpEnabledText = constants.server_setup.allow_regexp_filters ? "" : "not" -function getCategories(req) { - const user = getUser(req) +function getCategories(user) { const filters = user.getFilters() // Sort filters into categories for display. Titles are already sorted. @@ -39,7 +38,9 @@ function getCategories(req) { module.exports = [ { route: "/filters", methods: ["GET"], code: async ({req, url}) => { - const categories = getCategories(req) + const user = getUser(req) + const categories = getCategories(user) + const settings = user.getSettingsOrDefaults() let referrer = url.searchParams.get("referrer") || null let type = null @@ -54,7 +55,7 @@ module.exports = [ label = url.searchParams.get("label") } - return render(200, "pug/filters.pug", {categories, type, contents, label, referrer, filterMaxLength, regexpEnabledText}) + return render(200, "pug/filters.pug", {settings, categories, type, contents, label, referrer, filterMaxLength, regexpEnabledText}) } }, { @@ -100,8 +101,10 @@ module.exports = [ return true }, state => { const {type, contents, label, compileError} = state - const categories = getCategories(req) - return render(400, "pug/filters.pug", {categories, type, contents, label, compileError, filterMaxLength, regexpEnabledText}) + const user = getUser(req) + const categories = getCategories(user) + const settings = user.getSettingsOrDefaults() + return render(400, "pug/filters.pug", {settings, categories, type, contents, label, compileError, filterMaxLength, regexpEnabledText}) }) .last(state => { const {type, contents, label} = state diff --git a/api/pages.js b/api/pages.js index 88e8635..761052f 100644 --- a/api/pages.js +++ b/api/pages.js @@ -1,16 +1,35 @@ const {render} = require("pinski/plugins") +const {getUser} = require("../utils/getuser") module.exports = [ { route: "/", methods: ["GET"], code: async ({req}) => { const userAgent = req.headers["user-agent"] || "" const mobile = userAgent.toLowerCase().includes("mobile") - return render(200, "pug/home.pug", {mobile}) + const user = getUser(req) + const settings = user.getSettingsOrDefaults() + return render(200, "pug/home.pug", {settings, mobile}) } }, { - route: "/js-licenses", methods: ["GET"], code: async () => { - return render(200, "pug/js-licenses.pug") + route: "/(?:js-)?licenses", methods: ["GET"], code: async ({req}) => { + const user = getUser(req) + const settings = user.getSettingsOrDefaults() + return render(200, "pug/licenses.pug", {settings}) + } + }, + { + route: "/cant-think", methods: ["GET"], code: async ({req}) => { + const user = getUser(req) + const settings = user.getSettingsOrDefaults() + return render(200, "pug/cant-think.pug", {settings}) + } + }, + { + route: "/privacy", methods: ["GET"], code: async ({req}) => { + const user = getUser(req) + const settings = user.getSettingsOrDefaults() + return render(200, "pug/privacy.pug", {settings}) } } ] diff --git a/api/search.js b/api/search.js index 223b3b6..9cc9277 100644 --- a/api/search.js +++ b/api/search.js @@ -26,7 +26,7 @@ module.exports = [ const filters = user.getFilters() results = converters.applyVideoFilters(results, filters).videos - return render(200, "pug/search.pug", {url, query, results, instanceOrigin}) + return render(200, "pug/search.pug", {settings, url, query, results, instanceOrigin}) } } ] diff --git a/api/video.js b/api/video.js index 1161fd5..89084fa 100644 --- a/api/video.js +++ b/api/video.js @@ -111,7 +111,7 @@ module.exports = [ // Check if playback is allowed const videoTakedownInfo = db.prepare("SELECT id, org, url FROM TakedownVideos WHERE id = ?").get(id) if (videoTakedownInfo) { - return render(451, "pug/takedown-video.pug", videoTakedownInfo) + return render(451, "pug/takedown-video.pug", Object.assign({settings}, videoTakedownInfo)) } // Media fragment @@ -129,7 +129,7 @@ module.exports = [ // Work out how to fetch the video if (req.method === "GET") { if (settings.local) { // skip to the local fetching page, which will then POST video data in a moment - return render(200, "pug/local-video.pug", {id}) + return render(200, "pug/local-video.pug", {settings, id}) } var instanceOrigin = settings.instance var outURL = `${instanceOrigin}/api/v1/videos/${id}` @@ -153,7 +153,7 @@ module.exports = [ // automatically add the entry to the videos list, so it won't be fetched again const args = {id, ...channelTakedownInfo} db.prepare("INSERT INTO TakedownVideos (id, org, url) VALUES (@id, @org, @url)").run(args) - return render(451, "pug/takedown-video.pug", channelTakedownInfo) + return render(451, "pug/takedown-video.pug", Object.assign({settings}, channelTakedownInfo)) } // process stream list ordering @@ -225,7 +225,7 @@ module.exports = [ // Create appropriate formatted message const message = render(0, `pug/errors/${errorType}.pug`, locals).content - return render(500, "pug/video.pug", {video: {videoId: id}, error: true, message}) + return render(500, "pug/video.pug", {video: {videoId: id}, error: true, message, settings}) } } } diff --git a/html/static/images/arrow-down-wide.svg b/html/static/images/arrow-down-wide-dark.svg similarity index 100% rename from html/static/images/arrow-down-wide.svg rename to html/static/images/arrow-down-wide-dark.svg diff --git a/html/static/images/arrow-down-wide-light.svg b/html/static/images/arrow-down-wide-light.svg new file mode 100644 index 0000000..3be01f2 --- /dev/null +++ b/html/static/images/arrow-down-wide-light.svg @@ -0,0 +1 @@ + diff --git a/html/static/images/settings.svg b/html/static/images/settings.svg index a28bb15..c381540 100644 --- a/html/static/images/settings.svg +++ b/html/static/images/settings.svg @@ -1 +1 @@ - \ No newline at end of file +Settings diff --git a/html/static/images/subscriptions.svg b/html/static/images/subscriptions.svg index 420d620..0399a04 100644 --- a/html/static/images/subscriptions.svg +++ b/html/static/images/subscriptions.svg @@ -1 +1 @@ - \ No newline at end of file +Subscriptions diff --git a/pug/includes/layout.pug b/pug/includes/layout.pug index c837122..2cc0d91 100644 --- a/pug/includes/layout.pug +++ b/pug/includes/layout.pug @@ -3,7 +3,8 @@ html head meta(charset="utf-8") meta(name="viewport" content="width=device-width, initial-scale=1") - link(rel="stylesheet" type="text/css" href=getStaticURL("sass", "/main.sass")) + - const theme = settings && ["dark", "light", "edgeless-light"][settings.theme] || "dark" + link(rel="stylesheet" type="text/css" href=getStaticURL("sass", `/${theme}.sass`)) script(type="module" src=getStaticURL("html", "/static/js/focus.js")) block head @@ -15,13 +16,9 @@ html .links a(href="/").link.home CloudTube a(href="/subscriptions" title="Subscriptions").link.icon-link - svg(width=30 height=25) - image(href=getStaticURL("html", "/static/images/subscriptions.svg") alt="Subscriptions.").icon - title Subscriptions + != icons.get("subscriptions") a(href="/settings" title="Settings").link.icon-link - svg(width=25 height=25) - image(href=getStaticURL("html", "/static/images/settings.svg") alt="Settings.").icon - title Settings + != icons.get("settings") form(method="get" action="/search").search-form input(type="text" placeholder="Search" aria-label="Search a video" name="q" autocomplete="off" value=query).search diff --git a/pug/settings.pug b/pug/settings.pug index 80fda31..16f5741 100644 --- a/pug/settings.pug +++ b/pug/settings.pug @@ -36,6 +36,16 @@ block content form(method="post" action="/settings") +fieldset("Settings") + +select({ + id: "theme", + label: "Theme", + options: [ + {value: "0", text: "Standard dark"}, + {value: "1", text: "Standard light"}, + {value: "2", text: "Edgeless light"} + ] + }) + +input({ id: "instance", label: "Instance", diff --git a/pug/subscriptions.pug b/pug/subscriptions.pug index 4e8fbef..2846b01 100644 --- a/pug/subscriptions.pug +++ b/pug/subscriptions.pug @@ -31,8 +31,8 @@ block content if settings.save_history input(type="checkbox" id="watched-videos-display") - .watched-videos-display-container - label(for="watched-videos-display").watched-videos-display-label Hide watched videos + .checkbox-hider__container + label(for="watched-videos-display").checkbox-hider__label Hide watched videos each video in videos +video_list_item("subscriptions-video", video, instanceOrigin, {showMarkWatched: settings.save_history && !video.watched}) diff --git a/pug/video.pug b/pug/video.pug index 1000b92..28b8416 100644 --- a/pug/video.pug +++ b/pug/video.pug @@ -21,6 +21,7 @@ block content noscript meta(http-equiv="refresh" content=`${video.lengthSeconds+5};url=/watch?v=${first.videoId}&continuous=1&session-watched=${sessionWatchedNext}`) .video-page(class={ + "video-page--recommended-side": settings.recommended_mode === 0, "video-page--recommended-below": settings.recommended_mode === 1, "video-page--recommended-hidden": settings.recommended_mode === 2 }) diff --git a/sass/dark.sass b/sass/dark.sass new file mode 100644 index 0000000..fa4b58c --- /dev/null +++ b/sass/dark.sass @@ -0,0 +1,9 @@ +@use "themes/dark" as * +@use "includes/main" with ($_theme: $theme) + +@use "theme-modules/edgeless" with ($_theme: $theme) + +// navigation shadow +.main-nav + position: relative // needed for box shadow to overlap related videos section + box-shadow: 0px 0px 20px 5px rgba(0, 0, 0, 0.1) diff --git a/sass/edgeless-light.sass b/sass/edgeless-light.sass new file mode 100644 index 0000000..48ed88d --- /dev/null +++ b/sass/edgeless-light.sass @@ -0,0 +1,4 @@ +@use "themes/edgeless-light" as * +@use "includes/main" with ($_theme: $theme) + +@use "theme-modules/edgeless" with ($_theme: $theme) diff --git a/sass/includes/base.sass b/sass/includes/_base.sass similarity index 55% rename from sass/includes/base.sass rename to sass/includes/_base.sass index fa23dd3..06a7521 100644 --- a/sass/includes/base.sass +++ b/sass/includes/_base.sass @@ -1,8 +1,10 @@ -@use "colors.sass" as c +$_theme: () !default + +@use "sass:map" body - background-color: c.$bg-dark - color: c.$fg-main + background-color: map.get($_theme, "bg-2") + color: map.get($_theme, "fg-main") font-family: "Bariol", sans-serif font-size: 18px margin: 0 @@ -13,13 +15,13 @@ body flex-direction: column a - color: c.$link + color: map.get($_theme, "link") pre, code font-size: 0.88em code - background: c.$bg-darker + background: map.get($_theme, "bg-1") padding: 3px 5px border-radius: 4px @@ -32,7 +34,7 @@ button cursor: pointer ::placeholder - color: #c4c4c4 + color: map.get($_theme, "placeholder") opacity: 1 // focus section @@ -48,19 +50,20 @@ button select:-moz-focusring color: transparent - text-shadow: 0 0 0 c.$fg-bright + text-shadow: 0 0 0 map.get($_theme, "fg-bright") body.show-focus a, select, button, input, video, summary &:focus - outline: 2px dotted #ddd + outline: 2px dotted map.get($_theme, "fg-main") video background-color: black details - background-color: c.$bg-accent-x + background-color: map.get($_theme, "bg-3") padding: 12px + border: 1px solid map.get($_theme, "edge-grey") border-radius: 8px summary @@ -68,20 +71,22 @@ details line-height: 1 margin-bottom: 0 user-select: none - color: c.$fg-main + color: map.get($_theme, "fg-main") &[open] summary - margin-bottom: 16px + padding-bottom: 12px + border-bottom: 1px solid map.get($_theme, "edge-grey") + margin-bottom: 8px table - background-color: c.$bg-darker + background-color: map.get($_theme, "bg-1") table, td, th - border: 1px solid c.$edge-grey + border: 1px solid map.get($_theme, "edge-grey") border-collapse: collapse td, th padding: 4px 8px thead, tr:nth-child(even) - background-color: c.$bg-darkest + background-color: map.get($_theme, "bg-0") diff --git a/sass/includes/buttons.sass b/sass/includes/_buttons.sass similarity index 66% rename from sass/includes/buttons.sass rename to sass/includes/_buttons.sass index 6a40741..162c573 100644 --- a/sass/includes/buttons.sass +++ b/sass/includes/_buttons.sass @@ -1,10 +1,12 @@ +$_theme: () !default + @use "sass:selector" -@use "colors.sass" as c +@use "sass:map" @mixin button-base -webkit-appearance: none -moz-appearance: none - color: c.$fg-bright + color: map.get($_theme, "fg-bright") border: none border-radius: 4px padding: 8px @@ -14,7 +16,7 @@ @at-root #{selector.unify(&, "select")} padding: 8px 27px 8px 8px - background: url(/static/images/arrow-down-wide.svg) right 53% no-repeat c.$bg-accent-x + background: map.get($_theme, "image-dropdown") right 53% no-repeat map.get($_theme, "bg-4") @at-root #{selector.unify(&, "a")} padding: 7px 8px @@ -31,12 +33,12 @@ @mixin button-bg @include button-base - background-color: c.$bg-accent-x + background-color: map.get($_theme, "bg-4") @mixin border-button @include button-bg - border: 1px solid c.$edge-grey + border: 1px solid map.get($_theme, "edge-grey") @mixin button-size margin: 4px @@ -44,10 +46,10 @@ @mixin button-hover &:hover - background-color: c.$bg-accent + background-color: map.get($_theme, "bg-3") &:active - background-color: c.$bg-dark + background-color: map.get($_theme, "bg-2") .base-border-look @include border-button @@ -62,13 +64,13 @@ @include button-size -webkit-appearance: none -moz-appearance: none - color: c.$fg-bright + color: map.get($_theme, "fg-bright") text-decoration: none line-height: 1.25 margin: 0 padding: 8px 20px - background: c.$bg-accent - border: solid c.$bg-darker + background: map.get($_theme, "bg-3") + border: solid map.get($_theme, "edge-grey") border-width: 1px 0px 0px text-align: left @@ -76,7 +78,7 @@ border-width: 1px 0px 1px &:hover - background: c.$bg-accent-x + background: map.get($_theme, "bg-4") &:active - background: c.$bg-darker + background: map.get($_theme, "bg-1") diff --git a/sass/includes/cant-think-page.sass b/sass/includes/_cant-think-page.sass similarity index 88% rename from sass/includes/cant-think-page.sass rename to sass/includes/_cant-think-page.sass index ae9a594..36399ef 100644 --- a/sass/includes/cant-think-page.sass +++ b/sass/includes/_cant-think-page.sass @@ -1,5 +1,7 @@ +$_theme: () !default + @use "sass:list" -@use "colors.sass" as c +@use "sass:map" .cant-think-page .main-nav @@ -13,7 +15,7 @@ box-sizing: border-box .page-narration - background-color: c.$bg-accent + background-color: map.get($_theme, "bg-3") border: 1px solid #aaa color: #fff border-radius: 0 @@ -28,7 +30,7 @@ .leave margin: 26px 32px !important - color: #aaa + color: map.get($_theme, "fg-dim") $sizes: 14px 16px 21px 30px 72px @each $size in $sizes @@ -37,7 +39,7 @@ &.leave__final font-weight: bold - color: #f2f2f2 + color: map.get($_theme, "fg-bright") text-align: center .leave__actions diff --git a/sass/includes/channel-page.sass b/sass/includes/_channel-page.sass similarity index 77% rename from sass/includes/channel-page.sass rename to sass/includes/_channel-page.sass index 2b4cfd8..7f91f61 100644 --- a/sass/includes/channel-page.sass +++ b/sass/includes/_channel-page.sass @@ -1,6 +1,8 @@ -@use "colors.sass" as c -@use "video-list-item.sass" as * -@use "_dimensions.sass" as dimensions +$_theme: () !default + +@use "sass:map" +@use "_dimensions" as dimensions +@use "video-list-item" as * .channel-page padding: 40px 20px 20px @@ -17,7 +19,7 @@ align-self: flex-start .channel-data - background-color: c.$bg-darker + background-color: map.get($_theme, "bg-1") padding: 24px margin: 12px 0px 24px border-radius: 8px @@ -44,11 +46,11 @@ .name font-size: 30px font-weight: normal - color: c.$fg-bright + color: map.get($_theme, "fg-bright") margin: 0 .subscribers - color: c.$fg-main + color: map.get($_theme, "fg-main") font-size: 18px .subscribe-form @@ -61,7 +63,8 @@ line-height: 1 border-radius: 8px font-size: 22px - background-color: c.$power-deep + background-color: map.get($_theme, "power-deep") + color: map.get($_theme, "power-fg") border: none .description diff --git a/sass/includes/filters-page.sass b/sass/includes/_filters-page.sass similarity index 64% rename from sass/includes/filters-page.sass rename to sass/includes/_filters-page.sass index 4525f2b..85e42b3 100644 --- a/sass/includes/filters-page.sass +++ b/sass/includes/_filters-page.sass @@ -1,10 +1,12 @@ -@use "colors.sass" as c +$_theme: () !default + +@use "sass:map" @mixin filter-notice margin-top: 24px padding: 12px border-radius: 8px - background-color: c.$bg-darker + background-color: map.get($_theme, "bg-1") white-space: pre-line .filters-page @@ -20,23 +22,23 @@ .filter-confirmation-notice @include filter-notice - color: c.$fg-warning + color: map.get($_theme, "fg-warning") .filter-compile-error @include filter-notice &__header - color: c.$fg-warning + color: map.get($_theme, "fg-warning") &__trace - background-color: c.$bg-darkest + background-color: map.get($_theme, "bg-0") padding: 6px .save-filter margin-top: 12px .border-look - background-color: c.$bg-darker + background-color: map.get($_theme, "bg-1") font-size: 22px padding: 7px 16px 8px font-size: 24px @@ -48,17 +50,17 @@ .filter display: flex padding: 5px 0 - border-top: 1px solid c.$edge-grey + border-top: 1px solid map.get($_theme, "edge-grey") &:last-child - border-bottom: 1px solid c.$edge-grey + border-bottom: 1px solid map.get($_theme, "edge-grey") &__details flex: 1 &__type font-size: 15px - color: c.$fg-dim + color: map.get($_theme, "fg-dim") &__remove flex-shrink: 0 diff --git a/sass/includes/footer.sass b/sass/includes/_footer.sass similarity index 76% rename from sass/includes/footer.sass rename to sass/includes/_footer.sass index b624fa5..e0012c1 100644 --- a/sass/includes/footer.sass +++ b/sass/includes/_footer.sass @@ -1,4 +1,6 @@ -@use "./colors.sass" as c +$_theme: () !default + +@use "sass:map" .footer__container flex: 1 @@ -10,9 +12,10 @@ display: flex flex-direction: column align-items: center - background-color: c.$bg-darkest + background-color: map.get($_theme, "bg-dim") margin: 40px 0 0 padding: 10px 10px 30px + border-top: 1px solid map.get($_theme, "edge-grey") .footer__cols display: flex diff --git a/sass/includes/forms.sass b/sass/includes/_forms.sass similarity index 75% rename from sass/includes/forms.sass rename to sass/includes/_forms.sass index 7c8f0a7..e946d19 100644 --- a/sass/includes/forms.sass +++ b/sass/includes/_forms.sass @@ -1,7 +1,9 @@ -@use "colors.sass" as c +$_theme: () !default + +@use "sass:map" @mixin disabled - background-color: c.$bg-dark + background-color: map.get($_theme, "bg-2") color: #808080 fieldset @@ -20,7 +22,7 @@ fieldset font-size: 28px font-weight: bold padding: 0 - border-bottom: 1px solid #333 + border-bottom: 1px solid map.get($_theme, "edge-grey") // TODO: originally contrasted more line-height: 1.56 @media screen and (max-width: 400px) @@ -36,7 +38,7 @@ fieldset position: relative padding-bottom: 5px margin-bottom: 5px - border-bottom: 1px solid #999 + border-bottom: 1px solid map.get($_theme, "edge-grey") @media screen and (max-width: 400px) flex-direction: column @@ -52,7 +54,7 @@ fieldset &__label grid-area: label padding: 8px 8px 8px 0px - color: #fff + color: map.get($_theme, "fg-main") &__input grid-area: input @@ -63,7 +65,7 @@ fieldset white-space: pre-line margin: 12px 0px 18px font-size: 16px - color: #ccc + color: map.get($_theme, "fg-dim") line-height: 1.2 // @@ -79,7 +81,7 @@ fieldset width: 16px height: 16px padding: 0px - border: 1px solid #666 + border: 1px solid map.get($_theme, "edge-grey") border-radius: 3px margin-left: 8px position: relative @@ -110,18 +112,19 @@ fieldset height: 42px margin: 0 - .#{$base}-container - position: relative - display: grid // why does the default not work??? - top: -42px - background: c.$bg-accent-x - line-height: 1 - border-radius: 8px - margin-bottom: -18px +.checkbox-hider__container + position: relative + display: grid // why does the default not work??? + top: -42px + background: map.get($_theme, "bg-3") + line-height: 1 + border: 1px solid map.get($_theme, "edge-grey") + border-radius: 8px + margin-bottom: -18px - .#{$base}-label - padding: 12px 0px 12px 32px - cursor: pointer + .checkbox-hider__label + padding: 12px 0px 12px 32px + cursor: pointer @mixin single-button-form display: inline-block diff --git a/sass/includes/home-page.sass b/sass/includes/_home-page.sass similarity index 80% rename from sass/includes/home-page.sass rename to sass/includes/_home-page.sass index 77c65b2..0b8b42b 100644 --- a/sass/includes/home-page.sass +++ b/sass/includes/_home-page.sass @@ -1,4 +1,6 @@ -@use "colors.sass" as c +$_theme: () !default + +@use "sass:map" .home-page padding: 40px @@ -18,8 +20,8 @@ padding: 16px border-radius: 4px font-size: 20px - background-color: c.$bg-darker - color: c.$fg-main + background-color: map.get($_theme, "bg-1") + color: map.get($_theme, "fg-main") p margin: 0 32px diff --git a/sass/includes/licenses-page.sass b/sass/includes/_licenses-page.sass similarity index 71% rename from sass/includes/licenses-page.sass rename to sass/includes/_licenses-page.sass index 1794067..0b66909 100644 --- a/sass/includes/licenses-page.sass +++ b/sass/includes/_licenses-page.sass @@ -1,3 +1,5 @@ +$_theme: () !default + .js-licenses-page max-width: 800px margin: 0 auto diff --git a/sass/includes/_main.sass b/sass/includes/_main.sass new file mode 100644 index 0000000..c2a076f --- /dev/null +++ b/sass/includes/_main.sass @@ -0,0 +1,32 @@ +$_theme: () !default + +@use "sass:selector" + +// preload second-level includes with the theme (there will be conflicts due to reconfiguration they are loaded individually) +// this isn't _exactly_ what @forward is supposed to be used for, but it's the best option here +@forward "video-list-item" show _ with ($_theme: $_theme) +@forward "forms" show _ with ($_theme: $_theme) +@forward "buttons" show _ with ($_theme: $_theme) + +@use "base" with ($_theme: $_theme) +@use "video-page" with ($_theme: $_theme) +@use "search-page" with ($_theme: $_theme) +@use "home-page" with ($_theme: $_theme) +@use "channel-page" with ($_theme: $_theme) +@use "subscriptions-page" with ($_theme: $_theme) +@use "settings-page" with ($_theme: $_theme) +@use "cant-think-page" with ($_theme: $_theme) +@use "privacy-page" with ($_theme: $_theme) +@use "licenses-page" with ($_theme: $_theme) +@use "filters-page" with ($_theme: $_theme) +@use "takedown-page" with ($_theme: $_theme) +@use "nav" with ($_theme: $_theme) +@use "footer" with ($_theme: $_theme) + +@font-face + font-family: "Bariol" + src: url(/static/fonts/bariol.woff?statichash=1) + +.button-container + display: flex + flex-wrap: wrap diff --git a/sass/includes/nav.sass b/sass/includes/_nav.sass similarity index 52% rename from sass/includes/nav.sass rename to sass/includes/_nav.sass index f5e66dd..f1eab5f 100644 --- a/sass/includes/nav.sass +++ b/sass/includes/_nav.sass @@ -1,12 +1,14 @@ -@use "colors.sass" as c -@use "buttons.sass" as * -@use "_dimensions.sass" as dimensions +$_theme: () !default + +@use "sass:map" +@use "buttons" as * +@use "_dimensions" as dimensions .main-nav - background-color: c.$bg-accent + background-color: map.get($_theme, "bg-nav") display: flex padding: 8px - box-shadow: 0px 0px 20px 5px rgba(0, 0, 0, 0.1) + border-bottom: 1px solid map.get($_theme, "edge-grey") +dimensions.thin display: block @@ -30,10 +32,16 @@ font-weight: bold &, &:visited - color: #fff + color: map.get($_theme, "fg-bright") &:focus, &:hover - background-color: c.$bg-accent-x + background-color: map.get($_theme, "bg-4") + + &.icon-link + color: map.get($_theme, "fg-dim") + + &:hover, &:focus + color: map.get($_theme, "fg-bright") .search-form display: flex @@ -44,8 +52,7 @@ @include button-bg padding: 10px flex: 1 - margin: 1px + border: 1px solid map.get($_theme, "bg-nav") &:hover, &:focus - border: 1px solid c.$edge-grey - margin: 0px + border-color: map.get($_theme, "edge-grey") diff --git a/sass/includes/privacy-page.sass b/sass/includes/_privacy-page.sass similarity index 69% rename from sass/includes/privacy-page.sass rename to sass/includes/_privacy-page.sass index 51c8ac0..9f38ec3 100644 --- a/sass/includes/privacy-page.sass +++ b/sass/includes/_privacy-page.sass @@ -1,3 +1,5 @@ +$_theme: () !default + .privacy-page max-width: 600px margin: 0 auto diff --git a/sass/includes/search-page.sass b/sass/includes/_search-page.sass similarity index 63% rename from sass/includes/search-page.sass rename to sass/includes/_search-page.sass index b12de93..0d42cca 100644 --- a/sass/includes/search-page.sass +++ b/sass/includes/_search-page.sass @@ -1,5 +1,7 @@ -@use "video-list-item.sass" as * -@use "colors.sass" as c +$_theme: () !default + +@use "sass:map" +@use "video-list-item" as * .search-page padding: 40px 20px 20px diff --git a/sass/includes/settings-page.sass b/sass/includes/_settings-page.sass similarity index 77% rename from sass/includes/settings-page.sass rename to sass/includes/_settings-page.sass index 279c761..a3eb77f 100644 --- a/sass/includes/settings-page.sass +++ b/sass/includes/_settings-page.sass @@ -1,5 +1,7 @@ -@use "forms.sass" as forms -@use "colors.sass" as c +$_theme: () !default + +@use "sass:map" +@use "forms" as forms .settings-page padding: 40px 20px 20px @@ -19,8 +21,9 @@ .more-settings margin-top: 24px padding: 12px + border: 1px solid map.get($_theme, "edge-grey") border-radius: 8px - background-color: c.$bg-accent-x + background-color: map.get($_theme, "bg-3") &__list margin: 0 @@ -34,7 +37,7 @@ margin-top: 24px .delete-confirm-container - background: c.$bg-darker + background: map.get($_theme, "bg-1") margin-bottom: -36px @include forms.checkbox-hider("delete-confirm") diff --git a/sass/includes/subscriptions-page.sass b/sass/includes/_subscriptions-page.sass similarity index 83% rename from sass/includes/subscriptions-page.sass rename to sass/includes/_subscriptions-page.sass index 46f4050..bd70f37 100644 --- a/sass/includes/subscriptions-page.sass +++ b/sass/includes/_subscriptions-page.sass @@ -1,6 +1,8 @@ -@use "colors.sass" as c -@use "video-list-item.sass" as * -@use "forms.sass" as forms +$_theme: () !default + +@use "sass:map" +@use "forms" as forms +@use "video-list-item" as * .subscriptions-page padding: 40px 20px 20px @@ -33,7 +35,7 @@ .name font-size: 22px - color: c.$fg-main + color: map.get($_theme, "fg-main") @include forms.checkbox-hider("watched-videos-display") diff --git a/sass/includes/_takedown-page.sass b/sass/includes/_takedown-page.sass new file mode 100644 index 0000000..2535e5f --- /dev/null +++ b/sass/includes/_takedown-page.sass @@ -0,0 +1,16 @@ +$_theme: () !default + +@use "sass:map" + +.takedown-page + max-width: 700px + margin: 0 auto + + .new-section + margin-top: 200px + + .important-section + padding: 4px 20px + border: 1px solid map.get($_theme, "edge-grey") + color: map.get($_theme, "fg-bright") + background-color: map.get($_theme, "bg-1") diff --git a/sass/includes/video-list-item.sass b/sass/includes/_video-list-item.sass similarity index 84% rename from sass/includes/video-list-item.sass rename to sass/includes/_video-list-item.sass index d240360..321a964 100644 --- a/sass/includes/video-list-item.sass +++ b/sass/includes/_video-list-item.sass @@ -1,5 +1,7 @@ -@use "colors.sass" as c -@use "_dimensions.sass" as dimensions +$_theme: () !default + +@use "sass:map" +@use "_dimensions" as dimensions // navigator hacks .thumbnail > .thumbnail__options-container @@ -30,6 +32,7 @@ &__show-more display: block height: $more-size + color: #fff line-height: 16px font-size: 25px text-align: center @@ -52,7 +55,7 @@ &__options-list pointer-events: auto display: grid - background-color: c.$bg-accent + background-color: map.get($_theme, "bg-3") padding: 8px 0px border-radius: 8px box-shadow: 0 2px 6px 2px #000 @@ -67,7 +70,7 @@ right: 0 transform: translate(-6px, -1px) rotate(-45deg) clip-path: polygon(-5% -20%, 120% -20%, 120% 125%) - background-color: c.$bg-accent + background-color: map.get($_theme, "bg-3") box-shadow: 0px 0px 4px 0px #000 pointer-events: none @@ -80,7 +83,7 @@ margin-bottom: 12px @at-root .video-list-item--watched#{&} - background: c.$bg-darker + background: map.get($_theme, "bg-dim") padding: 4px 4px 0px margin: -4px -4px 8px @@ -93,7 +96,7 @@ .thumbnail position: relative display: flex - background: c.$bg-darkest + background: map.get($_theme, "bg-0") &__link font-size: 0 // remove whitespace around the image @@ -106,7 +109,7 @@ position: absolute bottom: 3px right: 3px - color: c.$fg-bright + color: #fff font-size: 14px background: rgba(20, 20, 20, 0.85) line-height: 1 @@ -119,20 +122,20 @@ line-height: 1.2 .title-link - color: c.$fg-main + color: map.get($_theme, "fg-main") text-decoration: none .author-line margin-top: 4px font-size: 15px - color: c.$fg-dim + color: map.get($_theme, "fg-dim") .author - color: c.$fg-dim + color: map.get($_theme, "fg-dim") text-decoration: none &:hover, &:active - color: c.$fg-bright + color: map.get($_theme, "fg-bright") text-decoration: underline @mixin recommendation-item @@ -176,15 +179,15 @@ .author-line font-size: 15px - color: c.$fg-main + color: map.get($_theme, "fg-main") .author - color: c.$fg-main + color: map.get($_theme, "fg-main") .description margin-top: 16px font-size: 15px - color: c.$fg-dim + color: map.get($_theme, "fg-dim") +dimensions.thin .description @@ -195,7 +198,7 @@ .description b font-weight: normal - color: c.$fg-main + color: map.get($_theme, "fg-main") @mixin channel-video @include large-item diff --git a/sass/includes/video-page.sass b/sass/includes/_video-page.sass similarity index 77% rename from sass/includes/video-page.sass rename to sass/includes/_video-page.sass index f134825..6774a83 100644 --- a/sass/includes/video-page.sass +++ b/sass/includes/_video-page.sass @@ -1,11 +1,11 @@ -@use "colors.sass" as c -@use "video-list-item.sass" as * +$_theme: () !default + +@use "sass:map" +@use "video-list-item" as * .video-page display: grid grid-auto-flow: row - padding: 20px - grid-gap: 16px @media screen and (min-width: 1000px) grid-template-columns: 1fr 400px @@ -13,10 +13,25 @@ &--recommended-below, &--recommended-hidden grid-template-columns: none - &--recommended-hidden .related-videos - display: none + &--recommended-side + .related-videos + border-left: 1px solid map.get($_theme, "edge-grey") + padding-left: 12px + padding-right: 20px + background-color: map.get($_theme, "bg-4") + padding-top: 12px + + &--recommended-below + .related-videos + padding: 20px + + &--recommended-hidden + .related-videos + display: none .main-video-section + padding: 20px + .video-container text-align: center @@ -27,7 +42,7 @@ max-height: 80vh .stream-notice - background: c.$bg-darkest + background: map.get($_theme, "bg-0") padding: 4px .info @@ -45,15 +60,15 @@ margin: 0px 0px 4px font-size: 30px font-weight: normal - color: c.$fg-bright + color: map.get($_theme, "fg-bright") word-break: break-word .author-link - color: c.$fg-main + color: map.get($_theme, "fg-main") text-decoration: none &:hover, &:active - color: c.$fg-bright + color: map.get($_theme, "fg-bright") text-decoration: underline .info-secondary @@ -75,7 +90,7 @@ margin: 16px 4px padding: 12px border-radius: 4px - background-color: c.$bg-darkest + background-color: map.get($_theme, "bg-0") &__description margin-left: 12px @@ -85,7 +100,7 @@ &__script-warning font-size: 15px - color: c.$fg-warning + color: map.get($_theme, "fg-warning") &__buttons display: flex @@ -97,12 +112,12 @@ line-height: 1.4 word-break: break-word margin: 16px 4px 4px 4px - background-color: c.$bg-accent-area + background-color: map.get($_theme, "bg-5") padding: 12px border-radius: 4px - --regular-background: #{c.$bg-accent-area} - --highlight-background: #{c.$bg-darker} + --regular-background: #{map.get($_theme, "bg-5")} + --highlight-background: #{map.get($_theme, "bg-1")} .subscribe-form display: inline-block diff --git a/sass/includes/colors.sass b/sass/includes/colors.sass deleted file mode 100644 index e60e409..0000000 --- a/sass/includes/colors.sass +++ /dev/null @@ -1,17 +0,0 @@ -$bg-darkest: #202123 -$bg-darker: #303336 -$bg-dark: #36393f -$bg-accent: #4f5359 -$bg-accent-x: #3f4247 -$bg-accent-area: #44474b - -$fg-bright: #fff -$fg-main: #ddd -$fg-dim: #bbb -$fg-warning: #fdca6d - -$edge-grey: #a0a0a0 - -$link: #8ac2f9 - -$power-deep: #c62727 diff --git a/sass/includes/takedown-page.sass b/sass/includes/takedown-page.sass deleted file mode 100644 index 36ede5d..0000000 --- a/sass/includes/takedown-page.sass +++ /dev/null @@ -1,14 +0,0 @@ -@use "colors.sass" as c - -.takedown-page - max-width: 700px - margin: 0 auto - - .new-section - margin-top: 200px - - .important-section - padding: 4px 20px - border: 1px solid c.$edge-grey - color: c.$fg-bright - background-color: c.$bg-darker diff --git a/sass/light.sass b/sass/light.sass new file mode 100644 index 0000000..4cece7e --- /dev/null +++ b/sass/light.sass @@ -0,0 +1,2 @@ +@use "themes/light" as * +@use "includes/main" with ($_theme: $theme) diff --git a/sass/main.sass b/sass/main.sass deleted file mode 100644 index 17c15df..0000000 --- a/sass/main.sass +++ /dev/null @@ -1,30 +0,0 @@ -@use "includes/colors.sass" as c - -@use "includes/base.sass" -@use "sass:selector" -@use "includes/video-page.sass" -@use "includes/search-page.sass" -@use "includes/home-page.sass" -@use "includes/channel-page.sass" -@use "includes/subscriptions-page.sass" -@use "includes/settings-page.sass" -@use "includes/cant-think-page.sass" -@use "includes/privacy-page.sass" -@use "includes/licenses-page.sass" -@use "includes/filters-page.sass" -@use "includes/takedown-page.sass" -@use "includes/forms.sass" -@use "includes/nav.sass" -@use "includes/footer.sass" - -@font-face - font-family: "Bariol" - src: url(/static/fonts/bariol.woff?statichash=1) - -.icon-link:hover, .icon-link:focus - .icon - filter: brightness(2) - -.button-container - display: flex - flex-wrap: wrap diff --git a/sass/theme-modules/_edgeless.sass b/sass/theme-modules/_edgeless.sass new file mode 100644 index 0000000..a23c11e --- /dev/null +++ b/sass/theme-modules/_edgeless.sass @@ -0,0 +1,27 @@ +$_theme: () !default + +@use "sass:map" + +// remove separating edges +.main-nav, .footer__center, .video-page--recommended-side .related-videos + border: none + +// no background change to recommended videos sidebar +.video-page--recommended-side .related-videos + background-color: map.get($_theme, "bg-2") + +// navigation shadow +.main-nav + position: relative // needed for box shadow to overlap related videos section + box-shadow: 0px 0px 20px 5px rgba(0, 0, 0, 0.1) + +// thumbnail dropdown menu dividers +.menu-look + border-color: map.get($_theme, "bg-0") + +// details areas +details, .checkbox-hider__container, .more-settings + border: none +details[open] summary + border: none + margin-bottom: 4px diff --git a/sass/themes/_dark.scss b/sass/themes/_dark.scss new file mode 100644 index 0000000..0308b83 --- /dev/null +++ b/sass/themes/_dark.scss @@ -0,0 +1,38 @@ +// Defined in scss file instead of sass because indented syntax does not have multiline maps +// https://github.com/sass/sass/issues/216 + +@use "sass:map"; + +// This section is for colour shades +$theme: ( + // darker + "bg-0": #252628, + "bg-1": #303336, + // regular + "bg-2": #36393f, + // lighter + "bg-3": #3f4247, // slightly + "bg-4": #44474b, // noticably + "bg-5": #4f5359, // brightly + + "fg-bright": #fff, + "fg-main": #ddd, + "fg-dim": #bbb, + "fg-warning": #fdca6d, + + "edge-grey": #a0a0a0, + "placeholder": #c4c4c4, + + "link": #8ac2f9, + + "power-deep": #c62727, + "power-fg": "#fff", + + "image-dropdown": url(/static/images/arrow-down-wide-dark.svg) +); + +// This section is for colour meanings +$theme: map.merge($theme, ( + "bg-dim": map.get($theme, "bg-0"), + "bg-nav": map.get($theme, "bg-5"), +)); diff --git a/sass/themes/_edgeless-light.scss b/sass/themes/_edgeless-light.scss new file mode 100644 index 0000000..be4f453 --- /dev/null +++ b/sass/themes/_edgeless-light.scss @@ -0,0 +1,8 @@ +// extend regular light theme to change a couple of shades +@use "light"; +@use "sass:map"; + +// this section is for colour meanings +$theme: map.merge(light.$theme, ( + "edge-grey": #c0c0c0, +)); diff --git a/sass/themes/_light.scss b/sass/themes/_light.scss new file mode 100644 index 0000000..a927ce0 --- /dev/null +++ b/sass/themes/_light.scss @@ -0,0 +1,38 @@ +// Defined in scss file instead of sass because indented syntax does not have multiline maps +// https://github.com/sass/sass/issues/216 + +@use "sass:map"; + +// this section is for colour shades +$theme: ( + // lighter + "bg-0": #fff, + "bg-1": #fff, + // regular + "bg-2": #f2f2f2, + // darker + "bg-3": #e8e8e8, // slightly + "bg-4": #dadada, // noticably + "bg-5": #d0d0d0, // brightly + + "fg-bright": #000, + "fg-main": #202020, + "fg-dim": #454545, + "fg-warning": #ce8600, + + "edge-grey": #909090, + "placeholder": #636363, + + "link": #0b51d4, + + "power-deep": #c62727, + "power-fg": #fff, + + "image-dropdown": url(/static/images/arrow-down-wide-light.svg) +); + +// this section is for colour meanings +$theme: map.merge($theme, ( + "bg-dim": map.get($theme, "bg-4"), + "bg-nav": map.get($theme, "bg-0") +)); diff --git a/server.js b/server.js index e9d7805..3dd550b 100644 --- a/server.js +++ b/server.js @@ -1,9 +1,11 @@ const {Pinski} = require("pinski") const {setInstance} = require("pinski/plugins") const constants = require("./utils/constants") +const iconLoader = require("./utils/icon-loader").icons ;(async () => { await require("./utils/upgradedb")() + const icons = await iconLoader const server = new Pinski({ port: 10412, @@ -13,19 +15,19 @@ const constants = require("./utils/constants") setInstance(server) server.pugDefaultLocals.constants = constants + server.pugDefaultLocals.icons = icons server.muteLogsStartingWith("/vi/") server.muteLogsStartingWith("/favicon") server.muteLogsStartingWith("/static") - server.addSassDir("sass", ["sass/includes"]) - server.addRoute("/static/css/main.css", "sass/main.sass", "sass") + server.addSassDir("sass", ["sass/includes", "sass/themes", "sass/theme-modules"]) + server.addRoute("/static/css/dark.css", "sass/dark.sass", "sass") + server.addRoute("/static/css/light.css", "sass/light.sass", "sass") + server.addRoute("/static/css/edgeless-light.css", "sass/edgeless-light.sass", "sass") server.addPugDir("pug", ["pug/includes"]) server.addPugDir("pug/errors") - server.addRoute("/cant-think", "pug/cant-think.pug", "pug") - server.addRoute("/privacy", "pug/privacy.pug", "pug") - server.addRoute("/licenses", "pug/licenses.pug", "pug") server.addStaticHashTableDir("html/static/js") server.addStaticHashTableDir("html/static/js/elemjs") diff --git a/utils/constants.js b/utils/constants.js index e4ed2ae..585ee9f 100644 --- a/utils/constants.js +++ b/utils/constants.js @@ -9,6 +9,10 @@ let constants = { type: "string", default: "http://localhost:3000" }, + theme: { + type: "integer", + default: 0 + }, save_history: { type: "boolean", default: false diff --git a/utils/icon-loader.js b/utils/icon-loader.js new file mode 100644 index 0000000..8e712ad --- /dev/null +++ b/utils/icon-loader.js @@ -0,0 +1,8 @@ +const fs = require("fs").promises + +const names = ["subscriptions", "settings"] +const icons = names.map(name => fs.readFile(`html/static/images/${name}.svg`, "utf8")) + +module.exports.icons = Promise.all(icons).then(resolvedIcons => { + return new Map(names.map((name, index) => [name, resolvedIcons[index]])) +}) diff --git a/utils/upgradedb.js b/utils/upgradedb.js index e5f65e5..27607c5 100644 --- a/utils/upgradedb.js +++ b/utils/upgradedb.js @@ -70,6 +70,11 @@ const deltas = [ .run() db.prepare("CREATE TABLE TakedownChannels (ucid TEXT NOT NULL, org TEXT, url TEXT, PRIMARY KEY (ucid))") .run() + }, + // 11: Settings +theme + function() { + db.prepare("ALTER TABLE Settings ADD COLUMN theme INTEGER DEFAULT 0") + .run() } ] @@ -82,7 +87,7 @@ async function createBackup(entry) { /** * @param {number} entry - * @param {boolean} log + * @param {boolean} [log] */ function runDelta(entry, log) { process.stdout.write(`Upgrading database to version ${entry}... `) From 15e3f06ad666dd6911f26ae4ceece98ef5063e90 Mon Sep 17 00:00:00 2001 From: Cadence Ember Date: Tue, 28 Dec 2021 20:36:54 +1300 Subject: [PATCH 03/12] Fix theme on can't think page --- sass/includes/_cant-think-page.sass | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sass/includes/_cant-think-page.sass b/sass/includes/_cant-think-page.sass index 36399ef..0bbf369 100644 --- a/sass/includes/_cant-think-page.sass +++ b/sass/includes/_cant-think-page.sass @@ -16,8 +16,8 @@ $_theme: () !default .page-narration background-color: map.get($_theme, "bg-3") - border: 1px solid #aaa - color: #fff + border: 1px solid map.get($_theme, "edge-grey") + color: map.get($_theme, "fg-bright") border-radius: 0 padding: 16px margin: 40px auto 60px From 109dcd22de2f044bfc9728ca255706a3a5d27988 Mon Sep 17 00:00:00 2001 From: Cadence Ember Date: Mon, 10 Jan 2022 14:18:45 +1300 Subject: [PATCH 04/12] Rework subscribing to deleted channels --- api/channels.js | 12 +++++- api/formapi.js | 2 - api/subscriptions.js | 4 +- background/feed-update.js | 30 ++++++++++---- pug/channel-error.pug | 27 +++++++++++++ pug/subscriptions.pug | 16 +++++++- sass/includes/_channel-page.sass | 13 ++++++ sass/includes/_subscriptions-page.sass | 4 ++ utils/constants.js | 1 + utils/getuser.js | 4 +- utils/upgradedb.js | 20 +++++++++ utils/youtube.js | 56 +++++++++++++++++++++++--- 12 files changed, 167 insertions(+), 22 deletions(-) create mode 100644 pug/channel-error.pug diff --git a/api/channels.js b/api/channels.js index de9bc2c..56320a3 100644 --- a/api/channels.js +++ b/api/channels.js @@ -13,6 +13,16 @@ module.exports = [ const data = await fetchChannel(id, settings.instance) const subscribed = user.isSubscribed(id) const instanceOrigin = settings.instance + + // problem with the channel? fetchChannel has collected the necessary information for us. + // we can render a skeleton page, display the message, and provide the option to unsubscribe. + if (data.error) { + const statusCode = data.missing ? 410 : 500 + return render(statusCode, "pug/channel-error.pug", {settings, data, subscribed, instanceOrigin}) + } + + // everything is fine + // normalise info, apply watched status if (!data.second__subCountText && data.subCount) { data.second__subCountText = converters.subscriberCountToText(data.subCount) @@ -24,7 +34,7 @@ module.exports = [ video.watched = watchedVideos.includes(video.videoId) }) } - return render(200, "pug/channel.pug", {settings, url, data, subscribed, instanceOrigin}) + return render(200, "pug/channel.pug", {settings, data, subscribed, instanceOrigin}) } } ] diff --git a/api/formapi.js b/api/formapi.js index 14f10d0..0f994d3 100644 --- a/api/formapi.js +++ b/api/formapi.js @@ -26,7 +26,6 @@ module.exports = [ await fetchChannel(ucid, settings.instance) db.prepare( "INSERT INTO Subscriptions (token, ucid) VALUES (?, ?)" - + " ON CONFLICT (token, ucid) DO UPDATE SET channel_missing = 0" ).run(token, ucid) } else { db.prepare("DELETE FROM Subscriptions WHERE token = ? AND ucid = ?").run(token, ucid) @@ -41,7 +40,6 @@ module.exports = [ }), content: "Success, redirecting..." } - return redirect(params.get("referrer"), 303) } else { return { statusCode: 200, diff --git a/api/subscriptions.js b/api/subscriptions.js index 6bb439b..bddce0c 100644 --- a/api/subscriptions.js +++ b/api/subscriptions.js @@ -11,12 +11,14 @@ module.exports = [ let hasSubscriptions = false let videos = [] let channels = [] + let missingChannelCount = 0 let refreshed = null if (user.token) { // trigger a background refresh, needed if they came back from being inactive refresher.skipWaiting() // get channels channels = db.prepare(`SELECT Channels.* FROM Channels INNER JOIN Subscriptions ON Channels.ucid = Subscriptions.ucid WHERE token = ? ORDER BY name`).all(user.token) + missingChannelCount = channels.reduce((a, c) => a + c.missing, 0) // get refreshed status refreshed = db.prepare(`SELECT min(refreshed) as min, max(refreshed) as max, count(refreshed) as count FROM Channels INNER JOIN Subscriptions ON Channels.ucid = Subscriptions.ucid WHERE token = ?`).get(user.token) // get watched videos @@ -37,7 +39,7 @@ module.exports = [ } const settings = user.getSettingsOrDefaults() const instanceOrigin = settings.instance - return render(200, "pug/subscriptions.pug", {url, settings, hasSubscriptions, videos, channels, refreshed, timeToPastText, instanceOrigin}) + return render(200, "pug/subscriptions.pug", {url, settings, hasSubscriptions, videos, channels, missingChannelCount, refreshed, timeToPastText, instanceOrigin}) } } ] diff --git a/background/feed-update.js b/background/feed-update.js index 069ee0d..6e46cfc 100644 --- a/background/feed-update.js +++ b/background/feed-update.js @@ -15,8 +15,8 @@ const prepared = { channel_refreshed_update: db.prepare( "UPDATE Channels SET refreshed = ? WHERE ucid = ?" ), - unsubscribe_all_from_channel: db.prepare( - "UPDATE Subscriptions SET channel_missing = 1 WHERE ucid = ?" + channel_mark_as_missing: db.prepare( + "UPDATE Channels SET missing = 1, missing_reason = ? WHERE ucid = ?" ) } @@ -35,7 +35,7 @@ class RefreshQueue { // get the next set of scheduled channels to refresh const afterTime = Date.now() - constants.caching.seen_token_subscriptions_eligible const channels = db.prepare( - "SELECT DISTINCT Subscriptions.ucid FROM SeenTokens INNER JOIN Subscriptions ON SeenTokens.token = Subscriptions.token AND SeenTokens.seen > ? WHERE Subscriptions.channel_missing = 0 ORDER BY SeenTokens.seen DESC" + "SELECT DISTINCT Subscriptions.ucid FROM SeenTokens INNER JOIN Subscriptions ON SeenTokens.token = Subscriptions.token INNER JOIN Channels ON Channels.ucid = Subscriptions.ucid WHERE Channels.missing = 0 AND SeenTokens.seen > ? ORDER BY SeenTokens.seen DESC" ).pluck().all(afterTime) this.addLast(channels) this.lastLoadTime = Date.now() @@ -72,11 +72,12 @@ class Refresher { this.refreshQueue = new RefreshQueue() this.state = this.sym.ACTIVE this.waitingTimeout = null + this.lastFakeNotFoundTime = 0 this.next() } refreshChannel(ucid) { - return fetch(`${constants.server_setup.local_instance_origin}/api/v1/channels/${ucid}/latest`).then(res => res.json()).then(root => { + return fetch(`${constants.server_setup.local_instance_origin}/api/v1/channels/${ucid}/latest`).then(res => res.json()).then(/** @param {any} root */ root => { if (Array.isArray(root)) { root.forEach(video => { // organise @@ -89,11 +90,24 @@ class Refresher { prepared.channel_refreshed_update.run(Date.now(), ucid) // console.log(`updated ${root.length} videos for channel ${ucid}`) } else if (root.identifier === "PUBLISHED_DATES_NOT_PROVIDED") { - return [] // nothing we can do. skip this iteration. + // nothing we can do. skip this iteration. } else if (root.identifier === "NOT_FOUND") { - // the channel does not exist. we should unsubscribe all users so we don't try again. - // console.log(`channel ${ucid} does not exist, unsubscribing all users`) - prepared.unsubscribe_all_from_channel.run(ucid) + // YouTube sometimes returns not found for absolutely no reason. + // There is no way to distinguish between a fake missing channel and a real missing channel without requesting the real endpoint. + // These fake missing channels often happen in bursts, which is why there is a cooldown. + const timeSinceLastFakeNotFound = Date.now() - this.lastFakeNotFoundTime + if (timeSinceLastFakeNotFound >= constants.caching.subscriptions_refesh_fake_not_found_cooldown) { + // We'll request the real endpoint to verify. + fetch(`${constants.server_setup.local_instance_origin}/api/v1/channels/${ucid}`).then(res => res.json()).then(/** @param {any} root */ root => { + if (root.error && (root.identifier === "NOT_FOUND" || root.identifier === "ACCOUNT_TERMINATED")) { + // The channel is really gone, and we should mark it as missing for everyone. + prepared.channel_mark_as_missing.run(root.error, ucid) + } else { + // The channel is not actually gone and YouTube is trolling us. + this.lastFakeNotFoundTime = Date.now() + } + }) + } // else youtube is currently trolling us, skip this until later. } else { throw new Error(root.error) } diff --git a/pug/channel-error.pug b/pug/channel-error.pug new file mode 100644 index 0000000..db4d226 --- /dev/null +++ b/pug/channel-error.pug @@ -0,0 +1,27 @@ +extends includes/layout + +include includes/video-list-item +include includes/subscribe-button + +block head + title= `${data.row ? data.row.name : "Deleted channel"} - CloudTube` + script(type="module" src=getStaticURL("html", "/static/js/channel.js")) + +block content + main.channel-page + if data.row + .channel-data + .info + - const iconURL = data.row.icon_url + if iconURL + .logo + img(src=iconURL alt="").thumbnail-image + .about + h1.name= data.row.name + +subscribe_button(data.ucid, subscribed, `/channel/${data.ucid}`).subscribe-button.base-border-look + + .channel-error + div= data.message + + if data.missing && subscribed + .you-should-unsubscribe To remove this channel from your subscriptions list, click Unsubscribe. diff --git a/pug/subscriptions.pug b/pug/subscriptions.pug index 2846b01..7710f64 100644 --- a/pug/subscriptions.pug +++ b/pug/subscriptions.pug @@ -11,12 +11,24 @@ block content if hasSubscriptions section details.channels-details - summary #{channels.length} subscriptions + summary + | #{channels.length} subscriptions + if missingChannelCount === 1 + = ` - ${missingChannelCount} channel is gone` + else if missingChannelCount > 1 + = ` - ${missingChannelCount} channels are gone` .channels-list for channel in channels a(href=`/channel/${channel.ucid}`).channel-item img(src=channel.icon_url width=512 height=512 alt="").thumbnail - span.name= channel.name + div + div.name= channel.name + if channel.missing + div.missing-reason + if channel.missing_reason + = channel.missing_reason + else + | This channel appears to be deleted or terminated. Click to check it. if refreshed section diff --git a/sass/includes/_channel-page.sass b/sass/includes/_channel-page.sass index 7f91f61..f1a8952 100644 --- a/sass/includes/_channel-page.sass +++ b/sass/includes/_channel-page.sass @@ -74,6 +74,19 @@ $_theme: () !default .channel-video @include channel-video +.channel-error + background-color: map.get($_theme, "bg-1") + padding: 24px + margin: 12px 0px 24px + border-radius: 8px + border: 1px solid map.get($_theme, "edge-grey") + font-size: 20px + color: map.get($_theme, "fg-warning") + +.you-should-unsubscribe + margin-top: 20px + color: map.get($_theme, "fg-main") + .about-description // class provided by youtube pre font-size: inherit diff --git a/sass/includes/_subscriptions-page.sass b/sass/includes/_subscriptions-page.sass index bd70f37..86c41b9 100644 --- a/sass/includes/_subscriptions-page.sass +++ b/sass/includes/_subscriptions-page.sass @@ -37,6 +37,10 @@ $_theme: () !default font-size: 22px color: map.get($_theme, "fg-main") + .missing-reason + font-size: 16px + color: map.get($_theme, "fg-warning") + @include forms.checkbox-hider("watched-videos-display") #watched-videos-display:checked ~ .video-list-item--watched diff --git a/utils/constants.js b/utils/constants.js index 585ee9f..55e916c 100644 --- a/utils/constants.js +++ b/utils/constants.js @@ -50,6 +50,7 @@ let constants = { csrf_time: 4*60*60*1000, seen_token_subscriptions_eligible: 40*60*60*1000, subscriptions_refresh_loop_min: 5*60*1000, + subscriptions_refesh_fake_not_found_cooldown: 10*60*1000, }, // Pattern matching. diff --git a/utils/getuser.js b/utils/getuser.js index d23fa0b..efc25ce 100644 --- a/utils/getuser.js +++ b/utils/getuser.js @@ -54,7 +54,7 @@ class User { getSubscriptions() { if (this.token) { - return db.prepare("SELECT ucid FROM Subscriptions WHERE token = ? AND channel_missing = 0").pluck().all(this.token) + return db.prepare("SELECT ucid FROM Subscriptions WHERE token = ?").pluck().all(this.token) } else { return [] } @@ -62,7 +62,7 @@ class User { isSubscribed(ucid) { if (this.token) { - return !!db.prepare("SELECT * FROM Subscriptions WHERE token = ? AND ucid = ? AND channel_missing = 0").get([this.token, ucid]) + return !!db.prepare("SELECT * FROM Subscriptions WHERE token = ? AND ucid = ?").get([this.token, ucid]) } else { return false } diff --git a/utils/upgradedb.js b/utils/upgradedb.js index 27607c5..545ed61 100644 --- a/utils/upgradedb.js +++ b/utils/upgradedb.js @@ -75,6 +75,26 @@ const deltas = [ function() { db.prepare("ALTER TABLE Settings ADD COLUMN theme INTEGER DEFAULT 0") .run() + }, + // 12: Channels +missing +missing_reason, Subscriptions - + // Better management for missing channels + // We totally discard the existing Subscriptions.channel_missing since it is unreliable. + function() { + db.prepare("ALTER TABLE Channels ADD COLUMN missing INTEGER NOT NULL DEFAULT 0") + .run() + db.prepare("ALTER TABLE Channels ADD COLUMN missing_reason TEXT") + .run() + // https://www.sqlite.org/lang_altertable.html#making_other_kinds_of_table_schema_changes + db.transaction(() => { + db.prepare("CREATE TABLE NEW_Subscriptions (token TEXT NOT NULL, ucid TEXT NOT NULL, PRIMARY KEY (token, ucid))") + .run() + db.prepare("INSERT INTO NEW_Subscriptions (token, ucid) SELECT token, ucid FROM Subscriptions") + .run() + db.prepare("DROP TABLE Subscriptions") + .run() + db.prepare("ALTER TABLE NEW_Subscriptions RENAME TO Subscriptions") + .run() + })() } ] diff --git a/utils/youtube.js b/utils/youtube.js index cc7e15a..991b884 100644 --- a/utils/youtube.js +++ b/utils/youtube.js @@ -2,14 +2,58 @@ const {request} = require("./request") const db = require("./db") async function fetchChannel(ucid, instance) { + function updateGoodData(channel) { + const bestIcon = channel.authorThumbnails.slice(-1)[0] + const iconURL = bestIcon ? bestIcon.url : null + db.prepare("REPLACE INTO Channels (ucid, name, icon_url, missing, missing_reason) VALUES (?, ?, ?, 0, NULL)").run(channel.authorId, channel.author, iconURL) + } + + function updateBadData(channel) { + if (channel.identifier === "NOT_FOUND" || channel.identifier === "ACCOUNT_TERMINATED") { + db.prepare("UPDATE Channels SET missing = 1, missing_reason = ? WHERE ucid = ?").run(channel.error, channel.authorId) + return { + missing: true, + message: channel.error + } + } else { + return { + missing: false, + message: channel.error + } + } + } + if (!instance) throw new Error("No instance parameter provided") - // fetch + + const row = db.prepare("SELECT * FROM Channels WHERE ucid = ?").get(ucid) + + // handle the case where the channel has a known error + if (row && row.missing_reason) { + return { + error: true, + ucid, + row, + missing: true, + message: row.missing_reason + } + } + + /** @type {any} */ const channel = await request(`${instance}/api/v1/channels/${ucid}`).then(res => res.json()) - // update database - const bestIcon = channel.authorThumbnails.slice(-1)[0] - const iconURL = bestIcon ? bestIcon.url : null - db.prepare("REPLACE INTO Channels (ucid, name, icon_url) VALUES (?, ?, ?)").run([channel.authorId, channel.author, iconURL]) - // return + + // handle the case where the channel has a newly discovered error + if (channel.error) { + const missingData = updateBadData(channel) + return { + error: true, + ucid, + row, + ...missingData + } + } + + // handle the case where the channel returns good data (this is the only remaining scenario) + updateGoodData(channel) return channel } From 893684c311231cbaa146d204fbd377f53ad18700 Mon Sep 17 00:00:00 2001 From: Cadence Ember Date: Thu, 13 Jan 2022 18:19:56 +1300 Subject: [PATCH 05/12] Fix data deletion checkbox styles --- sass/includes/_forms.sass | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/sass/includes/_forms.sass b/sass/includes/_forms.sass index e946d19..c544f70 100644 --- a/sass/includes/_forms.sass +++ b/sass/includes/_forms.sass @@ -103,15 +103,6 @@ fieldset @include acts-like-button cursor: pointer -@mixin checkbox-hider($base) - ##{$base} - position: relative - left: 10px - display: block - z-index: 1 - height: 42px - margin: 0 - .checkbox-hider__container position: relative display: grid // why does the default not work??? @@ -122,9 +113,30 @@ fieldset border-radius: 8px margin-bottom: -18px - .checkbox-hider__label - padding: 12px 0px 12px 32px - cursor: pointer +.checkbox-hider__label + padding: 12px 0px 12px 32px + cursor: pointer + +@mixin checkbox-hider($base) + ##{$base} + position: relative + left: 10px + display: block + z-index: 1 + height: 42px + margin: 0 + + /* + automatically add these styles too + this means that components based off this can either add the .checkbox-hider__container class, or they can add the .base-name-container class, + depending on which one is more reasonable in the moment + for example, .delete-confirm-container takes advantage of the @extend here. + + .#{$base}-container + @extend .checkbox-hider__container + + .#{$base}-label + @extend .checkbox-hider__label @mixin single-button-form display: inline-block From 1333b990f6102587e7eccd350555cfe67c909229 Mon Sep 17 00:00:00 2001 From: Cadence Ember Date: Mon, 14 Mar 2022 21:32:34 +1300 Subject: [PATCH 06/12] Add recommended videos to the can't think page this is probably some kind of sick irony yeah yeah no, no thinking. content. consume the content. watch more videos. https://tube.cadence.moe/cant-think watch more videos. https://tube.cadence.moe/cant-think watch more videos. https://tube.cadence.moe/cant-think watch more videos. https://tube.cadence.moe/cant-think watch more videos. https://tube.cadence.moe/cant-think ... can't think? --- pug/cant-think.pug | 6 ++++++ sass/includes/_cant-think-page.sass | 7 +++++++ 2 files changed, 13 insertions(+) diff --git a/pug/cant-think.pug b/pug/cant-think.pug index e730c57..2f88367 100644 --- a/pug/cant-think.pug +++ b/pug/cant-think.pug @@ -18,6 +18,7 @@ mixin leave(index, prefix="No more?", final) a(href="/search?q=cats+being+cute") [BLISS] block content + include includes/video-list-item main.cant-think-page - let src = constants.server_setup.cant_think_narration_url if src @@ -71,3 +72,8 @@ block content p You know what you must do. p.ultimatum: a(href="#i-understand").border-look I know what I must do. a#i-understand + + p.the-end Well, looks like you reached the end of the content.#[br]You know what happens now. + h3 Recommended videos + +video_list_item("related-video", {videoId: "jKKCF_Bqtw4", title: "dopamine review", author: "Jreg", authorId: "UCGSGPehp0RWfca-kENgBJ9Q", viewCountText: "84,651 views"}) + +video_list_item("related-video", {videoId: "gLYWLobR248", title: "I Watch My YouTube Videos At 2x Speed", author: "Jreg", authorId: "UCGSGPehp0RWfca-kENgBJ9Q", viewCountText: "125,625 views"}) diff --git a/sass/includes/_cant-think-page.sass b/sass/includes/_cant-think-page.sass index 0bbf369..2365a59 100644 --- a/sass/includes/_cant-think-page.sass +++ b/sass/includes/_cant-think-page.sass @@ -11,6 +11,7 @@ $_theme: () !default text-align: left max-width: 572px padding-top: 40px + margin-bottom: 12vh border-radius: 0px 0px 16px 16px box-sizing: border-box @@ -56,6 +57,12 @@ $_theme: () !default .ultimatum margin-top: 32px !important + .the-end + margin: 120px 0px 1em !important + + .thumbnail__more + display: none + #i-understand display: flex height: 20px From 25baf8c73bcefbb6ad8c969abe9abc6764044f09 Mon Sep 17 00:00:00 2001 From: Cadence Ember Date: Mon, 14 Mar 2022 21:48:33 +1300 Subject: [PATCH 07/12] Fix z-index on can't think page Because why would I be able to test if I'm not able to think? --- sass/includes/_cant-think-page.sass | 1 + 1 file changed, 1 insertion(+) diff --git a/sass/includes/_cant-think-page.sass b/sass/includes/_cant-think-page.sass index 2365a59..99faa21 100644 --- a/sass/includes/_cant-think-page.sass +++ b/sass/includes/_cant-think-page.sass @@ -74,6 +74,7 @@ $_theme: () !default &:target position: fixed + z-index: 1 top: 0 bottom: 0 left: 0 From f04be0d3f915a8adf838dfd9aa8d6ea784b9a5c3 Mon Sep 17 00:00:00 2001 From: Cadence Ember Date: Mon, 14 Mar 2022 21:54:42 +1300 Subject: [PATCH 08/12] Add video durations to can't think page Because why would I care when I instinctively click anyway? --- pug/cant-think.pug | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pug/cant-think.pug b/pug/cant-think.pug index 2f88367..05b876c 100644 --- a/pug/cant-think.pug +++ b/pug/cant-think.pug @@ -75,5 +75,5 @@ block content p.the-end Well, looks like you reached the end of the content.#[br]You know what happens now. h3 Recommended videos - +video_list_item("related-video", {videoId: "jKKCF_Bqtw4", title: "dopamine review", author: "Jreg", authorId: "UCGSGPehp0RWfca-kENgBJ9Q", viewCountText: "84,651 views"}) - +video_list_item("related-video", {videoId: "gLYWLobR248", title: "I Watch My YouTube Videos At 2x Speed", author: "Jreg", authorId: "UCGSGPehp0RWfca-kENgBJ9Q", viewCountText: "125,625 views"}) + +video_list_item("related-video", {videoId: "jKKCF_Bqtw4", title: "dopamine review", author: "Jreg", authorId: "UCGSGPehp0RWfca-kENgBJ9Q", viewCountText: "84,651 views", second__lengthText: "3:10"}) + +video_list_item("related-video", {videoId: "gLYWLobR248", title: "I Watch My YouTube Videos At 2x Speed", author: "Jreg", authorId: "UCGSGPehp0RWfca-kENgBJ9Q", viewCountText: "125,625 views", second__lengthText: "2:24"}) From 5e6b2bf31cbd6360ea4d1b1790fca9c7b6bed60c Mon Sep 17 00:00:00 2001 From: Cadence Ember Date: Wed, 27 Jul 2022 18:54:45 +1200 Subject: [PATCH 09/12] Add /api/settings to get current settings as JSON --- api/settings.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/api/settings.js b/api/settings.js index 4775b64..9be9ffd 100644 --- a/api/settings.js +++ b/api/settings.js @@ -7,6 +7,17 @@ const validate = require("../utils/validate") const V = validate.V module.exports = [ + { + route: "/api/settings", methods: ["GET"], code: async ({req}) => { + const user = getUser(req) + const settings = user.getSettingsOrDefaults() + return { + statusCode: 200, + contentType: "application/json", + content: settings + } + } + }, { route: "/settings", methods: ["GET"], code: async ({req}) => { const user = getUser(req) From 6de9abd499b596ce2e11bf2537e7322b01543615 Mon Sep 17 00:00:00 2001 From: Lomanic Date: Sat, 13 Nov 2021 02:17:07 +0100 Subject: [PATCH 10/12] Partially fix #29: add routes for /c/ and /user/ paths for channels --- api/channels.js | 8 ++++---- utils/youtube.js | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/api/channels.js b/api/channels.js index 56320a3..38f3d75 100644 --- a/api/channels.js +++ b/api/channels.js @@ -1,16 +1,16 @@ const {render} = require("pinski/plugins") -const constants = require("../utils/constants") const {fetchChannel} = require("../utils/youtube") const {getUser} = require("../utils/getuser") const converters = require("../utils/converters") module.exports = [ { - route: `/channel/(${constants.regex.ucid})`, methods: ["GET"], code: async ({req, fill, url}) => { - const id = fill[0] + route: `/(c|channel|user)/(.+)`, methods: ["GET"], code: async ({req, fill, url}) => { + const path = fill[0] + const id = fill[1] const user = getUser(req) const settings = user.getSettingsOrDefaults() - const data = await fetchChannel(id, settings.instance) + const data = await fetchChannel(id, path, settings.instance) const subscribed = user.isSubscribed(id) const instanceOrigin = settings.instance diff --git a/utils/youtube.js b/utils/youtube.js index 991b884..5e6b417 100644 --- a/utils/youtube.js +++ b/utils/youtube.js @@ -1,7 +1,7 @@ const {request} = require("./request") const db = require("./db") -async function fetchChannel(ucid, instance) { +async function fetchChannel(ucid, path="channel", instance) { function updateGoodData(channel) { const bestIcon = channel.authorThumbnails.slice(-1)[0] const iconURL = bestIcon ? bestIcon.url : null @@ -39,7 +39,7 @@ async function fetchChannel(ucid, instance) { } /** @type {any} */ - const channel = await request(`${instance}/api/v1/channels/${ucid}`).then(res => res.json()) + const channel = await request(`${instance}/api/v1/channels/${ucid}?second__path=${path}`).then(res => res.json()) // handle the case where the channel has a newly discovered error if (channel.error) { From a2dfeb2edcfe4dd82e6074fb8ae1c443b8c7c85d Mon Sep 17 00:00:00 2001 From: Cadence Ember Date: Tue, 23 Aug 2022 10:37:43 +1200 Subject: [PATCH 11/12] Fix calls to fetchChannel Should fix subscribing to channels --- api/channels.js | 2 +- api/formapi.js | 2 +- utils/youtube.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/api/channels.js b/api/channels.js index 38f3d75..c0df993 100644 --- a/api/channels.js +++ b/api/channels.js @@ -10,7 +10,7 @@ module.exports = [ const id = fill[1] const user = getUser(req) const settings = user.getSettingsOrDefaults() - const data = await fetchChannel(id, path, settings.instance) + const data = await fetchChannel(path, id, settings.instance) const subscribed = user.isSubscribed(id) const instanceOrigin = settings.instance diff --git a/api/formapi.js b/api/formapi.js index 0f994d3..1a4dd55 100644 --- a/api/formapi.js +++ b/api/formapi.js @@ -23,7 +23,7 @@ module.exports = [ const token = user.token if (add) { - await fetchChannel(ucid, settings.instance) + await fetchChannel("channel", ucid, settings.instance) db.prepare( "INSERT INTO Subscriptions (token, ucid) VALUES (?, ?)" ).run(token, ucid) diff --git a/utils/youtube.js b/utils/youtube.js index 5e6b417..c1554c3 100644 --- a/utils/youtube.js +++ b/utils/youtube.js @@ -1,7 +1,7 @@ const {request} = require("./request") const db = require("./db") -async function fetchChannel(ucid, path="channel", instance) { +async function fetchChannel(path, ucid, instance) { function updateGoodData(channel) { const bestIcon = channel.authorThumbnails.slice(-1)[0] const iconURL = bestIcon ? bestIcon.url : null From 61c8e205d8d81471e4e13f0636666655b1531f24 Mon Sep 17 00:00:00 2001 From: Cadence Ember Date: Fri, 16 Sep 2022 17:18:51 +1200 Subject: [PATCH 12/12] Show subscribed properly on /user or /c pages --- api/channels.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/api/channels.js b/api/channels.js index c0df993..be2c9e9 100644 --- a/api/channels.js +++ b/api/channels.js @@ -11,13 +11,13 @@ module.exports = [ const user = getUser(req) const settings = user.getSettingsOrDefaults() const data = await fetchChannel(path, id, settings.instance) - const subscribed = user.isSubscribed(id) const instanceOrigin = settings.instance // problem with the channel? fetchChannel has collected the necessary information for us. // we can render a skeleton page, display the message, and provide the option to unsubscribe. if (data.error) { const statusCode = data.missing ? 410 : 500 + const subscribed = user.isSubscribed(id) return render(statusCode, "pug/channel-error.pug", {settings, data, subscribed, instanceOrigin}) } @@ -34,6 +34,7 @@ module.exports = [ video.watched = watchedVideos.includes(video.videoId) }) } + const subscribed = user.isSubscribed(data.authorId) return render(200, "pug/channel.pug", {settings, data, subscribed, instanceOrigin}) } }