Compare commits
37 Commits
v0.4.2
...
fix/start-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bb09596485 | ||
|
|
894ec4b902 | ||
|
|
dd44602730 | ||
|
|
40b952d8bf | ||
|
|
4974848a56 | ||
|
|
623fa5d709 | ||
|
|
fc33050496 | ||
|
|
e02acda6fa | ||
|
|
f11a72d4b5 | ||
|
|
49cd558fa1 | ||
|
|
378a1f7464 | ||
|
|
35d2dd6505 | ||
|
|
017c2c847f | ||
|
|
de2b4b7dd8 | ||
|
|
5dc5741771 | ||
|
|
971c490c41 | ||
|
|
0f804f9f6e | ||
|
|
fdf454722f | ||
|
|
208158f4d1 | ||
|
|
032b94e81d | ||
|
|
4988163744 | ||
|
|
ee7e71b9fb | ||
|
|
7efa54687a | ||
|
|
2917ff25e5 | ||
|
|
e3839c35b7 | ||
|
|
c39678d733 | ||
|
|
06dea79c74 | ||
|
|
96b0652a06 | ||
|
|
49e0411be6 | ||
|
|
94819e6f16 | ||
|
|
a232af06ed | ||
|
|
b24535483e | ||
|
|
9521c287b6 | ||
|
|
55b9edec39 | ||
|
|
1e9c70eed9 | ||
|
|
3262e083fa | ||
|
|
ec1c719553 |
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 }}
|
||||
31
.github/workflows/release.yml
vendored
31
.github/workflows/release.yml
vendored
@@ -12,17 +12,32 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
os: [macos-latest, ubuntu-latest, windows-latest]
|
||||
include:
|
||||
- os: macos-latest
|
||||
platform: mac
|
||||
- os: ubuntu-latest
|
||||
platform: linux
|
||||
- os: windows-latest
|
||||
platform: windows
|
||||
|
||||
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:
|
||||
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
|
||||
uses: samuelmeuli/action-electron-builder@e4b12cd06ddf023422f1ac4e39632bd76f6e6928
|
||||
with:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
RELEASE: true
|
||||
run: |
|
||||
pnpm electron-builder --${{ matrix.platform }} --publish always
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
4
.github/workflows/test.yml
vendored
4
.github/workflows/test.yml
vendored
@@ -14,10 +14,10 @@ jobs:
|
||||
- uses: actions/checkout@v3
|
||||
- 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
|
||||
with:
|
||||
node-version: 18
|
||||
node-version: 18.18.2
|
||||
cache: "pnpm"
|
||||
|
||||
- name: Install dependencies
|
||||
|
||||
50
.vscode/settings.json
vendored
50
.vscode/settings.json
vendored
@@ -1,25 +1,25 @@
|
||||
{
|
||||
"editor.formatOnSave": true,
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll.eslint": true
|
||||
},
|
||||
"[typescript]": {
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
},
|
||||
"[javascript]": {
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
},
|
||||
"[typescriptreact]": {
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
},
|
||||
"[javascriptreact]": {
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
},
|
||||
"[json]": {
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
},
|
||||
"[jsonc]": {
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
},
|
||||
"cSpell.words": ["Vesktop"]
|
||||
}
|
||||
{
|
||||
"editor.formatOnSave": true,
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll.eslint": "explicit"
|
||||
},
|
||||
"[typescript]": {
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
},
|
||||
"[javascript]": {
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
},
|
||||
"[typescriptreact]": {
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
},
|
||||
"[javascriptreact]": {
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
},
|
||||
"[json]": {
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
},
|
||||
"[jsonc]": {
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
},
|
||||
"cSpell.words": ["Vesktop"]
|
||||
}
|
||||
|
||||
@@ -7,7 +7,9 @@ Vesktop is a cross platform desktop app aiming to give you a snappier Discord ex
|
||||
|
||||
Bug reports, feature requests & contributions are highly appreciated!!
|
||||
|
||||

|
||||

|
||||

|
||||
|
||||
|
||||
## Installing
|
||||
|
||||
@@ -21,6 +23,8 @@ Download and run Vesktop-VERSION.dmg from [releases](https://github.com/Vencord/
|
||||
|
||||
### Linux
|
||||
|
||||
[](https://flathub.org/apps/dev.vencord.Vesktop)
|
||||
|
||||
#### 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)
|
||||
@@ -37,7 +41,7 @@ Download Vesktop-VERSION.rpm from [releases](https://github.com/Vencord/Vesktop/
|
||||
|
||||
Either download Vesktop-VERSION.AppImage and just run it directly or grab Vesktop-VERSION.tar.gz, extract it somewhere and run `vencorddesktop`.
|
||||
|
||||
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
|
||||
|
||||
|
||||
167
meta/dev.vencord.Vesktop.metainfo.xml
Normal file
167
meta/dev.vencord.Vesktop.metainfo.xml
Normal file
@@ -0,0 +1,167 @@
|
||||
<?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="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>
|
||||
38
package.json
38
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "VencordDesktop",
|
||||
"version": "0.4.2",
|
||||
"version": "0.4.4",
|
||||
"private": true,
|
||||
"description": "",
|
||||
"keywords": [],
|
||||
@@ -20,26 +20,27 @@
|
||||
"start:watch": "pnpm build:dev && tsx scripts/startWatch.mts",
|
||||
"test": "pnpm lint && pnpm testTypes",
|
||||
"testTypes": "tsc --noEmit",
|
||||
"watch": "pnpm build --watch"
|
||||
"watch": "pnpm build --watch",
|
||||
"updateMeta": "tsx scripts/utils/updateMeta.mts"
|
||||
},
|
||||
"dependencies": {
|
||||
"arrpc": "github:OpenAsar/arrpc#89f4da610ccfac93f461826a446a17cd3b23953d"
|
||||
"arrpc": "github:OpenAsar/arrpc#3e22fd776273afaa4a80c51deb86077ffdd4d2ae"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@vencord/venmic": "^1.6.0"
|
||||
"@vencord/venmic": "^2.1.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@fal-works/esbuild-plugin-global-externals": "^2.1.2",
|
||||
"@types/node": "^20.8.4",
|
||||
"@types/react": "^18.2.28",
|
||||
"@typescript-eslint/eslint-plugin": "^6.7.5",
|
||||
"@typescript-eslint/parser": "^6.7.5",
|
||||
"@types/node": "^20.10.0",
|
||||
"@types/react": "^18.2.39",
|
||||
"@typescript-eslint/eslint-plugin": "^6.13.1",
|
||||
"@typescript-eslint/parser": "^6.13.1",
|
||||
"@vencord/types": "^0.1.2",
|
||||
"dotenv": "^16.3.1",
|
||||
"electron": "^27.0.0",
|
||||
"electron-builder": "^24.6.4",
|
||||
"esbuild": "^0.19.4",
|
||||
"eslint": "^8.51.0",
|
||||
"electron": "^27.1.2",
|
||||
"electron-builder": "^24.9.1",
|
||||
"esbuild": "^0.19.8",
|
||||
"eslint": "^8.54.0",
|
||||
"eslint-config-prettier": "^9.0.0",
|
||||
"eslint-import-resolver-alias": "^1.1.2",
|
||||
"eslint-plugin-license-header": "^0.6.0",
|
||||
@@ -47,13 +48,14 @@
|
||||
"eslint-plugin-prettier": "^5.0.1",
|
||||
"eslint-plugin-simple-import-sort": "^10.0.0",
|
||||
"eslint-plugin-unused-imports": "^3.0.0",
|
||||
"prettier": "^3.0.3",
|
||||
"prettier": "^3.1.0",
|
||||
"source-map-support": "^0.5.21",
|
||||
"tsx": "^3.13.0",
|
||||
"type-fest": "^4.4.0",
|
||||
"typescript": "^5.2.2"
|
||||
"tsx": "^4.6.0",
|
||||
"type-fest": "^4.8.2",
|
||||
"typescript": "^5.3.2",
|
||||
"xml-formatter": "^3.6.0"
|
||||
},
|
||||
"packageManager": "pnpm@8.6.11",
|
||||
"packageManager": "pnpm@8.11.0",
|
||||
"engines": {
|
||||
"node": ">=18",
|
||||
"pnpm": ">=8"
|
||||
@@ -68,6 +70,7 @@
|
||||
"package.json",
|
||||
"LICENSE"
|
||||
],
|
||||
"beforePack": "scripts/build/sandboxFix.js",
|
||||
"linux": {
|
||||
"icon": "build/icon.icns",
|
||||
"category": "Network",
|
||||
@@ -108,7 +111,6 @@
|
||||
"Type": "Application",
|
||||
"Categories": "Network;InstantMessaging;Chat;",
|
||||
"Keywords": "discord;vencord;electron;chat;",
|
||||
"WMClass": "VencordDesktop",
|
||||
"StartupWMClass": "VencordDesktop"
|
||||
}
|
||||
},
|
||||
|
||||
564
pnpm-lock.yaml
generated
564
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"],
|
||||
jsxFactory: "VencordCreateElement",
|
||||
jsxFragment: "VencordFragment",
|
||||
// Work around https://github.com/evanw/esbuild/issues/2460
|
||||
tsconfig: "./scripts/build/tsconfig.esbuild.json",
|
||||
external: ["@vencord/types/*"],
|
||||
plugins: [vencordDep],
|
||||
footer: { js: "//# sourceURL=VCDRenderer" }
|
||||
|
||||
74
scripts/build/sandboxFix.js
Normal file
74
scripts/build/sandboxFix.js
Normal file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
// Based on https://github.com/gergof/electron-builder-sandbox-fix/blob/master/lib/index.js
|
||||
|
||||
const fs = require("fs/promises");
|
||||
const path = require("path");
|
||||
let isApplied = false;
|
||||
|
||||
const hook = async () => {
|
||||
if (isApplied) return;
|
||||
isApplied = true;
|
||||
if (process.platform !== "linux") {
|
||||
// this fix is only required on linux
|
||||
return;
|
||||
}
|
||||
const AppImageTarget = require("app-builder-lib/out/targets/AppImageTarget");
|
||||
const oldBuildMethod = AppImageTarget.default.prototype.build;
|
||||
AppImageTarget.default.prototype.build = async function (...args) {
|
||||
console.log("Running AppImage builder hook", args);
|
||||
const oldPath = args[0];
|
||||
const newPath = oldPath + "-appimage-sandbox-fix";
|
||||
// just in case
|
||||
try {
|
||||
await fs.rm(newPath, {
|
||||
recursive: true
|
||||
});
|
||||
} catch {}
|
||||
|
||||
console.log("Copying to apply appimage fix", oldPath, newPath);
|
||||
await fs.cp(oldPath, newPath, {
|
||||
recursive: true
|
||||
});
|
||||
args[0] = newPath;
|
||||
|
||||
const executable = path.join(newPath, this.packager.executableName);
|
||||
|
||||
const loaderScript = `
|
||||
#!/usr/bin/env bash
|
||||
|
||||
SCRIPT_DIR="$( cd "$( dirname "\${BASH_SOURCE[0]}" )" && pwd )"
|
||||
IS_STEAMOS=0
|
||||
|
||||
if [[ "$SteamOS" == "1" && "$SteamGamepadUI" == "1" ]]; then
|
||||
echo "Running Vesktop on SteamOS, disabling sandbox"
|
||||
IS_STEAMOS=1
|
||||
fi
|
||||
|
||||
exec "$SCRIPT_DIR/${this.packager.executableName}.bin" "$([ "$IS_STEAMOS" == 1 ] && echo '--no-sandbox')" "$@"
|
||||
`.trim();
|
||||
|
||||
try {
|
||||
await fs.rename(executable, executable + ".bin");
|
||||
await fs.writeFile(executable, loaderScript);
|
||||
await fs.chmod(executable, 0o755);
|
||||
} catch (e) {
|
||||
console.error("failed to create loder for sandbox fix: " + e.message);
|
||||
throw new Error("Failed to create loader for sandbox fix");
|
||||
}
|
||||
|
||||
const ret = await oldBuildMethod.apply(this, args);
|
||||
|
||||
await fs.rm(newPath, {
|
||||
recursive: true
|
||||
});
|
||||
|
||||
return ret;
|
||||
};
|
||||
};
|
||||
|
||||
module.exports = hook;
|
||||
@@ -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");
|
||||
@@ -10,38 +10,51 @@ import { join } from "path";
|
||||
|
||||
interface AutoStart {
|
||||
isEnabled(): boolean;
|
||||
wasAutoStarted(): boolean;
|
||||
enable(): void;
|
||||
disable(): void;
|
||||
}
|
||||
|
||||
const isFlatpak = process.env.FLATPAK_ID !== undefined;
|
||||
|
||||
function makeAutoStartLinux(): AutoStart {
|
||||
const configDir = process.env.XDG_CONFIG_HOME || join(process.env.HOME!, ".config");
|
||||
const dir = join(configDir, "autostart");
|
||||
const file = join(dir, "vencord.desktop");
|
||||
|
||||
return {
|
||||
isEnabled: () => existsSync(file),
|
||||
isEnabled: () => existsSync(file), // TODO: flatpak
|
||||
wasAutoStarted: () => process.argv.includes("--autostart"),
|
||||
enable() {
|
||||
const desktopFile = `
|
||||
if (isFlatpak) {
|
||||
} else {
|
||||
const desktopFile = `
|
||||
[Desktop Entry]
|
||||
Type=Application
|
||||
Version=1.0
|
||||
Name=Vencord
|
||||
Comment=Vencord autostart script
|
||||
Exec=${process.execPath}
|
||||
Exec=${process.execPath} --autostart
|
||||
Terminal=false
|
||||
StartupNotify=false
|
||||
`.trim();
|
||||
|
||||
mkdirSync(dir, { recursive: true });
|
||||
writeFileSync(file, desktopFile);
|
||||
mkdirSync(dir, { recursive: true });
|
||||
writeFileSync(file, desktopFile);
|
||||
}
|
||||
},
|
||||
disable: () => rmSync(file, { force: true })
|
||||
disable: () => {
|
||||
if (isFlatpak) {
|
||||
} else {
|
||||
rmSync(file, { force: true });
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const autoStartWindowsMac: AutoStart = {
|
||||
isEnabled: () => app.getLoginItemSettings().openAtLogin,
|
||||
wasAutoStarted: () => app.getLoginItemSettings().wasOpenedAtLogin,
|
||||
enable: () => app.setLoginItemSettings({ openAtLogin: true }),
|
||||
disable: () => app.setLoginItemSettings({ openAtLogin: false })
|
||||
};
|
||||
|
||||
@@ -34,3 +34,8 @@ const UserAgents = {
|
||||
};
|
||||
|
||||
export const UserAgent = UserAgents[process.platform] || UserAgents.windows;
|
||||
|
||||
export const enum MessageBoxChoice {
|
||||
Default,
|
||||
Cancel
|
||||
}
|
||||
|
||||
@@ -24,6 +24,12 @@ if (IS_DEV) {
|
||||
process.env.VENCORD_USER_DATA_DIR = DATA_DIR;
|
||||
|
||||
function init() {
|
||||
const { disableSmoothScroll } = Settings.store;
|
||||
|
||||
if (disableSmoothScroll) {
|
||||
app.commandLine.appendSwitch("disable-smooth-scrolling");
|
||||
}
|
||||
|
||||
// work around chrome 66 disabling autoplay by default
|
||||
app.commandLine.appendSwitch("autoplay-policy", "no-user-gesture-required");
|
||||
|
||||
|
||||
@@ -24,10 +24,12 @@ import type { SettingsStore } from "shared/utils/SettingsStore";
|
||||
import { ICON_PATH } from "../shared/paths";
|
||||
import { createAboutWindow } from "./about";
|
||||
import { initArRPC } from "./arrpc";
|
||||
import { autoStart } from "./autoStart";
|
||||
import {
|
||||
DATA_DIR,
|
||||
DEFAULT_HEIGHT,
|
||||
DEFAULT_WIDTH,
|
||||
MessageBoxChoice,
|
||||
MIN_HEIGHT,
|
||||
MIN_WIDTH,
|
||||
UserAgent,
|
||||
@@ -36,11 +38,14 @@ import {
|
||||
import { Settings, VencordSettings } from "./settings";
|
||||
import { createSplashWindow } from "./splash";
|
||||
import { makeLinksOpenExternally } from "./utils/makeLinksOpenExternally";
|
||||
import { applyDeckKeyboardFix, askToApplySteamLayout, isDeckGameMode } from "./utils/steamOS";
|
||||
import { downloadVencordFiles, ensureVencordFiles } from "./utils/vencordLoader";
|
||||
|
||||
let isQuitting = false;
|
||||
let tray: Tray;
|
||||
|
||||
applyDeckKeyboardFix();
|
||||
|
||||
app.on("before-quit", () => {
|
||||
isQuitting = true;
|
||||
});
|
||||
@@ -128,11 +133,6 @@ function initTray(win: BrowserWindow) {
|
||||
});
|
||||
}
|
||||
|
||||
const enum MessageBoxChoice {
|
||||
Default,
|
||||
Cancel
|
||||
}
|
||||
|
||||
async function clearData(win: BrowserWindow) {
|
||||
const { response } = await dialog.showMessageBox(win, {
|
||||
message: "Are you sure you want to reset Vesktop?",
|
||||
@@ -266,6 +266,9 @@ function initMenuBar(win: BrowserWindow) {
|
||||
}
|
||||
|
||||
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 options = {
|
||||
@@ -288,7 +291,8 @@ function getWindowBoundsOptions(): BrowserWindowConstructorOptions {
|
||||
|
||||
function getDarwinOptions(): BrowserWindowConstructorOptions {
|
||||
const options = {
|
||||
titleBarStyle: "hiddenInset"
|
||||
titleBarStyle: "hidden",
|
||||
trafficLightPosition: { x: 10, y: 10 }
|
||||
} as BrowserWindowConstructorOptions;
|
||||
|
||||
const { splashTheming, splashBackground } = Settings.store;
|
||||
@@ -404,7 +408,7 @@ function createMainWindow() {
|
||||
win.setMenuBarVisibility(false);
|
||||
|
||||
win.on("close", e => {
|
||||
const useTray = Settings.store.minimizeToTray !== false && Settings.store.tray !== false;
|
||||
const useTray = !isDeckGameMode && Settings.store.minimizeToTray !== false && Settings.store.tray !== false;
|
||||
if (isQuitting || (process.platform !== "darwin" && !useTray)) return;
|
||||
|
||||
e.preventDefault();
|
||||
@@ -418,7 +422,7 @@ function createMainWindow() {
|
||||
if (Settings.store.staticTitle) win.on("page-title-updated", e => e.preventDefault());
|
||||
|
||||
initWindowBoundsListeners(win);
|
||||
if ((Settings.store.tray ?? true) && process.platform !== "darwin") initTray(win);
|
||||
if (!isDeckGameMode && (Settings.store.tray ?? true) && process.platform !== "darwin") initTray(win);
|
||||
initMenuBar(win);
|
||||
makeLinksOpenExternally(win);
|
||||
initSettingsListeners(win);
|
||||
@@ -439,18 +443,30 @@ function createMainWindow() {
|
||||
const runVencordMain = once(() => require(join(VENCORD_FILES_DIR, "vencordDesktopMain.js")));
|
||||
|
||||
export async function createWindows() {
|
||||
const splash = createSplashWindow();
|
||||
|
||||
const shouldStartMinimized = Settings.store.startMinimized && autoStart.wasAutoStarted();
|
||||
const splash = createSplashWindow(shouldStartMinimized);
|
||||
// SteamOS letterboxes and scales it terribly, so just full screen it
|
||||
if (isDeckGameMode) splash.setFullScreen(true);
|
||||
await ensureVencordFiles();
|
||||
runVencordMain();
|
||||
|
||||
mainWin = createMainWindow();
|
||||
|
||||
mainWin.once("ready-to-show", () => {
|
||||
mainWin.webContents.on("did-finish-load", () => {
|
||||
splash.destroy();
|
||||
mainWin!.show();
|
||||
|
||||
if (Settings.store.maximized) {
|
||||
if (!shouldStartMinimized || isDeckGameMode) mainWin!.show();
|
||||
|
||||
if (isDeckGameMode) {
|
||||
// always use entire display
|
||||
mainWin!.setFullScreen(true);
|
||||
|
||||
askToApplySteamLayout(mainWin);
|
||||
}
|
||||
});
|
||||
|
||||
mainWin.once("show", () => {
|
||||
if (Settings.store.maximized && !mainWin!.isMaximized() && !isDeckGameMode) {
|
||||
mainWin!.maximize();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -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"));
|
||||
|
||||
84
src/main/utils/steamOS.ts
Normal file
84
src/main/utils/steamOS.ts
Normal file
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* 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 { exec as callbackExec } from "child_process";
|
||||
import { BrowserWindow, dialog } from "electron";
|
||||
import { sleep } from "shared/utils/sleep";
|
||||
import { promisify } from "util";
|
||||
|
||||
import { MessageBoxChoice } from "../constants";
|
||||
import { Settings } from "../settings";
|
||||
|
||||
const exec = promisify(callbackExec);
|
||||
|
||||
// Bump this to re-show the prompt
|
||||
const layoutVersion = 2;
|
||||
// Get this from "show details" on the profile after exporting as a shared personal layout or using share with community
|
||||
const layoutId = "3080264545"; // Vesktop Layout v2
|
||||
const numberRegex = /^[0-9]*$/;
|
||||
|
||||
export const isDeckGameMode = process.env.SteamOS === "1" && process.env.SteamGamepadUI === "1";
|
||||
|
||||
export function applyDeckKeyboardFix() {
|
||||
if (!isDeckGameMode) return;
|
||||
// Prevent constant virtual keyboard spam that eventually crashes Steam.
|
||||
process.env.GTK_IM_MODULE = "None";
|
||||
}
|
||||
|
||||
// For some reason SteamAppId is always 0 for non-steam apps so we do this insanity instead.
|
||||
function getAppId(): string | null {
|
||||
// /home/deck/.local/share/Steam/steamapps/shadercache/APPID/fozmediav1
|
||||
const path = process.env.STEAM_COMPAT_MEDIA_PATH;
|
||||
if (!path) return null;
|
||||
const pathElems = path?.split("/");
|
||||
const appId = pathElems[pathElems.length - 2];
|
||||
if (appId.match(numberRegex)) {
|
||||
console.log(`Got Steam App ID ${appId}`);
|
||||
return appId;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
async function execSteamURL(url: string): Promise<void> {
|
||||
await exec(`steam -ifrunning ${url}`);
|
||||
}
|
||||
|
||||
async function showLayout(appId: string) {
|
||||
await 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) {
|
||||
const appId = getAppId();
|
||||
if (!appId) return;
|
||||
if (Settings.store.steamOSLayoutVersion === layoutVersion) return;
|
||||
const update = Boolean(Settings.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, {
|
||||
message: `${update ? "Update" : "Apply"} Vesktop Steam Input Layout?`,
|
||||
detail: `Would you like to ${update ? "Update" : "Apply"} Vesktop's recommended Steam Deck controller settings?
|
||||
${update ? "Click yes using the touchpad" : "Tap yes"}, then press the X button or tap Apply Layout to confirm.${
|
||||
update ? " Doing so will undo any customizations you have made." : ""
|
||||
}
|
||||
${update ? "Click" : "Tap"} no to keep your current layout.`,
|
||||
buttons: ["Yes", "No"],
|
||||
cancelId: MessageBoxChoice.Cancel,
|
||||
defaultId: MessageBoxChoice.Default,
|
||||
type: "question"
|
||||
});
|
||||
|
||||
if (Settings.store.steamOSLayoutVersion !== layoutVersion) {
|
||||
Settings.store.steamOSLayoutVersion = layoutVersion;
|
||||
}
|
||||
|
||||
if (response === MessageBoxChoice.Cancel) return;
|
||||
|
||||
await showLayout(appId);
|
||||
}
|
||||
@@ -53,10 +53,9 @@ ipcMain.handle(IpcEvents.VIRT_MIC_LIST, () => {
|
||||
|
||||
ipcMain.handle(
|
||||
IpcEvents.VIRT_MIC_START,
|
||||
(_, target: string) =>
|
||||
(_, targets: string[]) =>
|
||||
obtainVenmic()?.link({
|
||||
key: "application.name",
|
||||
value: target,
|
||||
props: targets.map(target => ({ key: "application.name", value: target })),
|
||||
mode: "include"
|
||||
})
|
||||
);
|
||||
@@ -65,8 +64,12 @@ ipcMain.handle(
|
||||
IpcEvents.VIRT_MIC_START_SYSTEM,
|
||||
() =>
|
||||
obtainVenmic()?.link({
|
||||
key: "application.process.id",
|
||||
value: getRendererAudioServicePid(),
|
||||
props: [
|
||||
{
|
||||
key: "application.process.id",
|
||||
value: getRendererAudioServicePid()
|
||||
}
|
||||
],
|
||||
mode: "exclude"
|
||||
})
|
||||
);
|
||||
|
||||
@@ -63,7 +63,7 @@ export const VesktopNative = {
|
||||
virtmic: {
|
||||
list: () =>
|
||||
invoke<{ ok: false; isGlibcxxToOld: boolean } | { ok: true; targets: string[] }>(IpcEvents.VIRT_MIC_LIST),
|
||||
start: (target: string) => invoke<void>(IpcEvents.VIRT_MIC_START, target),
|
||||
start: (targets: string[]) => invoke<void>(IpcEvents.VIRT_MIC_START, targets),
|
||||
startSystem: () => invoke<void>(IpcEvents.VIRT_MIC_START_SYSTEM),
|
||||
stop: () => invoke<void>(IpcEvents.VIRT_MIC_STOP)
|
||||
},
|
||||
|
||||
@@ -106,7 +106,7 @@ export function openScreenSharePicker(screens: Source[], skipPicker: boolean) {
|
||||
if (v.audioSource === "Entire System") {
|
||||
await VesktopNative.virtmic.startSystem();
|
||||
} else {
|
||||
await VesktopNative.virtmic.start(v.audioSource);
|
||||
await VesktopNative.virtmic.start([v.audioSource]);
|
||||
}
|
||||
}
|
||||
resolve(v);
|
||||
|
||||
@@ -42,13 +42,15 @@ export default function SettingsUi() {
|
||||
],
|
||||
["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."],
|
||||
["disableSmoothScroll", "Disable smooth scrolling", "Disables smooth scrolling in Vesktop", false],
|
||||
["splashTheming", "Splash theming", "Adapt the splash window colors to your custom theme", false],
|
||||
[
|
||||
"openLinksWithElectron",
|
||||
"Open Links in app (experimental)",
|
||||
"Opens links in a new Vesktop window instead of your web browser"
|
||||
],
|
||||
["checkUpdates", "Check for updates", "Automatically check for Vesktop updates", true]
|
||||
["checkUpdates", "Check for updates", "Automatically check for Vesktop updates", true],
|
||||
["startMinimized", "Start minimized", "Vesktop remains in minimized mode on start", false]
|
||||
];
|
||||
|
||||
const switches = allSwitches.filter(isTruthy);
|
||||
|
||||
4
src/shared/settings.d.ts
vendored
4
src/shared/settings.d.ts
vendored
@@ -15,9 +15,11 @@ export interface Settings {
|
||||
openLinksWithElectron?: boolean;
|
||||
staticTitle?: boolean;
|
||||
enableMenu?: boolean;
|
||||
disableSmoothScroll?: boolean;
|
||||
arRPC?: boolean;
|
||||
appBadge?: boolean;
|
||||
discordWindowsTitleBar?: boolean;
|
||||
startMinimized?: boolean;
|
||||
|
||||
maximized?: boolean;
|
||||
minimized?: boolean;
|
||||
@@ -31,4 +33,6 @@ export interface Settings {
|
||||
splashTheming?: boolean;
|
||||
splashColor?: string;
|
||||
splashBackground?: string;
|
||||
|
||||
steamOSLayoutVersion?: number;
|
||||
}
|
||||
|
||||
@@ -12,8 +12,8 @@ type ResolvePropDeep<T, P> = P extends `${infer Pre}.${infer Suf}`
|
||||
? ResolvePropDeep<T[Pre], Suf>
|
||||
: any
|
||||
: P extends keyof T
|
||||
? T[P]
|
||||
: any;
|
||||
? T[P]
|
||||
: any;
|
||||
|
||||
/**
|
||||
* The SettingsStore allows you to easily create a mutable store that
|
||||
|
||||
9
src/shared/utils/sleep.ts
Normal file
9
src/shared/utils/sleep.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
export function sleep(ms: number): Promise<void> {
|
||||
return new Promise(r => setTimeout(r, ms));
|
||||
}
|
||||
@@ -22,8 +22,9 @@
|
||||
}
|
||||
|
||||
img {
|
||||
width: 6em;
|
||||
height: 6em;
|
||||
width: 128px;
|
||||
height: 128px;
|
||||
image-rendering: pixelated;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
Reference in New Issue
Block a user