diff --git a/.eslintrc.json b/.eslintrc.json index 4287749..fb0e152 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -22,7 +22,13 @@ "eqeqeq": ["error", "always", { "null": "ignore" }], "spaced-comment": ["error", "always", { "markers": ["!"] }], "yoda": "error", - "prefer-destructuring": ["error", { "object": true, "array": false }], + "prefer-destructuring": [ + "error", + { + "VariableDeclarator": { "array": false, "object": true }, + "AssignmentExpression": { "array": false, "object": false } + } + ], "operator-assignment": ["error", "always"], "no-useless-computed-key": "error", "no-unneeded-ternary": ["error", { "defaultAssignment": false }], diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..443adc0 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,32 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: bug +assignees: '' + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Desktop (please complete the following information):** + - OS/Distro: [e.g. Windows / Fedora Linux / MacOs] + - Desktop Environment (linux only): [e.g. gnome, kde, sway] + - Version: [e.g. 22] + +**Additional context** +Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/custom.md b/.github/ISSUE_TEMPLATE/custom.md new file mode 100644 index 0000000..48d5f81 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/custom.md @@ -0,0 +1,10 @@ +--- +name: Custom issue template +about: Describe this issue template's purpose here. +title: '' +labels: '' +assignees: '' + +--- + + diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..11fc491 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,20 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: '' +labels: enhancement +assignees: '' + +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6054a10..1edd375 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -37,7 +37,16 @@ jobs: run: pnpm build - name: Run Electron Builder + if: ${{ matrix.platform != 'mac' }} run: | pnpm electron-builder --${{ matrix.platform }} --publish always env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Run Electron Builder + if: ${{ matrix.platform == 'mac' }} + run: | + pnpm electron-builder --${{ matrix.platform }} --publish always + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + CSC_LINK_: ${{ secrets.APPLE_SIGNING_CERT }} diff --git a/README.md b/README.md index c63c163..0e55685 100644 --- a/README.md +++ b/README.md @@ -3,14 +3,14 @@ Vesktop is a cross platform desktop app aiming to give you a snappier Discord experience with [Vencord](https://github.com/Vendicated/Vencord) pre-installed **Not yet supported**: -- Global Keybinds + +- Global Keybinds Bug reports, feature requests & contributions are highly appreciated!! ![](https://github.com/Vencord/Vesktop/assets/45497981/8608a899-96a9-4027-9725-2cb02ba189fd) ![grafik](https://github.com/Vencord/Vesktop/assets/45497981/8701e5de-52c4-4346-a990-719cb971642e) - ## Installing ### Windows @@ -39,7 +39,7 @@ Download Vesktop-VERSION.rpm from [releases](https://github.com/Vencord/Vesktop/ #### Other -Either download Vesktop-VERSION.AppImage and just run it directly or grab Vesktop-VERSION.tar.gz, extract it somewhere and run `vencorddesktop`. +Either download Vesktop-VERSION.AppImage and just run it directly or grab Vesktop-VERSION.tar.gz, extract it somewhere and run `vesktop`. If other packages are created, feel free to open an issue and we'll link them here. diff --git a/build/installer.nsh b/build/installer.nsh index 2877dba..2bce914 100644 --- a/build/installer.nsh +++ b/build/installer.nsh @@ -1,8 +1,8 @@ !macro preInit SetRegView 64 - WriteRegExpandStr HKLM "${INSTALL_REGISTRY_KEY}" InstallLocation "$LocalAppData\VencordDesktop" - WriteRegExpandStr HKCU "${INSTALL_REGISTRY_KEY}" InstallLocation "$LocalAppData\VencordDesktop" + WriteRegExpandStr HKLM "${INSTALL_REGISTRY_KEY}" InstallLocation "$LocalAppData\vesktop" + WriteRegExpandStr HKCU "${INSTALL_REGISTRY_KEY}" InstallLocation "$LocalAppData\vesktop" SetRegView 32 - WriteRegExpandStr HKLM "${INSTALL_REGISTRY_KEY}" InstallLocation "$LocalAppData\VencordDesktop" - WriteRegExpandStr HKCU "${INSTALL_REGISTRY_KEY}" InstallLocation "$LocalAppData\VencordDesktop" + WriteRegExpandStr HKLM "${INSTALL_REGISTRY_KEY}" InstallLocation "$LocalAppData\vesktop" + WriteRegExpandStr HKCU "${INSTALL_REGISTRY_KEY}" InstallLocation "$LocalAppData\vesktop" !macroend diff --git a/meta/dev.vencord.Vesktop.metainfo.xml b/meta/dev.vencord.Vesktop.metainfo.xml index d897226..be55d24 100644 --- a/meta/dev.vencord.Vesktop.metainfo.xml +++ b/meta/dev.vencord.Vesktop.metainfo.xml @@ -28,6 +28,22 @@ + + https://github.com/Vencord/Vesktop/releases/tag/v1.5.0 + +

What's Changed

+
    +
  • fully renamed to Vesktop. You will likely have to login to Discord again. You might have to re-create your vesktop shortcut
  • +
  • added option to disable smooth scrolling by @ZirixCZ
  • +
  • added setting to disable hardware acceleration by @zt64
  • +
  • fixed adding connections
  • +
  • fixed / improved discord popouts
  • +
  • you can now use the custom discord titlebar on linux/mac
  • +
  • the splash window is now draggable
  • +
  • now signed on mac
  • +
+
+
https://github.com/Vencord/Vesktop/releases/tag/v0.4.4 diff --git a/package.json b/package.json index fae146f..1de1c68 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { - "name": "VencordDesktop", - "version": "0.4.4", + "name": "vesktop", + "version": "1.5.0", "private": true, "description": "", "keywords": [], @@ -27,17 +27,17 @@ "arrpc": "github:OpenAsar/arrpc#98879cae0565e6fce34e4cb6f544bf42c6a7e7c8" }, "optionalDependencies": { - "@vencord/venmic": "^3.2.0" + "@vencord/venmic": "^3.2.3" }, "devDependencies": { "@fal-works/esbuild-plugin-global-externals": "^2.1.2", - "@types/node": "^20.10.6", - "@types/react": "^18.2.46", - "@typescript-eslint/eslint-plugin": "^6.17.0", - "@typescript-eslint/parser": "^6.17.0", + "@types/node": "^20.11.2", + "@types/react": "^18.2.48", + "@typescript-eslint/eslint-plugin": "^6.19.0", + "@typescript-eslint/parser": "^6.19.0", "@vencord/types": "^0.1.2", "dotenv": "^16.3.1", - "electron": "^28.1.1", + "electron": "^28.1.3", "electron-builder": "^24.9.1", "esbuild": "^0.19.11", "eslint": "^8.56.0", @@ -45,10 +45,10 @@ "eslint-import-resolver-alias": "^1.1.2", "eslint-plugin-license-header": "^0.6.0", "eslint-plugin-path-alias": "^1.0.0", - "eslint-plugin-prettier": "^5.1.2", + "eslint-plugin-prettier": "^5.1.3", "eslint-plugin-simple-import-sort": "^10.0.0", "eslint-plugin-unused-imports": "^3.0.0", - "prettier": "^3.1.1", + "prettier": "^3.2.2", "source-map-support": "^0.5.21", "tsx": "^4.7.0", "type-fest": "^4.9.0", @@ -61,7 +61,7 @@ "pnpm": ">=8" }, "build": { - "appId": "dev.vencord.desktop", + "appId": "dev.vencord.vesktop", "productName": "Vesktop", "files": [ "!*", @@ -110,8 +110,7 @@ "GenericName": "Internet Messenger", "Type": "Application", "Categories": "Network;InstantMessaging;Chat;", - "Keywords": "discord;vencord;electron;chat;", - "StartupWMClass": "VencordDesktop" + "Keywords": "discord;vencord;electron;chat;" } }, "mac": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 97ada2a..cf83791 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -11,25 +11,25 @@ dependencies: optionalDependencies: '@vencord/venmic': - specifier: ^3.2.0 - version: 3.2.0 + specifier: ^3.2.3 + version: 3.2.3 devDependencies: '@fal-works/esbuild-plugin-global-externals': specifier: ^2.1.2 version: 2.1.2 '@types/node': - specifier: ^20.10.6 - version: 20.10.6 + specifier: ^20.11.2 + version: 20.11.2 '@types/react': - specifier: ^18.2.46 - version: 18.2.46 + specifier: ^18.2.48 + version: 18.2.48 '@typescript-eslint/eslint-plugin': - specifier: ^6.17.0 - version: 6.17.0(@typescript-eslint/parser@6.17.0)(eslint@8.56.0)(typescript@5.3.3) + specifier: ^6.19.0 + version: 6.19.0(@typescript-eslint/parser@6.19.0)(eslint@8.56.0)(typescript@5.3.3) '@typescript-eslint/parser': - specifier: ^6.17.0 - version: 6.17.0(eslint@8.56.0)(typescript@5.3.3) + specifier: ^6.19.0 + version: 6.19.0(eslint@8.56.0)(typescript@5.3.3) '@vencord/types': specifier: ^0.1.2 version: 0.1.2 @@ -37,8 +37,8 @@ devDependencies: specifier: ^16.3.1 version: 16.3.1 electron: - specifier: ^28.1.1 - version: 28.1.1 + specifier: ^28.1.3 + version: 28.1.3 electron-builder: specifier: ^24.9.1 version: 24.9.1 @@ -61,17 +61,17 @@ devDependencies: specifier: ^1.0.0 version: 1.0.0(eslint@8.56.0) eslint-plugin-prettier: - specifier: ^5.1.2 - version: 5.1.2(eslint-config-prettier@9.1.0)(eslint@8.56.0)(prettier@3.1.1) + specifier: ^5.1.3 + version: 5.1.3(eslint-config-prettier@9.1.0)(eslint@8.56.0)(prettier@3.2.2) eslint-plugin-simple-import-sort: specifier: ^10.0.0 version: 10.0.0(eslint@8.56.0) eslint-plugin-unused-imports: specifier: ^3.0.0 - version: 3.0.0(@typescript-eslint/eslint-plugin@6.17.0)(eslint@8.56.0) + version: 3.0.0(@typescript-eslint/eslint-plugin@6.19.0)(eslint@8.56.0) prettier: - specifier: ^3.1.1 - version: 3.1.1 + specifier: ^3.2.2 + version: 3.2.2 source-map-support: specifier: ^0.5.21 version: 0.5.21 @@ -423,11 +423,11 @@ packages: resolution: {integrity: sha512-cEee/Z+I12mZcFJshKcCqC8tuX5hG3s+d+9nZ3LabqKF1vKdF41B92pJVCBggjAGORAeOzyyDDKrZwIkLffeOQ==} dev: true - /@humanwhocodes/config-array@0.11.13: - resolution: {integrity: sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==} + /@humanwhocodes/config-array@0.11.14: + resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==} engines: {node: '>=10.10.0'} dependencies: - '@humanwhocodes/object-schema': 2.0.1 + '@humanwhocodes/object-schema': 2.0.2 debug: 4.3.4 minimatch: 3.1.2 transitivePeerDependencies: @@ -439,8 +439,8 @@ packages: engines: {node: '>=12.22'} dev: true - /@humanwhocodes/object-schema@2.0.1: - resolution: {integrity: sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==} + /@humanwhocodes/object-schema@2.0.2: + resolution: {integrity: sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==} dev: true /@isaacs/cliui@8.0.2: @@ -529,7 +529,7 @@ packages: dependencies: '@types/http-cache-semantics': 4.0.4 '@types/keyv': 3.1.4 - '@types/node': 20.10.6 + '@types/node': 20.11.2 '@types/responselike': 1.0.3 dev: true @@ -542,7 +542,7 @@ packages: /@types/fs-extra@9.0.13: resolution: {integrity: sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==} dependencies: - '@types/node': 20.10.6 + '@types/node': 20.11.2 dev: true /@types/http-cache-semantics@4.0.4: @@ -560,7 +560,7 @@ packages: /@types/keyv@3.1.4: resolution: {integrity: sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==} dependencies: - '@types/node': 20.10.6 + '@types/node': 20.11.2 dev: true /@types/lodash@4.14.202: @@ -571,14 +571,14 @@ packages: resolution: {integrity: sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==} dev: true - /@types/node@18.19.4: - resolution: {integrity: sha512-xNzlUhzoHotIsnFoXmJB+yWmBvFZgKCI9TtPIEdYIMM1KWfwuY8zh7wvc1u1OAXlC7dlf6mZVx/s+Y5KfFz19A==} + /@types/node@18.19.7: + resolution: {integrity: sha512-IGRJfoNX10N/PfrReRZ1br/7SQ+2vF/tK3KXNwzXz82D32z5dMQEoOlFew18nLSN+vMNcLY4GrKfzwi/yWI8/w==} dependencies: undici-types: 5.26.5 dev: true - /@types/node@20.10.6: - resolution: {integrity: sha512-Vac8H+NlRNNlAmDfGUP7b5h/KA+AtWIzuXy0E6OyP8f1tCLYAtPvKRRDJjAPqhpCb0t6U2j7/xqAuLEebW2kiw==} + /@types/node@20.11.2: + resolution: {integrity: sha512-cZShBaVa+UO1LjWWBPmWRR4+/eY/JR/UIEcDlVsw3okjWEu+rB7/mH6X3B/L+qJVHDLjk9QW/y2upp9wp1yDXA==} dependencies: undici-types: 5.26.5 dev: true @@ -587,7 +587,7 @@ packages: resolution: {integrity: sha512-E6OCaRmAe4WDmWNsL/9RMqdkkzDCY1etutkflWk4c+AcjDU07Pcz1fQwTX0TQz+Pxqn9i4L1TU3UFpjnrcDgxA==} requiresBuild: true dependencies: - '@types/node': 20.10.6 + '@types/node': 20.11.2 xmlbuilder: 15.1.1 dev: true optional: true @@ -599,7 +599,7 @@ packages: /@types/react-dom@18.2.18: resolution: {integrity: sha512-TJxDm6OfAX2KJWJdMEVTwWke5Sc/E/RlnPGvGfS0W7+6ocy2xhDVQVh/KvC2Uf7kACs+gDytdusDSdWfWkaNzw==} dependencies: - '@types/react': 18.2.46 + '@types/react': 18.2.48 dev: true /@types/react@17.0.2: @@ -609,8 +609,8 @@ packages: csstype: 3.1.3 dev: true - /@types/react@18.2.46: - resolution: {integrity: sha512-nNCvVBcZlvX4NU1nRRNV/mFl1nNRuTuslAJglQsq+8ldXe5Xv0Wd2f7WTE3jOxhLH2BFfiZGC6GCp+kHQbgG+w==} + /@types/react@18.2.48: + resolution: {integrity: sha512-qboRCl6Ie70DQQG9hhNREz81jqC1cs9EVNcjQ1AU+jH6NFfSAhVVbrrY/+nSF+Bsk4AOwm9Qa61InvMCyV+H3w==} dependencies: '@types/prop-types': 15.7.11 '@types/scheduler': 0.16.8 @@ -620,7 +620,7 @@ packages: /@types/responselike@1.0.3: resolution: {integrity: sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==} dependencies: - '@types/node': 20.10.6 + '@types/node': 20.11.2 dev: true /@types/scheduler@0.16.8: @@ -641,12 +641,12 @@ packages: resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==} requiresBuild: true dependencies: - '@types/node': 20.10.6 + '@types/node': 20.11.2 dev: true optional: true - /@typescript-eslint/eslint-plugin@6.17.0(@typescript-eslint/parser@6.17.0)(eslint@8.56.0)(typescript@5.3.3): - resolution: {integrity: sha512-Vih/4xLXmY7V490dGwBQJTpIZxH4ZFH6eCVmQ4RFkB+wmaCTDAx4dtgoWwMNGKLkqRY1L6rPqzEbjorRnDo4rQ==} + /@typescript-eslint/eslint-plugin@6.19.0(@typescript-eslint/parser@6.19.0)(eslint@8.56.0)(typescript@5.3.3): + resolution: {integrity: sha512-DUCUkQNklCQYnrBSSikjVChdc84/vMPDQSgJTHBZ64G9bA9w0Crc0rd2diujKbTdp6w2J47qkeHQLoi0rpLCdg==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: '@typescript-eslint/parser': ^6.0.0 || ^6.0.0-alpha @@ -657,11 +657,11 @@ packages: optional: true dependencies: '@eslint-community/regexpp': 4.10.0 - '@typescript-eslint/parser': 6.17.0(eslint@8.56.0)(typescript@5.3.3) - '@typescript-eslint/scope-manager': 6.17.0 - '@typescript-eslint/type-utils': 6.17.0(eslint@8.56.0)(typescript@5.3.3) - '@typescript-eslint/utils': 6.17.0(eslint@8.56.0)(typescript@5.3.3) - '@typescript-eslint/visitor-keys': 6.17.0 + '@typescript-eslint/parser': 6.19.0(eslint@8.56.0)(typescript@5.3.3) + '@typescript-eslint/scope-manager': 6.19.0 + '@typescript-eslint/type-utils': 6.19.0(eslint@8.56.0)(typescript@5.3.3) + '@typescript-eslint/utils': 6.19.0(eslint@8.56.0)(typescript@5.3.3) + '@typescript-eslint/visitor-keys': 6.19.0 debug: 4.3.4 eslint: 8.56.0 graphemer: 1.4.0 @@ -674,8 +674,8 @@ packages: - supports-color dev: true - /@typescript-eslint/parser@6.17.0(eslint@8.56.0)(typescript@5.3.3): - resolution: {integrity: sha512-C4bBaX2orvhK+LlwrY8oWGmSl4WolCfYm513gEccdWZj0CwGadbIADb0FtVEcI+WzUyjyoBj2JRP8g25E6IB8A==} + /@typescript-eslint/parser@6.19.0(eslint@8.56.0)(typescript@5.3.3): + resolution: {integrity: sha512-1DyBLG5SH7PYCd00QlroiW60YJ4rWMuUGa/JBV0iZuqi4l4IK3twKPq5ZkEebmGqRjXWVgsUzfd3+nZveewgow==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: eslint: ^7.0.0 || ^8.0.0 @@ -684,10 +684,10 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/scope-manager': 6.17.0 - '@typescript-eslint/types': 6.17.0 - '@typescript-eslint/typescript-estree': 6.17.0(typescript@5.3.3) - '@typescript-eslint/visitor-keys': 6.17.0 + '@typescript-eslint/scope-manager': 6.19.0 + '@typescript-eslint/types': 6.19.0 + '@typescript-eslint/typescript-estree': 6.19.0(typescript@5.3.3) + '@typescript-eslint/visitor-keys': 6.19.0 debug: 4.3.4 eslint: 8.56.0 typescript: 5.3.3 @@ -695,16 +695,16 @@ packages: - supports-color dev: true - /@typescript-eslint/scope-manager@6.17.0: - resolution: {integrity: sha512-RX7a8lwgOi7am0k17NUO0+ZmMOX4PpjLtLRgLmT1d3lBYdWH4ssBUbwdmc5pdRX8rXon8v9x8vaoOSpkHfcXGA==} + /@typescript-eslint/scope-manager@6.19.0: + resolution: {integrity: sha512-dO1XMhV2ehBI6QN8Ufi7I10wmUovmLU0Oru3n5LVlM2JuzB4M+dVphCPLkVpKvGij2j/pHBWuJ9piuXx+BhzxQ==} engines: {node: ^16.0.0 || >=18.0.0} dependencies: - '@typescript-eslint/types': 6.17.0 - '@typescript-eslint/visitor-keys': 6.17.0 + '@typescript-eslint/types': 6.19.0 + '@typescript-eslint/visitor-keys': 6.19.0 dev: true - /@typescript-eslint/type-utils@6.17.0(eslint@8.56.0)(typescript@5.3.3): - resolution: {integrity: sha512-hDXcWmnbtn4P2B37ka3nil3yi3VCQO2QEB9gBiHJmQp5wmyQWqnjA85+ZcE8c4FqnaB6lBwMrPkgd4aBYz3iNg==} + /@typescript-eslint/type-utils@6.19.0(eslint@8.56.0)(typescript@5.3.3): + resolution: {integrity: sha512-mcvS6WSWbjiSxKCwBcXtOM5pRkPQ6kcDds/juxcy/727IQr3xMEcwr/YLHW2A2+Fp5ql6khjbKBzOyjuPqGi/w==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: eslint: ^7.0.0 || ^8.0.0 @@ -713,8 +713,8 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/typescript-estree': 6.17.0(typescript@5.3.3) - '@typescript-eslint/utils': 6.17.0(eslint@8.56.0)(typescript@5.3.3) + '@typescript-eslint/typescript-estree': 6.19.0(typescript@5.3.3) + '@typescript-eslint/utils': 6.19.0(eslint@8.56.0)(typescript@5.3.3) debug: 4.3.4 eslint: 8.56.0 ts-api-utils: 1.0.3(typescript@5.3.3) @@ -723,13 +723,13 @@ packages: - supports-color dev: true - /@typescript-eslint/types@6.17.0: - resolution: {integrity: sha512-qRKs9tvc3a4RBcL/9PXtKSehI/q8wuU9xYJxe97WFxnzH8NWWtcW3ffNS+EWg8uPvIerhjsEZ+rHtDqOCiH57A==} + /@typescript-eslint/types@6.19.0: + resolution: {integrity: sha512-lFviGV/vYhOy3m8BJ/nAKoAyNhInTdXpftonhWle66XHAtT1ouBlkjL496b5H5hb8dWXHwtypTqgtb/DEa+j5A==} engines: {node: ^16.0.0 || >=18.0.0} dev: true - /@typescript-eslint/typescript-estree@6.17.0(typescript@5.3.3): - resolution: {integrity: sha512-gVQe+SLdNPfjlJn5VNGhlOhrXz4cajwFd5kAgWtZ9dCZf4XJf8xmgCTLIqec7aha3JwgLI2CK6GY1043FRxZwg==} + /@typescript-eslint/typescript-estree@6.19.0(typescript@5.3.3): + resolution: {integrity: sha512-o/zefXIbbLBZ8YJ51NlkSAt2BamrK6XOmuxSR3hynMIzzyMY33KuJ9vuMdFSXW+H0tVvdF9qBPTHA91HDb4BIQ==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: typescript: '*' @@ -737,8 +737,8 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/types': 6.17.0 - '@typescript-eslint/visitor-keys': 6.17.0 + '@typescript-eslint/types': 6.19.0 + '@typescript-eslint/visitor-keys': 6.19.0 debug: 4.3.4 globby: 11.1.0 is-glob: 4.0.3 @@ -750,8 +750,8 @@ packages: - supports-color dev: true - /@typescript-eslint/utils@6.17.0(eslint@8.56.0)(typescript@5.3.3): - resolution: {integrity: sha512-LofsSPjN/ITNkzV47hxas2JCsNCEnGhVvocfyOcLzT9c/tSZE7SfhS/iWtzP1lKNOEfLhRTZz6xqI8N2RzweSQ==} + /@typescript-eslint/utils@6.19.0(eslint@8.56.0)(typescript@5.3.3): + resolution: {integrity: sha512-QR41YXySiuN++/dC9UArYOg4X86OAYP83OWTewpVx5ct1IZhjjgTLocj7QNxGhWoTqknsgpl7L+hGygCO+sdYw==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: eslint: ^7.0.0 || ^8.0.0 @@ -759,9 +759,9 @@ packages: '@eslint-community/eslint-utils': 4.4.0(eslint@8.56.0) '@types/json-schema': 7.0.15 '@types/semver': 7.5.6 - '@typescript-eslint/scope-manager': 6.17.0 - '@typescript-eslint/types': 6.17.0 - '@typescript-eslint/typescript-estree': 6.17.0(typescript@5.3.3) + '@typescript-eslint/scope-manager': 6.19.0 + '@typescript-eslint/types': 6.19.0 + '@typescript-eslint/typescript-estree': 6.19.0(typescript@5.3.3) eslint: 8.56.0 semver: 7.5.4 transitivePeerDependencies: @@ -769,11 +769,11 @@ packages: - typescript dev: true - /@typescript-eslint/visitor-keys@6.17.0: - resolution: {integrity: sha512-H6VwB/k3IuIeQOyYczyyKN8wH6ed8EwliaYHLxOIhyF0dYEIsN8+Bk3GE19qafeMKyZJJHP8+O1HiFhFLUNKSg==} + /@typescript-eslint/visitor-keys@6.19.0: + resolution: {integrity: sha512-hZaUCORLgubBvtGpp1JEFEazcuEdfxta9j4iUwdSAr7mEsYYAp3EAUyCZk3VEEqGj6W+AV4uWyrDGtrlawAsgQ==} engines: {node: ^16.0.0 || >=18.0.0} dependencies: - '@typescript-eslint/types': 6.17.0 + '@typescript-eslint/types': 6.19.0 eslint-visitor-keys: 3.4.3 dev: true @@ -785,16 +785,16 @@ packages: resolution: {integrity: sha512-C/dqZHn3aod/4izZT9sgZEef4478M7QNKTY8Gx2yB1CRYawJcs6hupXT/1SMmepKqrULbltL04Cnh5ieBm3Ucw==} dependencies: '@types/lodash': 4.14.202 - '@types/node': 18.19.4 - '@types/react': 18.2.46 + '@types/node': 18.19.7 + '@types/react': 18.2.48 '@types/react-dom': 18.2.18 discord-types: 1.3.26 standalone-electron-types: 1.0.0 type-fest: 3.13.1 dev: true - /@vencord/venmic@3.2.0: - resolution: {integrity: sha512-z+Lgmr6IgjkPEIfFZ3ZwVV4aP/OFjnB6k6Ll5YpBPuDZOyqCbKTNLADApbZa/WxMfm7YpZ22g46X4FfizuprEQ==} + /@vencord/venmic@3.2.3: + resolution: {integrity: sha512-mnpAa5aFRkMQhoeYjkygPY+U+/b7Nh55HekchWzl2y5RNHpCxooGANTcw4L80JoCiL+AYRUg8BQU31L7fFQcPw==} engines: {node: '>=14.15'} os: [linux] requiresBuild: true @@ -1066,7 +1066,7 @@ packages: resolution: {integrity: sha512-Ii012v05KEVuUoFWmMW/UQv9aRIc3ZwkWDcM+h5Il8izZCtRVpDUfwpoFf7eOtajT3QiGR4yDUx7lPqHJULgbg==} requiresBuild: true dependencies: - follow-redirects: 1.15.4(debug@4.3.4) + follow-redirects: 1.15.5(debug@4.3.4) form-data: 4.0.0 proxy-from-env: 1.1.0 transitivePeerDependencies: @@ -1225,7 +1225,7 @@ packages: dependencies: function-bind: 1.1.2 get-intrinsic: 1.2.2 - set-function-length: 1.1.1 + set-function-length: 1.2.0 dev: true /callsites@3.1.0: @@ -1651,14 +1651,14 @@ packages: - supports-color dev: true - /electron@28.1.1: - resolution: {integrity: sha512-HJSbGHpRl46jWCp5G4OH57KSm2F5u15tB10ixD8iFiz9dhwojqlSQTRAcjSwvga+Vqs1jv7iqwQRrolXP4DgOA==} + /electron@28.1.3: + resolution: {integrity: sha512-NSFyTo6SndTPXzU18XRePv4LnjmuM9rF5GMKta1/kPmi02ISoSRonnD7wUlWXD2x53XyJ6d/TbSVesMW6sXkEQ==} engines: {node: '>= 12.20.55'} hasBin: true requiresBuild: true dependencies: '@electron/get': 2.0.3 - '@types/node': 18.19.4 + '@types/node': 18.19.7 extract-zip: 2.0.1 transitivePeerDependencies: - supports-color @@ -1718,8 +1718,8 @@ packages: object-keys: 1.1.1 object.assign: 4.1.5 regexp.prototype.flags: 1.5.1 - safe-array-concat: 1.0.1 - safe-regex-test: 1.0.0 + safe-array-concat: 1.1.0 + safe-regex-test: 1.0.2 string.prototype.trim: 1.2.8 string.prototype.trimend: 1.0.7 string.prototype.trimstart: 1.0.7 @@ -1816,7 +1816,7 @@ packages: peerDependencies: eslint-plugin-import: '>=1.4.0' dependencies: - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.17.0)(eslint@8.56.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.19.0)(eslint@8.56.0) dev: true /eslint-import-resolver-node@0.3.9: @@ -1829,7 +1829,7 @@ packages: - supports-color dev: true - /eslint-module-utils@2.8.0(@typescript-eslint/parser@6.17.0)(eslint-import-resolver-node@0.3.9)(eslint@8.56.0): + /eslint-module-utils@2.8.0(@typescript-eslint/parser@6.19.0)(eslint-import-resolver-node@0.3.9)(eslint@8.56.0): resolution: {integrity: sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==} engines: {node: '>=4'} peerDependencies: @@ -1850,7 +1850,7 @@ packages: eslint-import-resolver-webpack: optional: true dependencies: - '@typescript-eslint/parser': 6.17.0(eslint@8.56.0)(typescript@5.3.3) + '@typescript-eslint/parser': 6.19.0(eslint@8.56.0)(typescript@5.3.3) debug: 3.2.7 eslint: 8.56.0 eslint-import-resolver-node: 0.3.9 @@ -1858,7 +1858,7 @@ packages: - supports-color dev: true - /eslint-plugin-import@2.29.1(@typescript-eslint/parser@6.17.0)(eslint@8.56.0): + /eslint-plugin-import@2.29.1(@typescript-eslint/parser@6.19.0)(eslint@8.56.0): resolution: {integrity: sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==} engines: {node: '>=4'} peerDependencies: @@ -1868,7 +1868,7 @@ packages: '@typescript-eslint/parser': optional: true dependencies: - '@typescript-eslint/parser': 6.17.0(eslint@8.56.0)(typescript@5.3.3) + '@typescript-eslint/parser': 6.19.0(eslint@8.56.0)(typescript@5.3.3) array-includes: 3.1.7 array.prototype.findlastindex: 1.2.3 array.prototype.flat: 1.3.2 @@ -1877,7 +1877,7 @@ packages: doctrine: 2.1.0 eslint: 8.56.0 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.17.0)(eslint-import-resolver-node@0.3.9)(eslint@8.56.0) + eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.19.0)(eslint-import-resolver-node@0.3.9)(eslint@8.56.0) hasown: 2.0.0 is-core-module: 2.13.1 is-glob: 4.0.3 @@ -1910,8 +1910,8 @@ packages: - supports-color dev: true - /eslint-plugin-prettier@5.1.2(eslint-config-prettier@9.1.0)(eslint@8.56.0)(prettier@3.1.1): - resolution: {integrity: sha512-dhlpWc9vOwohcWmClFcA+HjlvUpuyynYs0Rf+L/P6/0iQE6vlHW9l5bkfzN62/Stm9fbq8ku46qzde76T1xlSg==} + /eslint-plugin-prettier@5.1.3(eslint-config-prettier@9.1.0)(eslint@8.56.0)(prettier@3.2.2): + resolution: {integrity: sha512-C9GCVAs4Eq7ZC/XFQHITLiHJxQngdtraXaM+LoUFoFp/lHNl2Zn8f3WQbe9HvTBBQ9YnKFB0/2Ajdqwo5D1EAw==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: '@types/eslint': '>=8.0.0' @@ -1926,7 +1926,7 @@ packages: dependencies: eslint: 8.56.0 eslint-config-prettier: 9.1.0(eslint@8.56.0) - prettier: 3.1.1 + prettier: 3.2.2 prettier-linter-helpers: 1.0.0 synckit: 0.8.8 dev: true @@ -1939,7 +1939,7 @@ packages: eslint: 8.56.0 dev: true - /eslint-plugin-unused-imports@3.0.0(@typescript-eslint/eslint-plugin@6.17.0)(eslint@8.56.0): + /eslint-plugin-unused-imports@3.0.0(@typescript-eslint/eslint-plugin@6.19.0)(eslint@8.56.0): resolution: {integrity: sha512-sduiswLJfZHeeBJ+MQaG+xYzSWdRXoSw61DpU13mzWumCkR0ufD0HmO4kdNokjrkluMHpj/7PJeN35pgbhW3kw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -1949,7 +1949,7 @@ packages: '@typescript-eslint/eslint-plugin': optional: true dependencies: - '@typescript-eslint/eslint-plugin': 6.17.0(@typescript-eslint/parser@6.17.0)(eslint@8.56.0)(typescript@5.3.3) + '@typescript-eslint/eslint-plugin': 6.19.0(@typescript-eslint/parser@6.19.0)(eslint@8.56.0)(typescript@5.3.3) eslint: 8.56.0 eslint-rule-composer: 0.3.0 dev: true @@ -1981,7 +1981,7 @@ packages: '@eslint-community/regexpp': 4.10.0 '@eslint/eslintrc': 2.1.4 '@eslint/js': 8.56.0 - '@humanwhocodes/config-array': 0.11.13 + '@humanwhocodes/config-array': 0.11.14 '@humanwhocodes/module-importer': 1.0.1 '@nodelib/fs.walk': 1.2.8 '@ungap/structured-clone': 1.2.0 @@ -2168,8 +2168,8 @@ packages: resolution: {integrity: sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==} dev: true - /follow-redirects@1.15.4(debug@4.3.4): - resolution: {integrity: sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw==} + /follow-redirects@1.15.5(debug@4.3.4): + resolution: {integrity: sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==} engines: {node: '>=4.0'} requiresBuild: true peerDependencies: @@ -3388,8 +3388,8 @@ packages: fast-diff: 1.3.0 dev: true - /prettier@3.1.1: - resolution: {integrity: sha512-22UbSzg8luF4UuZtzgiUOfcGM8s4tjBv6dJRT7j275NXsy2jb4aJa4NNveul5x4eqlF1wuhuR2RElK71RvmVaw==} + /prettier@3.2.2: + resolution: {integrity: sha512-HTByuKZzw7utPiDO523Tt2pLtEyK7OibUD9suEJQrPUCYQqrHr74GGX6VidMrovbf/I50mPqr8j/II6oBAuc5A==} engines: {node: '>=14'} hasBin: true dev: true @@ -3570,8 +3570,8 @@ packages: queue-microtask: 1.2.3 dev: true - /safe-array-concat@1.0.1: - resolution: {integrity: sha512-6XbUAseYE2KtOuGueyeobCySj9L4+66Tn6KQMOPQJrAJEowYKW/YR/MGJZl7FdydUdaFu4LYyDZjxf4/Nmo23Q==} + /safe-array-concat@1.1.0: + resolution: {integrity: sha512-ZdQ0Jeb9Ofti4hbt5lX3T2JcAamT9hfzYU1MNB+z/jaEbB6wfFfPIR/zEORmZqobkCCJhSjodobH6WHNmJ97dg==} engines: {node: '>=0.4'} dependencies: call-bind: 1.0.5 @@ -3586,8 +3586,9 @@ packages: dev: false optional: true - /safe-regex-test@1.0.0: - resolution: {integrity: sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==} + /safe-regex-test@1.0.2: + resolution: {integrity: sha512-83S9w6eFq12BBIJYvjMux6/dkirb8+4zJRA9cxNBVb7Wq5fJBW+Xze48WqR8pxua7bDuAaaAxtVVd4Idjp1dBQ==} + engines: {node: '>= 0.4'} dependencies: call-bind: 1.0.5 get-intrinsic: 1.2.2 @@ -3647,11 +3648,12 @@ packages: dev: false optional: true - /set-function-length@1.1.1: - resolution: {integrity: sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==} + /set-function-length@1.2.0: + resolution: {integrity: sha512-4DBHDoyHlM1IRPGYcoxexgh67y4ueR53FKV1yyxwFMY7aCqcN/38M1+SwZ/qJQ8iLv7+ck385ot4CcisOAPT9w==} engines: {node: '>= 0.4'} dependencies: define-data-property: 1.1.1 + function-bind: 1.1.2 get-intrinsic: 1.2.2 gopd: 1.0.1 has-property-descriptors: 1.0.1 @@ -3802,7 +3804,7 @@ packages: /standalone-electron-types@1.0.0: resolution: {integrity: sha512-0HOi/tlTz3mjWhsAz4uRbpQcHMZ+ifj1JzWW9nugykOHClBBG77ps8QinrzX1eow4Iw2pnC+RFaSYRgufF4BOg==} dependencies: - '@types/node': 18.19.4 + '@types/node': 18.19.7 dev: true /stat-mode@1.0.0: diff --git a/src/main/constants.ts b/src/main/constants.ts index 068521b..5c4ecd7 100644 --- a/src/main/constants.ts +++ b/src/main/constants.ts @@ -5,9 +5,29 @@ */ import { app } from "electron"; +import { existsSync, readdirSync, renameSync, rmdirSync } from "fs"; import { join } from "path"; -export const DATA_DIR = process.env.VENCORD_USER_DATA_DIR || join(app.getPath("userData"), "VencordDesktop"); +const LEGACY_DATA_DIR = join(app.getPath("appData"), "VencordDesktop", "VencordDesktop"); +export const DATA_DIR = process.env.VENCORD_USER_DATA_DIR || join(app.getPath("userData")); +// TODO: remove eventually +if (existsSync(LEGACY_DATA_DIR)) { + try { + console.warn("Detected legacy settings dir", LEGACY_DATA_DIR + ".", "migrating to", DATA_DIR); + for (const file of readdirSync(LEGACY_DATA_DIR)) { + renameSync(join(LEGACY_DATA_DIR, file), join(DATA_DIR, file)); + } + rmdirSync(LEGACY_DATA_DIR); + renameSync( + join(app.getPath("appData"), "VencordDesktop", "IndexedDB"), + join(DATA_DIR, "sessionData", "IndexedDB") + ); + } catch (e) { + console.error("Migration failed", e); + } +} +app.setPath("sessionData", join(DATA_DIR, "sessionData")); + export const VENCORD_SETTINGS_DIR = join(DATA_DIR, "settings"); export const VENCORD_QUICKCSS_FILE = join(VENCORD_SETTINGS_DIR, "quickCss.css"); export const VENCORD_SETTINGS_FILE = join(VENCORD_SETTINGS_DIR, "settings.json"); @@ -26,6 +46,8 @@ export const MIN_HEIGHT = 500; export const DEFAULT_WIDTH = 1280; export const DEFAULT_HEIGHT = 720; +export const DISCORD_HOSTNAMES = ["discord.com", "canary.discord.com", "ptb.discord.com"]; + const UserAgents = { darwin: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36", linux: "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36", diff --git a/src/main/firstLaunch.ts b/src/main/firstLaunch.ts index 0ce585d..d1bbceb 100644 --- a/src/main/firstLaunch.ts +++ b/src/main/firstLaunch.ts @@ -14,7 +14,7 @@ import { ICON_PATH, VIEW_DIR } from "shared/paths"; import { autoStart } from "./autoStart"; import { DATA_DIR } from "./constants"; import { createWindows } from "./mainWindow"; -import { Settings } from "./settings"; +import { Settings, State } from "./settings"; import { makeLinksOpenExternally } from "./utils/makeLinksOpenExternally"; interface Data { @@ -44,9 +44,9 @@ export function createFirstLaunchTour() { if (!msg.startsWith("form:")) return; const data = JSON.parse(msg.slice(5)) as Data; + State.store.firstLaunch = false; Settings.store.minimizeToTray = data.minimizeToTray; Settings.store.discordBranch = data.discordBranch; - Settings.store.firstLaunch = false; Settings.store.arRPC = data.richPresence; if (data.autoStart) autoStart.enable(); diff --git a/src/main/index.ts b/src/main/index.ts index f73a543..9d6a52c 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -14,7 +14,7 @@ import { createFirstLaunchTour } from "./firstLaunch"; import { createWindows, mainWin } from "./mainWindow"; import { registerMediaPermissionsHandler } from "./mediaPermissions"; import { registerScreenShareHandler } from "./screenShare"; -import { Settings } from "./settings"; +import { Settings, State } from "./settings"; import { isDeckGameMode } from "./utils/steamOS"; if (IS_DEV) { @@ -58,7 +58,7 @@ function init() { app.whenReady().then(async () => { checkUpdates(); - if (process.platform === "win32") app.setAppUserModelId("dev.vencord.desktop"); + if (process.platform === "win32") app.setAppUserModelId("dev.vencord.vesktop"); registerScreenShareHandler(); registerMediaPermissionsHandler(); @@ -84,7 +84,7 @@ if (!app.requestSingleInstanceLock({ IS_DEV })) { } async function bootstrap() { - if (!Object.hasOwn(Settings.store, "firstLaunch")) { + if (!Object.hasOwn(State.store, "firstLaunch")) { createFirstLaunchTour(); } else { createWindows(); diff --git a/src/main/ipc.ts b/src/main/ipc.ts index 504bd10..e6a42af 100644 --- a/src/main/ipc.ts +++ b/src/main/ipc.ts @@ -4,10 +4,10 @@ * Copyright (c) 2023 Vendicated and Vencord contributors */ -if (process.platform === "linux") import("./virtmic"); +if (process.platform === "linux") import("./venmic"); import { execFile } from "child_process"; -import { app, BrowserWindow, dialog, RelaunchOptions, session, shell } from "electron"; +import { app, BrowserWindow, clipboard, dialog, nativeImage, RelaunchOptions, session, shell } from "electron"; import { mkdirSync, readFileSync, watch } from "fs"; import { open, readFile } from "fs/promises"; import { release } from "os"; @@ -120,6 +120,13 @@ handle(IpcEvents.SELECT_VENCORD_DIR, async () => { handle(IpcEvents.SET_BADGE_COUNT, (_, count: number) => setBadgeCount(count)); +handle(IpcEvents.CLIPBOARD_COPY_IMAGE, async (_, buf: ArrayBuffer, src: string) => { + clipboard.write({ + html: ``, + image: nativeImage.createFromBuffer(Buffer.from(buf)) + }); +}); + function readCss() { return readFile(VENCORD_QUICKCSS_FILE, "utf-8").catch(() => ""); } diff --git a/src/main/mainWindow.ts b/src/main/mainWindow.ts index 8fdb6ee..db44566 100644 --- a/src/main/mainWindow.ts +++ b/src/main/mainWindow.ts @@ -34,7 +34,7 @@ import { UserAgent, VENCORD_FILES_DIR } from "./constants"; -import { Settings, VencordSettings } from "./settings"; +import { Settings, State, VencordSettings } from "./settings"; import { createSplashWindow } from "./splash"; import { makeLinksOpenExternally } from "./utils/makeLinksOpenExternally"; import { applyDeckKeyboardFix, askToApplySteamLayout, isDeckGameMode } from "./utils/steamOS"; @@ -78,8 +78,7 @@ function initTray(win: BrowserWindow) { label: "Open", click() { win.show(); - }, - enabled: false + } }, { label: "About", @@ -122,14 +121,6 @@ function initTray(win: BrowserWindow) { tray.setToolTip("Vesktop"); tray.setContextMenu(trayMenu); tray.on("click", () => win.show()); - - win.on("show", () => { - trayMenu.items[0].enabled = false; - }); - - win.on("hide", () => { - trayMenu.items[0].enabled = true; - }); } async function clearData(win: BrowserWindow) { @@ -210,7 +201,6 @@ function initMenuBar(win: BrowserWindow) { type: "separator" }, { - label: "Hide Vesktop", // Should probably remove the label, but it says "Hide VencordDesktop" instead of "Hide Vesktop" role: "hide" }, { @@ -268,7 +258,7 @@ function getWindowBoundsOptions(): BrowserWindowConstructorOptions { // We want the default window behaivour to apply in game mode since it expects everything to be fullscreen and maximized. if (isDeckGameMode) return {}; - const { x, y, width, height } = Settings.store.windowBounds ?? {}; + const { x, y, width, height } = State.store.windowBounds ?? {}; const options = { width: width ?? DEFAULT_WIDTH, @@ -313,8 +303,8 @@ function getDarwinOptions(): BrowserWindowConstructorOptions { function initWindowBoundsListeners(win: BrowserWindow) { const saveState = () => { - Settings.store.maximized = win.isMaximized(); - Settings.store.minimized = win.isMinimized(); + State.store.maximized = win.isMaximized(); + State.store.minimized = win.isMinimized(); }; win.on("maximize", saveState); @@ -322,7 +312,7 @@ function initWindowBoundsListeners(win: BrowserWindow) { win.on("unmaximize", saveState); const saveBounds = () => { - Settings.store.windowBounds = win.getBounds(); + State.store.windowBounds = win.getBounds(); }; win.on("resize", saveBounds); @@ -375,11 +365,11 @@ function createMainWindow() { removeSettingsListeners(); removeVencordSettingsListeners(); - const { staticTitle, transparencyOption, enableMenu, discordWindowsTitleBar } = Settings.store; + const { staticTitle, transparencyOption, enableMenu, customTitleBar } = Settings.store; const { frameless } = VencordSettings.store; - const noFrame = frameless === true || (process.platform === "win32" && discordWindowsTitleBar === true); + const noFrame = frameless === true || customTitleBar === true; const win = (mainWin = new BrowserWindow({ show: false, @@ -396,7 +386,12 @@ function createMainWindow() { ...(transparencyOption && transparencyOption !== "none" && { backgroundColor: "#00000000", - backgroundMaterial: transparencyOption, + backgroundMaterial: transparencyOption + }), + // Fix transparencyOption for custom discord titlebar + ...(customTitleBar && + transparencyOption && + transparencyOption !== "none" && { transparent: true }), ...(staticTitle && { title: "Vesktop" }), @@ -442,7 +437,8 @@ function createMainWindow() { const runVencordMain = once(() => require(join(VENCORD_FILES_DIR, "vencordDesktopMain.js"))); export async function createWindows() { - const splash = createSplashWindow(); + const startMinimized = process.argv.includes("--start-minimized"); + const splash = createSplashWindow(startMinimized); // SteamOS letterboxes and scales it terribly, so just full screen it if (isDeckGameMode) splash.setFullScreen(true); await ensureVencordFiles(); @@ -452,10 +448,10 @@ export async function createWindows() { mainWin.webContents.on("did-finish-load", () => { splash.destroy(); - mainWin!.show(); - if (Settings.store.maximized && !isDeckGameMode) { - mainWin!.maximize(); + if (!startMinimized) { + mainWin!.show(); + if (State.store.maximized && !isDeckGameMode) mainWin!.maximize(); } if (isDeckGameMode) { @@ -464,6 +460,12 @@ export async function createWindows() { askToApplySteamLayout(mainWin); } + + mainWin.once("show", () => { + if (State.store.maximized && !mainWin!.isMaximized() && !isDeckGameMode) { + mainWin!.maximize(); + } + }); }); initArRPC(); diff --git a/src/main/settings.ts b/src/main/settings.ts index 6fad97f..03c705e 100644 --- a/src/main/settings.ts +++ b/src/main/settings.ts @@ -4,14 +4,15 @@ * Copyright (c) 2023 Vendicated and Vencord contributors */ -import { mkdirSync, readFileSync, writeFileSync } from "fs"; +import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs"; import { dirname, join } from "path"; -import type { Settings as TSettings } from "shared/settings"; +import type { Settings as TSettings, State as TState } from "shared/settings"; import { SettingsStore } from "shared/utils/SettingsStore"; import { DATA_DIR, VENCORD_SETTINGS_FILE } from "./constants"; const SETTINGS_FILE = join(DATA_DIR, "settings.json"); +const STATE_FILE = join(DATA_DIR, "state.json"); function loadSettings(file: string, name: string) { let settings = {} as T; @@ -20,7 +21,7 @@ function loadSettings(file: string, name: string) { try { settings = JSON.parse(content); } catch (err) { - console.error(`Failed to parse ${name} settings.json:`, err); + console.error(`Failed to parse ${name}.json:`, err); } } catch {} @@ -33,5 +34,31 @@ function loadSettings(file: string, name: string) { return store; } -export const Settings = loadSettings(SETTINGS_FILE, "Vesktop"); -export const VencordSettings = loadSettings(VENCORD_SETTINGS_FILE, "Vencord"); +export const Settings = loadSettings(SETTINGS_FILE, "Vesktop settings"); +if (Object.hasOwn(Settings.plain, "discordWindowsTitleBar")) { + Settings.plain.customTitleBar = Settings.plain.discordWindowsTitleBar; + delete Settings.plain.discordWindowsTitleBar; + Settings.markAsChanged(); +} + +export const VencordSettings = loadSettings(VENCORD_SETTINGS_FILE, "Vencord settings"); + +if (Object.hasOwn(Settings.plain, "firstLaunch") && !existsSync(STATE_FILE)) { + console.warn("legacy state in settings.json detected. migrating to state.json"); + const state = {} as TState; + for (const prop of [ + "firstLaunch", + "maximized", + "minimized", + "skippedUpdate", + "steamOSLayoutVersion", + "windowBounds" + ] as const) { + state[prop] = Settings.plain[prop]; + delete Settings.plain[prop]; + } + Settings.markAsChanged(); + writeFileSync(STATE_FILE, JSON.stringify(state, null, 4)); +} + +export const State = loadSettings(STATE_FILE, "Vesktop state"); diff --git a/src/main/splash.ts b/src/main/splash.ts index f21799d..7c05de9 100644 --- a/src/main/splash.ts +++ b/src/main/splash.ts @@ -11,10 +11,11 @@ import { ICON_PATH, VIEW_DIR } from "shared/paths"; import { Settings } from "./settings"; -export function createSplashWindow() { +export function createSplashWindow(startMinimized = false) { const splash = new BrowserWindow({ ...SplashProps, - icon: ICON_PATH + icon: ICON_PATH, + show: !startMinimized }); splash.loadFile(join(VIEW_DIR, "splash.html")); diff --git a/src/main/utils/ipcWrappers.ts b/src/main/utils/ipcWrappers.ts index b99298c..3ceb908 100644 --- a/src/main/utils/ipcWrappers.ts +++ b/src/main/utils/ipcWrappers.ts @@ -5,20 +5,14 @@ */ import { ipcMain, IpcMainEvent, IpcMainInvokeEvent, WebFrameMain } from "electron"; +import { DISCORD_HOSTNAMES } from "main/constants"; import { IpcEvents } from "shared/IpcEvents"; export function validateSender(frame: WebFrameMain) { const { hostname, protocol } = new URL(frame.url); if (protocol === "file:") return; - switch (hostname) { - case "discord.com": - case "ptb.discord.com": - case "canary.discord.com": - break; - default: - throw new Error("ipc: Disallowed host " + hostname); - } + if (!DISCORD_HOSTNAMES.includes(hostname)) throw new Error("ipc: Disallowed host " + hostname); } export function handleSync(event: IpcEvents, cb: (e: IpcMainEvent, ...args: any[]) => any) { diff --git a/src/main/utils/makeLinksOpenExternally.ts b/src/main/utils/makeLinksOpenExternally.ts index 5197261..12f2c3d 100644 --- a/src/main/utils/makeLinksOpenExternally.ts +++ b/src/main/utils/makeLinksOpenExternally.ts @@ -5,48 +5,67 @@ */ import { BrowserWindow, shell } from "electron"; +import { DISCORD_HOSTNAMES } from "main/constants"; import { Settings } from "../settings"; +import { createOrFocusPopup, setupPopout } from "./popout"; import { execSteamURL, isDeckGameMode, steamOpenURL } from "./steamOS"; -export function makeLinksOpenExternally(win: BrowserWindow) { - win.webContents.setWindowOpenHandler(({ url }) => { - switch (url) { - case "about:blank": - case "https://discord.com/popout": - return { action: "allow" }; - } - +export function handleExternalUrl(url: string, protocol?: string): { action: "deny" | "allow" } { + if (protocol == null) { try { - var { protocol } = new URL(url); + protocol = new URL(url).protocol; + } catch { + return { action: "deny" }; + } + } + + switch (protocol) { + case "http:": + case "https:": + if (Settings.store.openLinksWithElectron) { + return { action: "allow" }; + } + // eslint-disable-next-line no-fallthrough + case "mailto:": + case "spotify:": + if (isDeckGameMode) { + steamOpenURL(url); + } else { + shell.openExternal(url); + } + break; + case "steam:": + if (isDeckGameMode) { + execSteamURL(url); + } else { + shell.openExternal(url); + } + break; + } + + return { action: "deny" }; +} + +export function makeLinksOpenExternally(win: BrowserWindow) { + win.webContents.setWindowOpenHandler(({ url, frameName, features }) => { + try { + var { protocol, hostname, pathname } = new URL(url); } catch { return { action: "deny" }; } - switch (protocol) { - case "http:": - case "https:": - if (Settings.store.openLinksWithElectron) { - return { action: "allow" }; - } - // eslint-disable-next-line no-fallthrough - case "mailto:": - case "spotify:": - if (isDeckGameMode) { - steamOpenURL(url); - } else { - shell.openExternal(url); - } - break; - case "steam:": - if (isDeckGameMode) { - execSteamURL(url); - } else { - shell.openExternal(url); - } - break; + if (frameName.startsWith("DISCORD_") && pathname === "/popout" && DISCORD_HOSTNAMES.includes(hostname)) { + return createOrFocusPopup(frameName, features); } - return { action: "deny" }; + if (url === "about:blank" || (frameName === "authorize" && DISCORD_HOSTNAMES.includes(hostname))) + return { action: "allow" }; + + return handleExternalUrl(url, protocol); + }); + + win.webContents.on("did-create-window", (win, { frameName }) => { + if (frameName.startsWith("DISCORD_")) setupPopout(win, frameName); }); } diff --git a/src/main/utils/popout.ts b/src/main/utils/popout.ts new file mode 100644 index 0000000..754fdb0 --- /dev/null +++ b/src/main/utils/popout.ts @@ -0,0 +1,112 @@ +/* + * SPDX-License-Identifier: GPL-3.0 + * Vesktop, a desktop app aiming to give you a snappier Discord Experience + * Copyright (c) 2023 Vendicated and Vencord contributors + */ + +import { BrowserWindow, BrowserWindowConstructorOptions } from "electron"; + +import { handleExternalUrl } from "./makeLinksOpenExternally"; + +const ALLOWED_FEATURES = new Set([ + "width", + "height", + "left", + "top", + "resizable", + "movable", + "alwaysOnTop", + "frame", + "transparent", + "hasShadow", + "closable", + "skipTaskbar", + "backgroundColor", + "menubar", + "toolbar", + "location", + "directories", + "titleBarStyle" +]); + +const MIN_POPOUT_WIDTH = 320; +const MIN_POPOUT_HEIGHT = 180; +const DEFAULT_POPOUT_OPTIONS: BrowserWindowConstructorOptions = { + title: "Discord Popout", + backgroundColor: "#2f3136", + minWidth: MIN_POPOUT_WIDTH, + minHeight: MIN_POPOUT_HEIGHT, + frame: process.platform === "linux", + titleBarStyle: process.platform === "darwin" ? "hidden" : undefined, + trafficLightPosition: + process.platform === "darwin" + ? { + x: 10, + y: 3 + } + : undefined, + webPreferences: { + nodeIntegration: false, + contextIsolation: true + } +}; + +const PopoutWindows = new Map(); + +function focusWindow(window: BrowserWindow) { + window.setAlwaysOnTop(true); + window.focus(); + window.setAlwaysOnTop(false); +} + +function parseFeatureValue(feature: string) { + if (feature === "yes") return true; + if (feature === "no") return false; + + const n = Number(feature); + if (!isNaN(n)) return n; + + return feature; +} + +function parseWindowFeatures(features: string) { + const keyValuesParsed = features.split(","); + + return keyValuesParsed.reduce((features, feature) => { + const [key, value] = feature.split("="); + if (ALLOWED_FEATURES.has(key)) features[key] = parseFeatureValue(value); + + return features; + }, {}); +} + +export function createOrFocusPopup(key: string, features: string) { + const existingWindow = PopoutWindows.get(key); + if (existingWindow) { + focusWindow(existingWindow); + return { action: "deny" }; + } + + return { + action: "allow", + overrideBrowserWindowOptions: { + ...DEFAULT_POPOUT_OPTIONS, + ...parseWindowFeatures(features) + } + }; +} + +export function setupPopout(win: BrowserWindow, key: string) { + PopoutWindows.set(key, win); + + /* win.webContents.on("will-navigate", (evt, url) => { + // maybe prevent if not origin match + })*/ + + win.webContents.setWindowOpenHandler(({ url }) => handleExternalUrl(url)); + + win.once("closed", () => { + win.removeAllListeners(); + PopoutWindows.delete(key); + }); +} diff --git a/src/main/utils/steamOS.ts b/src/main/utils/steamOS.ts index 8145e5a..e61166c 100644 --- a/src/main/utils/steamOS.ts +++ b/src/main/utils/steamOS.ts @@ -9,7 +9,7 @@ import { writeFile } from "fs/promises"; import { join } from "path"; import { MessageBoxChoice } from "../constants"; -import { Settings } from "../settings"; +import { State } from "../settings"; // Bump this to re-show the prompt const layoutVersion = 2; @@ -70,8 +70,8 @@ async function showLayout(appId: string) { export async function askToApplySteamLayout(win: BrowserWindow) { const appId = getAppId(); if (!appId) return; - if (Settings.store.steamOSLayoutVersion === layoutVersion) return; - const update = Boolean(Settings.store.steamOSLayoutVersion); + if (State.store.steamOSLayoutVersion === layoutVersion) return; + const update = Boolean(State.store.steamOSLayoutVersion); // Touch screen breaks in some menus when native touch mode is enabled on latest SteamOS beta, remove most of the update specific text once that's fixed. const { response } = await dialog.showMessageBox(win, { @@ -87,8 +87,8 @@ ${update ? "Click" : "Tap"} no to keep your current layout.`, type: "question" }); - if (Settings.store.steamOSLayoutVersion !== layoutVersion) { - Settings.store.steamOSLayoutVersion = layoutVersion; + if (State.store.steamOSLayoutVersion !== layoutVersion) { + State.store.steamOSLayoutVersion = layoutVersion; } if (response === MessageBoxChoice.Cancel) return; diff --git a/src/main/virtmic.ts b/src/main/venmic.ts similarity index 73% rename from src/main/virtmic.ts rename to src/main/venmic.ts index ddbde63..fcc40de 100644 --- a/src/main/virtmic.ts +++ b/src/main/venmic.ts @@ -51,22 +51,17 @@ ipcMain.handle(IpcEvents.VIRT_MIC_LIST, () => { : { ok: false, isGlibcxxToOld }; }); -ipcMain.handle( - IpcEvents.VIRT_MIC_START, - (_, targets: string[]) => - obtainVenmic()?.link({ - include: targets.map(target => ({ key: "application.name", value: target })), - exclude: [{ key: "application.process.id", value: getRendererAudioServicePid() }] - }) +ipcMain.handle(IpcEvents.VIRT_MIC_START, (_, targets: string[]) => + obtainVenmic()?.link({ + include: targets.map(target => ({ key: "application.name", value: target })), + exclude: [{ key: "application.process.id", value: getRendererAudioServicePid() }] + }) ); -ipcMain.handle( - IpcEvents.VIRT_MIC_START_SYSTEM, - () => - // @ts-expect-error venmic types are wrong. include is actually optional but typed as required in vemic - obtainVenmic()?.link({ - exclude: [{ key: "application.process.id", value: getRendererAudioServicePid() }] - }) +ipcMain.handle(IpcEvents.VIRT_MIC_START_SYSTEM, () => + obtainVenmic()?.link({ + exclude: [{ key: "application.process.id", value: getRendererAudioServicePid() }] + }) ); ipcMain.handle(IpcEvents.VIRT_MIC_STOP, () => obtainVenmic()?.unlink()); diff --git a/src/preload/VesktopNative.ts b/src/preload/VesktopNative.ts index d72329d..d17bd23 100644 --- a/src/preload/VesktopNative.ts +++ b/src/preload/VesktopNative.ts @@ -71,5 +71,9 @@ export const VesktopNative = { onActivity(cb: (data: string) => void) { ipcRenderer.on(IpcEvents.ARRPC_ACTIVITY, (_, data: string) => cb(data)); } + }, + clipboard: { + copyImage: (imageBuffer: Uint8Array, imageSrc: string) => + invoke(IpcEvents.CLIPBOARD_COPY_IMAGE, imageBuffer, imageSrc) } }; diff --git a/src/renderer/components/Settings.tsx b/src/renderer/components/Settings.tsx index 0c22138..b9ef4d6 100644 --- a/src/renderer/components/Settings.tsx +++ b/src/renderer/components/Settings.tsx @@ -10,7 +10,7 @@ import { Margins } from "@vencord/types/utils"; import { Button, Forms, Select, Switch, Text, Toasts, useState } from "@vencord/types/webpack/common"; import { setBadge } from "renderer/appBadge"; import { useSettings } from "renderer/settings"; -import { isMac, isWindows } from "renderer/utils"; +import { isMac } from "renderer/utils"; import { isTruthy } from "shared/utils/guards"; export default function SettingsUi() { @@ -21,10 +21,10 @@ export default function SettingsUi() { const [autoStartEnabled, setAutoStartEnabled] = useState(autostart.isEnabled()); const allSwitches: Array boolean)?]> = [ - isWindows && [ - "discordWindowsTitleBar", + [ + "customTitleBar", "Discord Titlebar", - "Use Discord's custom title bar instead of the Windows one. Requires a full restart." + "Use Discord's custom title bar instead of the native system one. Requires a full restart." ], !isMac && ["tray", "Tray Icon", "Add a tray icon for Vesktop", true], !isMac && [ diff --git a/src/renderer/patches/platformClass.tsx b/src/renderer/patches/platformClass.tsx index 30fbfd0..58767a8 100644 --- a/src/renderer/patches/platformClass.tsx +++ b/src/renderer/patches/platformClass.tsx @@ -5,7 +5,7 @@ */ import { Settings } from "renderer/settings"; -import { isMac, isWindows } from "renderer/utils"; +import { isMac } from "renderer/utils"; import { addPatch } from "./shared"; @@ -22,8 +22,8 @@ addPatch({ ], getPlatformClass() { + if (Settings.store.customTitleBar) return "platform-win"; if (isMac) return "platform-osx"; - if (isWindows && Settings.store.discordWindowsTitleBar) return "platform-win"; return "platform-web"; } }); diff --git a/src/renderer/patches/windowsTitleBar.tsx b/src/renderer/patches/windowsTitleBar.tsx index 4ae50b2..401e1c5 100644 --- a/src/renderer/patches/windowsTitleBar.tsx +++ b/src/renderer/patches/windowsTitleBar.tsx @@ -8,7 +8,7 @@ import { Settings } from "renderer/settings"; import { addPatch } from "./shared"; -if (Settings.store.discordWindowsTitleBar) +if (Settings.store.customTitleBar) addPatch({ patches: [ { diff --git a/src/shared/IpcEvents.ts b/src/shared/IpcEvents.ts index bd857c4..df64403 100644 --- a/src/shared/IpcEvents.ts +++ b/src/shared/IpcEvents.ts @@ -47,5 +47,7 @@ export const enum IpcEvents { VIRT_MIC_START_SYSTEM = "VCD_VIRT_MIC_START_ALL", VIRT_MIC_STOP = "VCD_VIRT_MIC_STOP", - ARRPC_ACTIVITY = "VCD_ARRPC_ACTIVITY" + ARRPC_ACTIVITY = "VCD_ARRPC_ACTIVITY", + + CLIPBOARD_COPY_IMAGE = "VCD_CLIPBOARD_COPY_IMAGE" } diff --git a/src/shared/settings.d.ts b/src/shared/settings.d.ts index 6e5ccfc..d796e4b 100644 --- a/src/shared/settings.d.ts +++ b/src/shared/settings.d.ts @@ -19,20 +19,26 @@ export interface Settings { hardwareAcceleration?: boolean; arRPC?: boolean; appBadge?: boolean; - discordWindowsTitleBar?: boolean; - - maximized?: boolean; - minimized?: boolean; - windowBounds?: Rectangle; disableMinSize?: boolean; + /** @deprecated use customTitleBar */ + discordWindowsTitleBar?: boolean; + customTitleBar?: boolean; + checkUpdates?: boolean; - skippedUpdate?: string; - firstLaunch?: boolean; splashTheming?: boolean; splashColor?: string; splashBackground?: string; +} + +export interface State { + maximized?: boolean; + minimized?: boolean; + windowBounds?: Rectangle; + + skippedUpdate?: string; + firstLaunch?: boolean; steamOSLayoutVersion?: number; } diff --git a/src/shared/utils/SettingsStore.ts b/src/shared/utils/SettingsStore.ts index 89c57dd..22dd145 100644 --- a/src/shared/utils/SettingsStore.ts +++ b/src/shared/utils/SettingsStore.ts @@ -144,4 +144,11 @@ export class SettingsStore { listeners.delete(cb); if (!listeners.size) this.pathListeners.delete(path as string); } + + /** + * Call all global change listeners + */ + public markAsChanged() { + this.globalListeners.forEach(cb => cb(this.plain, "")); + } } diff --git a/src/updater/main.ts b/src/updater/main.ts index b84081c..059afb9 100644 --- a/src/updater/main.ts +++ b/src/updater/main.ts @@ -5,7 +5,7 @@ */ import { app, BrowserWindow, shell } from "electron"; -import { Settings } from "main/settings"; +import { Settings, State } from "main/settings"; import { handle } from "main/utils/ipcWrappers"; import { makeLinksOpenExternally } from "main/utils/makeLinksOpenExternally"; import { githubGet, ReleaseData } from "main/utils/vencordLoader"; @@ -52,7 +52,7 @@ handle(IpcEvents.UPDATER_DOWNLOAD, () => { }); handle(IpcEvents.UPDATE_IGNORE, () => { - Settings.store.skippedUpdate = updateData.latestVersion; + State.store.skippedUpdate = updateData.latestVersion; }); function isOutdated(oldVersion: string, newVersion: string) { @@ -91,7 +91,7 @@ export async function checkUpdates() { release: data }; - if (Settings.store.skippedUpdate !== newVersion && isOutdated(oldVersion, newVersion)) { + if (State.store.skippedUpdate !== newVersion && isOutdated(oldVersion, newVersion)) { openNewUpdateWindow(); } } catch (e) { diff --git a/static/views/splash.html b/static/views/splash.html index 94ef13e..bac2ad2 100644 --- a/static/views/splash.html +++ b/static/views/splash.html @@ -2,8 +2,9 @@