mirror of
https://github.com/Vencord/Vesktop.git
synced 2025-02-24 06:05:09 +00:00
Merge branch 'main' into 171-middle-click-autoscroll
This commit is contained in:
commit
8a1bff56f1
40 changed files with 1442 additions and 1154 deletions
|
@ -22,7 +22,13 @@
|
||||||
"eqeqeq": ["error", "always", { "null": "ignore" }],
|
"eqeqeq": ["error", "always", { "null": "ignore" }],
|
||||||
"spaced-comment": ["error", "always", { "markers": ["!"] }],
|
"spaced-comment": ["error", "always", { "markers": ["!"] }],
|
||||||
"yoda": "error",
|
"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"],
|
"operator-assignment": ["error", "always"],
|
||||||
"no-useless-computed-key": "error",
|
"no-useless-computed-key": "error",
|
||||||
"no-unneeded-ternary": ["error", { "defaultAssignment": false }],
|
"no-unneeded-ternary": ["error", { "defaultAssignment": false }],
|
||||||
|
|
32
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
32
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
|
@ -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.
|
10
.github/ISSUE_TEMPLATE/custom.md
vendored
Normal file
10
.github/ISSUE_TEMPLATE/custom.md
vendored
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
---
|
||||||
|
name: Custom issue template
|
||||||
|
about: Describe this issue template's purpose here.
|
||||||
|
title: ''
|
||||||
|
labels: ''
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
|
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
|
@ -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.
|
38
.github/workflows/meta.yml
vendored
Normal file
38
.github/workflows/meta.yml
vendored
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
name: Update metainfo on release
|
||||||
|
|
||||||
|
on:
|
||||||
|
release:
|
||||||
|
types:
|
||||||
|
- published
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
update:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- uses: pnpm/action-setup@v2 # Install pnpm using packageManager key in package.json
|
||||||
|
|
||||||
|
- name: Use Node.js 18.18.2
|
||||||
|
uses: actions/setup-node@v3
|
||||||
|
with:
|
||||||
|
node-version: 18.18.2
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: pnpm i
|
||||||
|
|
||||||
|
- name: Update metainfo
|
||||||
|
run: pnpm updateMeta
|
||||||
|
|
||||||
|
- name: Commit and merge in changes
|
||||||
|
run: |
|
||||||
|
git config user.name "github-actions[bot]"
|
||||||
|
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
||||||
|
git checkout -b ci/meta-update
|
||||||
|
git add meta/dev.vencord.Vesktop.metainfo.xml
|
||||||
|
git commit -m "Insert release changes for ${{ github.event.release.tag_name }}"
|
||||||
|
git push origin ci/meta-update
|
||||||
|
gh pr create -B main -H ci/meta-update -t "Metainfo for ${{ github.event.release.tag_name }}" -b "This PR updates the metainfo for release ${{ github.event.release.tag_name }}. @lewisakura @Vendicated"
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
40
.github/workflows/release.yml
vendored
40
.github/workflows/release.yml
vendored
|
@ -12,17 +12,41 @@ jobs:
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
os: [macos-latest, ubuntu-latest, windows-latest]
|
os: [macos-latest, ubuntu-latest, windows-latest]
|
||||||
|
include:
|
||||||
|
- os: macos-latest
|
||||||
|
platform: mac
|
||||||
|
- os: ubuntu-latest
|
||||||
|
platform: linux
|
||||||
|
- os: windows-latest
|
||||||
|
platform: windows
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Check out Git repository
|
- uses: actions/checkout@v3
|
||||||
uses: actions/checkout@v3
|
- uses: pnpm/action-setup@v2 # Install pnpm using packageManager key in package.json
|
||||||
|
|
||||||
- uses: actions/setup-node@v3
|
- name: Use Node.js 18.18.2
|
||||||
|
uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
node-version: 18
|
node-version: 18.18.2
|
||||||
|
cache: "pnpm"
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: pnpm install --frozen-lockfile
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: pnpm build
|
||||||
|
|
||||||
- name: Run Electron Builder
|
- name: Run Electron Builder
|
||||||
uses: samuelmeuli/action-electron-builder@e4b12cd06ddf023422f1ac4e39632bd76f6e6928
|
if: ${{ matrix.platform != 'mac' }}
|
||||||
with:
|
run: |
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
pnpm electron-builder --${{ matrix.platform }} --publish always
|
||||||
RELEASE: true
|
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 }}
|
||||||
|
|
4
.github/workflows/test.yml
vendored
4
.github/workflows/test.yml
vendored
|
@ -14,10 +14,10 @@ jobs:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- uses: pnpm/action-setup@v2 # Install pnpm using packageManager key in package.json
|
- uses: pnpm/action-setup@v2 # Install pnpm using packageManager key in package.json
|
||||||
|
|
||||||
- name: Use Node.js 18
|
- name: Use Node.js 18.18.2
|
||||||
uses: actions/setup-node@v3
|
uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
node-version: 18
|
node-version: 18.18.2
|
||||||
cache: "pnpm"
|
cache: "pnpm"
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
|
|
2
.vscode/settings.json
vendored
2
.vscode/settings.json
vendored
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"editor.formatOnSave": true,
|
"editor.formatOnSave": true,
|
||||||
"editor.codeActionsOnSave": {
|
"editor.codeActionsOnSave": {
|
||||||
"source.fixAll.eslint": true
|
"source.fixAll.eslint": "explicit"
|
||||||
},
|
},
|
||||||
"[typescript]": {
|
"[typescript]": {
|
||||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||||
|
|
14
README.md
14
README.md
|
@ -3,11 +3,13 @@
|
||||||
Vesktop is a cross platform desktop app aiming to give you a snappier Discord experience with [Vencord](https://github.com/Vendicated/Vencord) pre-installed
|
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**:
|
**Not yet supported**:
|
||||||
|
|
||||||
- Global Keybinds
|
- Global Keybinds
|
||||||
|
|
||||||
Bug reports, feature requests & contributions are highly appreciated!!
|
Bug reports, feature requests & contributions are highly appreciated!!
|
||||||
|
|
||||||

|

|
||||||
|

|
||||||
|
|
||||||
## Installing
|
## Installing
|
||||||
|
|
||||||
|
@ -21,6 +23,8 @@ Download and run Vesktop-VERSION.dmg from [releases](https://github.com/Vencord/
|
||||||
|
|
||||||
### Linux
|
### Linux
|
||||||
|
|
||||||
|
[](https://flathub.org/apps/dev.vencord.Vesktop)
|
||||||
|
|
||||||
#### Arch based
|
#### Arch based
|
||||||
|
|
||||||
Install [vencord-desktop-git](https://aur.archlinux.org/packages/vencord-desktop-git) from the AUR using your favourite AUR helper, for example [yay](https://github.com/Jguer/yay)
|
Install [vencord-desktop-git](https://aur.archlinux.org/packages/vencord-desktop-git) from the AUR using your favourite AUR helper, for example [yay](https://github.com/Jguer/yay)
|
||||||
|
@ -35,9 +39,9 @@ Download Vesktop-VERSION.rpm from [releases](https://github.com/Vencord/Vesktop/
|
||||||
|
|
||||||
#### Other
|
#### 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`.
|
||||||
|
|
||||||
A flatpak is planned, if you want packages for other repos, feel free to create them and they can be linked as unofficial here
|
If other packages are created, feel free to open an issue and we'll link them here.
|
||||||
|
|
||||||
## Building
|
## Building
|
||||||
|
|
||||||
|
@ -64,7 +68,3 @@ pnpm package:dir
|
||||||
## Motivation
|
## Motivation
|
||||||
|
|
||||||
The official Discord Desktop app is very resource heavy compared to Discord in your Browser. There are multiple alternative Electron apps (ArmCord, WebCord, probably more) that prove how much of a performance gain you can gain by using a custom app. ArmCord already supports Vencord but makes it pretty limited for us. Making our own standalone app gives us much more control.
|
The official Discord Desktop app is very resource heavy compared to Discord in your Browser. There are multiple alternative Electron apps (ArmCord, WebCord, probably more) that prove how much of a performance gain you can gain by using a custom app. ArmCord already supports Vencord but makes it pretty limited for us. Making our own standalone app gives us much more control.
|
||||||
|
|
||||||
This is just a random idea I (V) got, and might not actually ever be finished heh
|
|
||||||
|
|
||||||
Gluon also seems very attractive for this because of how lightweight it can be and because unlike electron, streaming just works out of the box like in any chromium browser. However, at the time of writing this, it still lacks some features necessary to make it work (synchronous ipc or a way to get node process variables into the onLoad function for instance, plus onLoad seems to load a little too late sometimes)
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
!macro preInit
|
!macro preInit
|
||||||
SetRegView 64
|
SetRegView 64
|
||||||
WriteRegExpandStr HKLM "${INSTALL_REGISTRY_KEY}" InstallLocation "$LocalAppData\VencordDesktop"
|
WriteRegExpandStr HKLM "${INSTALL_REGISTRY_KEY}" InstallLocation "$LocalAppData\vesktop"
|
||||||
WriteRegExpandStr HKCU "${INSTALL_REGISTRY_KEY}" InstallLocation "$LocalAppData\VencordDesktop"
|
WriteRegExpandStr HKCU "${INSTALL_REGISTRY_KEY}" InstallLocation "$LocalAppData\vesktop"
|
||||||
SetRegView 32
|
SetRegView 32
|
||||||
WriteRegExpandStr HKLM "${INSTALL_REGISTRY_KEY}" InstallLocation "$LocalAppData\VencordDesktop"
|
WriteRegExpandStr HKLM "${INSTALL_REGISTRY_KEY}" InstallLocation "$LocalAppData\vesktop"
|
||||||
WriteRegExpandStr HKCU "${INSTALL_REGISTRY_KEY}" InstallLocation "$LocalAppData\VencordDesktop"
|
WriteRegExpandStr HKCU "${INSTALL_REGISTRY_KEY}" InstallLocation "$LocalAppData\vesktop"
|
||||||
!macroend
|
!macroend
|
||||||
|
|
183
meta/dev.vencord.Vesktop.metainfo.xml
Normal file
183
meta/dev.vencord.Vesktop.metainfo.xml
Normal file
|
@ -0,0 +1,183 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<component type="desktop-application">
|
||||||
|
<!--Created with jdAppStreamEdit 7.1-->
|
||||||
|
<id>dev.vencord.Vesktop</id>
|
||||||
|
<name>Vesktop</name>
|
||||||
|
<summary>Snappier Discord app with Vencord</summary>
|
||||||
|
<developer_name>Vencord Contributors</developer_name>
|
||||||
|
<launchable type="desktop-id">dev.vencord.Vesktop.desktop</launchable>
|
||||||
|
<metadata_license>CC0-1.0</metadata_license>
|
||||||
|
<project_license>GPL-3.0</project_license>
|
||||||
|
<project_group>Vencord</project_group>
|
||||||
|
<description>
|
||||||
|
<p>Vesktop is a cross platform desktop app aiming to give you a snappier Discord experience with Vencord pre-installed.</p>
|
||||||
|
<p>Vesktop comes bundled with Venmic, a purpose-built library to provide functioning audio screenshare.</p>
|
||||||
|
</description>
|
||||||
|
<screenshots>
|
||||||
|
<screenshot type="default">
|
||||||
|
<caption>Vencord settings page and about window open</caption>
|
||||||
|
<image type="source">https://vencord.dev/assets/screenshots/vesktop-1-appstream.png</image>
|
||||||
|
</screenshot>
|
||||||
|
<screenshot>
|
||||||
|
<caption>A dialog showing screenshare options</caption>
|
||||||
|
<image type="source">https://vencord.dev/assets/screenshots/vesktop-2-appstream.png</image>
|
||||||
|
</screenshot>
|
||||||
|
<screenshot>
|
||||||
|
<caption>A screenshot of a Discord server</caption>
|
||||||
|
<image type="source">https://vencord.dev/assets/screenshots/vesktop-3-appstream.png</image>
|
||||||
|
</screenshot>
|
||||||
|
</screenshots>
|
||||||
|
<releases>
|
||||||
|
<release version="1.5.0" date="2024-01-16" type="stable">
|
||||||
|
<url>https://github.com/Vencord/Vesktop/releases/tag/v1.5.0</url>
|
||||||
|
<description>
|
||||||
|
<p>What's Changed</p>
|
||||||
|
<ul>
|
||||||
|
<li>fully renamed to Vesktop. You will likely have to login to Discord again. You might have to re-create your vesktop shortcut</li>
|
||||||
|
<li>added option to disable smooth scrolling by @ZirixCZ</li>
|
||||||
|
<li>added setting to disable hardware acceleration by @zt64</li>
|
||||||
|
<li>fixed adding connections</li>
|
||||||
|
<li>fixed / improved discord popouts</li>
|
||||||
|
<li>you can now use the custom discord titlebar on linux/mac</li>
|
||||||
|
<li>the splash window is now draggable</li>
|
||||||
|
<li>now signed on mac</li>
|
||||||
|
</ul>
|
||||||
|
</description>
|
||||||
|
</release>
|
||||||
|
<release version="0.4.4" date="2023-12-02" type="stable">
|
||||||
|
<url>https://github.com/Vencord/Vesktop/releases/tag/v0.4.4</url>
|
||||||
|
<description>
|
||||||
|
<p>What's Changed</p>
|
||||||
|
<ul>
|
||||||
|
<li>improve venmic system compatibility by @Curve</li>
|
||||||
|
<li>Update steamdeck controller layout by @AAGaming00</li>
|
||||||
|
<li>feat: Add option to disable smooth scrolling by @ZirixCZ</li>
|
||||||
|
<li>unblur shiggy in splash screen by @viacoro</li>
|
||||||
|
<li>update electron & arrpc @D3SOX</li>
|
||||||
|
</ul>
|
||||||
|
</description>
|
||||||
|
</release>
|
||||||
|
<release version="0.4.3" date="2023-11-01" type="stable">
|
||||||
|
<url>https://github.com/Vencord/Vesktop/releases/tag/v0.4.3</url>
|
||||||
|
</release>
|
||||||
|
<release version="0.4.2" date="2023-10-26" type="stable">
|
||||||
|
<url>https://github.com/Vencord/Vesktop/releases/tag/v0.4.2</url>
|
||||||
|
</release>
|
||||||
|
<release version="0.4.1" date="2023-10-24" type="stable">
|
||||||
|
<url>https://github.com/Vencord/Vesktop/releases/tag/v0.4.1</url>
|
||||||
|
</release>
|
||||||
|
<release version="0.4.0" date="2023-10-21" type="stable">
|
||||||
|
<url>https://github.com/Vencord/Vesktop/releases/tag/v0.4.0</url>
|
||||||
|
</release>
|
||||||
|
<release version="0.3.3" date="2023-09-30" type="stable">
|
||||||
|
<url>https://github.com/Vencord/Vesktop/releases/tag/v0.3.3</url>
|
||||||
|
</release>
|
||||||
|
<release version="0.3.2" date="2023-09-25" type="stable">
|
||||||
|
<url>https://github.com/Vencord/Vesktop/releases/tag/v0.3.2</url>
|
||||||
|
</release>
|
||||||
|
<release version="0.3.1" date="2023-09-25" type="stable">
|
||||||
|
<url>https://github.com/Vencord/Vesktop/releases/tag/v0.3.1</url>
|
||||||
|
</release>
|
||||||
|
<release version="0.3.0" date="2023-08-16" type="stable">
|
||||||
|
<url>https://github.com/Vencord/Vesktop/releases/tag/v0.3.0</url>
|
||||||
|
</release>
|
||||||
|
<release version="0.2.9" date="2023-08-12" type="stable">
|
||||||
|
<url>https://github.com/Vencord/Vesktop/releases/tag/v0.2.9</url>
|
||||||
|
</release>
|
||||||
|
<release version="0.2.8" date="2023-08-02" type="stable">
|
||||||
|
<url>https://github.com/Vencord/Vesktop/releases/tag/v0.2.8</url>
|
||||||
|
</release>
|
||||||
|
<release version="0.2.7" date="2023-07-26" type="stable">
|
||||||
|
<url>https://github.com/Vencord/Vesktop/releases/tag/v0.2.7</url>
|
||||||
|
</release>
|
||||||
|
<release version="0.2.6" date="2023-07-04" type="stable">
|
||||||
|
<url>https://github.com/Vencord/Vesktop/releases/tag/v0.2.6</url>
|
||||||
|
</release>
|
||||||
|
<release version="0.2.5" date="2023-06-26" type="stable">
|
||||||
|
<url>https://github.com/Vencord/Vesktop/releases/tag/v0.2.5</url>
|
||||||
|
</release>
|
||||||
|
<release version="0.2.4" date="2023-06-25" type="stable">
|
||||||
|
<url>https://github.com/Vencord/Vesktop/releases/tag/v0.2.4</url>
|
||||||
|
</release>
|
||||||
|
<release version="0.2.3" date="2023-06-23" type="stable">
|
||||||
|
<url>https://github.com/Vencord/Vesktop/releases/tag/v0.2.3</url>
|
||||||
|
</release>
|
||||||
|
<release version="0.2.2" date="2023-06-21" type="stable">
|
||||||
|
<url>https://github.com/Vencord/Vesktop/releases/tag/v0.2.2</url>
|
||||||
|
</release>
|
||||||
|
<release version="0.2.1" date="2023-06-21" type="stable">
|
||||||
|
<url>https://github.com/Vencord/Vesktop/releases/tag/v0.2.1</url>
|
||||||
|
</release>
|
||||||
|
<release version="0.2.0" date="2023-05-03" type="stable">
|
||||||
|
<url>https://github.com/Vencord/Vesktop/releases/tag/v0.2.0</url>
|
||||||
|
</release>
|
||||||
|
<release version="0.1.9" date="2023-04-27" type="stable">
|
||||||
|
<url>https://github.com/Vencord/Vesktop/releases/tag/v0.1.9</url>
|
||||||
|
</release>
|
||||||
|
<release version="0.1.8" date="2023-04-15" type="stable">
|
||||||
|
<url>https://github.com/Vencord/Vesktop/releases/tag/v0.1.8</url>
|
||||||
|
</release>
|
||||||
|
<release version="0.1.7" date="2023-04-15" type="stable">
|
||||||
|
<url>https://github.com/Vencord/Vesktop/releases/tag/v0.1.7</url>
|
||||||
|
</release>
|
||||||
|
<release version="0.1.6" date="2023-04-11" type="stable">
|
||||||
|
<url>https://github.com/Vencord/Vesktop/releases/tag/v0.1.6</url>
|
||||||
|
</release>
|
||||||
|
<release version="0.1.5" date="2023-04-10" type="stable">
|
||||||
|
<url>https://github.com/Vencord/Vesktop/releases/tag/v0.1.5</url>
|
||||||
|
</release>
|
||||||
|
<release version="0.1.4" date="2023-04-09" type="stable">
|
||||||
|
<url>https://github.com/Vencord/Vesktop/releases/tag/v0.1.4</url>
|
||||||
|
</release>
|
||||||
|
<release version="0.1.3" date="2023-04-06" type="stable">
|
||||||
|
<url>https://github.com/Vencord/Vesktop/releases/tag/v0.1.3</url>
|
||||||
|
</release>
|
||||||
|
<release version="0.1.2" date="2023-04-05" type="stable">
|
||||||
|
<url>https://github.com/Vencord/Vesktop/releases/tag/v0.1.2</url>
|
||||||
|
</release>
|
||||||
|
<release version="0.1.1" date="2023-04-04" type="stable">
|
||||||
|
<url>https://github.com/Vencord/Vesktop/releases/tag/v0.1.1</url>
|
||||||
|
</release>
|
||||||
|
<release version="0.1.0" date="2023-04-04" type="development">
|
||||||
|
<url>https://github.com/Vencord/Vesktop/releases/tag/v0.1.0</url>
|
||||||
|
</release>
|
||||||
|
</releases>
|
||||||
|
<url type="homepage">https://vencord.dev/</url>
|
||||||
|
<url type="bugtracker">https://github.com/Vencord/Vesktop/issues</url>
|
||||||
|
<url type="faq">https://vencord.dev/faq/</url>
|
||||||
|
<url type="help">https://github.com/Vencord/Vesktop/issues</url>
|
||||||
|
<url type="donation">https://github.com/sponsors/Vendicated</url>
|
||||||
|
<url type="vcs-browser">https://github.com/Vencord/Vesktop</url>
|
||||||
|
<categories>
|
||||||
|
<category>InstantMessaging</category>
|
||||||
|
<category>AudioVideo</category>
|
||||||
|
</categories>
|
||||||
|
<requires>
|
||||||
|
<control>pointing</control>
|
||||||
|
<control>keyboard</control>
|
||||||
|
<display_length compare="ge">420</display_length>
|
||||||
|
<internet>always</internet>
|
||||||
|
</requires>
|
||||||
|
<recommends>
|
||||||
|
<control>voice</control>
|
||||||
|
<display_length compare="ge">760</display_length>
|
||||||
|
<display_length compare="le">1200</display_length>
|
||||||
|
<internet>always</internet>
|
||||||
|
</recommends>
|
||||||
|
<supports>
|
||||||
|
<internet>always</internet>
|
||||||
|
</supports>
|
||||||
|
<content_rating type="oars-1.1">
|
||||||
|
<content_attribute id="social-chat">intense</content_attribute>
|
||||||
|
<content_attribute id="social-audio">intense</content_attribute>
|
||||||
|
<content_attribute id="social-contacts">intense</content_attribute>
|
||||||
|
<content_attribute id="social-info">intense</content_attribute>
|
||||||
|
</content_rating>
|
||||||
|
<keywords>
|
||||||
|
<keyword>Discord</keyword>
|
||||||
|
<keyword>Vencord</keyword>
|
||||||
|
<keyword>Vesktop</keyword>
|
||||||
|
<keyword>Privacy</keyword>
|
||||||
|
<keyword>Mod</keyword>
|
||||||
|
</keywords>
|
||||||
|
</component>
|
48
package.json
48
package.json
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "VencordDesktop",
|
"name": "vesktop",
|
||||||
"version": "0.4.3",
|
"version": "1.5.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"description": "",
|
"description": "",
|
||||||
"keywords": [],
|
"keywords": [],
|
||||||
|
@ -20,46 +20,48 @@
|
||||||
"start:watch": "pnpm build:dev && tsx scripts/startWatch.mts",
|
"start:watch": "pnpm build:dev && tsx scripts/startWatch.mts",
|
||||||
"test": "pnpm lint && pnpm testTypes",
|
"test": "pnpm lint && pnpm testTypes",
|
||||||
"testTypes": "tsc --noEmit",
|
"testTypes": "tsc --noEmit",
|
||||||
"watch": "pnpm build --watch"
|
"watch": "pnpm build --watch",
|
||||||
|
"updateMeta": "tsx scripts/utils/updateMeta.mts"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"arrpc": "github:OpenAsar/arrpc#89f4da610ccfac93f461826a446a17cd3b23953d"
|
"arrpc": "github:OpenAsar/arrpc#98879cae0565e6fce34e4cb6f544bf42c6a7e7c8"
|
||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"@vencord/venmic": "^2.1.2"
|
"@vencord/venmic": "^3.2.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@fal-works/esbuild-plugin-global-externals": "^2.1.2",
|
"@fal-works/esbuild-plugin-global-externals": "^2.1.2",
|
||||||
"@types/node": "^20.8.4",
|
"@types/node": "^20.11.2",
|
||||||
"@types/react": "^18.2.28",
|
"@types/react": "^18.2.48",
|
||||||
"@typescript-eslint/eslint-plugin": "^6.7.5",
|
"@typescript-eslint/eslint-plugin": "^6.19.0",
|
||||||
"@typescript-eslint/parser": "^6.7.5",
|
"@typescript-eslint/parser": "^6.19.0",
|
||||||
"@vencord/types": "^0.1.2",
|
"@vencord/types": "^0.1.2",
|
||||||
"dotenv": "^16.3.1",
|
"dotenv": "^16.3.1",
|
||||||
"electron": "^27.0.0",
|
"electron": "^28.1.3",
|
||||||
"electron-builder": "^24.6.4",
|
"electron-builder": "^24.9.1",
|
||||||
"esbuild": "^0.19.4",
|
"esbuild": "^0.19.11",
|
||||||
"eslint": "^8.51.0",
|
"eslint": "^8.56.0",
|
||||||
"eslint-config-prettier": "^9.0.0",
|
"eslint-config-prettier": "^9.1.0",
|
||||||
"eslint-import-resolver-alias": "^1.1.2",
|
"eslint-import-resolver-alias": "^1.1.2",
|
||||||
"eslint-plugin-license-header": "^0.6.0",
|
"eslint-plugin-license-header": "^0.6.0",
|
||||||
"eslint-plugin-path-alias": "^1.0.0",
|
"eslint-plugin-path-alias": "^1.0.0",
|
||||||
"eslint-plugin-prettier": "^5.0.1",
|
"eslint-plugin-prettier": "^5.1.3",
|
||||||
"eslint-plugin-simple-import-sort": "^10.0.0",
|
"eslint-plugin-simple-import-sort": "^10.0.0",
|
||||||
"eslint-plugin-unused-imports": "^3.0.0",
|
"eslint-plugin-unused-imports": "^3.0.0",
|
||||||
"prettier": "^3.0.3",
|
"prettier": "^3.2.2",
|
||||||
"source-map-support": "^0.5.21",
|
"source-map-support": "^0.5.21",
|
||||||
"tsx": "^3.13.0",
|
"tsx": "^4.7.0",
|
||||||
"type-fest": "^4.4.0",
|
"type-fest": "^4.9.0",
|
||||||
"typescript": "^5.2.2"
|
"typescript": "^5.3.3",
|
||||||
|
"xml-formatter": "^3.6.0"
|
||||||
},
|
},
|
||||||
"packageManager": "pnpm@8.6.11",
|
"packageManager": "pnpm@8.11.0",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18",
|
"node": ">=18",
|
||||||
"pnpm": ">=8"
|
"pnpm": ">=8"
|
||||||
},
|
},
|
||||||
"build": {
|
"build": {
|
||||||
"appId": "dev.vencord.desktop",
|
"appId": "dev.vencord.vesktop",
|
||||||
"productName": "Vesktop",
|
"productName": "Vesktop",
|
||||||
"files": [
|
"files": [
|
||||||
"!*",
|
"!*",
|
||||||
|
@ -108,9 +110,7 @@
|
||||||
"GenericName": "Internet Messenger",
|
"GenericName": "Internet Messenger",
|
||||||
"Type": "Application",
|
"Type": "Application",
|
||||||
"Categories": "Network;InstantMessaging;Chat;",
|
"Categories": "Network;InstantMessaging;Chat;",
|
||||||
"Keywords": "discord;vencord;electron;chat;",
|
"Keywords": "discord;vencord;electron;chat;"
|
||||||
"WMClass": "VencordDesktop",
|
|
||||||
"StartupWMClass": "VencordDesktop"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"mac": {
|
"mac": {
|
||||||
|
|
1499
pnpm-lock.yaml
generated
1499
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load diff
|
@ -78,8 +78,6 @@ await Promise.all([
|
||||||
inject: ["./scripts/build/injectReact.mjs"],
|
inject: ["./scripts/build/injectReact.mjs"],
|
||||||
jsxFactory: "VencordCreateElement",
|
jsxFactory: "VencordCreateElement",
|
||||||
jsxFragment: "VencordFragment",
|
jsxFragment: "VencordFragment",
|
||||||
// Work around https://github.com/evanw/esbuild/issues/2460
|
|
||||||
tsconfig: "./scripts/build/tsconfig.esbuild.json",
|
|
||||||
external: ["@vencord/types/*"],
|
external: ["@vencord/types/*"],
|
||||||
plugins: [vencordDep],
|
plugins: [vencordDep],
|
||||||
footer: { js: "//# sourceURL=VCDRenderer" }
|
footer: { js: "//# sourceURL=VCDRenderer" }
|
||||||
|
|
|
@ -1,7 +0,0 @@
|
||||||
// Work around https://github.com/evanw/esbuild/issues/2460
|
|
||||||
{
|
|
||||||
"extends": "../../tsconfig.json",
|
|
||||||
"compilerOptions": {
|
|
||||||
"jsx": "react"
|
|
||||||
}
|
|
||||||
}
|
|
93
scripts/utils/updateMeta.mts
Normal file
93
scripts/utils/updateMeta.mts
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
/*
|
||||||
|
* 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 { promises as fs } from "node:fs";
|
||||||
|
|
||||||
|
import { DOMParser, XMLSerializer } from "@xmldom/xmldom";
|
||||||
|
import xmlFormat from "xml-formatter";
|
||||||
|
|
||||||
|
function generateDescription(description: string, descriptionNode: Element) {
|
||||||
|
const lines = description.replace(/\r/g, "").split("\n");
|
||||||
|
let currentList: Element | null = null;
|
||||||
|
|
||||||
|
for (let i = 0; i < lines.length; i++) {
|
||||||
|
const line = lines[i];
|
||||||
|
|
||||||
|
if (line.includes("New Contributors")) {
|
||||||
|
// we're done, don't parse any more since the new contributors section is the last one
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line.startsWith("## ")) {
|
||||||
|
const pNode = descriptionNode.ownerDocument.createElement("p");
|
||||||
|
pNode.textContent = line.slice(3);
|
||||||
|
descriptionNode.appendChild(pNode);
|
||||||
|
} else if (line.startsWith("* ")) {
|
||||||
|
const liNode = descriptionNode.ownerDocument.createElement("li");
|
||||||
|
liNode.textContent = line.slice(2).split("in https://github.com")[0].trim(); // don't include links to github
|
||||||
|
|
||||||
|
if (!currentList) {
|
||||||
|
currentList = descriptionNode.ownerDocument.createElement("ul");
|
||||||
|
}
|
||||||
|
|
||||||
|
currentList.appendChild(liNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentList && !lines[i + 1].startsWith("* ")) {
|
||||||
|
descriptionNode.appendChild(currentList);
|
||||||
|
currentList = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const latestReleaseInformation = await fetch("https://api.github.com/repos/Vencord/Vesktop/releases/latest", {
|
||||||
|
headers: {
|
||||||
|
Accept: "application/vnd.github+json",
|
||||||
|
"X-Github-Api-Version": "2022-11-28"
|
||||||
|
}
|
||||||
|
}).then(res => res.json());
|
||||||
|
|
||||||
|
const metaInfo = await fs.readFile("./meta/dev.vencord.Vesktop.metainfo.xml", "utf-8");
|
||||||
|
|
||||||
|
const parser = new DOMParser().parseFromString(metaInfo, "text/xml");
|
||||||
|
|
||||||
|
const releaseList = parser.getElementsByTagName("releases")[0];
|
||||||
|
|
||||||
|
for (let i = 0; i < releaseList.childNodes.length; i++) {
|
||||||
|
const release = releaseList.childNodes[i] as Element;
|
||||||
|
|
||||||
|
if (release.nodeType === 1 && release.getAttribute("version") === latestReleaseInformation.name) {
|
||||||
|
console.log("Latest release already added, nothing to be done");
|
||||||
|
process.exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const release = parser.createElement("release");
|
||||||
|
release.setAttribute("version", latestReleaseInformation.name);
|
||||||
|
release.setAttribute("date", latestReleaseInformation.published_at.split("T")[0]);
|
||||||
|
release.setAttribute("type", "stable");
|
||||||
|
|
||||||
|
const releaseUrl = parser.createElement("url");
|
||||||
|
releaseUrl.textContent = latestReleaseInformation.html_url;
|
||||||
|
|
||||||
|
release.appendChild(releaseUrl);
|
||||||
|
|
||||||
|
const description = parser.createElement("description");
|
||||||
|
|
||||||
|
// we're not using a full markdown parser here since we don't have a lot of formatting options to begin with
|
||||||
|
generateDescription(latestReleaseInformation.body, description);
|
||||||
|
|
||||||
|
release.appendChild(description);
|
||||||
|
|
||||||
|
releaseList.insertBefore(release, releaseList.childNodes[0]);
|
||||||
|
|
||||||
|
const output = xmlFormat(new XMLSerializer().serializeToString(parser), {
|
||||||
|
lineSeparator: "\n",
|
||||||
|
collapseContent: true,
|
||||||
|
indentation: " "
|
||||||
|
});
|
||||||
|
|
||||||
|
await fs.writeFile("./meta/dev.vencord.Vesktop.metainfo.xml", output, "utf-8");
|
|
@ -5,9 +5,29 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { app } from "electron";
|
import { app } from "electron";
|
||||||
|
import { existsSync, readdirSync, renameSync, rmdirSync } from "fs";
|
||||||
import { join } from "path";
|
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_SETTINGS_DIR = join(DATA_DIR, "settings");
|
||||||
export const VENCORD_QUICKCSS_FILE = join(VENCORD_SETTINGS_DIR, "quickCss.css");
|
export const VENCORD_QUICKCSS_FILE = join(VENCORD_SETTINGS_DIR, "quickCss.css");
|
||||||
export const VENCORD_SETTINGS_FILE = join(VENCORD_SETTINGS_DIR, "settings.json");
|
export const VENCORD_SETTINGS_FILE = join(VENCORD_SETTINGS_DIR, "settings.json");
|
||||||
|
@ -26,11 +46,13 @@ export const MIN_HEIGHT = 500;
|
||||||
export const DEFAULT_WIDTH = 1280;
|
export const DEFAULT_WIDTH = 1280;
|
||||||
export const DEFAULT_HEIGHT = 720;
|
export const DEFAULT_HEIGHT = 720;
|
||||||
|
|
||||||
|
export const DISCORD_HOSTNAMES = ["discord.com", "canary.discord.com", "ptb.discord.com"];
|
||||||
|
|
||||||
const UserAgents = {
|
const UserAgents = {
|
||||||
darwin: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36",
|
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/118.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",
|
||||||
windows:
|
windows:
|
||||||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36"
|
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
|
||||||
};
|
};
|
||||||
|
|
||||||
export const UserAgent = UserAgents[process.platform] || UserAgents.windows;
|
export const UserAgent = UserAgents[process.platform] || UserAgents.windows;
|
||||||
|
|
|
@ -14,7 +14,7 @@ import { ICON_PATH, VIEW_DIR } from "shared/paths";
|
||||||
import { autoStart } from "./autoStart";
|
import { autoStart } from "./autoStart";
|
||||||
import { DATA_DIR } from "./constants";
|
import { DATA_DIR } from "./constants";
|
||||||
import { createWindows } from "./mainWindow";
|
import { createWindows } from "./mainWindow";
|
||||||
import { Settings } from "./settings";
|
import { Settings, State } from "./settings";
|
||||||
import { makeLinksOpenExternally } from "./utils/makeLinksOpenExternally";
|
import { makeLinksOpenExternally } from "./utils/makeLinksOpenExternally";
|
||||||
|
|
||||||
interface Data {
|
interface Data {
|
||||||
|
@ -44,9 +44,9 @@ export function createFirstLaunchTour() {
|
||||||
if (!msg.startsWith("form:")) return;
|
if (!msg.startsWith("form:")) return;
|
||||||
const data = JSON.parse(msg.slice(5)) as Data;
|
const data = JSON.parse(msg.slice(5)) as Data;
|
||||||
|
|
||||||
|
State.store.firstLaunch = false;
|
||||||
Settings.store.minimizeToTray = data.minimizeToTray;
|
Settings.store.minimizeToTray = data.minimizeToTray;
|
||||||
Settings.store.discordBranch = data.discordBranch;
|
Settings.store.discordBranch = data.discordBranch;
|
||||||
Settings.store.firstLaunch = false;
|
|
||||||
Settings.store.arRPC = data.richPresence;
|
Settings.store.arRPC = data.richPresence;
|
||||||
|
|
||||||
if (data.autoStart) autoStart.enable();
|
if (data.autoStart) autoStart.enable();
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
import "./ipc";
|
import "./ipc";
|
||||||
|
|
||||||
import { app, BrowserWindow } from "electron";
|
import { app, BrowserWindow, nativeTheme } from "electron";
|
||||||
import { checkUpdates } from "updater/main";
|
import { checkUpdates } from "updater/main";
|
||||||
|
|
||||||
import { DATA_DIR } from "./constants";
|
import { DATA_DIR } from "./constants";
|
||||||
|
@ -14,7 +14,8 @@ import { createFirstLaunchTour } from "./firstLaunch";
|
||||||
import { createWindows, mainWin } from "./mainWindow";
|
import { createWindows, mainWin } from "./mainWindow";
|
||||||
import { registerMediaPermissionsHandler } from "./mediaPermissions";
|
import { registerMediaPermissionsHandler } from "./mediaPermissions";
|
||||||
import { registerScreenShareHandler } from "./screenShare";
|
import { registerScreenShareHandler } from "./screenShare";
|
||||||
import { Settings } from "./settings";
|
import { Settings, State } from "./settings";
|
||||||
|
import { isDeckGameMode } from "./utils/steamOS";
|
||||||
|
|
||||||
if (IS_DEV) {
|
if (IS_DEV) {
|
||||||
require("source-map-support").install();
|
require("source-map-support").install();
|
||||||
|
@ -24,8 +25,9 @@ if (IS_DEV) {
|
||||||
process.env.VENCORD_USER_DATA_DIR = DATA_DIR;
|
process.env.VENCORD_USER_DATA_DIR = DATA_DIR;
|
||||||
|
|
||||||
function init() {
|
function init() {
|
||||||
const { disableSmoothScroll } = Settings.store;
|
const { disableSmoothScroll, hardwareAcceleration } = Settings.store;
|
||||||
|
|
||||||
|
if (hardwareAcceleration === false) app.disableHardwareAcceleration();
|
||||||
if (disableSmoothScroll) {
|
if (disableSmoothScroll) {
|
||||||
app.commandLine.appendSwitch("disable-smooth-scrolling");
|
app.commandLine.appendSwitch("disable-smooth-scrolling");
|
||||||
}
|
}
|
||||||
|
@ -42,6 +44,9 @@ function init() {
|
||||||
"WinRetrieveSuggestionsOnlyOnDemand,HardwareMediaKeyHandling,MediaSessionService,WidgetLayering"
|
"WinRetrieveSuggestionsOnlyOnDemand,HardwareMediaKeyHandling,MediaSessionService,WidgetLayering"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// In the Flatpak on SteamOS the theme is detected as light, but SteamOS only has a dark mode, so we just override it
|
||||||
|
if (isDeckGameMode) nativeTheme.themeSource = "dark";
|
||||||
|
|
||||||
app.on("second-instance", (_event, _cmdLine, _cwd, data: any) => {
|
app.on("second-instance", (_event, _cmdLine, _cwd, data: any) => {
|
||||||
if (data.IS_DEV) app.quit();
|
if (data.IS_DEV) app.quit();
|
||||||
else if (mainWin) {
|
else if (mainWin) {
|
||||||
|
@ -53,7 +58,7 @@ function init() {
|
||||||
|
|
||||||
app.whenReady().then(async () => {
|
app.whenReady().then(async () => {
|
||||||
checkUpdates();
|
checkUpdates();
|
||||||
if (process.platform === "win32") app.setAppUserModelId("dev.vencord.desktop");
|
if (process.platform === "win32") app.setAppUserModelId("dev.vencord.vesktop");
|
||||||
|
|
||||||
registerScreenShareHandler();
|
registerScreenShareHandler();
|
||||||
registerMediaPermissionsHandler();
|
registerMediaPermissionsHandler();
|
||||||
|
@ -79,7 +84,7 @@ if (!app.requestSingleInstanceLock({ IS_DEV })) {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function bootstrap() {
|
async function bootstrap() {
|
||||||
if (!Object.hasOwn(Settings.store, "firstLaunch")) {
|
if (!Object.hasOwn(State.store, "firstLaunch")) {
|
||||||
createFirstLaunchTour();
|
createFirstLaunchTour();
|
||||||
} else {
|
} else {
|
||||||
createWindows();
|
createWindows();
|
||||||
|
|
|
@ -4,10 +4,10 @@
|
||||||
* Copyright (c) 2023 Vendicated and Vencord contributors
|
* 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 { 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 { mkdirSync, readFileSync, watch } from "fs";
|
||||||
import { open, readFile } from "fs/promises";
|
import { open, readFile } from "fs/promises";
|
||||||
import { release } from "os";
|
import { release } from "os";
|
||||||
|
@ -21,6 +21,7 @@ import { VENCORD_FILES_DIR, VENCORD_QUICKCSS_FILE, VENCORD_THEMES_DIR } from "./
|
||||||
import { mainWin } from "./mainWindow";
|
import { mainWin } from "./mainWindow";
|
||||||
import { Settings } from "./settings";
|
import { Settings } from "./settings";
|
||||||
import { handle, handleSync } from "./utils/ipcWrappers";
|
import { handle, handleSync } from "./utils/ipcWrappers";
|
||||||
|
import { isDeckGameMode, showGamePage } from "./utils/steamOS";
|
||||||
import { isValidVencordInstall } from "./utils/vencordLoader";
|
import { isValidVencordInstall } from "./utils/vencordLoader";
|
||||||
|
|
||||||
handleSync(IpcEvents.GET_VENCORD_PRELOAD_FILE, () => join(VENCORD_FILES_DIR, "vencordDesktopPreload.js"));
|
handleSync(IpcEvents.GET_VENCORD_PRELOAD_FILE, () => join(VENCORD_FILES_DIR, "vencordDesktopPreload.js"));
|
||||||
|
@ -47,11 +48,14 @@ handle(IpcEvents.SET_SETTINGS, (_, settings: typeof Settings.store, path?: strin
|
||||||
Settings.setData(settings, path);
|
Settings.setData(settings, path);
|
||||||
});
|
});
|
||||||
|
|
||||||
handle(IpcEvents.RELAUNCH, () => {
|
handle(IpcEvents.RELAUNCH, async () => {
|
||||||
const options: RelaunchOptions = {
|
const options: RelaunchOptions = {
|
||||||
args: process.argv.slice(1).concat(["--relaunch"])
|
args: process.argv.slice(1).concat(["--relaunch"])
|
||||||
};
|
};
|
||||||
if (app.isPackaged && process.env.APPIMAGE) {
|
if (isDeckGameMode) {
|
||||||
|
// We can't properly relaunch when running under gamescope, but we can at least navigate to our page in Steam.
|
||||||
|
await showGamePage();
|
||||||
|
} else if (app.isPackaged && process.env.APPIMAGE) {
|
||||||
execFile(process.env.APPIMAGE, options.args);
|
execFile(process.env.APPIMAGE, options.args);
|
||||||
} else {
|
} else {
|
||||||
app.relaunch(options);
|
app.relaunch(options);
|
||||||
|
@ -116,6 +120,13 @@ handle(IpcEvents.SELECT_VENCORD_DIR, async () => {
|
||||||
|
|
||||||
handle(IpcEvents.SET_BADGE_COUNT, (_, count: number) => setBadgeCount(count));
|
handle(IpcEvents.SET_BADGE_COUNT, (_, count: number) => setBadgeCount(count));
|
||||||
|
|
||||||
|
handle(IpcEvents.CLIPBOARD_COPY_IMAGE, async (_, buf: ArrayBuffer, src: string) => {
|
||||||
|
clipboard.write({
|
||||||
|
html: `<img src="${src.replaceAll('"', '\\"')}">`,
|
||||||
|
image: nativeImage.createFromBuffer(Buffer.from(buf))
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
function readCss() {
|
function readCss() {
|
||||||
return readFile(VENCORD_QUICKCSS_FILE, "utf-8").catch(() => "");
|
return readFile(VENCORD_QUICKCSS_FILE, "utf-8").catch(() => "");
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,7 @@ import {
|
||||||
UserAgent,
|
UserAgent,
|
||||||
VENCORD_FILES_DIR
|
VENCORD_FILES_DIR
|
||||||
} from "./constants";
|
} from "./constants";
|
||||||
import { Settings, VencordSettings } from "./settings";
|
import { Settings, State, VencordSettings } from "./settings";
|
||||||
import { createSplashWindow } from "./splash";
|
import { createSplashWindow } from "./splash";
|
||||||
import { makeLinksOpenExternally } from "./utils/makeLinksOpenExternally";
|
import { makeLinksOpenExternally } from "./utils/makeLinksOpenExternally";
|
||||||
import { applyDeckKeyboardFix, askToApplySteamLayout, isDeckGameMode } from "./utils/steamOS";
|
import { applyDeckKeyboardFix, askToApplySteamLayout, isDeckGameMode } from "./utils/steamOS";
|
||||||
|
@ -78,8 +78,7 @@ function initTray(win: BrowserWindow) {
|
||||||
label: "Open",
|
label: "Open",
|
||||||
click() {
|
click() {
|
||||||
win.show();
|
win.show();
|
||||||
},
|
}
|
||||||
enabled: false
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "About",
|
label: "About",
|
||||||
|
@ -122,14 +121,6 @@ function initTray(win: BrowserWindow) {
|
||||||
tray.setToolTip("Vesktop");
|
tray.setToolTip("Vesktop");
|
||||||
tray.setContextMenu(trayMenu);
|
tray.setContextMenu(trayMenu);
|
||||||
tray.on("click", () => win.show());
|
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) {
|
async function clearData(win: BrowserWindow) {
|
||||||
|
@ -210,7 +201,6 @@ function initMenuBar(win: BrowserWindow) {
|
||||||
type: "separator"
|
type: "separator"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Hide Vesktop", // Should probably remove the label, but it says "Hide VencordDesktop" instead of "Hide Vesktop"
|
|
||||||
role: "hide"
|
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.
|
// We want the default window behaivour to apply in game mode since it expects everything to be fullscreen and maximized.
|
||||||
if (isDeckGameMode) return {};
|
if (isDeckGameMode) return {};
|
||||||
|
|
||||||
const { x, y, width, height } = Settings.store.windowBounds ?? {};
|
const { x, y, width, height } = State.store.windowBounds ?? {};
|
||||||
|
|
||||||
const options = {
|
const options = {
|
||||||
width: width ?? DEFAULT_WIDTH,
|
width: width ?? DEFAULT_WIDTH,
|
||||||
|
@ -313,8 +303,8 @@ function getDarwinOptions(): BrowserWindowConstructorOptions {
|
||||||
|
|
||||||
function initWindowBoundsListeners(win: BrowserWindow) {
|
function initWindowBoundsListeners(win: BrowserWindow) {
|
||||||
const saveState = () => {
|
const saveState = () => {
|
||||||
Settings.store.maximized = win.isMaximized();
|
State.store.maximized = win.isMaximized();
|
||||||
Settings.store.minimized = win.isMinimized();
|
State.store.minimized = win.isMinimized();
|
||||||
};
|
};
|
||||||
|
|
||||||
win.on("maximize", saveState);
|
win.on("maximize", saveState);
|
||||||
|
@ -322,7 +312,7 @@ function initWindowBoundsListeners(win: BrowserWindow) {
|
||||||
win.on("unmaximize", saveState);
|
win.on("unmaximize", saveState);
|
||||||
|
|
||||||
const saveBounds = () => {
|
const saveBounds = () => {
|
||||||
Settings.store.windowBounds = win.getBounds();
|
State.store.windowBounds = win.getBounds();
|
||||||
};
|
};
|
||||||
|
|
||||||
win.on("resize", saveBounds);
|
win.on("resize", saveBounds);
|
||||||
|
@ -375,11 +365,11 @@ function createMainWindow() {
|
||||||
removeSettingsListeners();
|
removeSettingsListeners();
|
||||||
removeVencordSettingsListeners();
|
removeVencordSettingsListeners();
|
||||||
|
|
||||||
const { staticTitle, transparencyOption, enableMenu, discordWindowsTitleBar } = Settings.store;
|
const { staticTitle, transparencyOption, enableMenu, customTitleBar } = Settings.store;
|
||||||
|
|
||||||
const { frameless } = VencordSettings.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({
|
const win = (mainWin = new BrowserWindow({
|
||||||
show: false,
|
show: false,
|
||||||
|
@ -397,7 +387,12 @@ function createMainWindow() {
|
||||||
...(transparencyOption &&
|
...(transparencyOption &&
|
||||||
transparencyOption !== "none" && {
|
transparencyOption !== "none" && {
|
||||||
backgroundColor: "#00000000",
|
backgroundColor: "#00000000",
|
||||||
backgroundMaterial: transparencyOption,
|
backgroundMaterial: transparencyOption
|
||||||
|
}),
|
||||||
|
// Fix transparencyOption for custom discord titlebar
|
||||||
|
...(customTitleBar &&
|
||||||
|
transparencyOption &&
|
||||||
|
transparencyOption !== "none" && {
|
||||||
transparent: true
|
transparent: true
|
||||||
}),
|
}),
|
||||||
...(staticTitle && { title: "Vesktop" }),
|
...(staticTitle && { title: "Vesktop" }),
|
||||||
|
@ -443,7 +438,8 @@ function createMainWindow() {
|
||||||
const runVencordMain = once(() => require(join(VENCORD_FILES_DIR, "vencordDesktopMain.js")));
|
const runVencordMain = once(() => require(join(VENCORD_FILES_DIR, "vencordDesktopMain.js")));
|
||||||
|
|
||||||
export async function createWindows() {
|
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
|
// SteamOS letterboxes and scales it terribly, so just full screen it
|
||||||
if (isDeckGameMode) splash.setFullScreen(true);
|
if (isDeckGameMode) splash.setFullScreen(true);
|
||||||
await ensureVencordFiles();
|
await ensureVencordFiles();
|
||||||
|
@ -453,10 +449,10 @@ export async function createWindows() {
|
||||||
|
|
||||||
mainWin.webContents.on("did-finish-load", () => {
|
mainWin.webContents.on("did-finish-load", () => {
|
||||||
splash.destroy();
|
splash.destroy();
|
||||||
mainWin!.show();
|
|
||||||
|
|
||||||
if (Settings.store.maximized && !isDeckGameMode) {
|
if (!startMinimized) {
|
||||||
mainWin!.maximize();
|
mainWin!.show();
|
||||||
|
if (State.store.maximized && !isDeckGameMode) mainWin!.maximize();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isDeckGameMode) {
|
if (isDeckGameMode) {
|
||||||
|
@ -465,6 +461,12 @@ export async function createWindows() {
|
||||||
|
|
||||||
askToApplySteamLayout(mainWin);
|
askToApplySteamLayout(mainWin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mainWin.once("show", () => {
|
||||||
|
if (State.store.maximized && !mainWin!.isMaximized() && !isDeckGameMode) {
|
||||||
|
mainWin!.maximize();
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
initArRPC();
|
initArRPC();
|
||||||
|
|
|
@ -4,14 +4,15 @@
|
||||||
* Copyright (c) 2023 Vendicated and Vencord contributors
|
* 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 { 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 { SettingsStore } from "shared/utils/SettingsStore";
|
||||||
|
|
||||||
import { DATA_DIR, VENCORD_SETTINGS_FILE } from "./constants";
|
import { DATA_DIR, VENCORD_SETTINGS_FILE } from "./constants";
|
||||||
|
|
||||||
const SETTINGS_FILE = join(DATA_DIR, "settings.json");
|
const SETTINGS_FILE = join(DATA_DIR, "settings.json");
|
||||||
|
const STATE_FILE = join(DATA_DIR, "state.json");
|
||||||
|
|
||||||
function loadSettings<T extends object = any>(file: string, name: string) {
|
function loadSettings<T extends object = any>(file: string, name: string) {
|
||||||
let settings = {} as T;
|
let settings = {} as T;
|
||||||
|
@ -20,7 +21,7 @@ function loadSettings<T extends object = any>(file: string, name: string) {
|
||||||
try {
|
try {
|
||||||
settings = JSON.parse(content);
|
settings = JSON.parse(content);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(`Failed to parse ${name} settings.json:`, err);
|
console.error(`Failed to parse ${name}.json:`, err);
|
||||||
}
|
}
|
||||||
} catch {}
|
} catch {}
|
||||||
|
|
||||||
|
@ -33,5 +34,31 @@ function loadSettings<T extends object = any>(file: string, name: string) {
|
||||||
return store;
|
return store;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const Settings = loadSettings<TSettings>(SETTINGS_FILE, "Vesktop");
|
export const Settings = loadSettings<TSettings>(SETTINGS_FILE, "Vesktop settings");
|
||||||
export const VencordSettings = loadSettings<any>(VENCORD_SETTINGS_FILE, "Vencord");
|
if (Object.hasOwn(Settings.plain, "discordWindowsTitleBar")) {
|
||||||
|
Settings.plain.customTitleBar = Settings.plain.discordWindowsTitleBar;
|
||||||
|
delete Settings.plain.discordWindowsTitleBar;
|
||||||
|
Settings.markAsChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
export const VencordSettings = loadSettings<any>(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<TState>(STATE_FILE, "Vesktop state");
|
||||||
|
|
|
@ -11,10 +11,11 @@ import { ICON_PATH, VIEW_DIR } from "shared/paths";
|
||||||
|
|
||||||
import { Settings } from "./settings";
|
import { Settings } from "./settings";
|
||||||
|
|
||||||
export function createSplashWindow() {
|
export function createSplashWindow(startMinimized = false) {
|
||||||
const splash = new BrowserWindow({
|
const splash = new BrowserWindow({
|
||||||
...SplashProps,
|
...SplashProps,
|
||||||
icon: ICON_PATH
|
icon: ICON_PATH,
|
||||||
|
show: !startMinimized
|
||||||
});
|
});
|
||||||
|
|
||||||
splash.loadFile(join(VIEW_DIR, "splash.html"));
|
splash.loadFile(join(VIEW_DIR, "splash.html"));
|
||||||
|
|
|
@ -5,20 +5,14 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { ipcMain, IpcMainEvent, IpcMainInvokeEvent, WebFrameMain } from "electron";
|
import { ipcMain, IpcMainEvent, IpcMainInvokeEvent, WebFrameMain } from "electron";
|
||||||
|
import { DISCORD_HOSTNAMES } from "main/constants";
|
||||||
import { IpcEvents } from "shared/IpcEvents";
|
import { IpcEvents } from "shared/IpcEvents";
|
||||||
|
|
||||||
export function validateSender(frame: WebFrameMain) {
|
export function validateSender(frame: WebFrameMain) {
|
||||||
const { hostname, protocol } = new URL(frame.url);
|
const { hostname, protocol } = new URL(frame.url);
|
||||||
if (protocol === "file:") return;
|
if (protocol === "file:") return;
|
||||||
|
|
||||||
switch (hostname) {
|
if (!DISCORD_HOSTNAMES.includes(hostname)) throw new Error("ipc: Disallowed host " + hostname);
|
||||||
case "discord.com":
|
|
||||||
case "ptb.discord.com":
|
|
||||||
case "canary.discord.com":
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new Error("ipc: Disallowed host " + hostname);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function handleSync(event: IpcEvents, cb: (e: IpcMainEvent, ...args: any[]) => any) {
|
export function handleSync(event: IpcEvents, cb: (e: IpcMainEvent, ...args: any[]) => any) {
|
||||||
|
|
|
@ -5,22 +5,20 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { BrowserWindow, shell } from "electron";
|
import { BrowserWindow, shell } from "electron";
|
||||||
|
import { DISCORD_HOSTNAMES } from "main/constants";
|
||||||
|
|
||||||
import { Settings } from "../settings";
|
import { Settings } from "../settings";
|
||||||
|
import { createOrFocusPopup, setupPopout } from "./popout";
|
||||||
|
import { execSteamURL, isDeckGameMode, steamOpenURL } from "./steamOS";
|
||||||
|
|
||||||
export function makeLinksOpenExternally(win: BrowserWindow) {
|
export function handleExternalUrl(url: string, protocol?: string): { action: "deny" | "allow" } {
|
||||||
win.webContents.setWindowOpenHandler(({ url }) => {
|
if (protocol == null) {
|
||||||
switch (url) {
|
|
||||||
case "about:blank":
|
|
||||||
case "https://discord.com/popout":
|
|
||||||
return { action: "allow" };
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
var { protocol } = new URL(url);
|
protocol = new URL(url).protocol;
|
||||||
} catch {
|
} catch {
|
||||||
return { action: "deny" };
|
return { action: "deny" };
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch (protocol) {
|
switch (protocol) {
|
||||||
case "http:":
|
case "http:":
|
||||||
|
@ -30,11 +28,44 @@ export function makeLinksOpenExternally(win: BrowserWindow) {
|
||||||
}
|
}
|
||||||
// eslint-disable-next-line no-fallthrough
|
// eslint-disable-next-line no-fallthrough
|
||||||
case "mailto:":
|
case "mailto:":
|
||||||
case "steam:":
|
|
||||||
case "spotify:":
|
case "spotify:":
|
||||||
|
if (isDeckGameMode) {
|
||||||
|
steamOpenURL(url);
|
||||||
|
} else {
|
||||||
shell.openExternal(url);
|
shell.openExternal(url);
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
case "steam:":
|
||||||
|
if (isDeckGameMode) {
|
||||||
|
execSteamURL(url);
|
||||||
|
} else {
|
||||||
|
shell.openExternal(url);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
return { action: "deny" };
|
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" };
|
||||||
|
}
|
||||||
|
|
||||||
|
if (frameName.startsWith("DISCORD_") && pathname === "/popout" && DISCORD_HOSTNAMES.includes(hostname)) {
|
||||||
|
return createOrFocusPopup(frameName, features);
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
112
src/main/utils/popout.ts
Normal file
112
src/main/utils/popout.ts
Normal file
|
@ -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<string, BrowserWindow>();
|
||||||
|
|
||||||
|
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 <const>{ action: "deny" };
|
||||||
|
}
|
||||||
|
|
||||||
|
return <const>{
|
||||||
|
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);
|
||||||
|
});
|
||||||
|
}
|
|
@ -4,15 +4,12 @@
|
||||||
* Copyright (c) 2023 Vendicated and Vencord contributors
|
* Copyright (c) 2023 Vendicated and Vencord contributors
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { exec as callbackExec } from "child_process";
|
|
||||||
import { BrowserWindow, dialog } from "electron";
|
import { BrowserWindow, dialog } from "electron";
|
||||||
import { sleep } from "shared/utils/sleep";
|
import { writeFile } from "fs/promises";
|
||||||
import { promisify } from "util";
|
import { join } from "path";
|
||||||
|
|
||||||
import { MessageBoxChoice } from "../constants";
|
import { MessageBoxChoice } from "../constants";
|
||||||
import { Settings } from "../settings";
|
import { State } from "../settings";
|
||||||
|
|
||||||
const exec = promisify(callbackExec);
|
|
||||||
|
|
||||||
// Bump this to re-show the prompt
|
// Bump this to re-show the prompt
|
||||||
const layoutVersion = 2;
|
const layoutVersion = 2;
|
||||||
|
@ -20,6 +17,8 @@ const layoutVersion = 2;
|
||||||
const layoutId = "3080264545"; // Vesktop Layout v2
|
const layoutId = "3080264545"; // Vesktop Layout v2
|
||||||
const numberRegex = /^[0-9]*$/;
|
const numberRegex = /^[0-9]*$/;
|
||||||
|
|
||||||
|
let steamPipeQueue = Promise.resolve();
|
||||||
|
|
||||||
export const isDeckGameMode = process.env.SteamOS === "1" && process.env.SteamGamepadUI === "1";
|
export const isDeckGameMode = process.env.SteamOS === "1" && process.env.SteamGamepadUI === "1";
|
||||||
|
|
||||||
export function applyDeckKeyboardFix() {
|
export function applyDeckKeyboardFix() {
|
||||||
|
@ -42,23 +41,37 @@ function getAppId(): string | null {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function execSteamURL(url: string): Promise<void> {
|
export function execSteamURL(url: string) {
|
||||||
await exec(`steam -ifrunning ${url}`);
|
// This doesn't allow arbitrary execution despite the weird syntax.
|
||||||
|
steamPipeQueue = steamPipeQueue.then(() =>
|
||||||
|
writeFile(
|
||||||
|
join(process.env.HOME || "/home/deck", ".steam", "steam.pipe"),
|
||||||
|
// replace ' to prevent argument injection
|
||||||
|
`'${process.env.HOME}/.local/share/Steam/ubuntu12_32/steam' '-ifrunning' '${url.replaceAll("'", "%27")}'\n`,
|
||||||
|
"utf-8"
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function steamOpenURL(url: string) {
|
||||||
|
execSteamURL(`steam://openurl/${url}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function showGamePage() {
|
||||||
|
const appId = getAppId();
|
||||||
|
if (!appId) return;
|
||||||
|
await execSteamURL(`steam://nav/games/details/${appId}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function showLayout(appId: string) {
|
async function showLayout(appId: string) {
|
||||||
await execSteamURL(`steam://controllerconfig/${appId}/${layoutId}`);
|
execSteamURL(`steam://controllerconfig/${appId}/${layoutId}`);
|
||||||
// because the UI doesn't consistently reload after the data for the config has loaded...
|
|
||||||
// HOW HAS NOBODY AT VALVE RUN INTO THIS YET
|
|
||||||
await sleep(100);
|
|
||||||
await execSteamURL(`steam://controllerconfig/${appId}/${layoutId}`);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function askToApplySteamLayout(win: BrowserWindow) {
|
export async function askToApplySteamLayout(win: BrowserWindow) {
|
||||||
const appId = getAppId();
|
const appId = getAppId();
|
||||||
if (!appId) return;
|
if (!appId) return;
|
||||||
if (Settings.store.steamOSLayoutVersion === layoutVersion) return;
|
if (State.store.steamOSLayoutVersion === layoutVersion) return;
|
||||||
const update = Boolean(Settings.store.steamOSLayoutVersion);
|
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.
|
// 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, {
|
const { response } = await dialog.showMessageBox(win, {
|
||||||
|
@ -74,8 +87,8 @@ ${update ? "Click" : "Tap"} no to keep your current layout.`,
|
||||||
type: "question"
|
type: "question"
|
||||||
});
|
});
|
||||||
|
|
||||||
if (Settings.store.steamOSLayoutVersion !== layoutVersion) {
|
if (State.store.steamOSLayoutVersion !== layoutVersion) {
|
||||||
Settings.store.steamOSLayoutVersion = layoutVersion;
|
State.store.steamOSLayoutVersion = layoutVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (response === MessageBoxChoice.Cancel) return;
|
if (response === MessageBoxChoice.Cancel) return;
|
||||||
|
|
|
@ -51,26 +51,16 @@ ipcMain.handle(IpcEvents.VIRT_MIC_LIST, () => {
|
||||||
: { ok: false, isGlibcxxToOld };
|
: { ok: false, isGlibcxxToOld };
|
||||||
});
|
});
|
||||||
|
|
||||||
ipcMain.handle(
|
ipcMain.handle(IpcEvents.VIRT_MIC_START, (_, targets: string[]) =>
|
||||||
IpcEvents.VIRT_MIC_START,
|
|
||||||
(_, targets: string[]) =>
|
|
||||||
obtainVenmic()?.link({
|
obtainVenmic()?.link({
|
||||||
props: targets.map(target => ({ key: "application.name", value: target })),
|
include: targets.map(target => ({ key: "application.name", value: target })),
|
||||||
mode: "include"
|
exclude: [{ key: "application.process.id", value: getRendererAudioServicePid() }]
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
ipcMain.handle(
|
ipcMain.handle(IpcEvents.VIRT_MIC_START_SYSTEM, () =>
|
||||||
IpcEvents.VIRT_MIC_START_SYSTEM,
|
|
||||||
() =>
|
|
||||||
obtainVenmic()?.link({
|
obtainVenmic()?.link({
|
||||||
props: [
|
exclude: [{ key: "application.process.id", value: getRendererAudioServicePid() }]
|
||||||
{
|
|
||||||
key: "application.process.id",
|
|
||||||
value: getRendererAudioServicePid()
|
|
||||||
}
|
|
||||||
],
|
|
||||||
mode: "exclude"
|
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
|
@ -71,5 +71,9 @@ export const VesktopNative = {
|
||||||
onActivity(cb: (data: string) => void) {
|
onActivity(cb: (data: string) => void) {
|
||||||
ipcRenderer.on(IpcEvents.ARRPC_ACTIVITY, (_, data: string) => cb(data));
|
ipcRenderer.on(IpcEvents.ARRPC_ACTIVITY, (_, data: string) => cb(data));
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
clipboard: {
|
||||||
|
copyImage: (imageBuffer: Uint8Array, imageSrc: string) =>
|
||||||
|
invoke<void>(IpcEvents.CLIPBOARD_COPY_IMAGE, imageBuffer, imageSrc)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -10,7 +10,7 @@ import { Margins } from "@vencord/types/utils";
|
||||||
import { Button, Forms, Select, Switch, Text, Toasts, useState } from "@vencord/types/webpack/common";
|
import { Button, Forms, Select, Switch, Text, Toasts, useState } from "@vencord/types/webpack/common";
|
||||||
import { setBadge } from "renderer/appBadge";
|
import { setBadge } from "renderer/appBadge";
|
||||||
import { useSettings } from "renderer/settings";
|
import { useSettings } from "renderer/settings";
|
||||||
import { isMac, isWindows, isLinux } from "renderer/utils";
|
import { isMac } from "renderer/utils";
|
||||||
import { isTruthy } from "shared/utils/guards";
|
import { isTruthy } from "shared/utils/guards";
|
||||||
|
|
||||||
export default function SettingsUi() {
|
export default function SettingsUi() {
|
||||||
|
@ -21,10 +21,10 @@ export default function SettingsUi() {
|
||||||
const [autoStartEnabled, setAutoStartEnabled] = useState(autostart.isEnabled());
|
const [autoStartEnabled, setAutoStartEnabled] = useState(autostart.isEnabled());
|
||||||
|
|
||||||
const allSwitches: Array<false | [keyof typeof Settings, string, string, boolean?, (() => boolean)?]> = [
|
const allSwitches: Array<false | [keyof typeof Settings, string, string, boolean?, (() => boolean)?]> = [
|
||||||
isWindows && [
|
[
|
||||||
"discordWindowsTitleBar",
|
"customTitleBar",
|
||||||
"Discord Titlebar",
|
"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 && ["tray", "Tray Icon", "Add a tray icon for Vesktop", true],
|
||||||
!isMac && [
|
!isMac && [
|
||||||
|
@ -34,7 +34,7 @@ export default function SettingsUi() {
|
||||||
true,
|
true,
|
||||||
() => Settings.tray ?? true
|
() => Settings.tray ?? true
|
||||||
],
|
],
|
||||||
isLinux && ["middleClickAutoscroll", "Middle Click Autoscroll", "Enables middle-click scrolling (Requires a full restart)", false],
|
!isMac && ["middleClickAutoscroll", "Middle Click Autoscroll", "Enables middle-click scrolling (Requires a full restart)", false],
|
||||||
["arRPC", "Rich Presence", "Enables Rich Presence via arRPC", false],
|
["arRPC", "Rich Presence", "Enables Rich Presence via arRPC", false],
|
||||||
[
|
[
|
||||||
"disableMinSize",
|
"disableMinSize",
|
||||||
|
@ -44,6 +44,7 @@ export default function SettingsUi() {
|
||||||
["staticTitle", "Static Title", 'Makes the window title "Vesktop" instead of changing to the current page'],
|
["staticTitle", "Static Title", 'Makes the window title "Vesktop" instead of changing to the current page'],
|
||||||
["enableMenu", "Enable Menu Bar", "Enables the application menu bar. Press ALT to toggle visibility."],
|
["enableMenu", "Enable Menu Bar", "Enables the application menu bar. Press ALT to toggle visibility."],
|
||||||
["disableSmoothScroll", "Disable smooth scrolling", "Disables smooth scrolling in Vesktop", false],
|
["disableSmoothScroll", "Disable smooth scrolling", "Disables smooth scrolling in Vesktop", false],
|
||||||
|
["hardwareAcceleration", "Hardware Acceleration", "Enable hardware acceleration", true],
|
||||||
["splashTheming", "Splash theming", "Adapt the splash window colors to your custom theme", false],
|
["splashTheming", "Splash theming", "Adapt the splash window colors to your custom theme", false],
|
||||||
[
|
[
|
||||||
"openLinksWithElectron",
|
"openLinksWithElectron",
|
||||||
|
|
|
@ -6,9 +6,7 @@
|
||||||
|
|
||||||
import "./hideGarbage.css";
|
import "./hideGarbage.css";
|
||||||
|
|
||||||
import { waitFor } from "@vencord/types/webpack";
|
import { isWindows, localStorage } from "./utils";
|
||||||
|
|
||||||
import { isFirstRun, isWindows, localStorage } from "./utils";
|
|
||||||
|
|
||||||
// Make clicking Notifications focus the window
|
// Make clicking Notifications focus the window
|
||||||
const originalSetOnClick = Object.getOwnPropertyDescriptor(Notification.prototype, "onclick")!.set!;
|
const originalSetOnClick = Object.getOwnPropertyDescriptor(Notification.prototype, "onclick")!.set!;
|
||||||
|
@ -22,15 +20,8 @@ Object.defineProperty(Notification.prototype, "onclick", {
|
||||||
configurable: true
|
configurable: true
|
||||||
});
|
});
|
||||||
|
|
||||||
if (isFirstRun) {
|
// Hide "Download Discord Desktop now!!!!" banner
|
||||||
// Hide "Download Discord Desktop now!!!!" banner
|
localStorage.setItem("hideNag", "true");
|
||||||
localStorage.setItem("hideNag", "true");
|
|
||||||
|
|
||||||
// Enable Desktop Notifications by default
|
|
||||||
waitFor("setDesktopType", m => {
|
|
||||||
m.setDesktopType("all");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME: Remove eventually.
|
// FIXME: Remove eventually.
|
||||||
// Originally, Vencord always used a Windows user agent. This seems to cause captchas
|
// Originally, Vencord always used a Windows user agent. This seems to cause captchas
|
||||||
|
|
21
src/renderer/patches/enableNotificationsByDefault.ts
Normal file
21
src/renderer/patches/enableNotificationsByDefault.ts
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
/*
|
||||||
|
* 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 { addPatch } from "./shared";
|
||||||
|
|
||||||
|
addPatch({
|
||||||
|
patches: [
|
||||||
|
{
|
||||||
|
find: '"NotificationSettingsStore',
|
||||||
|
replacement: {
|
||||||
|
// FIXME: fix eslint rule
|
||||||
|
// eslint-disable-next-line no-useless-escape
|
||||||
|
match: /\.isPlatformEmbedded(?=\?\i\.DesktopNotificationTypes\.ALL)/g,
|
||||||
|
replace: "$&||true"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
|
@ -5,7 +5,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// TODO: Possibly auto generate glob if we have more patches in the future
|
// TODO: Possibly auto generate glob if we have more patches in the future
|
||||||
import "./spellCheck";
|
import "./enableNotificationsByDefault";
|
||||||
import "./platformClass";
|
import "./platformClass";
|
||||||
import "./windowsTitleBar";
|
|
||||||
import "./screenShareAudio";
|
import "./screenShareAudio";
|
||||||
|
import "./spellCheck";
|
||||||
|
import "./windowsTitleBar";
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Settings } from "renderer/settings";
|
import { Settings } from "renderer/settings";
|
||||||
import { isMac, isWindows } from "renderer/utils";
|
import { isMac } from "renderer/utils";
|
||||||
|
|
||||||
import { addPatch } from "./shared";
|
import { addPatch } from "./shared";
|
||||||
|
|
||||||
|
@ -22,8 +22,8 @@ addPatch({
|
||||||
],
|
],
|
||||||
|
|
||||||
getPlatformClass() {
|
getPlatformClass() {
|
||||||
|
if (Settings.store.customTitleBar) return "platform-win";
|
||||||
if (isMac) return "platform-osx";
|
if (isMac) return "platform-osx";
|
||||||
if (isWindows && Settings.store.discordWindowsTitleBar) return "platform-win";
|
|
||||||
return "platform-web";
|
return "platform-web";
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -8,7 +8,7 @@ import { Settings } from "renderer/settings";
|
||||||
|
|
||||||
import { addPatch } from "./shared";
|
import { addPatch } from "./shared";
|
||||||
|
|
||||||
if (Settings.store.discordWindowsTitleBar)
|
if (Settings.store.customTitleBar)
|
||||||
addPatch({
|
addPatch({
|
||||||
patches: [
|
patches: [
|
||||||
{
|
{
|
||||||
|
|
|
@ -47,5 +47,7 @@ export const enum IpcEvents {
|
||||||
VIRT_MIC_START_SYSTEM = "VCD_VIRT_MIC_START_ALL",
|
VIRT_MIC_START_SYSTEM = "VCD_VIRT_MIC_START_ALL",
|
||||||
VIRT_MIC_STOP = "VCD_VIRT_MIC_STOP",
|
VIRT_MIC_STOP = "VCD_VIRT_MIC_STOP",
|
||||||
|
|
||||||
ARRPC_ACTIVITY = "VCD_ARRPC_ACTIVITY"
|
ARRPC_ACTIVITY = "VCD_ARRPC_ACTIVITY",
|
||||||
|
|
||||||
|
CLIPBOARD_COPY_IMAGE = "VCD_CLIPBOARD_COPY_IMAGE"
|
||||||
}
|
}
|
||||||
|
|
21
src/shared/settings.d.ts
vendored
21
src/shared/settings.d.ts
vendored
|
@ -17,22 +17,29 @@ export interface Settings {
|
||||||
staticTitle?: boolean;
|
staticTitle?: boolean;
|
||||||
enableMenu?: boolean;
|
enableMenu?: boolean;
|
||||||
disableSmoothScroll?: boolean;
|
disableSmoothScroll?: boolean;
|
||||||
|
hardwareAcceleration?: boolean;
|
||||||
arRPC?: boolean;
|
arRPC?: boolean;
|
||||||
appBadge?: boolean;
|
appBadge?: boolean;
|
||||||
discordWindowsTitleBar?: boolean;
|
|
||||||
|
|
||||||
maximized?: boolean;
|
|
||||||
minimized?: boolean;
|
|
||||||
windowBounds?: Rectangle;
|
|
||||||
disableMinSize?: boolean;
|
disableMinSize?: boolean;
|
||||||
|
|
||||||
|
/** @deprecated use customTitleBar */
|
||||||
|
discordWindowsTitleBar?: boolean;
|
||||||
|
customTitleBar?: boolean;
|
||||||
|
|
||||||
checkUpdates?: boolean;
|
checkUpdates?: boolean;
|
||||||
skippedUpdate?: string;
|
|
||||||
firstLaunch?: boolean;
|
|
||||||
|
|
||||||
splashTheming?: boolean;
|
splashTheming?: boolean;
|
||||||
splashColor?: string;
|
splashColor?: string;
|
||||||
splashBackground?: string;
|
splashBackground?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface State {
|
||||||
|
maximized?: boolean;
|
||||||
|
minimized?: boolean;
|
||||||
|
windowBounds?: Rectangle;
|
||||||
|
|
||||||
|
skippedUpdate?: string;
|
||||||
|
firstLaunch?: boolean;
|
||||||
|
|
||||||
steamOSLayoutVersion?: number;
|
steamOSLayoutVersion?: number;
|
||||||
}
|
}
|
||||||
|
|
|
@ -144,4 +144,11 @@ export class SettingsStore<T extends object> {
|
||||||
listeners.delete(cb);
|
listeners.delete(cb);
|
||||||
if (!listeners.size) this.pathListeners.delete(path as string);
|
if (!listeners.size) this.pathListeners.delete(path as string);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call all global change listeners
|
||||||
|
*/
|
||||||
|
public markAsChanged() {
|
||||||
|
this.globalListeners.forEach(cb => cb(this.plain, ""));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { app, BrowserWindow, shell } from "electron";
|
import { app, BrowserWindow, shell } from "electron";
|
||||||
import { Settings } from "main/settings";
|
import { Settings, State } from "main/settings";
|
||||||
import { handle } from "main/utils/ipcWrappers";
|
import { handle } from "main/utils/ipcWrappers";
|
||||||
import { makeLinksOpenExternally } from "main/utils/makeLinksOpenExternally";
|
import { makeLinksOpenExternally } from "main/utils/makeLinksOpenExternally";
|
||||||
import { githubGet, ReleaseData } from "main/utils/vencordLoader";
|
import { githubGet, ReleaseData } from "main/utils/vencordLoader";
|
||||||
|
@ -52,7 +52,7 @@ handle(IpcEvents.UPDATER_DOWNLOAD, () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
handle(IpcEvents.UPDATE_IGNORE, () => {
|
handle(IpcEvents.UPDATE_IGNORE, () => {
|
||||||
Settings.store.skippedUpdate = updateData.latestVersion;
|
State.store.skippedUpdate = updateData.latestVersion;
|
||||||
});
|
});
|
||||||
|
|
||||||
function isOutdated(oldVersion: string, newVersion: string) {
|
function isOutdated(oldVersion: string, newVersion: string) {
|
||||||
|
@ -91,7 +91,7 @@ export async function checkUpdates() {
|
||||||
release: data
|
release: data
|
||||||
};
|
};
|
||||||
|
|
||||||
if (Settings.store.skippedUpdate !== newVersion && isOutdated(oldVersion, newVersion)) {
|
if (State.store.skippedUpdate !== newVersion && isOutdated(oldVersion, newVersion)) {
|
||||||
openNewUpdateWindow();
|
openNewUpdateWindow();
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|
|
@ -2,8 +2,9 @@
|
||||||
<link rel="stylesheet" href="./style.css" type="text/css" />
|
<link rel="stylesheet" href="./style.css" type="text/css" />
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
* {
|
body {
|
||||||
user-select: none;
|
user-select: none;
|
||||||
|
-webkit-app-region: drag;
|
||||||
}
|
}
|
||||||
|
|
||||||
.wrapper {
|
.wrapper {
|
||||||
|
@ -22,8 +23,9 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
img {
|
img {
|
||||||
width: 6em;
|
width: 128px;
|
||||||
height: 6em;
|
height: 128px;
|
||||||
|
image-rendering: pixelated;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
|
|
Loading…
Add table
Reference in a new issue