Compare commits

...

51 commits

Author SHA1 Message Date
smartfrigde
92beb1c8f1 v3.0.6 2022-05-14 23:45:30 +02:00
smartfrigde
1251733d24 Add release workflow 2022-05-14 23:43:01 +02:00
smartfridge
407d0eb075
Update utils.ts 2022-05-14 23:36:25 +02:00
smartfrigde
b1aac435e6 Remove the remainings from auto launch 2022-05-14 21:39:58 +02:00
smartfrigde
d2eeb054d4 Remove auto launch 2022-05-14 21:33:43 +02:00
smartfrigde
22343e00ed Fix path finding for auto-launch 2022-05-14 21:12:16 +02:00
smartfrigde
5893f5bea9 Add auto-launch and bunch of other things 2022-05-14 21:02:09 +02:00
smartfrigde
6663b6de5f Add missing setting to setup and settings menu 2022-05-14 20:00:33 +02:00
smartfrigde
1222a37a44 Fix image pasting 2022-05-14 19:55:06 +02:00
smartfridge
d1d7c5834c
Fix broken json 2022-05-13 21:34:22 +02:00
smartfridge
aac1df6ca9
Update Electron to 18.2.3
Fixes #112
2022-05-13 21:32:54 +02:00
smartfridge
0eeb1b3855
Update package.json 2022-05-13 21:27:09 +02:00
dependabot[bot]
dfcdd14fb2
Bump ejs from 3.1.6 to 3.1.8 (#113)
Bumps [ejs](https://github.com/mde/ejs) from 3.1.6 to 3.1.8.
- [Release notes](https://github.com/mde/ejs/releases)
- [Changelog](https://github.com/mde/ejs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/mde/ejs/compare/v3.1.6...v3.1.8)

---
updated-dependencies:
- dependency-name: ejs
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-05-13 21:24:07 +02:00
dependabot[bot]
9a24d44bfa
Bump ws from 8.5.0 to 8.6.0 (#106)
Bumps [ws](https://github.com/websockets/ws) from 8.5.0 to 8.6.0.
- [Release notes](https://github.com/websockets/ws/releases)
- [Commits](https://github.com/websockets/ws/compare/8.5.0...8.6.0)

---
updated-dependencies:
- dependency-name: ws
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-05-13 21:23:18 +02:00
dependabot[bot]
b86cb5546d
Bump husky from 7.0.4 to 8.0.1 (#108)
Bumps [husky](https://github.com/typicode/husky) from 7.0.4 to 8.0.1.
- [Release notes](https://github.com/typicode/husky/releases)
- [Commits](https://github.com/typicode/husky/compare/v7.0.4...v8.0.1)

---
updated-dependencies:
- dependency-name: husky
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-05-13 21:23:11 +02:00
dependabot[bot]
466597727e
Bump @types/node from 17.0.25 to 17.0.33 (#111)
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 17.0.25 to 17.0.33.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-05-13 21:23:04 +02:00
dependabot[bot]
e3a7d9797f
Bump typescript from 4.6.3 to 4.6.4 (#104)
Bumps [typescript](https://github.com/Microsoft/TypeScript) from 4.6.3 to 4.6.4.
- [Release notes](https://github.com/Microsoft/TypeScript/releases)
- [Commits](https://github.com/Microsoft/TypeScript/compare/v4.6.3...v4.6.4)

---
updated-dependencies:
- dependency-name: typescript
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-05-13 21:22:44 +02:00
smartfridge
94183d8fee
Add Jetbrains logo into readme 2022-05-13 15:17:29 +02:00
Alyxia Sother
0df10b79ee
Upgrade Electron to 18.1.0 (#100) 2022-04-25 18:43:28 +02:00
smartfrigde
28994989ab Move all of the translations to this repo 2022-04-24 16:06:00 +02:00
smartfridge
abd2d9d920
Add English translation 2022-04-24 16:02:09 +02:00
Alyxia Sother
eca41529d4
Re-do the setup page (#98) 2022-04-24 14:49:16 +02:00
smartfridge
46ddad4044
Delete codeql-analysis.yml 2022-04-22 22:26:57 +02:00
Alyxia Sother
a69e617660
Merge branch 'dev' of git-a:ArmCord/ArmCord into dev 2022-04-22 22:21:36 +02:00
Alyxia Sother
73347d557e
Skip updater if running development version 2022-04-22 22:20:47 +02:00
Alyxia Sother
6876cc0ec1
Replace the version number for dev builds 2022-04-22 21:24:37 +02:00
smartfrigde
4c8cd2bf57 Make window decorations work on Gnome Wayland 2022-04-22 20:39:00 +02:00
smartfrigde
3e8526f0f7 Add wayland specific patches 2022-04-22 20:30:09 +02:00
smartfrigde
41933e3c4f Update assets and add new ones 2022-04-21 18:20:58 +02:00
smartfrigde
1666b8a098 Fix corrupted settings checker 2022-04-21 15:23:06 +02:00
smartfrigde
495a813af1 Add experimental Discord AC theme 2022-04-20 21:50:23 +02:00
smartfrigde
c5368da0ca Add no client mods option to settings 2022-04-20 21:05:03 +02:00
smartfrigde
4b4e72ccf4 Readme fixes and weblate mention 2022-04-20 20:43:38 +02:00
smartfrigde
97e8fb5e69 Fix setup not working, css additions 2022-04-20 20:30:52 +02:00
smartfridge
61104a166e
Make dev workflow only trigger on dev branch 2022-04-20 17:32:54 +02:00
smartfridge
aac52167f1
Add dev build notice 2022-04-20 17:15:51 +02:00
smartfridge
009f6ba19a
Fix github token not loading 2022-04-20 16:53:50 +02:00
smartfridge
03082d3d7f
Arm64 build + delete latest prerelease 2022-04-20 16:52:37 +02:00
smartfridge
095a060be5
Update README.md 2022-04-19 22:45:01 +02:00
dependabot[bot]
07d5cd15d0
Bump @types/node from 17.0.24 to 17.0.25 (#96)
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 17.0.24 to 17.0.25.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-04-19 22:45:01 +02:00
dependabot[bot]
9599013977
Bump electron-builder from 22.5.1 to 23.0.3 (#95)
Bumps [electron-builder](https://github.com/electron-userland/electron-builder/tree/HEAD/packages/electron-builder) from 22.5.1 to 23.0.3.
- [Release notes](https://github.com/electron-userland/electron-builder/releases)
- [Changelog](https://github.com/electron-userland/electron-builder/blob/master/packages/electron-builder/CHANGELOG.md)
- [Commits](https://github.com/electron-userland/electron-builder/commits/v23.0.3/packages/electron-builder)

---
updated-dependencies:
- dependency-name: electron-builder
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-04-19 22:45:00 +02:00
smartfrigde
be6364cdfa
Add dev build CI 2022-04-19 22:44:05 +02:00
smartfrigde
7a7dd05163 Make invite websocket togglable 2022-04-19 19:59:52 +02:00
smartfrigde
37966b985a Fix websocket not unlocking when window is closed manually 2022-04-19 16:10:12 +02:00
smartfrigde
eda6621989 Fix websocket logger 2022-04-19 16:02:30 +02:00
smartfrigde
3d0fd7071b Add websocket for invitation link requests 2022-04-19 15:56:04 +02:00
smartfrigde
bac604a7cc Get rid of electron-json-storage and switch to our own solution 2022-04-18 13:03:26 +02:00
smartfrigde
9d2a1190cf Remove legacy config helper functions 2022-04-18 12:25:10 +02:00
smartfrigde
a39fe281f6 Add ArmCord storage manager 2022-04-18 12:20:38 +02:00
smartfrigde
40239159ed Fix corrupted config checker 2022-04-18 12:06:17 +02:00
smartfrigde
1a461e9a32 Backport things from stable branch back to dev 2022-04-18 12:05:06 +02:00
37 changed files with 1454 additions and 963 deletions

3
.github/release.md vendored Normal file
View file

@ -0,0 +1,3 @@
# Thanks for checking out ArmCord dev builds!
These builds are unstable and not ready for full release. They contain new experimental features and changes. We provide no official support for them.
Make sure to join our [Discord server](https://discord.gg/uaW5vMY3V6) to share opinions, or to chat with ArmCord developers!

40
.github/workflows/build.yml vendored Normal file
View file

@ -0,0 +1,40 @@
name: Build/release
on:
push:
branches:
- stable
jobs:
release:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [macos-latest, ubuntu-latest, windows-latest]
steps:
- name: Check out Git repository
uses: actions/checkout@v1
- name: Install Node.js, NPM and Yarn
uses: actions/setup-node@v1
with:
node-version: 16
- name: Build/release Electron app
uses: samuelmeuli/action-electron-builder@v1
with:
# GitHub token, automatically provided to the action
# (No need to define this secret in the repo settings)
github_token: ${{ secrets.github_token }}
# skip npm run build as there's no script like that
skip_build: false
# If the commit is tagged with a version (e.g. "v1.0.0"),
# release the app after building
release: ${{ startsWith(github.ref, 'refs/tags/v') }} #disabled for now as it caused problems (nvm)
- name: Archive production builds
uses: actions/upload-artifact@v2
with:
name: dist folder
path: dist/**

View file

@ -1,71 +0,0 @@
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL"
on:
push:
branches: [ main ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ main ]
schedule:
- cron: '23 16 * * 4'
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
language: [ 'javascript' ]
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ]
# Learn more:
# https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed
steps:
- name: Checkout repository
uses: actions/checkout@v2
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v1
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# queries: ./path/to/local/query, your-org/your-repo/queries@main
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v1
# Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
# and modify them (or add more) to build your code if your project
# uses a compiled language
#- run: |
# make bootstrap
# make release
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v1

161
.github/workflows/dev.yml vendored Normal file
View file

@ -0,0 +1,161 @@
name: Dev build
on:
push:
branches:
- dev
env:
FORCE_COLOR: true
jobs:
build-linux:
runs-on: ubuntu-latest
steps:
- uses: actions/setup-node@v3
with:
node-version: '18'
- name: Checkout code
uses: actions/checkout@v2
- name: Install Node dependencies
run: npm install
- name: Install Electron-Builder
run: npm install -g electron-builder
- name: Replace the version number
run: cat src/utils.ts | sed -e 's/[[:digit:]]\.[[:digit:]]\.[[:digit:]]/DEV/g' | tee src/utils.ts > /dev/null
- name: Build
run: npm run build && electron-builder --linux zip && electron-builder --arm64 --linux zip
- name: Upload artifact
uses: actions/upload-artifact@v2
with:
name: ArmCordLinux.zip
path: dist/ArmCord-3.1.0.zip
- name: Upload artifact
uses: actions/upload-artifact@v2
with:
name: ArmCordLinuxArm64.zip
path: dist/ArmCord-3.1.0-arm64.zip
build-mac:
runs-on: macos-latest
steps:
- uses: actions/setup-node@v3
with:
node-version: '18'
- name: Checkout code
uses: actions/checkout@v2
- name: Install Node dependencies
run: npm install
- name: Install Electron-Builder
run: npm install -g electron-builder
- name: Replace the version number
run: cat src/utils.ts | sed -e 's/[[:digit:]]\.[[:digit:]]\.[[:digit:]]/DEV/g' | tee src/utils.ts > /dev/null
- name: Build
run: npm run build && electron-builder --macos zip
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Upload artifact
uses: actions/upload-artifact@v2
with:
name: ArmCordMac.zip
path: dist/ArmCord-3.1.0-mac.zip
build-windows:
runs-on: windows-latest
steps:
- uses: actions/setup-node@v3
with:
node-version: '18'
- name: Checkout code
uses: actions/checkout@v2
- name: Install Node dependencies
run: npm install
- name: Install Electron-Builder
run: npm install -g electron-builder
- name: Replace the version number
run: (Get-Content src/utils.ts) -replace "\d\.\d\.\d", "DEV" | Out-File src/utils.ts
- name: Build
run: npm run build && electron-builder --windows zip
- name: Upload artifact
uses: actions/upload-artifact@v2
with:
name: ArmCordWindows.zip
path: dist/ArmCord-3.1.0-win.zip
release:
runs-on: ubuntu-latest
needs: [build-linux, build-mac, build-windows]
steps:
- name: Checkout code
uses: actions/checkout@v2
- uses: actions/download-artifact@v2
with:
name: ArmCordMac.zip
path: macos
- uses: actions/download-artifact@v2
with:
name: ArmCordWindows.zip
path: windows
- uses: actions/download-artifact@v2
with:
name: ArmCordLinux.zip
path: linux
- uses: actions/download-artifact@v2
with:
name: ArmCordLinuxArm64.zip
path: linux
- name: Get some values needed for the release
id: vars
shell: bash
run: |
echo "::set-output name=sha_short::$(git rev-parse --short HEAD)"
- uses: dev-drprasad/delete-tag-and-release@v0.2.0
with:
delete_release: true
tag_name: devbuild
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Create the release
uses: softprops/action-gh-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: devbuild
name: Dev Build ${{ steps.vars.outputs.sha_short }}
draft: false
prerelease: true
body_path: .github/release.md
files: |
linux/ArmCord-3.1.0.zip
linux/ArmCord-3.1.0-arm64.zip
macos/ArmCord-3.1.0-mac.zip
windows/ArmCord-3.1.0-win.zip

View file

@ -1,6 +1,7 @@
# Some prettier-specific files so it doesn't die.
**/*.png
**/*.ico
**/*.woff
LICENSE
.gitignore

View file

@ -32,7 +32,7 @@
# How to run/install it?
### Recommended:
Check releases tab for precompiled packages for Linux, Windows and ~~Mac OS~~ (Mac OS is broken see [#48](https://github.com/ArmCord/ArmCord/issues/48)). Alternatively use our Sourceforge mirror.
Check releases tab for precompiled packages for Linux, Windows and Mac OS. Alternatively use our Sourceforge mirror.
<a href="https://sourceforge.net/projects/armcord/files/latest/download"><img alt="Download ArmCord" src="https://a.fsdn.com/con/app/sf-download-button" width=276 height=48 srcset="https://a.fsdn.com/con/app/sf-download-button?button_size=2x 2x"></a>
### AUR Package
Armcord is also available on the Arch User Repository (AUR) [here](https://aur.archlinux.org/packages/armcord-bin/).
@ -51,14 +51,15 @@ Install it via an AUR helper tool like `yay`.
# FAQ
## 1. Will I get banned from using it?
-You are breaking Discord ToS if you decided to use client mods. But no one ever got banned from using ArmCord or any of the client mods included. If you wish to remove mods, check our documentation.
- You are breaking Discord ToS if you decided to use client mods. But no one ever got banned from using ArmCord or any of the client mods included. If you wish to remove mods, check our documentation.
## 2. How does this work?
-We are using official web app and adding some magic powder to make it all work!
- We are using official web app and adding some magic powder to make it all work!
## 3. Can I use this on other architectures or operating systems?
-Yes! ArmCord should work normally under Windows, ~~Mac OS~~ (Mac OS is broken see [#48](https://github.com/ArmCord/ArmCord/issues/48)) and Linux as long as it has NodeJS, npm and Electron support.
- Yes! ArmCord should work normally under Windows, Mac OS and Linux as long as it has NodeJS, npm and Electron support.
## 4. Where can I translate this?
- Translations are done using our [Weblate page](https://hosted.weblate.org/projects/armcord/armcord/). They're pushed to this [repo](https://github.com/ArmCord/i18n).
# Credits
[ArmCord UI Elements and few features](https://github.com/kckarnige)
[Cumcord](https://github.com/Cumcord/Cumcord)
@ -67,3 +68,6 @@ Install it via an AUR helper tool like `yay`.
[electron-discord-webapp](https://github.com/SpacingBat3/electron-discord-webapp)
[custom-electron-titlebar (css only)](https://github.com/AlexTorresSk/custom-electron-titlebar)
[electron-builder](https://electron.build)
# Sponsors
[![JetBrains supports ArmCord with free licenses to their software to core developers](https://resources.jetbrains.com/storage/products/company/brand/logos/jb_beam.svg)](https://jb.gg/OpenSourceSupport)

BIN
assets/ac_icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 81 KiB

After

Width:  |  Height:  |  Size: 46 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 107 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Before After
Before After

BIN
assets/ac_white_plug.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

BIN
assets/dsc-tray.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

28
assets/lang/en_US.json Normal file
View file

@ -0,0 +1,28 @@
{
"loading_screen_start": "Starting ArmCord…",
"loading_screen_offline": "You appear to be offline. Please connect to the Internet and try again.",
"loading_screen_update": "A new version of ArmCord is available. Please update to the latest version.",
"setup_question1": "Select what kind of setup you want to perform:",
"setup_question1_answer1": "Express setup",
"setup_question1_answer2": "Full setup",
"setup_offline": "You appear to be offline. Please connect to the Internet and restart the ArmCord setup.",
"setup_question2": "Choose your Discord channel/instance:",
"setup_question3": "Should ArmCord handle client mods installation?",
"yes": "Yes",
"no": "No",
"next": "Next",
"setup_question4": "Select a client mod you want to install:",
"setup_question4_clientmodnotice": "Why not all of them? Having many client mods at the same time can cause issues. If you really want to do it though, check our documentation.",
"settings-theme": "ArmCord Theme:",
"settings-theme-glasstron": "Glasstron (experimental)",
"settings-theme-tabs": "Tabs (experimental)",
"settings-theme-default": "Default",
"settings-theme-native": "Native",
"settings-tray": "Minimize to tray",
"settings-patches": "Automatic Patches",
"settings-channel": "Discord channel:",
"settings-invitewebsocket": "discord.gg support",
"settings-mod": "Client mod:",
"settings-save": "Save settings",
"settings-updater": "Check for updates"
}

28
assets/lang/fr-FR.json Normal file
View file

@ -0,0 +1,28 @@
{
"loading_screen_start": "Démarrage d'ArmCord…",
"loading_screen_update": "Une nouvelle version de ArmCord est disponible. Veuillez mettre à jour la dernière version.",
"setup_question1": "Sélectionnez le type de configuration que vous souhaitez effectuer :",
"setup_question1_answer1": "Configuration express",
"setup_question1_answer2": "Configuration complète",
"setup_question2": "Choisissez votre canal/instance Discord :",
"setup_question3": "ArmCord doit-il s'occuper de l'installation des mods clients ?",
"yes": "Oui",
"no": "Non",
"next": "Suivant",
"setup_question4": "Sélectionnez le mod client que vous souhaitez installer :",
"setup_question4_clientmodnotice": "Pourquoi pas tous ? Le fait d'avoir plusieurs mods clients en même temps peut causer des problèmes. Si vous voulez vraiment le faire, consultez notre documentation.",
"loading_screen_offline": "Vous semblez être hors ligne. Veuillez vous connecter à internet et réessayer.",
"setup_offline": "Vous semblez être hors ligne. Veuillez vous connecter à internet et redémarrer ArmCord Setup.",
"settings-tray": "Minimize to tray",
"settings-channel": "Discord channel:",
"settings-mod": "Client mod:",
"settings-save": "Save settings",
"settings-updater": "Check for updates",
"settings-theme": "ArmCord Theme:",
"settings-theme-tabs": "Tabs (experimental)",
"settings-theme-default": "Default",
"settings-theme-glasstron": "Glasstron (experimental)",
"settings-theme-native": "Native",
"settings-patches": "Automatic Patches",
"settings-invitewebsocket": "discord.gg support"
}

28
assets/lang/it-IT.json Normal file
View file

@ -0,0 +1,28 @@
{
"loading_screen_update": "Una nuova versione di ArmCord è disponibile. Per favore aggiorna all'ultima versione.",
"setup_question1_answer1": "Configurazione veloce",
"loading_screen_start": "Avviando Armcord…",
"loading_screen_offline": "Sembri essere offline. Per favore connettiti all'Internet e riprova.",
"setup_question1": "Seleziona quale tipo di setup vuoi eseguire:",
"setup_question2": "Seleziona il tuo canale/istanza di Discord:",
"setup_question3": "ArmCord dovrebbe gestire l'installazione di client mod?",
"yes": "Sì",
"no": "No",
"next": "Avanti",
"setup_question4": "Seleziona una client mod che vuoi installare:",
"setup_question1_answer2": "Configurazione completa",
"setup_offline": "Sembri essere offline. Per favore connettiti all'Internet e riavvia la configurazione di ArmCord.",
"setup_question4_clientmodnotice": "Perché non tutti? Avere molte client mod allo stesso tempo puo causare problemi. Se davvero vuoi farlo, vedi la nostra documentazione.",
"settings-tray": "Riduci ad icona",
"settings-channel": "Canale Discord:",
"settings-save": "Salva impostazioni",
"settings-updater": "Controlla gli aggiornamenti",
"settings-mod": "Client mod:",
"settings-theme": "ArmCord Theme:",
"settings-theme-glasstron": "Glasstron (experimental)",
"settings-theme-tabs": "Tabs (experimental)",
"settings-theme-default": "Default",
"settings-theme-native": "Native",
"settings-patches": "Automatic Patches",
"settings-invitewebsocket": "discord.gg support"
}

28
assets/lang/nb-NO.json Normal file
View file

@ -0,0 +1,28 @@
{
"loading_screen_start": "Starter ArmCord …",
"loading_screen_offline": "Koble til Internett og prøv igjen.",
"loading_screen_update": "En ny versjon av ArmCord er tilgjengelig. Oppgrader til siste versjon.",
"setup_question1": "Velg hvilket oppsett du ønsker å utføre:",
"setup_question1_answer2": "Fullt oppsett",
"setup_question2": "Velg din Discor-kanal/instans:",
"yes": "Ja",
"no": "Nei",
"setup_question1_answer1": "Hurtigoppsett",
"setup_question3": "Skal ArmCord håndtere installasjon av klient-modifikasjoner?",
"setup_offline": "Koble til Internett og start ArmCord-oppsett på ny.",
"next": "Neste",
"setup_question4": "Velg en klient-modifikasjon du ønsker å installere:",
"setup_question4_clientmodnotice": "Hvorfor ikke alle? Å ha mange klient-modifikasjoner samtidig kan forårsake problemer. Hvis du vil gjøre det likevel bør du lese dokumentasjonen vår.",
"settings-tray": "Minimize to tray",
"settings-channel": "Discord channel:",
"settings-mod": "Client mod:",
"settings-save": "Save settings",
"settings-updater": "Check for updates",
"settings-theme": "ArmCord Theme:",
"settings-theme-glasstron": "Glasstron (experimental)",
"settings-theme-tabs": "Tabs (experimental)",
"settings-theme-default": "Default",
"settings-theme-native": "Native",
"settings-patches": "Automatic Patches",
"settings-invitewebsocket": "discord.gg support"
}

28
assets/lang/nl-NL.json Normal file
View file

@ -0,0 +1,28 @@
{
"setup_question1": "Selecteer wat voor soort setup je wilt starten:",
"setup_question1_answer1": "Express setup",
"setup_question1_answer2": "Volledige setup",
"setup_question3": "Moet ArmCord client mods installeren?",
"yes": "Ja",
"no": "Nee",
"setup_offline": "Het lijkt erop alsof je offline bent. Verbind met het Internet en herstart ArmCord setup.",
"loading_screen_start": "ArmCord starten…",
"next": "Volgende",
"setup_question4": "Selecteer een client mod om te installeren:",
"setup_question4_clientmodnotice": "Waarom niet allemaal? Meerdere client mods installeren kan problemen veroorzaken. Als je dit echt wilt doen, kan je de documentatie bekijken.",
"loading_screen_offline": "Het lijkt erop alsof je offline bent. Verbind met het Internet en probeer opnieuw.",
"loading_screen_update": "Een nieuwe versie van ArmCord is beschikbaar. Update alstublieft naar de nieuwste versie.",
"setup_question2": "Kies je Discord kanaal/instantie:",
"settings-tray": "Minimaliseer naar pictogram in het systeemvak",
"settings-channel": "Discord kanaal:",
"settings-mod": "Client mod:",
"settings-save": "Instellingen opslaan",
"settings-updater": "Check voor updates",
"settings-patches": "Automatische Patches",
"settings-theme": "ArmCord Thema:",
"settings-theme-glasstron": "Glasstron (experimenteel)",
"settings-theme-tabs": "Tabs (experimenteel)",
"settings-theme-default": "Standaard",
"settings-theme-native": "Native",
"settings-invitewebsocket": "discord.gg support"
}

28
assets/lang/pl-PL.json Normal file
View file

@ -0,0 +1,28 @@
{
"loading_screen_update": "Nowa wersja ArmCord jest dostępna. Proszę zaktualizować aplikację do najnowszej wersji.",
"setup_question1_answer2": "Pełna konfiguracja",
"setup_question2": "Wybierz swój kanał/odmianę Discorda:",
"setup_question3": "Czy ArmCord powinienem zajmować sie instalacją modyfikacji klienta?",
"yes": "Tak",
"no": "Nie",
"next": "Dalej",
"setup_question4": "Wybierz modyfikację klienta którą chcesz zainstalować:",
"setup_question4_clientmodnotice": "Dlaczego nie wszystkie na raz? Posiadanie wielu modyfikacji może spowodować wiele błędów. Jeśli jednak nalegasz możesz sprawdzić naszą dokumentację.",
"loading_screen_start": "Ładowanie ArmCord…",
"loading_screen_offline": "Wydaje nam się, że nie jesteś połączony z Internetem. Połącz się z internetem i spróbuj ponownie.",
"setup_question1_answer1": "Ekspresowa konfiguracja",
"setup_question1": "Wybierz w jaki sposób chcesz skonfigurować ArmCord:",
"setup_offline": "Wydaje nam się że nie jesteś połączony z internetem. Połącz się z internetem i uruchom ponownie konfiguracje ArmCord .",
"settings-channel": "Kanał Discorda:",
"settings-updater": "Sprawdź aktualizacje",
"settings-tray": "Zminimalizuj do zasobnika zadań",
"settings-save": "Zapisz ustawienia",
"settings-mod": "Modyfikacja klienta:",
"settings-theme": "Motyw ArmCord:",
"settings-theme-glasstron": "Glasstron (eksperymentalne)",
"settings-theme-tabs": "Karty (eksperymentalne)",
"settings-theme-default": "Domyślny",
"settings-theme-native": "Natywny",
"settings-patches": "Automatyczne łatki",
"settings-invitewebsocket": "Wsparcie linków discord.gg"
}

680
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,6 @@
{
"name": "ArmCord",
"version": "3.1.0",
"version": "3.0.6",
"description": "ArmCord is a custom client designed to enhance your Discord experience while keeping everything lightweight.",
"main": "ts-out/main.js",
"scripts": {
@ -9,6 +9,7 @@
"start": "npm run build && electron ./ts-out/main.js",
"package": "npm run build && electron-builder",
"format": "prettier --write src/**/*",
"CIbuild": "npm run build && electron-builder --linux zip && electron-builder --windows zip && electron-builder --macos zip",
"postinstall": "husky install"
},
"repository": {
@ -22,21 +23,19 @@
},
"homepage": "https://github.com/armcord/armcord#readme",
"devDependencies": {
"@types/electron-json-storage": "^4.5.0",
"@types/node": "^17.0.24",
"@types/node": "^17.0.33",
"@types/ws": "^8.5.3",
"copyfiles": "^2.4.1",
"electron": "^18.0.4",
"electron": "^18.2.3",
"electron-builder": "^23.0.3",
"husky": "^7.0.4",
"husky": "^8.0.1",
"prettier": "^2.5.1",
"typescript": "^4.5.4"
"typescript": "^4.6.3"
},
"dependencies": {
"electron-context-menu": "^3.1.2",
"electron-json-storage": "^4.5.0",
"electron-tabs": "^0.17.0",
"glasstron": "^0.1.1",
"v8-compile-cache": "^2.3.0"
"electron-context-menu": "https://github.com/ArmCord/electron-context-menu.git",
"v8-compile-cache": "^2.3.0",
"ws": "^8.6.0"
},
"build": {
"appId": "com.smartfridge.armcord",

View file

@ -10,3 +10,6 @@
.notice-2HEN-u {
display: none;
}
.sidebar-1tnWFu {
border-top-left-radius: 8px !important;
}

Binary file not shown.

View file

@ -1,91 +1,148 @@
/*CSS ONLY FOR INTERNAL USE (setup and loading)*/
@import url("https://kckarnige.github.io/femboi_owo/discord-font.css");
@import url("https://armcord.smartfridge.space/logofont.css");
/* Meta {{{ */
:root {
background-color: #2c2f33 !important;
--header-secondary: #b9bbbe !important;
--header-primary: #fff !important;
--background-tertiary: #202225 !important;
--background-primary: #282b30;
--background-secondary: rgba(255, 255, 255, 0.1);
--brand-experiment: #7289da;
--header-primary: #fff;
--text-muted: #72767d;
--font-primary: "Whitney";
}
@font-face {
font-family: Whitney;
font-weight: 400;
font-style: normal;
src: url(https://armcord.smartfridge.space/whitney_400.woff) format("woff");
}
html,
body {
background-color: #2c2f33;
color: white;
overflow: hidden;
margin: 0;
padding-top: 30px;
width: 100%;
height: 100%;
background: var(--background-primary);
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
p {
color: white;
* {
font-family: var(--font-primary), sans-serif;
box-sizing: border-box;
user-select: none;
cursor: default;
}
/* }}} */
/* Utility classes {{{ */
.hidden {
display: none !important;
}
.text-center {
text-align: center;
font-weight: 100;
font-family: Whitney, Helvetica Neue, Helvetica, Arial, sans-serif;
text-rendering: optimizeLegibility;
}
.logo {
font-size: 0px;
text-align: center;
transform: translateY(-105%);
}
.logo:before {
content: "ARM";
color: #7289da;
font-weight: normal;
font-family: Helvetica, sans-serif;
font-size: 32px;
}
.logo:after {
content: "Cord";
color: #ffffff;
font-weight: normal;
font-family: Discordinated;
font-size: 32px;
}
span {
text-align: center;
}
.logo {
display: block;
margin-left: auto;
margin-right: auto;
max-height: 204px;
max-width: 204px;
transform: translateY(5%);
}
.container {
position: fixed;
top: 50%;
left: 50%;
color: #fff;
transform: translate(-50%, -50%);
}
button#express {
margin-right: 84px;
}
button {
background-color: #7289da;
font-family: Whitney, "Helvetica Neue", Helvetica, Arial, sans-serif;
color: #ffffff;
padding: 4px;
border-radius: 5px;
margin-top: 5px;
text-align: center;
border-style: none;
outline: none;
}
.setup-ask {
font-size: 20px;
}
.center {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
/* }}} */
#setup {
display: flex;
flex-direction: column;
align-items: center;
color: white;
}
/* Warning {{{ */
#warning {
font-size: 1.5em;
font-weight: bold;
text-align: center;
margin-top: 10px;
margin-bottom: 10px;
max-width: 328px;
background-color: rgba(255, 0, 0, 0.1);
border: red solid 2px;
border-radius: 0.5rem;
}
#warning > p {
color: white;
font-weight: bold;
margin: 1rem;
}
/* }}} */
/* Logo {{{ */
#logo {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
}
#logo p:first-child {
color: #7289da;
margin: 0;
font-weight: normal;
font-family: Helvetica, sans-serif;
font-size: 32px;
}
#logo p:last-child {
color: white;
margin: 0;
font-weight: normal;
font-family: Discordinated;
font-size: 32px;
}
/* }}} */
/* Buttons {{{ */
#buttons {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
gap: 1rem;
user-select: all !important;
margin-top: 10px;
margin-bottom: 10px;
}
button {
background: var(--brand-experiment);
color: var(--header-primary);
border: none;
border-radius: 4px;
padding: 8px 20px;
}
button:hover {
background-color: #687dc6;
border-style: none;
outline: none;
filter: brightness(85%);
cursor: pointer;
}
/* }}} */
/* Dropdowns {{{ */
select {
-webkit-appearance: button;
-moz-appearance: button;
@ -106,6 +163,4 @@ select {
text-overflow: ellipsis;
white-space: nowrap;
}
.center {
text-align: center;
}
/* }}} */

View file

@ -1,4 +1,4 @@
@import url("https://kckarnige.github.io/femboi_owo/discord-font.css");
@import url("https://armcord.smartfridge.space/logofont.css");
:root {
--window-buttons: var(--header-secondary);
--cord-color: var(--header-primary);

View file

@ -1,60 +1,33 @@
<!--- This is awful and should be replaced in later versions. Possibly based of current settings as of 3.1.0 version. If you have time please PR a better setup screen. --->
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="https://cdn.metroui.org.ua/v4/css/metro-all.min.css" />
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>ArmCord Setup</title>
<style>
@import url("css/setup.css");
</style>
</head>
<body>
<div class="container">
<h1 class="logo"></h1>
<div id="warning" class="hidden">
<p>You appear to be offline. Please connect to the internet and restart ArmCord Setup.</p>
</div>
<div id="setup">
<p>Select what kind of setup you want to perform:</p>
<button id="express" class="center">Express setup</button>
<button id="full" class="center">Full setup</button>
<div id="logo" class="hidden">
<p>ARM</p>
<p>Cord</p>
</div>
<div id="page1" class="hidden">
<p>Select the type of setup you want to perform.</p>
<div id="buttons">
<button id="express" class="center">Express</button>
<button id="full" class="center">Full</button>
</div>
</div>
<script>
function fade(element) {
var op = 1; // initial opacity
var timer = setInterval(function () {
if (op <= 0.1) {
clearInterval(timer);
element.style.display = "none";
}
element.style.opacity = op;
element.style.filter = "alpha(opacity=" + op * 100 + ")";
op -= op * 0.1;
}, 50);
}
if (window.navigator.onLine === false) {
document.getElementById("setup").innerHTML =
"You appear to be offline. Please connect to the internet and restart ArmCord Setup.";
} else {
console.log("Starting ArmCord Setup...");
document.getElementById("express").addEventListener("click", function () {
window.armcordinternal.saveSettings({
windowStyle: "default",
channel: "stable",
armcordCSP: true,
minimizeToTray: true,
automaticPatches: false,
mods: "cumcord",
blurType: "acrylic"
});
fade(document.getElementById("setup"));
setTimeout(function () {
window.armcordinternal.restart();
}, 5000);
});
document.getElementById("full").addEventListener("click", function () {
document.getElementById("setup").innerHTML = `
<div id="page2" class="hidden">
<p class="text-center setup-ask">Choose your Discord channel/instance:</p>
<div class="center">
<select name="channel" id="channel" class="dropdown-button">
@ -71,13 +44,12 @@
<option value="false">No</option>
</select>
</div>
<div id="buttons">
<button id="next" class="center">Next</button>
`;
document.getElementById("next").addEventListener("click", function () {
var branch = document.getElementById("channel").value;
var csp = document.getElementById("csp").value;
if (csp === "true") {
document.getElementById("setup").innerHTML = `
</div>
</div>
<div id="page3" class="hidden">
<p class="text-center setup-ask">Select a client mod you want to install:</p>
<div class="center">
<select name="mod" id="mod" class="dropdown-button">
@ -86,43 +58,99 @@
<option value="flicker">Flicker (Heavily WIP)</option>
</select>
</div>
<p>Why not all of them? Having many client mods at the same time can cause issues. If you really want to do it though, check our documentation ;)</p>
<p>
Why not all of them? Having many client mods at the same time can cause issues. If you really
want to do it though, check our documentation ;)
</p>
<div id="buttons">
<button id="next" class="center">Next</button>
`;
document.getElementById("next").addEventListener("click", function () {
var mod = document.getElementById("mod").value;
</div>
</div>
</div>
</div>
<script>
// Accessors {{{
let options = {};
let logo = document.getElementById("logo");
logo.classList.remove("hidden");
let page1 = document.getElementById("page1");
page1.classList.remove("hidden");
page1.buttons = document.querySelectorAll("#page1 > #buttons > button");
// Connection check
let warning = document.getElementById("warning");
if (window.navigator.onLine === false) {
warning.classList.remove("hidden");
}
let page2 = document.getElementById("page2");
let page3 = document.getElementById("page3");
// }}}
// Express
page1.buttons[0].addEventListener("click", () => {
window.armcordinternal.saveSettings({
windowStyle: "default",
channel: branch,
channel: "stable",
armcordCSP: true,
autoLaunch: true,
minimizeToTray: true,
automaticPatches: false,
mods: mod,
mods: "cumcord",
inviteWebsocket: true,
blurType: "acrylic"
});
fade(document.getElementById("setup"));
setTimeout(function () {
window.armcordinternal.restart();
}, 5000);
setTimeout(() => window.armcordinternal.restart(), 5000);
});
// Full
page1.buttons[1].addEventListener("click", () => {
page1.classList.add("hidden");
page2.classList.remove("hidden");
});
page2.buttons = document.querySelectorAll("#page2 > #buttons > button");
page2.buttons[0].addEventListener("click", () => {
options.channel = document.getElementById("channel").value;
options.csp = document.getElementById("csp").value;
page2.classList.add("hidden");
page3.buttons = document.querySelectorAll("#page3 > #buttons > button");
if (options.csp === "true") {
page3.classList.remove("hidden");
page3.buttons[0].addEventListener("click", () => {
options.mod = document.getElementById("mod").value;
window.armcordinternal.saveSettings({
windowStyle: "default",
channel: options.channel,
armcordCSP: true,
autoLaunch: true,
minimizeToTray: true,
automaticPatches: false,
mods: options.mod,
inviteWebsocket: true,
blurType: "acrylic"
});
setTimeout(() => window.armcordinternal.restart(), 500);
});
} else {
window.armcordinternal.saveSettings({
windowStyle: "default",
channel: branch,
channel: options.channel,
armcordCSP: true,
minimizeToTray: true,
automaticPatches: false,
autoLaunch: true,
mods: "none",
inviteWebsocket: true,
blurType: "acrylic"
});
fade(document.getElementById("setup"));
setTimeout(function () {
window.armcordinternal.restart();
}, 5000);
setTimeout(() => window.armcordinternal.restart(), 500);
}
});
});
}
</script>
</body>
</html>

View file

@ -22,7 +22,10 @@
text.innerHTML = "You appear to be offline. Please connect to the internet and try again.";
} else {
text.innerHTML = "Starting ArmCord...";
fetch("https://armcord.smartfridge.space/latest.json")
if (window.armcord.version === "DEV") {
console.log("Running a development build of ArmCord. Skipping updater.");
} else {
fetch("https://armcord.xyz/latest.json")
.then((response) => response.json())
.then((data) => {
if (data.version !== window.armcord.version) {
@ -31,11 +34,13 @@
elem.src = "https://armcord.smartfridge.space/update.webp";
document.body.prepend(elem);
document.getElementById("splashscreen-armcord").remove();
text.innerHTML = "A new version of ArmCord is available. Please update to the latest version.";
text.innerHTML =
"A new version of ArmCord is available. Please update to the latest version.";
} else {
console.log("ArmCord is up to date.");
}
});
}
setTimeout(() => {
window.armcordinternal.splashEnd();
switch (window.armcord.channel) {

View file

@ -9,7 +9,7 @@ The above copyright notice and this permission notice shall be included in all c
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
import electron from "electron";
import * as storage from "electron-json-storage";
import {getConfig} from "../utils";
const otherMods = {
generic: {
electronProxy: require("util").types.isProxy(electron) // Many modern mods overwrite electron with a proxy with a custom BrowserWindow (copied from PowerCord)
@ -55,9 +55,9 @@ const unstrictCSP = () => {
done({responseHeaders});
});
};
storage.get("settings", function (error, data: any) {
if (error) throw error;
if (data.armcordCSP) {
electron.app.whenReady().then(async () => {
if (await getConfig("armcordCSP")) {
unstrictCSP();
} else {
console.log("ArmCord CSP is disabled. The CSP should be managed by third-party plugin.");

View file

@ -1,8 +1,8 @@
//ipc stuff
import {app, ipcMain, shell, desktopCapturer} from "electron";
import {createTabsGuest, mainWindow} from "./window";
import {saveSettings, getVersion} from "./utils";
import {settings, customTitlebar, tabs} from "./main";
import {setConfigBulk, getVersion, getConfig} from "./utils";
import {customTitlebar, tabs} from "./main";
import {createSettingsWindow} from "./settings/main";
export function registerIpc() {
ipcMain.on("get-app-path", (event, arg) => {
@ -46,17 +46,16 @@ export function registerIpc() {
app.exit();
});
ipcMain.on("saveSettings", (event, args) => {
saveSettings(args);
setConfigBulk(args);
});
ipcMain.on("minimizeToTray", (event) => {
console.log(settings.minimizeToTray);
event.returnValue = settings.minimizeToTray;
ipcMain.on("minimizeToTray", async (event) => {
event.returnValue = await getConfig("minimizeToTray");
});
ipcMain.on("channel", (event) => {
event.returnValue = settings.channel;
ipcMain.on("channel", async (event) => {
event.returnValue = await getConfig("channel");
});
ipcMain.on("clientmod", (event, arg) => {
event.returnValue = settings.mods;
ipcMain.on("clientmod", async (event, arg) => {
event.returnValue = await getConfig("mods");
});
ipcMain.on("titlebar", (event, arg) => {
event.returnValue = customTitlebar;
@ -64,14 +63,14 @@ export function registerIpc() {
ipcMain.on("tabs", (event, arg) => {
event.returnValue = tabs;
});
ipcMain.on("shouldPatch", (event, arg) => {
event.returnValue = settings.automaticPatches;
ipcMain.on("shouldPatch", async (event, arg) => {
event.returnValue = await getConfig("automaticPatches");
});
ipcMain.on("openSettingsWindow", (event, arg) => {
createSettingsWindow();
});
ipcMain.on("setting-armcordCSP", (event) => {
if (settings.armcordCSP) {
ipcMain.on("setting-armcordCSP", async (event) => {
if (await getConfig("armcordCSP")) {
event.returnValue = true;
} else {
event.returnValue = false;

View file

@ -1,52 +1,32 @@
// Modules to control application life and create native browser window
import {app, BrowserWindow, session} from "electron";
import * as path from "path";
import {app, BrowserWindow, session, dialog} from "electron";
import "v8-compile-cache";
import * as storage from "electron-json-storage";
import {getConfigUnsafe, setup} from "./utils";
import {getConfig, setup, checkIfConfigExists} from "./utils";
import "./extensions/mods";
import "./extensions/plugin";
import "./tray";
import {mainWindow, createCustomWindow, createNativeWindow, createGlasstronWindow, createTabsHost} from "./window";
import {createCustomWindow, createNativeWindow, createTabsHost} from "./window";
import "./shortcuts";
export var contentPath: string;
var channel: string;
export var settings: any;
export var customTitlebar: boolean;
export var tabs: boolean;
async function appendSwitch() {
if ((await getConfigUnsafe("windowStyle")) == "glasstron") {
console.log("Enabling transparency visuals.");
app.commandLine.appendSwitch("enable-transparent-visuals");
if (process.platform == "linux") {
if (process.env.$XDG_SESSION_TYPE == "wayland") {
console.log("Wayland specific patches applied.")
app.commandLine.appendSwitch("ozone-platform=wayland");
if (process.env.$XDG_CURRENT_DESKTOP == "GNOME") {
app.commandLine.appendSwitch("enable-features=UseOzonePlatform,WaylandWindowDecorations");
} else {
app.commandLine.appendSwitch("enable-features=UseOzonePlatform");
}
}
}
appendSwitch();
storage.has("settings", function (error, hasKey) {
if (error) throw error;
checkIfConfigExists();
if (!hasKey) {
console.log("First run of the ArmCord. Starting setup.");
setup();
contentPath = path.join(__dirname, "/content/setup.html");
if (!contentPath.includes("ts-out")) {
contentPath = path.join(__dirname, "/ts-out/content/setup.html");
}
} else {
console.log("ArmCord has been run before. Skipping setup.");
contentPath = path.join(__dirname, "/content/splash.html");
if (!contentPath.includes("ts-out")) {
contentPath = path.join(__dirname, "/ts-out/content/splash.html");
}
}
});
storage.get("settings", function (error, data: any) {
if (error) throw error;
console.log(data);
channel = data.channel;
settings = data;
});
app.whenReady().then(async () => {
switch (await getConfigUnsafe("windowStyle")) {
switch (await getConfig("windowStyle")) {
case "default":
createCustomWindow();
customTitlebar = true;
@ -54,16 +34,15 @@ app.whenReady().then(async () => {
case "native":
createNativeWindow();
break;
case "discord":
createNativeWindow();
break;
case "glasstron":
setTimeout(
createGlasstronWindow,
process.platform == "linux" ? 1000 : 0
// Electron has a bug on linux where it
// won't initialize properly when using
// transparency. To work around that, it
// is necessary to delay the window
// spawn function.
dialog.showErrorBox(
"Glasstron is unsupported.",
"This build doesn't include Glasstron functionality, please edit windowStyle value in your settings.json to something different (default for example)"
);
app.quit();
break;
case "tabs":
createTabsHost();
@ -86,7 +65,7 @@ app.whenReady().then(async () => {
});
app.on("activate", async function () {
if (BrowserWindow.getAllWindows().length === 0)
switch (await getConfigUnsafe("windowStyle")) {
switch (await getConfig("windowStyle")) {
case "default":
createCustomWindow();
break;
@ -94,7 +73,15 @@ app.whenReady().then(async () => {
createNativeWindow();
break;
case "glasstron":
createGlasstronWindow();
dialog.showErrorBox(
"Glasstron is unsupported.",
"This build doesn't include Glasstron functionality, please edit windowStyle value in your settings.json to something different (default for example)"
);
app.quit();
break;
case "tabs":
createTabsHost();
tabs = true;
break;
default:
createCustomWindow();

View file

@ -1,22 +1,21 @@
import {BrowserWindow, shell, ipcMain} from "electron";
import * as storage from "electron-json-storage";
import {getConfigUnsafe, saveSettings, Settings} from "../utils";
import {getConfig, setConfigBulk, Settings} from "../utils";
import path from "path";
var settings: any;
var isAlreadyCreated: boolean = false;
storage.get("settings", function (error, data: any) {
if (error) throw error;
console.log(data);
settings = data;
});
var settingsWindow: BrowserWindow;
var instance: number = 0;
export function createSettingsWindow() {
if (isAlreadyCreated) {
console.log("Creating a settings window.");
instance = instance + 1;
if (instance > 1) {
if (settingsWindow) {
settingsWindow.show();
settingsWindow.restore();
}
} else {
settingsWindow = new BrowserWindow({
width: 500,
height: 500,
height: 555,
title: "ArmCord Settings",
darkTheme: true,
frame: true,
@ -27,20 +26,20 @@ export function createSettingsWindow() {
});
ipcMain.on("saveSettings", (event, args: Settings) => {
console.log(args);
saveSettings(args);
setConfigBulk(args);
});
ipcMain.handle("getSetting", (event, toGet: string) => {
return getConfigUnsafe(toGet);
return getConfig(toGet);
});
settingsWindow.webContents.setWindowOpenHandler(({url}) => {
shell.openExternal(url);
return {action: "deny"};
});
settingsWindow.loadURL(`file://${__dirname}/settings.html`);
settingsWindow.on("close", async (e) => {
e.preventDefault();
settingsWindow.hide();
settingsWindow.on("close", (event: Event) => {
ipcMain.removeHandler("getSetting");
ipcMain.removeAllListeners("saveSettings");
instance = 0;
});
isAlreadyCreated = true;
}
}

View file

@ -4,7 +4,7 @@
<meta charset="UTF-8" />
<title>ArmCord Settings</title>
<style>
@import url("settings.css");
@import url("../content/css/settings.css");
</style>
</head>
@ -13,8 +13,6 @@
<select name="theme" id="theme" class="left">
<option value="default">Default</option>
<option value="native">Native</option>
<option value="glasstron">Glasstron (experimental)</option>
<option value="tabs">Tabs (experimental)</option>
</select>
<p class="header">ArmCord theme:</p>
</div>
@ -36,6 +34,12 @@
<input class="tgl tgl-light left" id="patches" type="checkbox" />
<label class="tgl-btn left" for="patches"></label>
</div>
<br />
<div class="switch">
<label class="header">Invite Websocket</label>
<input class="tgl tgl-light left" id="websocket" type="checkbox" />
<label class="tgl-btn left" for="websocket"></label>
</div>
<div class="switch">
<select name="channel" id="channel" class="left">
<option value="stable">Stable</option>
@ -50,18 +54,11 @@
<option value="cumcord">Cumcord</option>
<option value="goosemod">GooseMod</option>
<option value="flicker">Flicker</option>
<option value="none">None</option>
</select>
<p class="header">Client mod:</p>
</div>
<div class="switch">
<select name="blurType" id="blurType" class="left">
<option value="acrylic">Acrylic</option>
<option value="blurbehind">Blur Behind</option>
<option value="transparent">Transparent</option>
<option value="none">None</option>
</select>
<p class="header">Glasstron blur type:</p>
</div>
<button id="save" class="center">Save settings</button>
</body>
@ -69,24 +66,26 @@
async function loadSettings() {
document.getElementById("csp").checked = await settings.get("armcordCSP");
document.getElementById("tray").checked = await settings.get("minimizeToTray");
document.getElementById("websocket").checked = await settings.get("inviteWebsocket");
document.getElementById("patches").value = await settings.get("automaticPatches");
document.getElementById("mod").value = await settings.get("mods");
document.getElementById("channel").value = await settings.get("channel");
document.getElementById("theme").value = await settings.get("windowStyle");
document.getElementById("blurType").value = await settings.get("blurType");
}
loadSettings();
document.getElementById("save").addEventListener("click", function () {
//function saveSettings(windowStyle: string, channelSetting: string, armcordCSPSetting: boolean, minimizeToTray: boolean, automaticPatches: boolean,modsSetting: string, blurType: string)
settings.save(
document.getElementById("theme").value,
document.getElementById("channel").value,
document.getElementById("csp").checked,
document.getElementById("tray").checked,
document.getElementById("patches").checked,
document.getElementById("mod").value,
document.getElementById("blurType").value
);
settings.save({
windowStyle: document.getElementById("theme").value,
channel: document.getElementById("channel").value,
armcordCSP: document.getElementById("csp").checked,
minimizeToTray: document.getElementById("tray").checked,
automaticPatches: document.getElementById("patches").checked,
mods: document.getElementById("mod").value,
blurType: "acrylic",
inviteWebsocket: document.getElementById("websocket").checked,
doneSetup: true
});
});
</script>
</html>

182
src/socket.ts Normal file
View file

@ -0,0 +1,182 @@
// MIT License
// Copyright (c) 2020-2022 Dawid Papiewski "SpacingBat3"
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
import type {Server, WebSocket} from "ws";
import {inviteWindow, createInviteWindow} from "./window";
async function wsLog(message: string, ...args: unknown[]) {
console.log("[WebSocket]" + message, ...args);
}
/** Generates an inclusive range (as `Array`) from `start` to `end`. */
function range(start: number, end: number) {
return Array.from({length: end - start + 1}, (_v, k) => start + k);
}
interface InviteResponse {
/** Response type/command. */
cmd: "INVITE_BROWSER";
/** Response arguments. */
args: {
/** An invitation code. */
code: string;
};
/** Nonce indentifying the communication. */
nonce: string;
}
function isInviteResponse(data: unknown): data is InviteResponse {
if (!(data instanceof Object)) return false;
if ((data as Partial<InviteResponse>)?.cmd !== "INVITE_BROWSER") return false;
if (typeof (data as Partial<InviteResponse>)?.args?.code !== "string") return false;
if (typeof (data as Partial<InviteResponse>)?.nonce !== "string") return false;
return true;
}
const messages = {
/**
* A fake, hard-coded Discord command to spoof the presence of
* official Discord client (which makes browser to actually start a
* communication with the ArmCord).
*/
handShake: {
/** Message command. */
cmd: "DISPATCH",
/** Message data. */
data: {
/** Message scheme version. */
v: 1,
/** Client properties. */
config: {
/** Discord CDN host (hard-coded for `dicscord.com` instance). */
cdn_host: "cdn.discordapp.com",
/** API endpoint (hard-coded for `dicscord.com` instance). */
api_endpoint: "//discord.com/api",
/** Client type. Can be (probably) `production` or `canary`. */
environment: "production"
}
},
evt: "READY",
nonce: null
}
};
/**
* Tries to reserve the server at given port.
*
* @returns `Promise`, which always resolves (either to `Server<WebSocket>` on
* success or `null` on failure).
*/
async function getServer(port: number) {
const {WebSocketServer} = await import("ws");
return new Promise<Server<WebSocket> | null>((resolve) => {
const wss = new WebSocketServer({host: "127.0.0.1", port});
wss.once("listening", () => resolve(wss));
wss.once("error", () => resolve(null));
});
}
/**
* Tries to start a WebSocket server at given port range. If it suceed, it will
* listen to the browser requests which are meant to be sent to official
* Discord client.
*
* Currently it supports only the invitation link requests.
*
*/
export default async function startServer() {
function isJsonSyntaxCorrect(string: string) {
try {
JSON.parse(string);
} catch {
return false;
}
return true;
}
/** Known Discord instances, including the official ones. */
const knownInstancesList = [
["Discord", new URL("https://discord.com/app")],
["Discord Canary", new URL("https://canary.discord.com/app")],
["Discord PTB", new URL("https://ptb.discord.com/app")],
["Fosscord", new URL("https://dev.fosscord.com/app")]
] as const;
let wss = null, wsPort = 6463;
for(const port of range(6463, 6472)) {
wss = await getServer(port);
if(wss !== null) {
void wsLog("ArmCord is listening at " + (port.toString()));
wsPort = port;
break;
}
}
if(wss === null) return;
let lock = false;
wss.on('connection', (wss, request) => {
const origin = request.headers.origin??'https://discord.com';
let known = false;
for(const instance of knownInstancesList) {
if(instance[1].origin === origin)
known = true;
}
if(!known) return;
wss.send(JSON.stringify(messages.handShake));
wss.once('message', (data, isBinary) => {
if(lock) return;
lock = true;
let parsedData:unknown = data;
if(!isBinary)
parsedData = data.toString();
if(isJsonSyntaxCorrect(parsedData as string))
parsedData = JSON.parse(parsedData as string);
if(isInviteResponse(parsedData)) {
// Replies to browser, so it finds the communication successful.
wss.send(JSON.stringify({
cmd: parsedData.cmd,
data: {
invite: null,
code: parsedData.args.code
},
evt: null,
nonce: parsedData.nonce
}));
createInviteWindow()
const child = inviteWindow;
if(child === undefined) return;
void child.loadURL(origin+'/invite/'+parsedData.args.code);
child.webContents.once("did-finish-load", () => {
child.show();
});
child.webContents.once("will-navigate", () => {
lock = false;
child.close();
})
child.on("close", (e) => {
lock = false;
})
// Blocks requests to ArmCord's WS, to prevent loops.
child.webContents.session.webRequest.onBeforeRequest({
urls: ['ws://127.0.0.1:'+wsPort.toString()+'/*']
}, (_details,callback) => callback({cancel: true}));
}
})
})
}

View file

@ -1,11 +1,38 @@
import {app, Menu, Tray} from "electron";
import {mainWindow} from "./window";
import { app, Menu, Tray } from "electron";
import { mainWindow } from "./window";
import { getConfig } from "./utils";
import * as path from "path";
import {createSettingsWindow} from "./settings/main";
let tray = null;
app.whenReady().then(() => {
import { createSettingsWindow } from "./settings/main";
let tray: any = null;
app.whenReady().then(async () => {
if (await getConfig("windowStyle") == "discord") {
tray = new Tray(path.join(__dirname, "../", "/assets/dsc-tray.png"));
const contextMenu = Menu.buildFromTemplate([
{
label: "Open ArmCord",
click: function () {
mainWindow.show();
}
},
{
label: "Quit ArmCord",
click: function () {
app.quit();
}
}
]);
tray.setToolTip("Discord");
tray.setContextMenu(contextMenu);
} else {
tray = new Tray(path.join(__dirname, "../", "/assets/ac_plug.png"));
const contextMenu = Menu.buildFromTemplate([
{
label: "ArmCord",
},
{
type: "separator"
},
{
label: "Open ArmCord",
click: function () {
@ -25,6 +52,9 @@ app.whenReady().then(() => {
mainWindow.loadURL("https://discord.gg/TnhxcqynZ2");
}
},
{
type: "separator"
},
{
label: "Quit ArmCord",
click: function () {
@ -35,4 +65,5 @@ app.whenReady().then(() => {
tray.setToolTip("ArmCord " + app.getVersion());
tray.setContextMenu(contextMenu);
}
});

View file

@ -1,70 +0,0 @@
declare module "glasstron" {
export class BrowserWindow extends Electron.BrowserWindow {
getBlur(): Promise<boolean>;
setBlur(value: boolean): Promise<boolean>;
blurType: WindowsBlurType;
setVibrancy(vibrancy: MacOSVibrancy): void;
}
/**
* @deprecated
*/
export function init(): void;
/**
* @deprecated
*/
export function update(
window: Electron.BrowserWindow,
values: {
windows?: {
blurType: WindowsBlurType;
};
macos?: {
vibrancy: MacOSVibrancy;
};
linux?: {
requestBlur: boolean;
};
}
): void;
export class Hacks {
static injectOnElectron(): void;
static delayReadyEvent(): void;
}
export type WindowsBlurType = "acrylic" | "blurbehind" | "transparent" | "none";
export type MacOSVibrancy =
| (
| "appearance-based"
| "light"
| "dark"
| "titlebar"
| "selection"
| "menu"
| "popover"
| "sidebar"
| "medium-light"
| "ultra-dark"
| "header"
| "sheet"
| "window"
| "hud"
| "fullscreen-ui"
| "tooltip"
| "content"
| "under-window"
| "under-page"
)
| null;
}
declare module "glasstron/src/utils" {
class Utils {
static getSavePath(): string;
static copyToPath(innerFile: string, outerFilename?: string, flags?: number): void;
static removeFromPath(filename: string): void;
static isInPath(filename: string): boolean;
static getPlatform(): any;
static parseKeyValString(string: string, keyvalSeparator?: string, pairSeparator?: string): any;
static makeKeyValString(object: any, keyvalSeparator?: string, pairSeparator?: string): string;
}
export = Utils;
}

View file

@ -1,9 +1,9 @@
import * as storage from "electron-json-storage";
import * as fs from "fs";
import {app} from "electron";
import {app, dialog} from "electron";
import path from "path";
export var firstRun: boolean;
export var isSetup: boolean;
export var contentPath: string;
//utillity functions that are used all over the codebase or just too obscure to be put in the file used in
export function addStyle(styleString: string) {
const style = document.createElement("style");
@ -21,21 +21,17 @@ export async function sleep(ms: number) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
export async function checkIfConfigIsNew() {
if ((await getConfigUnsafe("automaticPatches")) == undefined) {
firstRun = true;
export async function checkIfConfigIsBroken() {
if ((await getConfig("0")) == "d") {
console.log("Detected a corrupted config");
setup();
dialog.showErrorBox(
"Oops, something went wrong.",
"ArmCord has detected that your configuration file is corrupted, please restart the app and set your settings again. If this issue persists, report it on the support server/Github issues."
);
}
}
export interface Settings {
windowStyle: string;
channel: string;
armcordCSP: boolean;
minimizeToTray: boolean;
automaticPatches: boolean;
mods: string;
blurType: string;
}
export function setup() {
console.log("Setting up temporary ArmCord settings.");
const defaults: Settings = {
@ -45,50 +41,18 @@ export function setup() {
minimizeToTray: true,
automaticPatches: false,
mods: "cumcord",
blurType: "acrylic"
};
storage.set(
"settings",
{
...defaults,
blurType: "acrylic",
inviteWebsocket: true,
doneSetup: false
},
function (error) {
if (error) throw error;
}
);
};
setConfigBulk({
...defaults
});
}
export function saveSettings(settings: Settings) {
console.log("Setting up ArmCord settings.");
storage.set(
"settings",
{
...settings,
doneSetup: true
},
function (error) {
if (error) throw error;
}
);
}
export async function getConfigUnsafe(object: string) {
try {
const userDataPath = app.getPath("userData");
const storagePath = path.join(userDataPath, "/storage/");
let rawdata = fs.readFileSync(storagePath + "settings.json", "utf-8");
let returndata = JSON.parse(rawdata);
console.log(returndata[object]);
return returndata[object];
} catch (e) {
console.log("Config probably doesn't exist yet. Returning setup value.");
firstRun = true;
return "setup";
}
}
export function getVersion() {
//to-do better way of doing this
return "3.1.0";
return "3.0.6";
}
export async function injectJS(inject: string) {
const js = await (await fetch(`${inject}`)).text();
@ -99,3 +63,96 @@ export async function injectJS(inject: string) {
document.body.appendChild(el);
}
//ArmCord Settings/Storage manager
export interface Settings {
windowStyle: string;
channel: string;
armcordCSP: boolean;
minimizeToTray: boolean;
automaticPatches: boolean;
mods: string;
blurType: string;
inviteWebsocket: boolean;
doneSetup: boolean;
}
export async function getConfig(object: string) {
try {
const userDataPath = app.getPath("userData");
const storagePath = path.join(userDataPath, "/storage/");
const settingsFile = storagePath + "settings.json";
let rawdata = fs.readFileSync(settingsFile, "utf-8");
let returndata = JSON.parse(rawdata);
console.log(object + ": " + returndata[object]);
return returndata[object];
} catch (e) {
console.log("Config probably doesn't exist yet. Returning setup value.");
firstRun = true;
return "setup";
}
}
export async function setConfig(object: string, toSet: any) {
try {
const userDataPath = app.getPath("userData");
const storagePath = path.join(userDataPath, "/storage/");
const settingsFile = storagePath + "settings.json";
let rawdata = fs.readFileSync(settingsFile, "utf-8");
let parsed = JSON.parse(rawdata);
parsed[object] = toSet;
let toSave = JSON.stringify(parsed);
fs.writeFileSync(settingsFile, toSave, "utf-8");
} catch (e) {
console.log("Config probably doesn't exist yet. Returning setup value.");
firstRun = true;
return "setup";
}
}
export async function setConfigBulk(object: Settings) {
try {
const userDataPath = app.getPath("userData");
const storagePath = path.join(userDataPath, "/storage/");
const settingsFile = storagePath + "settings.json";
let toSave = JSON.stringify(object);
fs.writeFileSync(settingsFile, toSave, "utf-8");
} catch (e) {
console.log("Config probably doesn't exist yet. Returning setup value.");
firstRun = true;
return "setup";
}
}
export async function checkIfConfigExists() {
const userDataPath = app.getPath("userData");
const storagePath = path.join(userDataPath, "/storage/");
const settingsFile = storagePath + "settings.json";
if (!fs.existsSync(settingsFile)) {
if (!fs.existsSync(storagePath)) {
fs.mkdirSync(storagePath);
console.log("Created missing storage folder");
}
console.log("First run of the ArmCord. Starting setup.");
setup();
isSetup = true;
contentPath = path.join(__dirname, "/content/setup.html");
if (!contentPath.includes("ts-out")) {
contentPath = path.join(__dirname, "/ts-out/content/setup.html");
}
} else {
if (await getConfig("doneSetup") == false) {
console.log("First run of the ArmCord. Starting setup.");
setup();
isSetup = true;
contentPath = path.join(__dirname, "/content/setup.html");
if (!contentPath.includes("ts-out")) {
contentPath = path.join(__dirname, "/ts-out/content/setup.html");
}
} else {
console.log("ArmCord has been run before. Skipping setup.");
contentPath = path.join(__dirname, "/content/splash.html");
if (!contentPath.includes("ts-out")) {
contentPath = path.join(__dirname, "/ts-out/content/splash.html");
}
}
}
}

View file

@ -2,27 +2,29 @@
// I had to add most of the window creation code here to split both into seperete functions
// WHY? Because I can't use the same code for both due to annoying bug with value `frame` not responding to variables
// I'm sorry for this mess but I'm not sure how to fix it.
import {BrowserWindow, shell, app, ipcMain} from "electron";
import {BrowserWindow, shell, app, ipcMain, dialog, clipboard} from "electron";
import path from "path";
import {contentPath} from "./main";
import {checkIfConfigIsNew, firstRun, getConfigUnsafe} from "./utils";
import {checkIfConfigIsBroken, firstRun, getConfig, contentPath, isSetup} from "./utils";
import {registerIpc} from "./ipc";
import startServer from "./socket"
import contextMenu from "electron-context-menu";
import os from "os";
export var icon: string;
export let mainWindow: BrowserWindow;
import * as glasstron from "glasstron";
export let inviteWindow: BrowserWindow;
let guestWindows: BrowserWindow[] = [];
contextMenu({
showSaveImageAs: true,
showCopyImageAddress: true,
showSearchWithGoogle: true
});
function doAfterDefiningTheWindow() {
checkIfConfigIsNew();
async function doAfterDefiningTheWindow() {
checkIfConfigIsBroken();
registerIpc();
mainWindow.webContents.userAgent =
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36"; //fake useragent for screenshare to work
`Mozilla/5.0 (X11; ${os.type()} ${os.arch()}) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36`; //fake useragent for screenshare to work
mainWindow.webContents.setWindowOpenHandler(({url}) => {
shell.openExternal(url);
return {action: "deny"};
@ -32,18 +34,24 @@ function doAfterDefiningTheWindow() {
return callback({});
});
mainWindow.on("close", async (e) => {
if (await getConfigUnsafe("minimizeToTray")) {
if (await getConfig("minimizeToTray")) {
e.preventDefault();
mainWindow.hide();
} else if (!(await getConfigUnsafe("minimizeToTray"))) {
} else if (!(await getConfig("minimizeToTray"))) {
e.preventDefault();
app.exit();
app.quit();
}
});
console.log(contentPath);
if (await getConfig("inviteWebsocket") == true) {
startServer()
}
try {
mainWindow.loadFile(contentPath);
if (isSetup) {
mainWindow.setSize(390, 470);
}
} catch (e) {
console.log(
"Major error detected while starting up. User is most likely on Windows platform. Fallback to alternative startup."
@ -51,12 +59,14 @@ function doAfterDefiningTheWindow() {
console.log(process.platform);
if (process.platform === "win32") {
if (firstRun) {
mainWindow.setSize(390, 470);
mainWindow.loadURL(`file://${__dirname}/content/setup.html`);
} else {
mainWindow.loadURL(`file://${__dirname}/content/splash.html`);
}
} else {
if (firstRun) {
mainWindow.setSize(390, 470);
mainWindow.loadURL(`file://${__dirname}/ts-out/content/setup.html`);
} else {
mainWindow.loadURL(`file://${__dirname}/ts-out/content/splash.html`);
@ -96,28 +106,12 @@ export function createNativeWindow() {
});
doAfterDefiningTheWindow();
}
export function createGlasstronWindow() {
mainWindow = new glasstron.BrowserWindow({
width: 300,
height: 350,
title: "ArmCord",
darkTheme: true,
icon: path.join(__dirname, "/assets/icon_transparent.png"),
frame: true,
autoHideMenuBar: true,
webPreferences: {
preload: path.join(__dirname, "preload/preload.js"),
spellcheck: true
}
});
//@ts-expect-error
mainWindow.blurType = getConfigUnsafe("blurType");
//@ts-expect-error
mainWindow.setBlur(true);
doAfterDefiningTheWindow();
}
export function createTabsHost() {
dialog.showErrorBox(
"READ THIS BEFORE USING THE APP",
"ArmCord Tabs are highly experimental and should be only used for strict testing purposes. Please don't ask for support, however you can still report bugs!"
);
guestWindows[1] = mainWindow;
mainWindow = new BrowserWindow({
width: 300,
@ -184,3 +178,18 @@ export function createTabsGuest(number: number) {
guestWindows[number].loadURL("https://discord.com/app");
}
}
export function createInviteWindow() {
inviteWindow = new BrowserWindow({
width: 800,
height: 600,
title: "ArmCord Invite Manager",
darkTheme: true,
icon: path.join(__dirname, "/assets/icon_transparent.png"),
frame: true,
autoHideMenuBar: true,
webPreferences: {
spellcheck: true
}
});
inviteWindow.hide()
}