mirror of
https://github.com/System-End/Vencord.git
synced 2026-04-19 16:28:16 +00:00
PlatformIndicators: fix & refactor (#3827)
Co-authored-by: Vendicated <vendicated@riseup.net>
This commit is contained in:
parent
bf3edaed6a
commit
ea271496a3
11 changed files with 208 additions and 59 deletions
|
|
@ -69,6 +69,7 @@
|
|||
"standalone-electron-types": "^34.2.0",
|
||||
"stylelint": "^16.25.0",
|
||||
"stylelint-config-standard": "^39.0.1",
|
||||
"svgo": "^4.0.0",
|
||||
"ts-patch": "^3.3.0",
|
||||
"ts-pattern": "^5.6.0",
|
||||
"tsx": "^4.20.6",
|
||||
|
|
|
|||
1
packages/discord-types/src/utils.d.ts
vendored
1
packages/discord-types/src/utils.d.ts
vendored
|
|
@ -274,6 +274,7 @@ export interface UsernameUtils {
|
|||
humanizeStatus: any;
|
||||
}
|
||||
|
||||
// TODO: fix type
|
||||
export class DisplayProfile {
|
||||
userId: string;
|
||||
banner?: string;
|
||||
|
|
|
|||
111
pnpm-lock.yaml
generated
111
pnpm-lock.yaml
generated
|
|
@ -110,6 +110,9 @@ importers:
|
|||
stylelint-config-standard:
|
||||
specifier: ^39.0.1
|
||||
version: 39.0.1(stylelint@16.25.0(typescript@5.9.3))
|
||||
svgo:
|
||||
specifier: ^4.0.0
|
||||
version: 4.0.0
|
||||
ts-patch:
|
||||
specifier: ^3.3.0
|
||||
version: 3.3.0
|
||||
|
|
@ -964,6 +967,9 @@ packages:
|
|||
resolution: {integrity: sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==}
|
||||
engines: {node: '>=10.0.0'}
|
||||
|
||||
boolbase@1.0.0:
|
||||
resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==}
|
||||
|
||||
brace-expansion@1.1.12:
|
||||
resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==}
|
||||
|
||||
|
|
@ -1045,6 +1051,10 @@ packages:
|
|||
resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==}
|
||||
engines: {node: '>=14'}
|
||||
|
||||
commander@11.1.0:
|
||||
resolution: {integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==}
|
||||
engines: {node: '>=16'}
|
||||
|
||||
commander@2.20.3:
|
||||
resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==}
|
||||
|
||||
|
|
@ -1075,15 +1085,30 @@ packages:
|
|||
resolution: {integrity: sha512-IQOkD3hbR5KrN93MtcYuad6YPuTSUhntLHDuLEbFWE+ff2/XSZNdZG+LcbbIW5AXKg/WFIfYItIzVoHngHXZzA==}
|
||||
engines: {node: '>=12 || >=16'}
|
||||
|
||||
css-select@5.2.2:
|
||||
resolution: {integrity: sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==}
|
||||
|
||||
css-tree@2.2.1:
|
||||
resolution: {integrity: sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==}
|
||||
engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'}
|
||||
|
||||
css-tree@3.1.0:
|
||||
resolution: {integrity: sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w==}
|
||||
engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0}
|
||||
|
||||
css-what@6.2.2:
|
||||
resolution: {integrity: sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==}
|
||||
engines: {node: '>= 6'}
|
||||
|
||||
cssesc@3.0.0:
|
||||
resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==}
|
||||
engines: {node: '>=4'}
|
||||
hasBin: true
|
||||
|
||||
csso@5.0.5:
|
||||
resolution: {integrity: sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==}
|
||||
engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'}
|
||||
|
||||
csstype@3.1.3:
|
||||
resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
|
||||
|
||||
|
|
@ -1177,9 +1202,22 @@ packages:
|
|||
resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
dom-serializer@2.0.0:
|
||||
resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==}
|
||||
|
||||
domelementtype@2.3.0:
|
||||
resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==}
|
||||
|
||||
domhandler@5.0.3:
|
||||
resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==}
|
||||
engines: {node: '>= 4'}
|
||||
|
||||
dompurify@3.1.7:
|
||||
resolution: {integrity: sha512-VaTstWtsneJY8xzy7DekmYWEOZcmzIe3Qb3zPd4STve1OBTa+e+WmS1ITQec1fZYXI3HCsOZZiSMpG6oxoWMWQ==}
|
||||
|
||||
domutils@3.2.2:
|
||||
resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==}
|
||||
|
||||
dot-case@3.0.4:
|
||||
resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==}
|
||||
|
||||
|
|
@ -1979,6 +2017,9 @@ packages:
|
|||
mathml-tag-names@2.1.3:
|
||||
resolution: {integrity: sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==}
|
||||
|
||||
mdn-data@2.0.28:
|
||||
resolution: {integrity: sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==}
|
||||
|
||||
mdn-data@2.12.2:
|
||||
resolution: {integrity: sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==}
|
||||
|
||||
|
|
@ -2051,6 +2092,9 @@ packages:
|
|||
resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
nth-check@2.1.1:
|
||||
resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==}
|
||||
|
||||
object-assign@4.1.1:
|
||||
resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
|
@ -2330,6 +2374,9 @@ packages:
|
|||
safe-regex@1.1.0:
|
||||
resolution: {integrity: sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==}
|
||||
|
||||
sax@1.4.3:
|
||||
resolution: {integrity: sha512-yqYn1JhPczigF94DMS+shiDMjDowYO6y9+wB/4WgO0Y19jWYk0lQ4tuG5KI7kj4FTp1wxPj5IFfcrz/s1c3jjQ==}
|
||||
|
||||
semver@6.3.1:
|
||||
resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==}
|
||||
hasBin: true
|
||||
|
|
@ -2520,6 +2567,11 @@ packages:
|
|||
svg-tags@1.0.0:
|
||||
resolution: {integrity: sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==}
|
||||
|
||||
svgo@4.0.0:
|
||||
resolution: {integrity: sha512-VvrHQ+9uniE+Mvx3+C9IEe/lWasXCU0nXMY2kZeLrHNICuRiC8uMPyM14UEaMOFA5mhyQqEkB02VoQ16n3DLaw==}
|
||||
engines: {node: '>=16'}
|
||||
hasBin: true
|
||||
|
||||
table@6.9.0:
|
||||
resolution: {integrity: sha512-9kY+CygyYM6j02t5YFHbNz2FN5QmYGv9zAjVp4lCDjlCw7amdckXlEt/bjMhUIfj4ThGRE4gCUH5+yGnNuPo5A==}
|
||||
engines: {node: '>=10.0.0'}
|
||||
|
|
@ -3454,6 +3506,8 @@ snapshots:
|
|||
|
||||
basic-ftp@5.0.5: {}
|
||||
|
||||
boolbase@1.0.0: {}
|
||||
|
||||
brace-expansion@1.1.12:
|
||||
dependencies:
|
||||
balanced-match: 1.0.2
|
||||
|
|
@ -3558,6 +3612,8 @@ snapshots:
|
|||
|
||||
commander@10.0.1: {}
|
||||
|
||||
commander@11.1.0: {}
|
||||
|
||||
commander@2.20.3: {}
|
||||
|
||||
component-emitter@1.3.1: {}
|
||||
|
|
@ -3583,13 +3639,32 @@ snapshots:
|
|||
|
||||
css-functions-list@3.2.3: {}
|
||||
|
||||
css-select@5.2.2:
|
||||
dependencies:
|
||||
boolbase: 1.0.0
|
||||
css-what: 6.2.2
|
||||
domhandler: 5.0.3
|
||||
domutils: 3.2.2
|
||||
nth-check: 2.1.1
|
||||
|
||||
css-tree@2.2.1:
|
||||
dependencies:
|
||||
mdn-data: 2.0.28
|
||||
source-map-js: 1.2.1
|
||||
|
||||
css-tree@3.1.0:
|
||||
dependencies:
|
||||
mdn-data: 2.12.2
|
||||
source-map-js: 1.2.1
|
||||
|
||||
css-what@6.2.2: {}
|
||||
|
||||
cssesc@3.0.0: {}
|
||||
|
||||
csso@5.0.5:
|
||||
dependencies:
|
||||
css-tree: 2.2.1
|
||||
|
||||
csstype@3.1.3: {}
|
||||
|
||||
csstype@3.2.1: {}
|
||||
|
|
@ -3673,8 +3748,26 @@ snapshots:
|
|||
dependencies:
|
||||
esutils: 2.0.3
|
||||
|
||||
dom-serializer@2.0.0:
|
||||
dependencies:
|
||||
domelementtype: 2.3.0
|
||||
domhandler: 5.0.3
|
||||
entities: 4.5.0
|
||||
|
||||
domelementtype@2.3.0: {}
|
||||
|
||||
domhandler@5.0.3:
|
||||
dependencies:
|
||||
domelementtype: 2.3.0
|
||||
|
||||
dompurify@3.1.7: {}
|
||||
|
||||
domutils@3.2.2:
|
||||
dependencies:
|
||||
dom-serializer: 2.0.0
|
||||
domelementtype: 2.3.0
|
||||
domhandler: 5.0.3
|
||||
|
||||
dot-case@3.0.4:
|
||||
dependencies:
|
||||
no-case: 3.0.4
|
||||
|
|
@ -4651,6 +4744,8 @@ snapshots:
|
|||
|
||||
mathml-tag-names@2.1.3: {}
|
||||
|
||||
mdn-data@2.0.28: {}
|
||||
|
||||
mdn-data@2.12.2: {}
|
||||
|
||||
meow@13.2.0: {}
|
||||
|
|
@ -4721,6 +4816,10 @@ snapshots:
|
|||
|
||||
normalize-path@3.0.0: {}
|
||||
|
||||
nth-check@2.1.1:
|
||||
dependencies:
|
||||
boolbase: 1.0.0
|
||||
|
||||
object-assign@4.1.1: {}
|
||||
|
||||
object-copy@0.1.0:
|
||||
|
|
@ -5038,6 +5137,8 @@ snapshots:
|
|||
dependencies:
|
||||
ret: 0.1.15
|
||||
|
||||
sax@1.4.3: {}
|
||||
|
||||
semver@6.3.1: {}
|
||||
|
||||
semver@7.7.1: {}
|
||||
|
|
@ -5317,6 +5418,16 @@ snapshots:
|
|||
|
||||
svg-tags@1.0.0: {}
|
||||
|
||||
svgo@4.0.0:
|
||||
dependencies:
|
||||
commander: 11.1.0
|
||||
css-select: 5.2.2
|
||||
css-tree: 3.1.0
|
||||
css-what: 6.2.2
|
||||
csso: 5.0.5
|
||||
picocolors: 1.1.1
|
||||
sax: 1.4.3
|
||||
|
||||
table@6.9.0:
|
||||
dependencies:
|
||||
ajv: 8.17.1
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ import esbuild, { build, context } from "esbuild";
|
|||
import { constants as FsConstants, readFileSync } from "fs";
|
||||
import { access, readdir, readFile } from "fs/promises";
|
||||
import { minify as minifyHtml } from "html-minifier-terser";
|
||||
import { optimize as optimizeSvg } from 'svgo';
|
||||
import { join, relative, resolve } from "path";
|
||||
import { promisify } from "util";
|
||||
|
||||
|
|
@ -278,6 +279,12 @@ export const fileUrlPlugin = {
|
|||
removeStyleLinkTypeAttributes: true,
|
||||
useShortDoctype: true
|
||||
});
|
||||
} else if (path.endsWith(".svg")) {
|
||||
content = optimizeSvg(await readFile(path, "utf-8"), {
|
||||
datauri: base64 ? 'base64' : void 0,
|
||||
multipass: true,
|
||||
floatPrecision: 2,
|
||||
}).data;
|
||||
} else if (/[mc]?[jt]sx?$/.test(path)) {
|
||||
const res = await esbuild.build({
|
||||
entryPoints: [path],
|
||||
|
|
@ -289,7 +296,7 @@ export const fileUrlPlugin = {
|
|||
throw new Error(`Don't know how to minify file type: ${path}`);
|
||||
}
|
||||
|
||||
if (base64)
|
||||
if (base64 && !content.startsWith("data:"))
|
||||
content = Buffer.from(content).toString("base64");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -47,7 +47,8 @@ export interface ProfileBadge {
|
|||
key?: string;
|
||||
|
||||
/**
|
||||
* Allows dynamically returning multiple badges
|
||||
* Allows dynamically returning multiple badges.
|
||||
* May call hooks but then you must not use shouldShow
|
||||
*/
|
||||
getBadges?(userInfo: BadgeUserArgs): ProfileBadge[];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,7 +31,6 @@ import { Margins } from "@utils/margins";
|
|||
import { shouldShowContributorBadge } from "@utils/misc";
|
||||
import { closeModal, ModalContent, ModalFooter, ModalHeader, ModalRoot, openModal } from "@utils/modal";
|
||||
import definePlugin from "@utils/types";
|
||||
import { User } from "@vencord/discord-types";
|
||||
import { ContextMenuApi, Forms, Menu, Toasts, UserStore } from "@webpack/common";
|
||||
|
||||
const CONTRIBUTOR_BADGE = "https://cdn.discordapp.com/emojis/1092089799109775453.png?size=64";
|
||||
|
|
@ -88,16 +87,13 @@ export default definePlugin({
|
|||
authors: [Devs.Megu, Devs.Ven, Devs.TheSun],
|
||||
required: true,
|
||||
patches: [
|
||||
{
|
||||
find: ".MODAL]:26",
|
||||
replacement: {
|
||||
match: /(?=;return 0===(\i)\.length\?)(?<=(\i)\.useMemo.+?)/,
|
||||
replace: ";$1=$2.useMemo(()=>[...$self.getBadges(arguments[0].displayProfile),...$1],[$1])"
|
||||
}
|
||||
},
|
||||
{
|
||||
find: "#{intl::PROFILE_USER_BADGES}",
|
||||
replacement: [
|
||||
{
|
||||
match: /(?<=\{[^}]*?)badges:\i(?=[^}]*?}=(\i))/,
|
||||
replace: "_$&=$self.useBadges($1.displayProfile).concat($1.badges)"
|
||||
},
|
||||
{
|
||||
match: /alt:" ","aria-hidden":!0,src:.{0,50}(\i).iconSrc/,
|
||||
replace: "...$1.props,$&"
|
||||
|
|
@ -112,13 +108,6 @@ export default definePlugin({
|
|||
replace: "...$self.getBadgeMouseEventHandlers($1),$&"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
find: "profileCardUsernameRow,children:",
|
||||
replacement: {
|
||||
match: /badges:(\i)(?<=displayProfile:(\i).+?)/,
|
||||
replace: "badges:[...$self.getBadges($2),...$1]"
|
||||
}
|
||||
}
|
||||
],
|
||||
|
||||
|
|
@ -151,15 +140,14 @@ export default definePlugin({
|
|||
clearInterval(intervalId);
|
||||
},
|
||||
|
||||
getBadges(props: { userId: string; user?: User; guildId: string; }) {
|
||||
if (!props) return [];
|
||||
// doesn't use hooks itself, but some plugins might do so in their getBadges function
|
||||
useBadges(profile: { userId: string; guildId: string; }) {
|
||||
if (!profile) return [];
|
||||
|
||||
try {
|
||||
props.userId ??= props.user?.id!;
|
||||
|
||||
return _getBadges(props);
|
||||
return _getBadges(profile);
|
||||
} catch (e) {
|
||||
new Logger("BadgeAPI#hasBadges").error(e);
|
||||
new Logger("BadgeAPI#useBadges").error(e);
|
||||
return [];
|
||||
}
|
||||
},
|
||||
|
|
|
|||
3
src/plugins/platformIndicators/icons/desktopIcon.svg
Normal file
3
src/plugins/platformIndicators/icons/desktopIcon.svg
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
<svg height="20" width="20" viewBox="0 0 24 24" fill="#000000" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M4 2.5c-1.103 0-2 .897-2 2v11c0 1.104.897 2 2 2h7v2H7v2h10v-2h-4v-2h7c1.103 0 2-.896 2-2v-11c0-1.103-.897-2-2-2H4Zm16 2v9H4v-9h16Z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 254 B |
3
src/plugins/platformIndicators/icons/embeddedIcon.svg
Normal file
3
src/plugins/platformIndicators/icons/embeddedIcon.svg
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
<svg height="20" width="20" viewBox="0 0 50 50" fill="#000000" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M14.8 2.7 9 3.1V47h3.3c1.7 0 6.2.3 10 .7l6.7.6V2l-4.2.2c-2.4.1-6.9.3-10 .5zm1.8 6.4c1 1.7-1.3 3.6-2.7 2.2C12.7 10.1 13.5 8 15 8c.5 0 1.2.5 1.6 1.1zM16 33c0 6-.4 10-1 10s-1-4-1-10 .4-10 1-10 1 4 1 10zm15-8v23.3l3.8-.7c2-.3 4.7-.6 6-.6H43V3h-2.2c-1.3 0-4-.3-6-.6L31 1.7V25z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 395 B |
3
src/plugins/platformIndicators/icons/mobileIcon.svg
Normal file
3
src/plugins/platformIndicators/icons/mobileIcon.svg
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
<svg height="17" width="17" viewBox="0 0 1000 1500" fill="#000000" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M 187 0 L 813 0 C 916.277 0 1000 83.723 1000 187 L 1000 1313 C 1000 1416.277 916.277 1500 813 1500 L 187 1500 C 83.723 1500 0 1416.277 0 1313 L 0 187 C 0 83.723 83.723 0 187 0 Z M 125 1000 L 875 1000 L 875 250 L 125 250 Z M 500 1125 C 430.964 1125 375 1180.964 375 1250 C 375 1319.036 430.964 1375 500 1375 C 569.036 1375 625 1319.036 625 1250 C 625 1180.964 569.036 1125 500 1125 Z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 510 B |
3
src/plugins/platformIndicators/icons/webIcon.svg
Normal file
3
src/plugins/platformIndicators/icons/webIcon.svg
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
<svg height="20" width="20" viewBox="0 0 24 24" fill="#000000" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2Zm-1 17.93c-3.95-.49-7-3.85-7-7.93 0-.62.08-1.21.21-1.79L9 15v1c0 1.1.9 2 2 2v1.93Zm6.9-2.54c-.26-.81-1-1.39-1.9-1.39h-1v-3c0-.55-.45-1-1-1H8v-2h2c.55 0 1-.45 1-1V7h2c1.1 0 2-.9 2-2v-.41c2.93 1.19 5 4.06 5 7.41 0 2.08-.8 3.97-2.1 5.39Z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 424 B |
|
|
@ -24,9 +24,14 @@ import { addMessageDecoration, removeMessageDecoration } from "@api/MessageDecor
|
|||
import { Settings } from "@api/Settings";
|
||||
import { Devs } from "@utils/constants";
|
||||
import definePlugin, { OptionType } from "@utils/types";
|
||||
import { DiscordPlatform, User } from "@vencord/discord-types";
|
||||
import { DiscordPlatform, OnlineStatus, User } from "@vencord/discord-types";
|
||||
import { filters, findStoreLazy, mapMangledModuleLazy } from "@webpack";
|
||||
import { AuthenticationStore, PresenceStore, Tooltip, UserStore, useStateFromStores } from "@webpack/common";
|
||||
import desktopIcon from "file://icons/desktopIcon.svg?minify";
|
||||
import embeddedIcon from "file://icons/embeddedIcon.svg?minify";
|
||||
import mobileIcon from "file://icons/mobileIcon.svg?minify";
|
||||
import webIcon from "file://icons/webIcon.svg?minify";
|
||||
import type { JSX } from "react";
|
||||
|
||||
export interface Session {
|
||||
sessionId: string;
|
||||
|
|
@ -42,42 +47,56 @@ export interface Session {
|
|||
const SessionsStore = findStoreLazy("SessionsStore") as {
|
||||
getSessions(): Record<string, Session>;
|
||||
};
|
||||
const { useStatusFillColor } = mapMangledModuleLazy(".concat(.5625*", {
|
||||
useStatusFillColor: filters.byCode(".hex")
|
||||
});
|
||||
|
||||
function Icon(path: string, opts?: { viewBox?: string; width?: number; height?: number; }) {
|
||||
function Icon(svg: string, size = 20) {
|
||||
return ({ color, tooltip, small }: { color: string; tooltip: string; small: boolean; }) => (
|
||||
<Tooltip text={tooltip} >
|
||||
{(tooltipProps: any) => (
|
||||
<svg
|
||||
{tooltipProps => (
|
||||
<img
|
||||
{...tooltipProps}
|
||||
height={(opts?.height ?? 20) - (small ? 3 : 0)}
|
||||
width={(opts?.width ?? 20) - (small ? 3 : 0)}
|
||||
viewBox={opts?.viewBox ?? "0 0 24 24"}
|
||||
fill={color}
|
||||
>
|
||||
<path d={path} />
|
||||
</svg>
|
||||
src={"data:image/svg+xml;utf8," + encodeURIComponent(svg.replace("#000000", color))}
|
||||
height={size - (small ? 3 : 0)}
|
||||
width={size - (small ? 3 : 0)}
|
||||
/>
|
||||
)}
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
|
||||
const Icons = {
|
||||
desktop: Icon("M4 2.5c-1.103 0-2 .897-2 2v11c0 1.104.897 2 2 2h7v2H7v2h10v-2h-4v-2h7c1.103 0 2-.896 2-2v-11c0-1.103-.897-2-2-2H4Zm16 2v9H4v-9h16Z"),
|
||||
web: Icon("M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2Zm-1 17.93c-3.95-.49-7-3.85-7-7.93 0-.62.08-1.21.21-1.79L9 15v1c0 1.1.9 2 2 2v1.93Zm6.9-2.54c-.26-.81-1-1.39-1.9-1.39h-1v-3c0-.55-.45-1-1-1H8v-2h2c.55 0 1-.45 1-1V7h2c1.1 0 2-.9 2-2v-.41c2.93 1.19 5 4.06 5 7.41 0 2.08-.8 3.97-2.1 5.39Z"),
|
||||
mobile: Icon("M 187 0 L 813 0 C 916.277 0 1000 83.723 1000 187 L 1000 1313 C 1000 1416.277 916.277 1500 813 1500 L 187 1500 C 83.723 1500 0 1416.277 0 1313 L 0 187 C 0 83.723 83.723 0 187 0 Z M 125 1000 L 875 1000 L 875 250 L 125 250 Z M 500 1125 C 430.964 1125 375 1180.964 375 1250 C 375 1319.036 430.964 1375 500 1375 C 569.036 1375 625 1319.036 625 1250 C 625 1180.964 569.036 1125 500 1125 Z", { viewBox: "0 0 1000 1500", height: 17, width: 17 }),
|
||||
embedded: Icon("M14.8 2.7 9 3.1V47h3.3c1.7 0 6.2.3 10 .7l6.7.6V2l-4.2.2c-2.4.1-6.9.3-10 .5zm1.8 6.4c1 1.7-1.3 3.6-2.7 2.2C12.7 10.1 13.5 8 15 8c.5 0 1.2.5 1.6 1.1zM16 33c0 6-.4 10-1 10s-1-4-1-10 .4-10 1-10 1 4 1 10zm15-8v23.3l3.8-.7c2-.3 4.7-.6 6-.6H43V3h-2.2c-1.3 0-4-.3-6-.6L31 1.7V25z", { viewBox: "0 0 50 50" }),
|
||||
} satisfies Record<DiscordPlatform, any>;
|
||||
type IconData = {
|
||||
svg: string,
|
||||
size: number,
|
||||
component: (props: { color: string, tooltip: string, small: boolean; }) => JSX.Element;
|
||||
};
|
||||
|
||||
const { useStatusFillColor } = mapMangledModuleLazy(".concat(.5625*", {
|
||||
useStatusFillColor: filters.byCode(".hex")
|
||||
});
|
||||
const Icons: Record<DiscordPlatform, IconData> = {
|
||||
desktop: iconData(desktopIcon),
|
||||
web: iconData(webIcon),
|
||||
mobile: iconData(mobileIcon),
|
||||
embedded: iconData(embeddedIcon),
|
||||
};
|
||||
|
||||
const PlatformIcon = ({ platform, status, small }: { platform: DiscordPlatform, status: string; small: boolean; }) => {
|
||||
const tooltip = platform === "embedded"
|
||||
function iconData(svg: string, size: number = 20): IconData {
|
||||
return {
|
||||
svg,
|
||||
size,
|
||||
component: Icon(svg, size),
|
||||
};
|
||||
}
|
||||
|
||||
function getPlatformTooltip(platform: DiscordPlatform): string {
|
||||
return platform === "embedded"
|
||||
? "Console"
|
||||
: platform[0].toUpperCase() + platform.slice(1);
|
||||
}
|
||||
|
||||
const Icon = Icons[platform] ?? Icons.desktop;
|
||||
const PlatformIcon = ({ platform, status, small }: { platform: DiscordPlatform, status: OnlineStatus; small: boolean; }) => {
|
||||
const tooltip = getPlatformTooltip(platform as DiscordPlatform);
|
||||
|
||||
const Icon = (Icons[platform] ?? Icons.desktop).component;
|
||||
|
||||
return <Icon color={useStatusFillColor(status)} tooltip={tooltip} small={small} />;
|
||||
};
|
||||
|
|
@ -107,6 +126,14 @@ function ensureOwnStatus(user: User) {
|
|||
}
|
||||
|
||||
function getBadges({ userId }: BadgeUserArgs): ProfileBadge[] {
|
||||
const colorMap = {
|
||||
online: useStatusFillColor("online"),
|
||||
idle: useStatusFillColor("idle"),
|
||||
dnd: useStatusFillColor("dnd"),
|
||||
offline: useStatusFillColor("offline"),
|
||||
streaming: useStatusFillColor("streaming"),
|
||||
};
|
||||
|
||||
const user = UserStore.getUser(userId);
|
||||
|
||||
if (!user || user.bot) return [];
|
||||
|
|
@ -116,19 +143,20 @@ function getBadges({ userId }: BadgeUserArgs): ProfileBadge[] {
|
|||
const status = PresenceStore.getClientStatus(user.id);
|
||||
if (!status) return [];
|
||||
|
||||
return Object.entries(status).map(([platform, status]) => ({
|
||||
component: () => (
|
||||
<span className="vc-platform-indicator">
|
||||
<PlatformIcon
|
||||
key={platform}
|
||||
platform={platform as DiscordPlatform}
|
||||
status={status}
|
||||
small={false}
|
||||
/>
|
||||
</span>
|
||||
),
|
||||
key: `vc-platform-indicator-${platform}`
|
||||
}));
|
||||
return Object.entries(status).map(([platform, status]) => {
|
||||
const tooltip = getPlatformTooltip(platform as DiscordPlatform);
|
||||
|
||||
const icon = Icons[platform as DiscordPlatform] ?? Icons.desktop;
|
||||
|
||||
return {
|
||||
description: tooltip,
|
||||
iconSrc: "data:image/svg+xml;utf8," + encodeURIComponent(icon.svg.replace("#000000", colorMap[status] ?? colorMap.offline)),
|
||||
props: {
|
||||
style: { width: icon.size, height: icon.size },
|
||||
},
|
||||
key: `vc-platform-indicator-${platform}`,
|
||||
} satisfies ProfileBadge;
|
||||
});
|
||||
}
|
||||
|
||||
const PlatformIndicator = ({ user, small = false }: { user: User; small?: boolean; }) => {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue