From 19b5c44e0afcb4ee4949689efd063f116e79e50d Mon Sep 17 00:00:00 2001 From: Tharki-God Date: Sun, 21 Apr 2024 15:49:36 +0530 Subject: [PATCH] meow --- .github/workflows/lint.yml | 2 +- .github/workflows/release.yml | 2 +- README.md | 4 +- esbuild.extra.mjs | 10 + flashcord/store/fakedeafen.html | 20 +- flashcord/store/fakedeafen/embed.html | 16 +- manifest.json | 6 +- package.json | 2 +- pnpm-lock.yaml | 406 +++-------- src/Components/AccountDetailsButton.tsx | 20 +- src/Components/CenterTrayButton.tsx | 67 ++ src/Components/ContextMenu.tsx | 56 +- src/Components/Settings.tsx | 18 +- src/assets/assets.d.ts | 3 + src/assets/fd_disable.mp3 | Bin 0 -> 7149 bytes src/assets/fd_enable.mp3 | Bin 0 -> 15299 bytes src/index.ts | 19 +- .../AccountContextMenu.tsx} | 74 +- src/{patches => injections}/AudioResolver.ts | 11 +- src/injections/CenterControlTray.tsx | 19 + .../GatewayConnectionStore.ts | 4 +- src/{patches => injections}/SettingValues.ts | 0 src/injections/index.ts | 16 + src/lib/consts.ts | 13 +- src/lib/requiredModules.ts | 82 ++- src/lib/utils.ts | 94 ++- src/listeners/CleanCallback.ts | 4 +- src/listeners/KeybindListener.ts | 4 +- src/listeners/index.ts | 11 +- src/patches/index.ts | 10 - src/plaintextPatches.ts | 2 +- src/types.ts | 640 ++++++++++-------- tsconfig.json | 2 +- 33 files changed, 838 insertions(+), 799 deletions(-) create mode 100644 esbuild.extra.mjs create mode 100644 src/Components/CenterTrayButton.tsx create mode 100644 src/assets/assets.d.ts create mode 100644 src/assets/fd_disable.mp3 create mode 100644 src/assets/fd_enable.mp3 rename src/{patches/Menu.tsx => injections/AccountContextMenu.tsx} (52%) rename src/{patches => injections}/AudioResolver.ts (64%) create mode 100644 src/injections/CenterControlTray.tsx rename src/{patches => injections}/GatewayConnectionStore.ts (91%) rename src/{patches => injections}/SettingValues.ts (100%) create mode 100644 src/injections/index.ts delete mode 100644 src/patches/index.ts diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index cce817f..e545ce4 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -20,7 +20,7 @@ jobs: - name: Set up Node.js uses: actions/setup-node@v3 with: - node-version: 18 + node-version: 20 - uses: pnpm/action-setup@v2 with: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b669bc2..4542987 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -19,7 +19,7 @@ jobs: - name: Set up Node.js uses: actions/setup-node@v3 with: - node-version: 18 + node-version: 20 - uses: pnpm/action-setup@v2 with: diff --git a/README.md b/README.md index 191ffff..277e82e 100644 --- a/README.md +++ b/README.md @@ -4,11 +4,11 @@ Show that you are deafened to others, while in reality you can still hear them. It's also possible to fake mute and fake video. -Direct Download Link: [dev.tharki.FakeDeafen.asar](https://github.com/TharkiDev/FakeDeafen/releases/latest/download/dev.tharki.FakeDeafen.asar) +Direct Download Link: [dev.tharki.FakeDeafen.asar](https://github.com/YofukashiNo/FakeDeafen/releases/latest/download/dev.tharki.FakeDeafen.asar) Install Link: -[![Install in Replugged](https://img.shields.io/badge/-Install%20in%20Replugged-blue?style=for-the-badge&logo=none)](https://replugged.dev/install?identifier=TharkiDev/FakeDeafen&source=github) +[![Install in Replugged](https://img.shields.io/badge/-Install%20in%20Replugged-blue?style=for-the-badge&logo=none)](https://replugged.dev/install?identifier=YofukashiNo/FakeDeafen&source=github) ![fake deaf](https://i.imgur.com/hLCUDCO.gif) diff --git a/esbuild.extra.mjs b/esbuild.extra.mjs new file mode 100644 index 0000000..391e74f --- /dev/null +++ b/esbuild.extra.mjs @@ -0,0 +1,10 @@ +export default ({ loader, ...buildInfo }) => { + // return c + return { + ...buildInfo, + loader: { + ...(loader ?? {}), + ".mp3": "dataurl", + }, + }; +}; diff --git a/flashcord/store/fakedeafen.html b/flashcord/store/fakedeafen.html index c23d8da..fb08cfc 100644 --- a/flashcord/store/fakedeafen.html +++ b/flashcord/store/fakedeafen.html @@ -12,17 +12,17 @@ // Show that you are deafened to others, while in reality you can still hear them. Show that you are deafened to others, while in reality you can still hear them. - // TharkiDev: Note to be careful to edit the correct name for the Github links to work. - TharkiDev + // YofukashiNo: Note to be careful to edit the correct name for the Github links to work. + YofukashiNo // Module License Unlicense // Module's Github Repository - https://github.com/TharkiDev/FakeDeafen + https://github.com/YofukashiNo/FakeDeafen // Your Github Profile - https://github.com/TharkiDev + https://github.com/YofukashiNo // Module's Discord Server https://discord.gg/SgKSKyh9gY @@ -43,7 +43,7 @@ FakeDeafen - Flashcord Store - + @@ -79,21 +79,21 @@

Show that you are deafened to others, while in reality you can still hear them.

It's also possible to fake mute and fake video.

-

Direct Download Link: dev.tharki.FakeDeafen.asar

+

Direct Download Link: dev.tharki.FakeDeafen.asar

FakeDeafen

-

💿

+

💿

How to install this Plugin:

🔌 Replugged

-

Click here to install the plugin, your web browser will then communicate with your Replugged Client to install the plugin.

+

Click here to install the plugin, your web browser will then communicate with your Replugged Client to install the plugin.

@@ -105,7 +105,7 @@

Disclaimer

- +
diff --git a/flashcord/store/fakedeafen/embed.html b/flashcord/store/fakedeafen/embed.html index 2ee6ed8..fe3edb8 100644 --- a/flashcord/store/fakedeafen/embed.html +++ b/flashcord/store/fakedeafen/embed.html @@ -12,17 +12,17 @@ // Show that you are deafened to others, while in reality you can still hear them. Show that you are deafened to others, while in reality you can still hear them. - // TharkiDev: Note to be careful to edit the correct name for the Github links to work. - TharkiDev + // YofukashiNo: Note to be careful to edit the correct name for the Github links to work. + YofukashiNo // Module License Unlicense // Module's Github Repository - https://github.com/TharkiDev/FakeDeafen + https://github.com/YofukashiNo/FakeDeafen // Your Github Profile - https://github.com/TharkiDev + https://github.com/YofukashiNo // Module's Discord Server https://discord.gg/SgKSKyh9gY @@ -38,7 +38,7 @@ FakeDeafen - Flashcord Store - + @@ -63,15 +63,15 @@

Show that you are deafened to others, while in reality you can still hear them.

- +
diff --git a/manifest.json b/manifest.json index 1dd438c..31ecde1 100644 --- a/manifest.json +++ b/manifest.json @@ -3,16 +3,16 @@ "name": "FakeDeafen", "description": "Fake your audio status, to make it look like you are muted or deafened from other's perspective when you're not.", "image": "https://i.imgur.com/hLCUDCO.gif", - "source": "https://github.com/TharkiDev/FakeDeafen", + "source": "https://github.com/YofukashiNo/FakeDeafen", "author": { "name": "Ahlawat", "discordID": "1121961711080050780", - "github": "TharkiDev" + "github": "YofukashiNo" }, "version": "1.1.4", "updater": { "type": "github", - "id": "TharkiDev/FakeDeafen" + "id": "YofukashiNo/FakeDeafen" }, "license": "MIT", "type": "replugged-plugin", diff --git a/package.json b/package.json index 34341f2..bcbc143 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,7 @@ "eslint-plugin-node": "^11.1.0", "eslint-plugin-react": "^7.33.2", "prettier": "^2.8.8", - "replugged": "^4.7.6", + "replugged": "4.7.9", "typescript": "^5.3.2" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 30c65ca..9a66802 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -33,8 +33,8 @@ devDependencies: specifier: ^2.8.8 version: 2.8.8 replugged: - specifier: ^4.7.6 - version: 4.7.6(@codemirror/view@6.22.1)(@lezer/common@1.1.1) + specifier: 4.7.9 + version: 4.7.9(@codemirror/view@6.22.1)(@lezer/common@1.1.1) typescript: specifier: ^5.3.2 version: 5.3.2 @@ -139,17 +139,17 @@ packages: minimatch: 3.1.2 dev: true - /@esbuild/android-arm64@0.18.20: - resolution: {integrity: sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==} + /@esbuild/aix-ppc64@0.19.11: + resolution: {integrity: sha512-FnzU0LyE3ySQk7UntJO4+qIiQgI7KoODnZg5xzXIrFJlKd2P2gwHsHY4927xj9y5PJmJSzULiUCWmv7iWnNa7g==} engines: {node: '>=12'} - cpu: [arm64] - os: [android] + cpu: [ppc64] + os: [aix] requiresBuild: true dev: true optional: true - /@esbuild/android-arm64@0.19.8: - resolution: {integrity: sha512-B8JbS61bEunhfx8kasogFENgQfr/dIp+ggYXwTqdbMAgGDhRa3AaPpQMuQU0rNxDLECj6FhDzk1cF9WHMVwrtA==} + /@esbuild/android-arm64@0.19.11: + resolution: {integrity: sha512-aiu7K/5JnLj//KOnOfEZ0D90obUkRzDMyqd/wNAUQ34m4YUPVhRZpnqKV9uqDGxT7cToSDnIHsGooyIczu9T+Q==} engines: {node: '>=12'} cpu: [arm64] os: [android] @@ -157,8 +157,8 @@ packages: dev: true optional: true - /@esbuild/android-arm@0.18.20: - resolution: {integrity: sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==} + /@esbuild/android-arm@0.19.11: + resolution: {integrity: sha512-5OVapq0ClabvKvQ58Bws8+wkLCV+Rxg7tUVbo9xu034Nm536QTII4YzhaFriQ7rMrorfnFKUsArD2lqKbFY4vw==} engines: {node: '>=12'} cpu: [arm] os: [android] @@ -166,17 +166,8 @@ packages: dev: true optional: true - /@esbuild/android-arm@0.19.8: - resolution: {integrity: sha512-31E2lxlGM1KEfivQl8Yf5aYU/mflz9g06H6S15ITUFQueMFtFjESRMoDSkvMo8thYvLBax+VKTPlpnx+sPicOA==} - engines: {node: '>=12'} - cpu: [arm] - os: [android] - requiresBuild: true - dev: true - optional: true - - /@esbuild/android-x64@0.18.20: - resolution: {integrity: sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==} + /@esbuild/android-x64@0.19.11: + resolution: {integrity: sha512-eccxjlfGw43WYoY9QgB82SgGgDbibcqyDTlk3l3C0jOVHKxrjdc9CTwDUQd0vkvYg5um0OH+GpxYvp39r+IPOg==} engines: {node: '>=12'} cpu: [x64] os: [android] @@ -184,17 +175,8 @@ packages: dev: true optional: true - /@esbuild/android-x64@0.19.8: - resolution: {integrity: sha512-rdqqYfRIn4jWOp+lzQttYMa2Xar3OK9Yt2fhOhzFXqg0rVWEfSclJvZq5fZslnz6ypHvVf3CT7qyf0A5pM682A==} - engines: {node: '>=12'} - cpu: [x64] - os: [android] - requiresBuild: true - dev: true - optional: true - - /@esbuild/darwin-arm64@0.18.20: - resolution: {integrity: sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==} + /@esbuild/darwin-arm64@0.19.11: + resolution: {integrity: sha512-ETp87DRWuSt9KdDVkqSoKoLFHYTrkyz2+65fj9nfXsaV3bMhTCjtQfw3y+um88vGRKRiF7erPrh/ZuIdLUIVxQ==} engines: {node: '>=12'} cpu: [arm64] os: [darwin] @@ -202,26 +184,8 @@ packages: dev: true optional: true - /@esbuild/darwin-arm64@0.19.8: - resolution: {integrity: sha512-RQw9DemMbIq35Bprbboyf8SmOr4UXsRVxJ97LgB55VKKeJOOdvsIPy0nFyF2l8U+h4PtBx/1kRf0BelOYCiQcw==} - engines: {node: '>=12'} - cpu: [arm64] - os: [darwin] - requiresBuild: true - dev: true - optional: true - - /@esbuild/darwin-x64@0.18.20: - resolution: {integrity: sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [darwin] - requiresBuild: true - dev: true - optional: true - - /@esbuild/darwin-x64@0.19.8: - resolution: {integrity: sha512-3sur80OT9YdeZwIVgERAysAbwncom7b4bCI2XKLjMfPymTud7e/oY4y+ci1XVp5TfQp/bppn7xLw1n/oSQY3/Q==} + /@esbuild/darwin-x64@0.19.11: + resolution: {integrity: sha512-fkFUiS6IUK9WYUO/+22omwetaSNl5/A8giXvQlcinLIjVkxwTLSktbF5f/kJMftM2MJp9+fXqZ5ezS7+SALp4g==} engines: {node: '>=12'} cpu: [x64] os: [darwin] @@ -229,8 +193,8 @@ packages: dev: true optional: true - /@esbuild/freebsd-arm64@0.18.20: - resolution: {integrity: sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==} + /@esbuild/freebsd-arm64@0.19.11: + resolution: {integrity: sha512-lhoSp5K6bxKRNdXUtHoNc5HhbXVCS8V0iZmDvyWvYq9S5WSfTIHU2UGjcGt7UeS6iEYp9eeymIl5mJBn0yiuxA==} engines: {node: '>=12'} cpu: [arm64] os: [freebsd] @@ -238,17 +202,8 @@ packages: dev: true optional: true - /@esbuild/freebsd-arm64@0.19.8: - resolution: {integrity: sha512-WAnPJSDattvS/XtPCTj1tPoTxERjcTpH6HsMr6ujTT+X6rylVe8ggxk8pVxzf5U1wh5sPODpawNicF5ta/9Tmw==} - engines: {node: '>=12'} - cpu: [arm64] - os: [freebsd] - requiresBuild: true - dev: true - optional: true - - /@esbuild/freebsd-x64@0.18.20: - resolution: {integrity: sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==} + /@esbuild/freebsd-x64@0.19.11: + resolution: {integrity: sha512-JkUqn44AffGXitVI6/AbQdoYAq0TEullFdqcMY/PCUZ36xJ9ZJRtQabzMA+Vi7r78+25ZIBosLTOKnUXBSi1Kw==} engines: {node: '>=12'} cpu: [x64] os: [freebsd] @@ -256,26 +211,8 @@ packages: dev: true optional: true - /@esbuild/freebsd-x64@0.19.8: - resolution: {integrity: sha512-ICvZyOplIjmmhjd6mxi+zxSdpPTKFfyPPQMQTK/w+8eNK6WV01AjIztJALDtwNNfFhfZLux0tZLC+U9nSyA5Zg==} - engines: {node: '>=12'} - cpu: [x64] - os: [freebsd] - requiresBuild: true - dev: true - optional: true - - /@esbuild/linux-arm64@0.18.20: - resolution: {integrity: sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==} - engines: {node: '>=12'} - cpu: [arm64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/linux-arm64@0.19.8: - resolution: {integrity: sha512-z1zMZivxDLHWnyGOctT9JP70h0beY54xDDDJt4VpTX+iwA77IFsE1vCXWmprajJGa+ZYSqkSbRQ4eyLCpCmiCQ==} + /@esbuild/linux-arm64@0.19.11: + resolution: {integrity: sha512-LneLg3ypEeveBSMuoa0kwMpCGmpu8XQUh+mL8XXwoYZ6Be2qBnVtcDI5azSvh7vioMDhoJFZzp9GWp9IWpYoUg==} engines: {node: '>=12'} cpu: [arm64] os: [linux] @@ -283,17 +220,8 @@ packages: dev: true optional: true - /@esbuild/linux-arm@0.18.20: - resolution: {integrity: sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==} - engines: {node: '>=12'} - cpu: [arm] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/linux-arm@0.19.8: - resolution: {integrity: sha512-H4vmI5PYqSvosPaTJuEppU9oz1dq2A7Mr2vyg5TF9Ga+3+MGgBdGzcyBP7qK9MrwFQZlvNyJrvz6GuCaj3OukQ==} + /@esbuild/linux-arm@0.19.11: + resolution: {integrity: sha512-3CRkr9+vCV2XJbjwgzjPtO8T0SZUmRZla+UL1jw+XqHZPkPgZiyWvbDvl9rqAN8Zl7qJF0O/9ycMtjU67HN9/Q==} engines: {node: '>=12'} cpu: [arm] os: [linux] @@ -301,17 +229,8 @@ packages: dev: true optional: true - /@esbuild/linux-ia32@0.18.20: - resolution: {integrity: sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==} - engines: {node: '>=12'} - cpu: [ia32] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/linux-ia32@0.19.8: - resolution: {integrity: sha512-1a8suQiFJmZz1khm/rDglOc8lavtzEMRo0v6WhPgxkrjcU0LkHj+TwBrALwoz/OtMExvsqbbMI0ChyelKabSvQ==} + /@esbuild/linux-ia32@0.19.11: + resolution: {integrity: sha512-caHy++CsD8Bgq2V5CodbJjFPEiDPq8JJmBdeyZ8GWVQMjRD0sU548nNdwPNvKjVpamYYVL40AORekgfIubwHoA==} engines: {node: '>=12'} cpu: [ia32] os: [linux] @@ -319,17 +238,8 @@ packages: dev: true optional: true - /@esbuild/linux-loong64@0.18.20: - resolution: {integrity: sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==} - engines: {node: '>=12'} - cpu: [loong64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/linux-loong64@0.19.8: - resolution: {integrity: sha512-fHZWS2JJxnXt1uYJsDv9+b60WCc2RlvVAy1F76qOLtXRO+H4mjt3Tr6MJ5l7Q78X8KgCFudnTuiQRBhULUyBKQ==} + /@esbuild/linux-loong64@0.19.11: + resolution: {integrity: sha512-ppZSSLVpPrwHccvC6nQVZaSHlFsvCQyjnvirnVjbKSHuE5N24Yl8F3UwYUUR1UEPaFObGD2tSvVKbvR+uT1Nrg==} engines: {node: '>=12'} cpu: [loong64] os: [linux] @@ -337,17 +247,8 @@ packages: dev: true optional: true - /@esbuild/linux-mips64el@0.18.20: - resolution: {integrity: sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==} - engines: {node: '>=12'} - cpu: [mips64el] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/linux-mips64el@0.19.8: - resolution: {integrity: sha512-Wy/z0EL5qZYLX66dVnEg9riiwls5IYnziwuju2oUiuxVc+/edvqXa04qNtbrs0Ukatg5HEzqT94Zs7J207dN5Q==} + /@esbuild/linux-mips64el@0.19.11: + resolution: {integrity: sha512-B5x9j0OgjG+v1dF2DkH34lr+7Gmv0kzX6/V0afF41FkPMMqaQ77pH7CrhWeR22aEeHKaeZVtZ6yFwlxOKPVFyg==} engines: {node: '>=12'} cpu: [mips64el] os: [linux] @@ -355,17 +256,8 @@ packages: dev: true optional: true - /@esbuild/linux-ppc64@0.18.20: - resolution: {integrity: sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/linux-ppc64@0.19.8: - resolution: {integrity: sha512-ETaW6245wK23YIEufhMQ3HSeHO7NgsLx8gygBVldRHKhOlD1oNeNy/P67mIh1zPn2Hr2HLieQrt6tWrVwuqrxg==} + /@esbuild/linux-ppc64@0.19.11: + resolution: {integrity: sha512-MHrZYLeCG8vXblMetWyttkdVRjQlQUb/oMgBNurVEnhj4YWOr4G5lmBfZjHYQHHN0g6yDmCAQRR8MUHldvvRDA==} engines: {node: '>=12'} cpu: [ppc64] os: [linux] @@ -373,8 +265,8 @@ packages: dev: true optional: true - /@esbuild/linux-riscv64@0.18.20: - resolution: {integrity: sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==} + /@esbuild/linux-riscv64@0.19.11: + resolution: {integrity: sha512-f3DY++t94uVg141dozDu4CCUkYW+09rWtaWfnb3bqe4w5NqmZd6nPVBm+qbz7WaHZCoqXqHz5p6CM6qv3qnSSQ==} engines: {node: '>=12'} cpu: [riscv64] os: [linux] @@ -382,26 +274,8 @@ packages: dev: true optional: true - /@esbuild/linux-riscv64@0.19.8: - resolution: {integrity: sha512-T2DRQk55SgoleTP+DtPlMrxi/5r9AeFgkhkZ/B0ap99zmxtxdOixOMI570VjdRCs9pE4Wdkz7JYrsPvsl7eESg==} - engines: {node: '>=12'} - cpu: [riscv64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/linux-s390x@0.18.20: - resolution: {integrity: sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==} - engines: {node: '>=12'} - cpu: [s390x] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/linux-s390x@0.19.8: - resolution: {integrity: sha512-NPxbdmmo3Bk7mbNeHmcCd7R7fptJaczPYBaELk6NcXxy7HLNyWwCyDJ/Xx+/YcNH7Im5dHdx9gZ5xIwyliQCbg==} + /@esbuild/linux-s390x@0.19.11: + resolution: {integrity: sha512-A5xdUoyWJHMMlcSMcPGVLzYzpcY8QP1RtYzX5/bS4dvjBGVxdhuiYyFwp7z74ocV7WDc0n1harxmpq2ePOjI0Q==} engines: {node: '>=12'} cpu: [s390x] os: [linux] @@ -409,8 +283,8 @@ packages: dev: true optional: true - /@esbuild/linux-x64@0.18.20: - resolution: {integrity: sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==} + /@esbuild/linux-x64@0.19.11: + resolution: {integrity: sha512-grbyMlVCvJSfxFQUndw5mCtWs5LO1gUlwP4CDi4iJBbVpZcqLVT29FxgGuBJGSzyOxotFG4LoO5X+M1350zmPA==} engines: {node: '>=12'} cpu: [x64] os: [linux] @@ -418,26 +292,8 @@ packages: dev: true optional: true - /@esbuild/linux-x64@0.19.8: - resolution: {integrity: sha512-lytMAVOM3b1gPypL2TRmZ5rnXl7+6IIk8uB3eLsV1JwcizuolblXRrc5ShPrO9ls/b+RTp+E6gbsuLWHWi2zGg==} - engines: {node: '>=12'} - cpu: [x64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/netbsd-x64@0.18.20: - resolution: {integrity: sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==} - engines: {node: '>=12'} - cpu: [x64] - os: [netbsd] - requiresBuild: true - dev: true - optional: true - - /@esbuild/netbsd-x64@0.19.8: - resolution: {integrity: sha512-hvWVo2VsXz/8NVt1UhLzxwAfo5sioj92uo0bCfLibB0xlOmimU/DeAEsQILlBQvkhrGjamP0/el5HU76HAitGw==} + /@esbuild/netbsd-x64@0.19.11: + resolution: {integrity: sha512-13jvrQZJc3P230OhU8xgwUnDeuC/9egsjTkXN49b3GcS5BKvJqZn86aGM8W9pd14Kd+u7HuFBMVtrNGhh6fHEQ==} engines: {node: '>=12'} cpu: [x64] os: [netbsd] @@ -445,17 +301,8 @@ packages: dev: true optional: true - /@esbuild/openbsd-x64@0.18.20: - resolution: {integrity: sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==} - engines: {node: '>=12'} - cpu: [x64] - os: [openbsd] - requiresBuild: true - dev: true - optional: true - - /@esbuild/openbsd-x64@0.19.8: - resolution: {integrity: sha512-/7Y7u77rdvmGTxR83PgaSvSBJCC2L3Kb1M/+dmSIvRvQPXXCuC97QAwMugBNG0yGcbEGfFBH7ojPzAOxfGNkwQ==} + /@esbuild/openbsd-x64@0.19.11: + resolution: {integrity: sha512-ysyOGZuTp6SNKPE11INDUeFVVQFrhcNDVUgSQVDzqsqX38DjhPEPATpid04LCoUr2WXhQTEZ8ct/EgJCUDpyNw==} engines: {node: '>=12'} cpu: [x64] os: [openbsd] @@ -463,8 +310,8 @@ packages: dev: true optional: true - /@esbuild/sunos-x64@0.18.20: - resolution: {integrity: sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==} + /@esbuild/sunos-x64@0.19.11: + resolution: {integrity: sha512-Hf+Sad9nVwvtxy4DXCZQqLpgmRTQqyFyhT3bZ4F2XlJCjxGmRFF0Shwn9rzhOYRB61w9VMXUkxlBy56dk9JJiQ==} engines: {node: '>=12'} cpu: [x64] os: [sunos] @@ -472,26 +319,8 @@ packages: dev: true optional: true - /@esbuild/sunos-x64@0.19.8: - resolution: {integrity: sha512-9Lc4s7Oi98GqFA4HzA/W2JHIYfnXbUYgekUP/Sm4BG9sfLjyv6GKKHKKVs83SMicBF2JwAX6A1PuOLMqpD001w==} - engines: {node: '>=12'} - cpu: [x64] - os: [sunos] - requiresBuild: true - dev: true - optional: true - - /@esbuild/win32-arm64@0.18.20: - resolution: {integrity: sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==} - engines: {node: '>=12'} - cpu: [arm64] - os: [win32] - requiresBuild: true - dev: true - optional: true - - /@esbuild/win32-arm64@0.19.8: - resolution: {integrity: sha512-rq6WzBGjSzihI9deW3fC2Gqiak68+b7qo5/3kmB6Gvbh/NYPA0sJhrnp7wgV4bNwjqM+R2AApXGxMO7ZoGhIJg==} + /@esbuild/win32-arm64@0.19.11: + resolution: {integrity: sha512-0P58Sbi0LctOMOQbpEOvOL44Ne0sqbS0XWHMvvrg6NE5jQ1xguCSSw9jQeUk2lfrXYsKDdOe6K+oZiwKPilYPQ==} engines: {node: '>=12'} cpu: [arm64] os: [win32] @@ -499,17 +328,8 @@ packages: dev: true optional: true - /@esbuild/win32-ia32@0.18.20: - resolution: {integrity: sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==} - engines: {node: '>=12'} - cpu: [ia32] - os: [win32] - requiresBuild: true - dev: true - optional: true - - /@esbuild/win32-ia32@0.19.8: - resolution: {integrity: sha512-AIAbverbg5jMvJznYiGhrd3sumfwWs8572mIJL5NQjJa06P8KfCPWZQ0NwZbPQnbQi9OWSZhFVSUWjjIrn4hSw==} + /@esbuild/win32-ia32@0.19.11: + resolution: {integrity: sha512-6YOrWS+sDJDmshdBIQU+Uoyh7pQKrdykdefC1avn76ss5c+RN6gut3LZA4E2cH5xUEp5/cA0+YxRaVtRAb0xBg==} engines: {node: '>=12'} cpu: [ia32] os: [win32] @@ -517,17 +337,8 @@ packages: dev: true optional: true - /@esbuild/win32-x64@0.18.20: - resolution: {integrity: sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [win32] - requiresBuild: true - dev: true - optional: true - - /@esbuild/win32-x64@0.19.8: - resolution: {integrity: sha512-bfZ0cQ1uZs2PqpulNL5j/3w+GDhP36k1K5c38QdQg+Swy51jFZWWeIkteNsufkQxp986wnqRRsb/bHbY1WQ7TA==} + /@esbuild/win32-x64@0.19.11: + resolution: {integrity: sha512-vfkhltrjCAb603XaFhqhAF4LGDi2M4OrCRrFusyQ+iTLQ/o60QQXxc9cZC/FFpihBI9N1Grn6SMKVJ4KP7Fuiw==} engines: {node: '>=12'} cpu: [x64] os: [win32] @@ -1127,10 +938,6 @@ packages: fill-range: 7.0.1 dev: true - /buffer-from@1.1.2: - resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} - dev: true - /cacheable-lookup@7.0.0: resolution: {integrity: sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==} engines: {node: '>=14.16'} @@ -1478,74 +1285,45 @@ packages: is-symbol: 1.0.4 dev: true - /esbuild-sass-plugin@2.16.0(esbuild@0.19.8): + /esbuild-sass-plugin@2.16.0(esbuild@0.19.11): resolution: {integrity: sha512-mGCe9MxNYvZ+j77Q/QFO+rwUGA36mojDXkOhtVmoyz1zwYbMaNrtVrmXwwYDleS/UMKTNU3kXuiTtPiAD3K+Pw==} peerDependencies: esbuild: ^0.19.4 dependencies: - esbuild: 0.19.8 + esbuild: 0.19.11 resolve: 1.22.8 sass: 1.69.5 dev: true - /esbuild@0.18.20: - resolution: {integrity: sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==} + /esbuild@0.19.11: + resolution: {integrity: sha512-HJ96Hev2hX/6i5cDVwcqiJBBtuo9+FeIJOtZ9W1kA5M6AMJRHUZlpYZ1/SbEwtO0ioNAW8rUooVpC/WehY2SfA==} engines: {node: '>=12'} hasBin: true requiresBuild: true optionalDependencies: - '@esbuild/android-arm': 0.18.20 - '@esbuild/android-arm64': 0.18.20 - '@esbuild/android-x64': 0.18.20 - '@esbuild/darwin-arm64': 0.18.20 - '@esbuild/darwin-x64': 0.18.20 - '@esbuild/freebsd-arm64': 0.18.20 - '@esbuild/freebsd-x64': 0.18.20 - '@esbuild/linux-arm': 0.18.20 - '@esbuild/linux-arm64': 0.18.20 - '@esbuild/linux-ia32': 0.18.20 - '@esbuild/linux-loong64': 0.18.20 - '@esbuild/linux-mips64el': 0.18.20 - '@esbuild/linux-ppc64': 0.18.20 - '@esbuild/linux-riscv64': 0.18.20 - '@esbuild/linux-s390x': 0.18.20 - '@esbuild/linux-x64': 0.18.20 - '@esbuild/netbsd-x64': 0.18.20 - '@esbuild/openbsd-x64': 0.18.20 - '@esbuild/sunos-x64': 0.18.20 - '@esbuild/win32-arm64': 0.18.20 - '@esbuild/win32-ia32': 0.18.20 - '@esbuild/win32-x64': 0.18.20 - dev: true - - /esbuild@0.19.8: - resolution: {integrity: sha512-l7iffQpT2OrZfH2rXIp7/FkmaeZM0vxbxN9KfiCwGYuZqzMg/JdvX26R31Zxn/Pxvsrg3Y9N6XTcnknqDyyv4w==} - engines: {node: '>=12'} - hasBin: true - requiresBuild: true - optionalDependencies: - '@esbuild/android-arm': 0.19.8 - '@esbuild/android-arm64': 0.19.8 - '@esbuild/android-x64': 0.19.8 - '@esbuild/darwin-arm64': 0.19.8 - '@esbuild/darwin-x64': 0.19.8 - '@esbuild/freebsd-arm64': 0.19.8 - '@esbuild/freebsd-x64': 0.19.8 - '@esbuild/linux-arm': 0.19.8 - '@esbuild/linux-arm64': 0.19.8 - '@esbuild/linux-ia32': 0.19.8 - '@esbuild/linux-loong64': 0.19.8 - '@esbuild/linux-mips64el': 0.19.8 - '@esbuild/linux-ppc64': 0.19.8 - '@esbuild/linux-riscv64': 0.19.8 - '@esbuild/linux-s390x': 0.19.8 - '@esbuild/linux-x64': 0.19.8 - '@esbuild/netbsd-x64': 0.19.8 - '@esbuild/openbsd-x64': 0.19.8 - '@esbuild/sunos-x64': 0.19.8 - '@esbuild/win32-arm64': 0.19.8 - '@esbuild/win32-ia32': 0.19.8 - '@esbuild/win32-x64': 0.19.8 + '@esbuild/aix-ppc64': 0.19.11 + '@esbuild/android-arm': 0.19.11 + '@esbuild/android-arm64': 0.19.11 + '@esbuild/android-x64': 0.19.11 + '@esbuild/darwin-arm64': 0.19.11 + '@esbuild/darwin-x64': 0.19.11 + '@esbuild/freebsd-arm64': 0.19.11 + '@esbuild/freebsd-x64': 0.19.11 + '@esbuild/linux-arm': 0.19.11 + '@esbuild/linux-arm64': 0.19.11 + '@esbuild/linux-ia32': 0.19.11 + '@esbuild/linux-loong64': 0.19.11 + '@esbuild/linux-mips64el': 0.19.11 + '@esbuild/linux-ppc64': 0.19.11 + '@esbuild/linux-riscv64': 0.19.11 + '@esbuild/linux-s390x': 0.19.11 + '@esbuild/linux-x64': 0.19.11 + '@esbuild/netbsd-x64': 0.19.11 + '@esbuild/openbsd-x64': 0.19.11 + '@esbuild/sunos-x64': 0.19.11 + '@esbuild/win32-arm64': 0.19.11 + '@esbuild/win32-ia32': 0.19.11 + '@esbuild/win32-x64': 0.19.11 dev: true /escalade@3.1.1: @@ -2708,8 +2486,8 @@ packages: rc: 1.2.8 dev: true - /replugged@4.7.6(@codemirror/view@6.22.1)(@lezer/common@1.1.1): - resolution: {integrity: sha512-E7qxlBRlvpQiXz3zXUO/IH0TQqXxgLmQCO/BMugNDqqtWEbm3W5VIIXYnnrPce5UA0n8TgIzxh0fORl+22sS2w==} + /replugged@4.7.9(@codemirror/view@6.22.1)(@lezer/common@1.1.1): + resolution: {integrity: sha512-Eh44KEzXVLRO7UtrZm5mvYXr12KJV4zpifYUEFlNoGaT9mzO598f8WgiMdCQdaUf27bZl+nk6qUngMR4YfkXoA==} engines: {node: '>=18.0.0', pnpm: '>=8.0.0'} hasBin: true requiresBuild: true @@ -2724,14 +2502,14 @@ packages: adm-zip: 0.5.10 chalk: 5.3.0 codemirror: 6.0.1(@lezer/common@1.1.1) - esbuild: 0.19.8 - esbuild-sass-plugin: 2.16.0(esbuild@0.19.8) + esbuild: 0.19.11 + esbuild-sass-plugin: 2.16.0(esbuild@0.19.11) esm: 3.2.25 node-fetch: 3.3.2 prompts: 2.4.2 semver: 7.5.4 standalone-electron-types: 1.0.0 - tsx: 3.14.0 + tsx: 4.7.0 update-notifier: 6.0.2 ws: 8.14.2 yargs: 17.7.2 @@ -2909,18 +2687,6 @@ packages: engines: {node: '>=0.10.0'} dev: true - /source-map-support@0.5.21: - resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} - dependencies: - buffer-from: 1.1.2 - source-map: 0.6.1 - dev: true - - /source-map@0.6.1: - resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} - engines: {node: '>=0.10.0'} - dev: true - /standalone-electron-types@1.0.0: resolution: {integrity: sha512-0HOi/tlTz3mjWhsAz4uRbpQcHMZ+ifj1JzWW9nugykOHClBBG77ps8QinrzX1eow4Iw2pnC+RFaSYRgufF4BOg==} dependencies: @@ -3044,13 +2810,13 @@ packages: typescript: 5.3.2 dev: true - /tsx@3.14.0: - resolution: {integrity: sha512-xHtFaKtHxM9LOklMmJdI3BEnQq/D5F73Of2E1GDrITi9sgoVkvIsrQUTY1G8FlmGtA+awCI4EBlTRRYxkL2sRg==} + /tsx@4.7.0: + resolution: {integrity: sha512-I+t79RYPlEYlHn9a+KzwrvEwhJg35h/1zHsLC2JXvhC2mdynMv6Zxzvhv5EMV6VF5qJlLlkSnMVvdZV3PSIGcg==} + engines: {node: '>=18.0.0'} hasBin: true dependencies: - esbuild: 0.18.20 + esbuild: 0.19.11 get-tsconfig: 4.7.2 - source-map-support: 0.5.21 optionalDependencies: fsevents: 2.3.3 dev: true diff --git a/src/Components/AccountDetailsButton.tsx b/src/Components/AccountDetailsButton.tsx index bd0b9be..f537dc4 100644 --- a/src/Components/AccountDetailsButton.tsx +++ b/src/Components/AccountDetailsButton.tsx @@ -1,18 +1,23 @@ import { plugins } from "replugged"; -import { contextMenu as ContextMenuApi } from "replugged/common"; +import { contextMenu as ContextMenuApi, React } from "replugged/common"; import { SettingValues } from "../index"; -import { PanelButton } from "../lib/requiredModules"; +import Modules from "../lib/requiredModules"; import { defaultSettings } from "../lib/consts"; import FakeDeafenContextMenu from "./ContextMenu"; import Icons from "../Components/Icons"; import Utils from "../lib/utils"; -export default (): React.ReactElement | null => { +export const AccountDetailsButton = () => { if ( !SettingValues.get("userPanel", defaultSettings.userPanel) || plugins.getDisabled().includes("dev.tharki.FakeDeafen") ) return null; - const enabled = SettingValues.get("enabled", defaultSettings.enabled); + const [enabled, setEnabled] = React.useState( + SettingValues.get("enabled", defaultSettings.enabled), + ); + React.useEffect(() => { + setEnabled(SettingValues.get("enabled", defaultSettings.enabled)); + }, [SettingValues.get("enabled", defaultSettings.enabled)]); const Icon = ; const DisabledIcon = ( @@ -25,10 +30,10 @@ export default (): React.ReactElement | null => { ); return ( - - ContextMenuApi.open(event, (e) => ( - + ContextMenuApi.open(event, (props) => ( + )) } icon={() => (enabled ? DisabledIcon : Icon)} @@ -37,3 +42,4 @@ export default (): React.ReactElement | null => { /> ); }; +export default () => (Modules.PanelButton ? : <>); diff --git a/src/Components/CenterTrayButton.tsx b/src/Components/CenterTrayButton.tsx new file mode 100644 index 0000000..9cb0267 --- /dev/null +++ b/src/Components/CenterTrayButton.tsx @@ -0,0 +1,67 @@ +import { React, components } from "replugged/common"; +import { SettingValues } from "../index"; +import Modules from "../lib/requiredModules"; +import { defaultSettings } from "../lib/consts"; +import FakeDeafenContextMenu from "./ContextMenu"; +import Icons from "../Components/Icons"; +import Utils from "../lib/utils"; +import Types from "../types"; +const DiscordComponents = components as typeof components & { Popout: Types.Popout }; +export default (): React.ReactElement | null => { + if (!SettingValues.get("centerTray", defaultSettings.centerTray)) return null; + const [enabled, setEnabled] = React.useState( + SettingValues.get("enabled", defaultSettings.enabled), + ); + React.useEffect(() => { + setEnabled(SettingValues.get("enabled", defaultSettings.enabled)); + }, [SettingValues.get("enabled", defaultSettings.enabled)]); + const Icon = ; + const DisabledIcon = ( + + + + ); + return ( + { + const { preventIdle, allowIdle } = Modules.IdleHandler!.usePreventIdle("popup"); + React.useEffect(() => { + preventIdle(); + return () => allowIdle(); + }, [preventIdle, allowIdle]); + return ( + + + + ); + }} + align="center" + position="top" + animation={DiscordComponents.Popout.Animation.FADE}> + {({ + onClick: onPopoutClick, + "aria-expanded": popoutOpen, + }: { + onClick: Types.DefaultTypes.AnyFunction; + "aria-expanded": boolean; + }) => { + return ( + (enabled ? DisabledIcon : Icon)} + isActive={enabled} + label={`${enabled ? "Unfake" : "Fake"} VC Status`} + onClick={() => Utils.toggleSoundStatus(enabled)} + onPopoutClick={onPopoutClick} + popoutOpen={popoutOpen} + /> + ); + }} + + ); +}; diff --git a/src/Components/ContextMenu.tsx b/src/Components/ContextMenu.tsx index 6791e4f..fe4ab5b 100644 --- a/src/Components/ContextMenu.tsx +++ b/src/Components/ContextMenu.tsx @@ -3,45 +3,49 @@ import { ContextMenu } from "replugged/components"; import { SettingValues } from "../index"; import { defaultSettings } from "../lib/consts"; import Utils from "../lib/utils"; - -export default (props) => { - const { value: muteValue, onChange: muteOnChange } = Utils.useSetting( +import Types from "../types"; +export default (props: Types.MenuProps | { onClose: Types.DefaultTypes.AnyFunction }) => { + const [muteValue, muteOnChange] = Utils.useSettingArray( SettingValues, "soundStatus.mute", defaultSettings.soundStatus.mute, ); - const { value: deafValue, onChange: deafOnChange } = Utils.useSetting( + const [deafValue, deafOnChange] = Utils.useSettingArray( SettingValues, "soundStatus.deaf", defaultSettings.soundStatus.deaf, ); - const { value: videoValue, onChange: videoOnChange } = Utils.useSetting( + const [videoValue, videoOnChange] = Utils.useSettingArray( SettingValues, "soundStatus.video", defaultSettings.soundStatus.video, ); return ( - - - - muteOnChange(!muteValue)} - /> - deafOnChange(!deafValue)} - /> - videoOnChange(!videoValue)} - /> + + + + muteOnChange(!muteValue)} + /> + deafOnChange(!deafValue)} + /> + videoOnChange(!videoValue)} + /> + ); }; diff --git a/src/Components/Settings.tsx b/src/Components/Settings.tsx index 5b9eafb..7fd9113 100644 --- a/src/Components/Settings.tsx +++ b/src/Components/Settings.tsx @@ -1,7 +1,6 @@ -import { components } from "replugged"; +import { Category, SwitchItem } from "replugged/components"; import { PluginLogger, SettingValues } from "../index"; import { defaultSettings } from "../lib/consts"; -const { SwitchItem, Category } = components; import KeybindItem from "./KeybindItem"; import Utils from "../lib/utils"; import Types from "../types"; @@ -48,11 +47,11 @@ export const Settings = (): React.ReactElement => { { Show toasts Status picker User panel + + Center Tray + { ); }; + +export default { registerSettings, Settings }; diff --git a/src/assets/assets.d.ts b/src/assets/assets.d.ts new file mode 100644 index 0000000..056db3b --- /dev/null +++ b/src/assets/assets.d.ts @@ -0,0 +1,3 @@ +declare module "*.mp3" { + export default content as string; +} diff --git a/src/assets/fd_disable.mp3 b/src/assets/fd_disable.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..0c7e4591c2f9926cd1e6a3a4bc51be63ddc5796d GIT binary patch literal 7149 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 O0KoqTVf?@SivIv5=A%#m literal 0 HcmV?d00001 diff --git a/src/assets/fd_enable.mp3 b/src/assets/fd_enable.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..688d9649038961ca1d4743abd893c7e90bb430da GIT binary patch literal 15299 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�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 DM?$!s literal 0 HcmV?d00001 diff --git a/src/index.ts b/src/index.ts index d596a21..a181fb5 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,25 +1,24 @@ import { Injector, Logger, settings } from "replugged"; import { defaultSettings } from "./lib/consts"; import "./style.css"; -import { registerSettings } from "./Components/Settings"; -export const CurrentlyPressed = new Map(); export const PluginInjector = new Injector(); export const { utils: PluginInjectorUtils } = PluginInjector; -export const PluginLogger = Logger.plugin("FakeDeafen"); +export const PluginLogger = Logger.plugin("FakeDeafen", "#b380ff"); export const SettingValues = await settings.init("dev.tharki.FakeDeafen", defaultSettings); - -import { applyInjections } from "./patches/index"; -import { addListeners, removeListeners } from "./listeners/index"; +export const CurrentlyPressed = new Map(); +import Settings from "./Components/Settings"; +import Injections from "./injections/index"; +import Listeners from "./listeners/index"; export const start = (): void => { - registerSettings(); - applyInjections(); - addListeners(); + Settings.registerSettings(); + void Injections.applyInjections(); + void Listeners.addListeners(); }; export const stop = (): void => { PluginInjector.uninjectAll(); - removeListeners(); + Listeners.removeListeners(); }; export { default as _addPanelButton } from "./Components/AccountDetailsButton"; diff --git a/src/patches/Menu.tsx b/src/injections/AccountContextMenu.tsx similarity index 52% rename from src/patches/Menu.tsx rename to src/injections/AccountContextMenu.tsx index 4587b08..6d39098 100644 --- a/src/patches/Menu.tsx +++ b/src/injections/AccountContextMenu.tsx @@ -1,3 +1,4 @@ +import { React } from "replugged/common"; import { ContextMenu } from "replugged/components"; import { PluginInjectorUtils, SettingValues } from "../index"; import { defaultSettings } from "../lib/consts"; @@ -8,22 +9,27 @@ import Types from "../types"; export default (): void => { PluginInjectorUtils.addMenuItem(Types.DefaultTypes.ContextMenuTypes.Account, (_data, menu) => { if (!SettingValues.get("statusPicker", defaultSettings.statusPicker)) return; - const { value: muteValue, onChange: muteOnChange } = Utils.useSetting( + const [muteValue, muteOnChange] = Utils.useSettingArray( SettingValues, "soundStatus.mute", defaultSettings.soundStatus.mute, ); - const { value: deafValue, onChange: deafOnChange } = Utils.useSetting( + const [deafValue, deafOnChange] = Utils.useSettingArray( SettingValues, "soundStatus.deaf", defaultSettings.soundStatus.deaf, ); - const { value: videoValue, onChange: videoOnChange } = Utils.useSetting( + const [videoValue, videoOnChange] = Utils.useSettingArray( SettingValues, "soundStatus.video", defaultSettings.soundStatus.video, ); - const enabled = SettingValues.get("enabled", defaultSettings.enabled); + const [enabled, setEnabled] = React.useState( + SettingValues.get("enabled", defaultSettings.enabled), + ); + React.useEffect(() => { + setEnabled(SettingValues.get("enabled", defaultSettings.enabled)); + }, [SettingValues.get("enabled", defaultSettings.enabled)]); const Icon = ( { fill: "#a61616", }} points="22.6,2.7 22.6,2.8 19.3,6.1 16,9.3 16,9.4 15,10.4 15,10.4 10.3,15 2.8,22.5 1.4,21.1 21.2,1.3 " - />{" "} + /> ); const { children } = menu as { children: React.ReactElement[] }; const switchAccount = children.find((c) => c?.props?.children?.key === "switch-account"); - if (!children.find((c) => c?.props?.className === "tharki")) + if (!children.find((c) => c?.props?.className === "yofukashino")) children.splice( - children.indexOf(switchAccount), + children.indexOf(switchAccount!), 0, - , + , ); - const section = children.find((c) => c?.props?.className === "tharki"); - section.props.children = section.props.children.filter((m) => m?.props?.id !== "fake-deafen"); - if (!section.props.children.find((m) => m?.props?.id === "fake-deafen")) + const section = children.find((c) => c?.props?.className === "yofukashino"); + if (!section) return; + section.props.children = section.props.children.filter( + (m: React.ReactElement) => m?.props?.id !== "fake-deafen", + ); + if (!section.props.children.find((m: React.ReactElement) => m?.props?.id === "fake-deafen")) section.props.children.push( Utils.toggleSoundStatus(enabled)} icon={() => (enabled ? DisabledIcon : Icon)} showIconFirst={true}> - - - muteOnChange(!muteValue)} - /> - deafOnChange(!deafValue)} - /> - videoOnChange(!videoValue)} - /> + + + muteOnChange(!muteValue)} + /> + deafOnChange(!deafValue)} + /> + videoOnChange(!videoValue)} + /> + , ); }); diff --git a/src/patches/AudioResolver.ts b/src/injections/AudioResolver.ts similarity index 64% rename from src/patches/AudioResolver.ts rename to src/injections/AudioResolver.ts index 3618f71..530ab39 100644 --- a/src/patches/AudioResolver.ts +++ b/src/injections/AudioResolver.ts @@ -1,9 +1,9 @@ import { PluginInjector } from "../index"; -import { AudioResolverPromise } from "../lib/requiredModules"; +import Modules from "../lib/requiredModules"; import { Sounds } from "../lib/consts"; export default async (): Promise => { - const AudioResolver = await AudioResolverPromise; + const AudioResolver = await Modules.AudioResolverPromise; PluginInjector.instead(AudioResolver, "exports", ([sound]: [string], res) => { switch (sound) { case `./${Sounds.Enable}.mp3`: { @@ -12,9 +12,10 @@ export default async (): Promise => { case `./${Sounds.Disable}.mp3`: { return Sounds.DisableURL; } - default: { - return res(sound); - } + default: + if (AudioResolver.exports.keys().includes(sound)) { + return res(sound); + } } }); }; diff --git a/src/injections/CenterControlTray.tsx b/src/injections/CenterControlTray.tsx new file mode 100644 index 0000000..cc98961 --- /dev/null +++ b/src/injections/CenterControlTray.tsx @@ -0,0 +1,19 @@ +import CenterTrayButton from "../Components/CenterTrayButton"; +import { PluginInjector } from "../index"; +import Modules from "../lib/requiredModules"; +import Utils from "../lib/utils"; +import Types from "../types"; +export default (): void => { + PluginInjector.after(Modules.CenterControlTray, "default", (_args, res: Types.ReactTree) => { + const Container = Utils.findInReactTree( + res, + (c: Types.ReactTree) => Array.isArray(c?.props?.children) && c.type === "div", + ) as Types.ReactTree; + if (!Container) return res; + const Index = Container.props.children.findIndex((c) => + c?.props?.renderPopout?.toString()?.includes("renderInputModes"), + ); + Container.props.children.splice(Index, 0, ); + return res; + }); +}; diff --git a/src/patches/GatewayConnectionStore.ts b/src/injections/GatewayConnectionStore.ts similarity index 91% rename from src/patches/GatewayConnectionStore.ts rename to src/injections/GatewayConnectionStore.ts index 3d9ebbc..d02ed54 100644 --- a/src/patches/GatewayConnectionStore.ts +++ b/src/injections/GatewayConnectionStore.ts @@ -1,11 +1,11 @@ import { PluginInjector, SettingValues } from "../index"; -import { GatewayConnectionStore } from "../lib/requiredModules"; import { defaultSettings } from "../lib/consts"; +import Modules from "../lib/requiredModules"; import Types from "../types"; export default (): void => { PluginInjector.before( - GatewayConnectionStore.getSocket(), + Modules.GatewayConnectionStore.getSocket(), "voiceStateUpdate", (args: [Types.voiceStateUpdateArgs]) => { const [voiceStateUpdateArgs] = args; diff --git a/src/patches/SettingValues.ts b/src/injections/SettingValues.ts similarity index 100% rename from src/patches/SettingValues.ts rename to src/injections/SettingValues.ts diff --git a/src/injections/index.ts b/src/injections/index.ts new file mode 100644 index 0000000..022260f --- /dev/null +++ b/src/injections/index.ts @@ -0,0 +1,16 @@ +import Modules from "../lib/requiredModules"; +import injectAudioResolver from "./AudioResolver"; +import injectCenterControlTray from "./CenterControlTray"; +import injectGatewayConnectionStore from "./GatewayConnectionStore"; +import injectAccountContextMenu from "./AccountContextMenu"; +import injectSettingSetter from "./SettingValues"; +export const applyInjections = async (): Promise => { + await Modules.loadModules(); + void injectAudioResolver(); + injectCenterControlTray(); + injectGatewayConnectionStore(); + injectAccountContextMenu(); + injectSettingSetter(); +}; + +export default { applyInjections }; diff --git a/src/lib/consts.ts b/src/lib/consts.ts index 3684918..c289d37 100644 --- a/src/lib/consts.ts +++ b/src/lib/consts.ts @@ -1,4 +1,6 @@ -import { KeybindUtils } from "./requiredModules"; +import Modules from "./requiredModules"; +import EnableURL from "../assets/fd_enable.mp3"; +import DisableURL from "../assets/fd_disable.mp3"; export const defaultSettings = { enabled: true, soundStatus: { @@ -8,16 +10,19 @@ export const defaultSettings = { }, statusPicker: true, userPanel: true, + centerTray: true, playAudio: { enable: true, disable: true, }, showToast: true, - keybind: KeybindUtils.toCombo("ctrl+d") as number[][], + get keybind() { + return Modules.KeybindUtils.toCombo("ctrl+d") as number[][]; + }, }; export const Sounds = { Enable: "fd_start", Disable: "fd_stop", - EnableURL: "https://tharkidev.github.io/files-random-host/fd_enable.mp3", - DisableURL: "https://tharkidev.github.io/files-random-host/fd_disable.mp3", + EnableURL, + DisableURL, }; diff --git a/src/lib/requiredModules.ts b/src/lib/requiredModules.ts index 9850e0f..c74dfa2 100644 --- a/src/lib/requiredModules.ts +++ b/src/lib/requiredModules.ts @@ -1,45 +1,43 @@ import { webpack } from "replugged"; import Types from "../types"; -export const WindowInfoStore = webpack.getByProps( - "isFocused", - "isElementFullScreen", - "addChangeListener", - "removeChangeListener", -); - -export const SoundUtils = webpack.getByProps( - "playSound", - "createSound", - "createSoundForPack", -); - -export const KeybindUtils = webpack.getByProps("toCombo"); - -export const StatusPickerClasses = webpack.getByProps( - "status", - "statusItem", -); - -export const GatewayConnectionStore = - webpack.getBySource("GatewayConnectionStore"); - -export const MediaEngineStore = webpack.getByStoreName("MediaEngineStore"); - -export const PanelButton = webpack.getBySource< - React.ComponentClass<{ - onContextMenu?: (event: React.MouseEvent) => void; - icon?: () => React.ReactNode; - tooltipText?: string; - onClick?: () => void; - }> ->("Masks.PANEL_BUTTON"); - -export const AccountDetailsClasses = webpack.getByProps( - "godlike", - "container", -); - -export const AudioResolverPromise = webpack.waitForModule<{ - exports: Types.DefaultTypes.AnyFunction; -}>(webpack.filters.bySource("./mute.mp3"), { raw: true }); +export const Modules: Types.Modules = {}; + +Modules.loadModules = async (): Promise => { + Modules.WindowInfoStore ??= await webpack.waitForProps( + "isFocused", + "isElementFullScreen", + "addChangeListener", + "removeChangeListener", + ); + + Modules.SoundUtils ??= await webpack.waitForProps( + "playSound", + "createSound", + "createSoundForPack", + ); + Modules.KeybindUtils ??= await webpack.waitForProps("toCombo"); + + Modules.GatewayConnection ??= await webpack.waitForProps("Opcode"); + + Modules.CenterControlTray ??= await webpack.waitForProps("GoLiveButton"); + Modules.CenterControlButton ??= await webpack + .waitForProps<{ + CenterControlButton: Types.CenterControlButton; + }>("CenterControlButton") + .then(({ CenterControlButton }) => CenterControlButton); + Modules.IdleHandler ??= await webpack.waitForProps("usePreventIdle"); + Modules.PanelButton ??= await webpack.waitForModule( + webpack.filters.bySource("Masks.PANEL_BUTTON"), + ); + + Modules.AudioResolverPromise = webpack.waitForModule( + webpack.filters.bySource("./mute.mp3"), + { raw: true }, + ); + Modules.GatewayConnectionStore ??= + webpack.getByStoreName("GatewayConnectionStore"); + Modules.MediaEngineStore ??= webpack.getByStoreName("MediaEngineStore"); +}; + +export default Modules; diff --git a/src/lib/utils.ts b/src/lib/utils.ts index 87bc5c7..b927b40 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -1,12 +1,7 @@ import { settings, util } from "replugged"; import { React, channels as UltimateChannelStore, lodash } from "replugged/common"; import { PluginInjector, PluginLogger, SettingValues } from "../index"; -import { - AccountDetailsClasses, - GatewayConnectionStore, - MediaEngineStore, - SoundUtils, -} from "./requiredModules"; +import Modules from "./requiredModules"; import { Sounds, defaultSettings } from "./consts"; import Types from "../types"; @@ -22,11 +17,14 @@ export const forceRerenderElement = async (selector: string): Promise => { }; export const updateSoundStatus = (): void => { - const Channel = UltimateChannelStore.getChannel(UltimateChannelStore.getVoiceChannelId()); + const { MediaEngineStore, GatewayConnectionStore } = Modules; + const Channel = UltimateChannelStore.getChannel(UltimateChannelStore.getVoiceChannelId()!); if (!Channel) return; PluginLogger.log("Updating Voice State."); - GatewayConnectionStore.getSocket().voiceStateUpdate({ + const Socket = GatewayConnectionStore.getSocket(); + const voiceStateUpdate = Socket.voiceStateUpdate.bind(Socket); + voiceStateUpdate({ channelId: Channel.id, guildId: Channel.guild_id, selfDeaf: SettingValues.get("enabled", defaultSettings.enabled) @@ -48,40 +46,38 @@ export const toggleSoundStatus = (enabled: boolean): void => { (enabled && (SettingValues.get("playAudio", defaultSettings.playAudio).disable ?? true)) || (!enabled && (SettingValues.get("playAudio", defaultSettings.playAudio).enable ?? true)) ) { - SoundUtils.playSound(enabled ? Sounds.Disable : Sounds.Enable, 0.5); + Modules.SoundUtils.playSound(enabled ? Sounds.Disable : Sounds.Enable, 0.5); } + PluginLogger.log(enabled ? "Disabled Fake Voice State" : "Enabled Fake Voice State"); SettingValues.set("enabled", !enabled); - if (SettingValues.get("userPanel", defaultSettings.userPanel)) - void forceRerenderElement(`.${AccountDetailsClasses.container}:not(.spotify-modal)`); }; export const useSetting = < T extends Record, D extends keyof T, K extends Extract, F extends Types.NestedType | T[K] | undefined, - P extends `${K}.${string}` | K, + P extends `${K}.${string}` | `${K}/${string}` | `${K}-${string}` | K, + V extends P extends `${K}.${string}` | `${K}/${string}` | `${K}-${string}` + ? NonNullable> + : P extends D + ? NonNullable + : F extends null | undefined + ? T[P] | undefined + : NonNullable | F, >( settings: settings.SettingsManager, key: P, fallback?: F, ): { - value: Types.NestedType | F; - onChange: (newValue: Types.ValType | F>) => void; + value: V; + onChange: (newValue: Types.ValType> | Types.ValType) => void; } => { - const [initialKey, ...pathArray] = Object.keys(settings.all()).includes(key) - ? ([key] as [K]) - : (key.split(".") as [K, ...string[]]); - const path = pathArray.join("."); - const initial = settings.get(initialKey, path.length ? ({} as T[K]) : (fallback as T[K])); - const [value, setValue] = React.useState>( - path.length - ? (lodash.get(initial, path, fallback) as Types.NestedType) - : (initial as Types.NestedType), - ); + const initial = settings.get(key as K) ?? lodash.get(settings.all(), key) ?? fallback; + const [value, setValue] = React.useState(initial as V); return { value, - onChange: (newValue: Types.ValType | F>) => { + onChange: (newValue: Types.ValType> | Types.ValType) => { const isObj = newValue && typeof newValue === "object"; const value = isObj && "value" in newValue ? newValue.value : newValue; const checked = isObj && "checked" in newValue ? newValue.checked : void 0; @@ -91,15 +87,49 @@ export const useSetting = < : void 0; const targetValue = target && "value" in target ? target.value : void 0; const targetChecked = target && "checked" in target ? target.checked : void 0; - const finalValue = checked ?? targetChecked ?? targetValue ?? value ?? newValue; + const finalValue = (checked ?? targetChecked ?? targetValue ?? value ?? newValue) as T[K]; - setValue(finalValue as Types.NestedType); - settings.set( - initialKey, - path.length ? (lodash.set(initial, path, finalValue) as T[K]) : (finalValue as T[K]), - ); + setValue(finalValue as V); + + if (settings.get(key as K)) { + settings.set(key as K, finalValue); + } else { + const [rootKey] = key.split(/[-/.]/); + const setting = lodash.set(settings.all(), key, finalValue)[rootKey as K]; + settings.set(rootKey as K, setting); + } }, }; }; -export default { ...util, forceRerenderElement, updateSoundStatus, toggleSoundStatus, useSetting }; +export const useSettingArray = < + T extends Record, + D extends keyof T, + K extends Extract, + F extends Types.NestedType | T[K] | undefined, + P extends `${K}.${string}` | `${K}/${string}` | `${K}-${string}` | K, + V extends P extends `${K}.${string}` | `${K}/${string}` | `${K}-${string}` + ? NonNullable> + : P extends D + ? NonNullable + : F extends null | undefined + ? T[P] | undefined + : NonNullable | F, +>( + settings: settings.SettingsManager, + key: P, + fallback?: F, +): [V, (newValue: Types.ValType> | Types.ValType) => void] => { + const { value, onChange } = useSetting(settings, key, fallback); + + return [value as V, onChange]; +}; + +export default { + ...util, + forceRerenderElement, + updateSoundStatus, + toggleSoundStatus, + useSetting, + useSettingArray, +}; diff --git a/src/listeners/CleanCallback.ts b/src/listeners/CleanCallback.ts index 059a7c9..51223b5 100644 --- a/src/listeners/CleanCallback.ts +++ b/src/listeners/CleanCallback.ts @@ -1,5 +1,5 @@ import { CurrentlyPressed } from "../index"; -import { WindowInfoStore } from "../lib/requiredModules"; +import Modules from "../lib/requiredModules"; export const cleanKeybindsCallback = (): void => { - if (WindowInfoStore.isFocused()) CurrentlyPressed.clear(); + if (Modules.WindowInfoStore.isFocused()) CurrentlyPressed.clear(); }; diff --git a/src/listeners/KeybindListener.ts b/src/listeners/KeybindListener.ts index 03cd021..1a72c4d 100644 --- a/src/listeners/KeybindListener.ts +++ b/src/listeners/KeybindListener.ts @@ -1,12 +1,12 @@ import { toast as Toasts } from "replugged/common"; import { CurrentlyPressed, SettingValues } from "../index"; import { defaultSettings } from "../lib/consts"; -import { KeybindUtils } from "../lib/requiredModules"; +import Modules from "../lib/requiredModules"; import Utils from "../lib/utils"; import Types from "../types"; export const keybindListener = (e: Types.KeybindEvent): void => { - const keybindEvents = KeybindUtils.toBrowserEvents( + const keybindEvents = Modules.KeybindUtils.toBrowserEvents( SettingValues.get("keybind", defaultSettings.keybind), ) as Types.KeybindEvent[]; if ( diff --git a/src/listeners/index.ts b/src/listeners/index.ts index 6622a05..cc6a02e 100644 --- a/src/listeners/index.ts +++ b/src/listeners/index.ts @@ -1,14 +1,17 @@ -import { WindowInfoStore } from "../lib/requiredModules"; +import Modules from "../lib/requiredModules"; import { cleanKeybindsCallback } from "./CleanCallback"; import { keybindListener } from "./KeybindListener"; -export const addListeners = (): void => { - WindowInfoStore.addChangeListener(cleanKeybindsCallback); +export const addListeners = async (): Promise => { + await Modules.loadModules(); + Modules.WindowInfoStore?.addChangeListener(cleanKeybindsCallback); window.addEventListener("keydown", keybindListener); window.addEventListener("keyup", keybindListener); }; export const removeListeners = (): void => { - WindowInfoStore.removeChangeListener(cleanKeybindsCallback); + Modules.WindowInfoStore.removeChangeListener(cleanKeybindsCallback); window.removeEventListener("keydown", keybindListener); window.removeEventListener("keyup", keybindListener); }; + +export default { addListeners, removeListeners }; diff --git a/src/patches/index.ts b/src/patches/index.ts deleted file mode 100644 index 43e11c8..0000000 --- a/src/patches/index.ts +++ /dev/null @@ -1,10 +0,0 @@ -import patchAudioResolver from "./AudioResolver"; -import patchGatewayConnectionStore from "./GatewayConnectionStore"; -import patchStatusPicker from "./Menu"; -import patchSettingSetter from "./SettingValues"; -export const applyInjections = (): void => { - void patchAudioResolver(); - patchGatewayConnectionStore(); - patchStatusPicker(); - patchSettingSetter(); -}; diff --git a/src/plaintextPatches.ts b/src/plaintextPatches.ts index 06e58a2..22053b2 100644 --- a/src/plaintextPatches.ts +++ b/src/plaintextPatches.ts @@ -15,7 +15,7 @@ export default [ replacements: [ { match: /null==\w+\?void 0:\w+\.selfDeaf/, - replace: `$&&&replugged.webpack.getByStoreName("MediaEngineStore").isDeaf()`, + replace: `$&&&replugged.webpack.getByStoreName("MediaEngineStore")?.isDeaf?.()`, }, ], }, diff --git a/src/types.ts b/src/types.ts index c29fdb1..6cd7f05 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,277 +1,385 @@ -import { types as DefaultTypes } from "replugged"; +import { types } from "replugged"; import type { Store } from "replugged/dist/renderer/modules/common/flux"; -export { types as DefaultTypes } from "replugged"; -export interface GenericModule extends Record {} -export interface WindowInfoStore { - isFocused: () => boolean; - addChangeListener: (callback: DefaultTypes.AnyFunction) => void; - removeChangeListener: (callback: DefaultTypes.AnyFunction) => void; - isElementFullScreen: () => boolean; -} -export interface Socket { - analytics: object; - compressionHandler: object; - connectionStartTime: number; - connectionState: string; - didForceClearGuildHashes: boolean; - dispatchExceptionBackoff: object; - dispatchSuccessTimer: number; - expeditedHeartbeatTimeout: null | number; - gatewayBackoff: object; - handleIdentify: DefaultTypes.AnyFunction; - hasConnectedOnce: boolean; - heartbeatAck: boolean; - heartbeatInterval: number; - heartbeater: number; - helloTimeout: null | number; - identifyCompressedByteSize: number; - identifyStartTime: number; - identifyUncompressedByteSize: number; - initialHeartbeatTimeout: null | number; - isDeferringDispatches: boolean; - isFastConnect: boolean; - lastHeartbeatAckTime: number; - nextReconnectIsImmediate: boolean; - queuedDispatches: []; - resumeAnalytics: object; - resumeUrl: string; - send: DefaultTypes.AnyFunction; - voiceStateUpdate: DefaultTypes.AnyFunction; - seq: number; - sessionId: string; - token: string; - webSocket: object; - _events: object; - _eventsCount: number; - _maxListeners: undefined | number; -} -export interface GatewayConnectionStore extends Store { - getSocket: () => Socket; - initialize: DefaultTypes.AnyFunction; - isConnected: DefaultTypes.AnyFunction; - isConnectedOrOverlay: DefaultTypes.AnyFunction; - isTryingToConnect: DefaultTypes.AnyFunction; - lastTimeConnectedChanged: DefaultTypes.AnyFunction; -} -export interface voiceStateUpdateArgs { - channelId: string; - guildId: string; - preferredRegion: string; - selfDeaf: boolean; - selfMute: boolean; - selfVideo: boolean; -} -export interface MediaEngineStore extends Store { - getAecDump: DefaultTypes.AnyFunction; - getAttenuateWhileSpeakingOthers: DefaultTypes.AnyFunction; - getAttenuateWhileSpeakingSelf: DefaultTypes.AnyFunction; - getAttenuation: DefaultTypes.AnyFunction; - getAudioSubsystem: DefaultTypes.AnyFunction; - getAutomaticGainControl: DefaultTypes.AnyFunction; - getAv1Enabled: DefaultTypes.AnyFunction; - getCameraComponent: DefaultTypes.AnyFunction; - getDebugLogging: DefaultTypes.AnyFunction; - getEchoCancellation: DefaultTypes.AnyFunction; - getEnableSilenceWarning: DefaultTypes.AnyFunction; - getEverSpeakingWhileMuted: DefaultTypes.AnyFunction; - getExperimentalEncoders: DefaultTypes.AnyFunction; - getExperimentalSoundshare: DefaultTypes.AnyFunction; - getGoLiveContext: DefaultTypes.AnyFunction; - getGoLiveSource: DefaultTypes.AnyFunction; - getH265Enabled: DefaultTypes.AnyFunction; - getHardwareH264: DefaultTypes.AnyFunction; - getInputDetected: DefaultTypes.AnyFunction; - getInputDeviceId: DefaultTypes.AnyFunction; - getInputDevices: DefaultTypes.AnyFunction; - getInputVolume: DefaultTypes.AnyFunction; - getLocalPan: DefaultTypes.AnyFunction; - getLocalVolume: DefaultTypes.AnyFunction; - getLoopback: DefaultTypes.AnyFunction; - getMediaEngine: DefaultTypes.AnyFunction; - getMode: DefaultTypes.AnyFunction; - getModeOptions: DefaultTypes.AnyFunction; - getNoInputDetectedNotice: DefaultTypes.AnyFunction; - getNoiseCancellation: DefaultTypes.AnyFunction; - getNoiseSuppression: DefaultTypes.AnyFunction; - getOpenH264: DefaultTypes.AnyFunction; - getOutputDeviceId: DefaultTypes.AnyFunction; - getOutputDevices: DefaultTypes.AnyFunction; - getOutputVolume: DefaultTypes.AnyFunction; - getPacketDelay: DefaultTypes.AnyFunction; - getQoS: DefaultTypes.AnyFunction; - getSettings: DefaultTypes.AnyFunction; - getShortcuts: DefaultTypes.AnyFunction; - getSoundshareEnabled: DefaultTypes.AnyFunction; - getState: DefaultTypes.AnyFunction; - getSupportedSecureFramesProtocolVersion: DefaultTypes.AnyFunction; - getVideoComponent: DefaultTypes.AnyFunction; - getVideoDeviceId: DefaultTypes.AnyFunction; - getVideoDevices: DefaultTypes.AnyFunction; - getVideoHook: DefaultTypes.AnyFunction; - getVideoStreamParameters: DefaultTypes.AnyFunction; - getVideoToggleState: DefaultTypes.AnyFunction; - hasContext: DefaultTypes.AnyFunction; - initialize: DefaultTypes.AnyFunction; - isAdvancedVoiceActivitySupported: DefaultTypes.AnyFunction; - isAecDumpSupported: DefaultTypes.AnyFunction; - isAnyLocalVideoAutoDisabled: DefaultTypes.AnyFunction; - isAutomaticGainControlSupported: DefaultTypes.AnyFunction; - isDeaf: DefaultTypes.AnyFunction; - isEnabled: DefaultTypes.AnyFunction; - isExperimentalEncodersSupported: DefaultTypes.AnyFunction; - isHardwareMute: DefaultTypes.AnyFunction; - isInteractionRequired: DefaultTypes.AnyFunction; - isLocalMute: DefaultTypes.AnyFunction; - isLocalVideoAutoDisabled: DefaultTypes.AnyFunction; - isLocalVideoDisabled: DefaultTypes.AnyFunction; - isMediaFilterSettingLoading: DefaultTypes.AnyFunction; - isMute: DefaultTypes.AnyFunction; - isNativeAudioPermissionReady: DefaultTypes.AnyFunction; - isNoiseCancellationError: DefaultTypes.AnyFunction; - isNoiseCancellationSupported: DefaultTypes.AnyFunction; - isNoiseSuppressionSupported: DefaultTypes.AnyFunction; - isScreenSharing: DefaultTypes.AnyFunction; - isSelfDeaf: DefaultTypes.AnyFunction; - isSelfMute: DefaultTypes.AnyFunction; - isSelfMutedTemporarily: DefaultTypes.AnyFunction; - isSimulcastSupported: DefaultTypes.AnyFunction; - isSoundSharing: DefaultTypes.AnyFunction; - isSupported: DefaultTypes.AnyFunction; - isVideoAvailable: DefaultTypes.AnyFunction; - isVideoEnabled: DefaultTypes.AnyFunction; - setCanHavePriority: DefaultTypes.AnyFunction; - supports: DefaultTypes.AnyFunction; - supportsDisableLocalVideo: DefaultTypes.AnyFunction; - supportsEnableSoundshare: DefaultTypes.AnyFunction; - supportsExperimentalSoundshare: DefaultTypes.AnyFunction; - supportsInApp: DefaultTypes.AnyFunction; - supportsScreenSoundshare: DefaultTypes.AnyFunction; - supportsVideoHook: DefaultTypes.AnyFunction; -} +import { ContextMenuProps } from "replugged/dist/renderer/modules/components/ContextMenu"; +import type util from "replugged/util"; -export interface KeybindUtils { - toCombo: DefaultTypes.AnyFunction; - toBrowserEvents: DefaultTypes.AnyFunction; -} -export interface SoundUtils { - createSound: DefaultTypes.AnyFunction; - createSoundForPack: DefaultTypes.AnyFunction; - playSound: DefaultTypes.AnyFunction; -} +export namespace Types { + export import DefaultTypes = types; + export type MenuProps = ContextMenuProps["ContextMenu"]; + export type UtilTree = util.Tree; + export type ReactTree = util.Tree & React.ReactElement; + export interface GenericModule extends Record {} + export interface WindowInfoStore { + isFocused: () => boolean; + addChangeListener: (callback: DefaultTypes.AnyFunction) => void; + removeChangeListener: (callback: DefaultTypes.AnyFunction) => void; + isElementFullScreen: () => boolean; + } + export interface AudioResolver { + exports: Types.DefaultTypes.AnyFunction & { keys: () => string[] }; + } + export interface Popout + extends React.ComponentClass<{ + align: string; + renderPopout: DefaultTypes.AnyFunction; + children: DefaultTypes.AnyFunction; + animation?: string; + autoInvert?: boolean; + nudgeAlignIntoViewport?: boolean; + position?: string; + positionKey?: string; + spacing?: number; + }> { + Animation: { + FADE: string; + NONE: string; + SCALE: string; + TRANSLATE: string; + }; -export interface AccountDetailsClasses { - accountProfilePopoutWrapper: string; - avatar: string; - avatarWrapper: string; - buildOverrideButton: string; - canCopy: string; - container: string; - copySuccess: string; - customStatus: string; - emoji: string; - godlike: string; - hasBuildOverride: string; - nameTag: string; - panelSubtextContainer: string; - panelTitleContainer: string; - redIcon: string; - statusTooltip: string; - strikethrough: string; - usernameContainer: string; - withTagAsButton: string; - withTagless: string; -} -export interface AccountDetails { - AccountDetails: DefaultTypes.AnyFunction; -} -export interface CloseButtonProps { - size?: string; - className?: string; - onClick?: () => void; -} -export interface KeybindEvent { - type: string; - altKey: boolean; - ctrlKey: boolean; - keyCode: number; - metaKey: boolean; - shiftKey: boolean; -} -export interface KeybindRecorderItemProps { - title?: string; - note?: string; - size?: string; - className?: string; - value?: number[][]; - onChange?: (value: unknown) => void; - disabled?: boolean; - clearable?: boolean; -} -export interface StatusPickerClasses { - description: string; - divider: string; - icon: string; - mainStatusIcon: string; - menu: string; - menuItemFocused: string; - menuItemFocusedPremium: string; - modal: string; - status: string; - statusItem: string; - statusPickerModalMenu: string; -} + defaultProps: { + animation: string; + autoInvert: boolean; + nudgeAlignIntoViewport: boolean; + position: string; + positionKey?: string; + spacing: number; + }; + } + export interface Socket { + analytics: object; + compressionHandler: object; + connectionStartTime: number; + connectionState: string; + didForceClearGuildHashes: boolean; + dispatchExceptionBackoff: object; + dispatchSuccessTimer: number; + expeditedHeartbeatTimeout: null | number; + gatewayBackoff: object; + handleIdentify: DefaultTypes.AnyFunction; + hasConnectedOnce: boolean; + heartbeatAck: boolean; + heartbeatInterval: number; + heartbeater: number; + helloTimeout: null | number; + identifyCompressedByteSize: number; + identifyStartTime: number; + identifyUncompressedByteSize: number; + initialHeartbeatTimeout: null | number; + isDeferringDispatches: boolean; + isFastConnect: boolean; + lastHeartbeatAckTime: number; + nextReconnectIsImmediate: boolean; + queuedDispatches: []; + resumeAnalytics: object; + resumeUrl: string; + send: DefaultTypes.AnyFunction; + voiceStateUpdate: DefaultTypes.AnyFunction; + seq: number; + sessionId: string; + token: string; + webSocket: object; + _events: object; + _eventsCount: number; + _maxListeners: undefined | number; + } + export interface GatewayConnectionStore extends Store { + getSocket: () => Socket; + initialize: DefaultTypes.AnyFunction; + isConnected: DefaultTypes.AnyFunction; + isConnectedOrOverlay: DefaultTypes.AnyFunction; + isTryingToConnect: DefaultTypes.AnyFunction; + lastTimeConnectedChanged: DefaultTypes.AnyFunction; + } + export interface voiceStateUpdateArgs { + channelId: string; + guildId: string; + preferredRegion: string; + selfDeaf: boolean; + selfMute: boolean; + selfVideo: boolean; + } + export interface MediaEngineStore extends Store { + getAecDump: DefaultTypes.AnyFunction; + getAttenuateWhileSpeakingOthers: DefaultTypes.AnyFunction; + getAttenuateWhileSpeakingSelf: DefaultTypes.AnyFunction; + getAttenuation: DefaultTypes.AnyFunction; + getAudioSubsystem: DefaultTypes.AnyFunction; + getAutomaticGainControl: DefaultTypes.AnyFunction; + getAv1Enabled: DefaultTypes.AnyFunction; + getCameraComponent: DefaultTypes.AnyFunction; + getDebugLogging: DefaultTypes.AnyFunction; + getEchoCancellation: DefaultTypes.AnyFunction; + getEnableSilenceWarning: DefaultTypes.AnyFunction; + getEverSpeakingWhileMuted: DefaultTypes.AnyFunction; + getExperimentalEncoders: DefaultTypes.AnyFunction; + getExperimentalSoundshare: DefaultTypes.AnyFunction; + getGoLiveContext: DefaultTypes.AnyFunction; + getGoLiveSource: DefaultTypes.AnyFunction; + getH265Enabled: DefaultTypes.AnyFunction; + getHardwareH264: DefaultTypes.AnyFunction; + getInputDetected: DefaultTypes.AnyFunction; + getInputDeviceId: DefaultTypes.AnyFunction; + getInputDevices: DefaultTypes.AnyFunction; + getInputVolume: DefaultTypes.AnyFunction; + getLocalPan: DefaultTypes.AnyFunction; + getLocalVolume: DefaultTypes.AnyFunction; + getLoopback: DefaultTypes.AnyFunction; + getMediaEngine: DefaultTypes.AnyFunction; + getMode: DefaultTypes.AnyFunction; + getModeOptions: DefaultTypes.AnyFunction; + getNoInputDetectedNotice: DefaultTypes.AnyFunction; + getNoiseCancellation: DefaultTypes.AnyFunction; + getNoiseSuppression: DefaultTypes.AnyFunction; + getOpenH264: DefaultTypes.AnyFunction; + getOutputDeviceId: DefaultTypes.AnyFunction; + getOutputDevices: DefaultTypes.AnyFunction; + getOutputVolume: DefaultTypes.AnyFunction; + getPacketDelay: DefaultTypes.AnyFunction; + getQoS: DefaultTypes.AnyFunction; + getSettings: DefaultTypes.AnyFunction; + getShortcuts: DefaultTypes.AnyFunction; + getSoundshareEnabled: DefaultTypes.AnyFunction; + getState: DefaultTypes.AnyFunction; + getSupportedSecureFramesProtocolVersion: DefaultTypes.AnyFunction; + getVideoComponent: DefaultTypes.AnyFunction; + getVideoDeviceId: DefaultTypes.AnyFunction; + getVideoDevices: DefaultTypes.AnyFunction; + getVideoHook: DefaultTypes.AnyFunction; + getVideoStreamParameters: DefaultTypes.AnyFunction; + getVideoToggleState: DefaultTypes.AnyFunction; + hasContext: DefaultTypes.AnyFunction; + initialize: DefaultTypes.AnyFunction; + isAdvancedVoiceActivitySupported: DefaultTypes.AnyFunction; + isAecDumpSupported: DefaultTypes.AnyFunction; + isAnyLocalVideoAutoDisabled: DefaultTypes.AnyFunction; + isAutomaticGainControlSupported: DefaultTypes.AnyFunction; + isDeaf: DefaultTypes.AnyFunction; + isEnabled: DefaultTypes.AnyFunction; + isExperimentalEncodersSupported: DefaultTypes.AnyFunction; + isHardwareMute: DefaultTypes.AnyFunction; + isInteractionRequired: DefaultTypes.AnyFunction; + isLocalMute: DefaultTypes.AnyFunction; + isLocalVideoAutoDisabled: DefaultTypes.AnyFunction; + isLocalVideoDisabled: DefaultTypes.AnyFunction; + isMediaFilterSettingLoading: DefaultTypes.AnyFunction; + isMute: DefaultTypes.AnyFunction; + isNativeAudioPermissionReady: DefaultTypes.AnyFunction; + isNoiseCancellationError: DefaultTypes.AnyFunction; + isNoiseCancellationSupported: DefaultTypes.AnyFunction; + isNoiseSuppressionSupported: DefaultTypes.AnyFunction; + isScreenSharing: DefaultTypes.AnyFunction; + isSelfDeaf: DefaultTypes.AnyFunction; + isSelfMute: DefaultTypes.AnyFunction; + isSelfMutedTemporarily: DefaultTypes.AnyFunction; + isSimulcastSupported: DefaultTypes.AnyFunction; + isSoundSharing: DefaultTypes.AnyFunction; + isSupported: DefaultTypes.AnyFunction; + isVideoAvailable: DefaultTypes.AnyFunction; + isVideoEnabled: DefaultTypes.AnyFunction; + setCanHavePriority: DefaultTypes.AnyFunction; + supports: DefaultTypes.AnyFunction; + supportsDisableLocalVideo: DefaultTypes.AnyFunction; + supportsEnableSoundshare: DefaultTypes.AnyFunction; + supportsExperimentalSoundshare: DefaultTypes.AnyFunction; + supportsInApp: DefaultTypes.AnyFunction; + supportsScreenSoundshare: DefaultTypes.AnyFunction; + supportsVideoHook: DefaultTypes.AnyFunction; + } -export type Jsonifiable = - | null - | undefined - | boolean - | number - | string - | Jsonifiable[] - | { [key: string]: Jsonifiable }; -export type ValType = - | T - | React.ChangeEvent - | (Record & { value?: T; checked?: T }); - -export type NestedType = P extends `${infer Left}.${infer Right}` - ? Left extends keyof T - ? NestedType - : Left extends `${infer FieldKey}[${infer IndexKey}]` - ? FieldKey extends keyof T - ? NestedType extends infer U ? U : never, IndexKey> - : undefined - : undefined - : P extends keyof T - ? T[P] - : P extends `${infer FieldKey}[${infer _IndexKey}]` - ? FieldKey extends keyof T - ? Exclude extends infer U - ? U - : never - : undefined - : undefined; + export interface KeybindUtils { + toCombo: DefaultTypes.AnyFunction; + toBrowserEvents: DefaultTypes.AnyFunction; + } + export interface SoundUtils { + createSound: DefaultTypes.AnyFunction; + createSoundForPack: DefaultTypes.AnyFunction; + playSound: DefaultTypes.AnyFunction; + } + export interface IdleHandler { + usePreventIdle: (e: string) => { + preventIdle: () => void; + allowIdle: () => void; + }; + default: DefaultTypes.AnyFunction; + } + export type PanelButton = React.ComponentClass<{ + onContextMenu?: (event: React.MouseEvent) => void; + icon?: () => React.ReactNode; + tooltipText?: string; + onClick?: () => void; + }>; + export type CenterControlButton = React.ComponentType<{ + className: string; + iconComponent: () => React.ReactElement; -export interface Settings { - enabled: boolean; - soundStatus: { - mute: boolean; - deaf: boolean; - video: boolean; - }; - statusPicker: boolean; - userPanel: boolean; - playAudio: boolean; - showToast: boolean; - keybind: Array<{ + isActive: boolean; + label: string; + onClick: DefaultTypes.AnyFunction; + onPopoutClick: DefaultTypes.AnyFunction; + popoutOpen: boolean; + }>; + export interface CenterControlTray { + GoLiveButton: DefaultTypes.AnyFunction; + default: DefaultTypes.AnyFunction; + handleToggleVideo: DefaultTypes.AnyFunction; + } + export interface AccountDetailsClasses { + accountProfilePopoutWrapper: string; + avatar: string; + avatarWrapper: string; + buildOverrideButton: string; + canCopy: string; + container: string; + copySuccess: string; + customStatus: string; + emoji: string; + godlike: string; + hasBuildOverride: string; + nameTag: string; + panelSubtextContainer: string; + panelTitleContainer: string; + redIcon: string; + statusTooltip: string; + strikethrough: string; + usernameContainer: string; + withTagAsButton: string; + withTagless: string; + } + export interface AccountDetails { + AccountDetails: DefaultTypes.AnyFunction; + } + export interface CloseButtonProps { + size?: string; + className?: string; + onClick?: () => void; + } + export interface KeybindEvent { + type: string; altKey: boolean; - code: string; ctrlKey: boolean; - key: string; keyCode: number; metaKey: boolean; shiftKey: boolean; - }>; -} + } + export interface KeybindRecorderItemProps { + title?: string; + note?: string; + size?: string; + className?: string; + value?: number[][]; + onChange?: (value: unknown) => void; + disabled?: boolean; + clearable?: boolean; + } + export enum OpCode { + CALL_CONNECT = 13, + DISPATCH = 0, + EMBEDDED_ACTIVITY_CLOSE = 26, + EMBEDDED_ACTIVITY_LAUNCH = 25, + EMBEDDED_ACTIVITY_UPDATE = 27, + GET_DELETED_ENTITY_IDS_NOT_MATCHING_HASH = 30, + GUILD_SUBSCRIPTIONS = 14, + GUILD_SUBSCRIPTIONS_BULK = 37, + HEARTBEAT = 1, + HEARTBEAT_ACK = 11, + HELLO = 10, + IDENTIFY = 2, + INVALID_SESSION = 9, + PRESENCE_UPDATE = 3, + RECONNECT = 7, + REMOTE_COMMAND = 29, + REQUEST_CHANNEL_STATUSES = 36, + REQUEST_FORUM_UNREADS = 28, + REQUEST_GUILD_APPLICATION_COMMANDS = 24, + REQUEST_GUILD_MEMBERS = 8, + REQUEST_LAST_MESSAGES = 34, + REQUEST_SOUNDBOARD_SOUNDS = 31, + RESUME = 6, + SEARCH_RECENT_MEMBERS = 35, + SPEED_TEST_CREATE = 32, + SPEED_TEST_DELETE = 33, + STREAM_CREATE = 18, + STREAM_DELETE = 19, + STREAM_PING = 21, + STREAM_SET_PAUSED = 22, + STREAM_WATCH = 20, + VOICE_SERVER_PING = 5, + VOICE_STATE_UPDATE = 4, + } + export interface GatewayConnection { + OpCode: typeof OpCode; + default: DefaultTypes.AnyFunction; + } + export interface Modules { + loadModules?: () => Promise; + WindowInfoStore?: WindowInfoStore; + SoundUtils?: SoundUtils; + KeybindUtils?: KeybindUtils; + GatewayConnectionStore?: GatewayConnectionStore; + GatewayConnection?: GatewayConnection; + MediaEngineStore?: MediaEngineStore; + CenterControlTray?: CenterControlTray; + CenterControlButton?: CenterControlButton; + IdleHandler?: IdleHandler; + PanelButton?: PanelButton; + AudioResolverPromise?: Promise; + } + export type Jsonifiable = + | null + | undefined + | boolean + | number + | string + | Jsonifiable[] + | { [key: string]: Jsonifiable }; + export type ValType = + | T + | React.ChangeEvent + | (Record & { value?: T; checked?: T }); + + export type NestedType = P extends + | `${infer Left}.${infer Right}` + | `${infer Left}/${infer Right}` + | `${infer Left}-${infer Right}` + ? Left extends keyof T + ? NestedType + : Left extends `${infer FieldKey}[${infer IndexKey}]` + ? FieldKey extends keyof T + ? NestedType extends infer U ? U : never, IndexKey> + : undefined + : undefined + : P extends keyof T + ? T[P] + : P extends `${infer FieldKey}[${infer _IndexKey}]` + ? FieldKey extends keyof T + ? Exclude extends infer U + ? U + : never + : undefined + : undefined; -export * as default from "./types"; + export interface Settings { + enabled: boolean; + soundStatus: { + mute: boolean; + deaf: boolean; + video: boolean; + }; + statusPicker: boolean; + userPanel: boolean; + centerTray: boolean; + playAudio: boolean; + showToast: boolean; + keybind: Array<{ + altKey: boolean; + code: string; + ctrlKey: boolean; + key: string; + keyCode: number; + metaKey: boolean; + shiftKey: boolean; + }>; + } +} +export default Types; diff --git a/tsconfig.json b/tsconfig.json index 49bf61b..cf94040 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -76,7 +76,7 @@ "forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */, /* Type Checking */ - // "strict": true /* Enable all strict type-checking options. */, + "strict": false /* Enable all strict type-checking options. */, // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */