Compare commits

...

49 commits

Author SHA1 Message Date
smartfrigde
538bd10412 v3.0.7 2022-06-17 15:05:16 +02:00
smartfrigde
9efce82462 Add fallback to English 2022-06-17 09:37:18 +02:00
smartfrigde
a216475618 Add theme loader 2022-06-16 23:09:41 +02:00
smartfrigde
b7a0d1face formatting 2022-06-16 17:31:57 +02:00
smartfrigde
0b165e64bc Remove left over from tabs in armcord api 2022-06-16 17:31:57 +02:00
Hosted Weblate
8c62d9dd86
Update translation files
Updated by "Cleanup translation files" hook in Weblate.

Translation: ArmCord/ArmCord
Translate-URL: https://hosted.weblate.org/projects/armcord/armcord/
2022-06-16 17:25:18 +02:00
smartfrigde
86f885c41f Add window state manager 2022-06-16 17:25:09 +02:00
dfa1665b19
Translated using Weblate (Thai)
Currently translated at 100.0% (28 of 28 strings)

Translation: ArmCord/ArmCord
Translate-URL: https://hosted.weblate.org/projects/armcord/armcord/th/
2022-06-16 17:19:39 +02:00
altinat
3957bb1c57
Translated using Weblate (Thai)
Currently translated at 100.0% (28 of 28 strings)

Translation: ArmCord/ArmCord
Translate-URL: https://hosted.weblate.org/projects/armcord/armcord/th/
2022-06-15 16:33:58 +02:00
Anonymous
31e3426ad1
Translated using Weblate (Thai)
Currently translated at 100.0% (0 of 0 strings)

Translation: ArmCord/ArmCord
Translate-URL: https://hosted.weblate.org/projects/armcord/armcord/th/
2022-06-15 12:58:55 +02:00
lukacchi
715afdd79d
Translated using Weblate (Spanish (Latin America))
Currently translated at 96.4% (27 of 28 strings)

Translation: ArmCord/ArmCord
Translate-URL: https://hosted.weblate.org/projects/armcord/armcord/es_419/
2022-06-15 12:58:54 +02:00
altinat
e7c6b2101d
Added translation using Weblate (Thai) 2022-06-15 12:58:51 +02:00
Anonymous
72c35cb2f3
Translated using Weblate (Spanish (Latin America))
Currently translated at 100.0% (0 of 0 strings)

Translation: ArmCord/ArmCord
Translate-URL: https://hosted.weblate.org/projects/armcord/armcord/es_419/
2022-06-14 19:12:41 +02:00
smartfridge
4cf0187ef8
Added translation using Weblate (Spanish (Latin America)) 2022-06-14 19:12:34 +02:00
Hosted Weblate
f677b0e4fb
Update translation files
Updated by "Cleanup translation files" hook in Weblate.

Translation: ArmCord/ArmCord
Translate-URL: https://hosted.weblate.org/projects/armcord/armcord/
2022-06-14 17:55:22 +02:00
smartfrigde
7f9b93dc79 Remove unused translation string 2022-06-14 17:55:14 +02:00
smartfrigde
a29cb2a6a5 Add translation loading to splash 2022-06-14 17:54:50 +02:00
smartfrigde
c979328aee Remove glasstron and tabs completely 2022-06-14 17:02:37 +02:00
smartfrigde
8d85591e1c Change default tray icon for macOS to avoid issues 2022-06-14 16:49:12 +02:00
smartfrigde
c6e2244ce8 Move attribute logic to main 2022-06-14 16:30:18 +02:00
smartfrigde
9ab08b16d8 Update dependencies 2022-06-14 16:07:33 +02:00
smartfrigde
e86b1a8924 Don't remove the getLang handler 2022-06-14 14:55:47 +02:00
smartfrigde
ef73af66c4 Move the getLang handler to main ipc module instead of storing it in settings 2022-06-14 14:54:34 +02:00
smartfrigde
bdb09bb912 Remove unwanted getLang handlers 2022-06-14 14:53:26 +02:00
smartfrigde
7f53710d6a Remove unused import 2022-06-12 22:17:09 +02:00
smartfrigde
0a7ec74b0f I forgot to uncomment a function 2022-06-12 21:03:58 +02:00
smartfrigde
86c3636a19 Add setup translation loading 2022-06-12 20:59:59 +02:00
smartfrigde
994ab5f5b0 Add fallback to English US if language doesn't exist 2022-06-12 13:32:54 +02:00
Phorcys
ade35473a8
Translated using Weblate (French)
Currently translated at 100.0% (30 of 30 strings)

Translation: ArmCord/ArmCord
Translate-URL: https://hosted.weblate.org/projects/armcord/armcord/fr/
2022-06-12 13:18:36 +02:00
smartfrigde
f9bfed7585 Add translation loading for settings 2022-06-12 13:18:31 +02:00
smartfridge
410c899c84
Translated using Weblate (Polish)
Currently translated at 100.0% (30 of 30 strings)

Translation: ArmCord/ArmCord
Translate-URL: https://hosted.weblate.org/projects/armcord/armcord/pl/
2022-06-12 00:15:32 +02:00
smartfrigde
fa24b7996f Add language detection from Discord 2022-06-11 22:14:33 +02:00
Anonymous
e518c0f04e
Translated using Weblate (Indonesian)
Currently translated at 0.0% (0 of 30 strings)

Translation: ArmCord/ArmCord
Translate-URL: https://hosted.weblate.org/projects/armcord/armcord/id/
2022-06-10 23:22:42 +02:00
Anonymous
113a693603
Translated using Weblate (Polish)
Currently translated at 76.6% (23 of 30 strings)

Translation: ArmCord/ArmCord
Translate-URL: https://hosted.weblate.org/projects/armcord/armcord/pl/
2022-06-10 23:22:41 +02:00
Anonymous
85dea97312
Translated using Weblate (Dutch)
Currently translated at 76.6% (23 of 30 strings)

Translation: ArmCord/ArmCord
Translate-URL: https://hosted.weblate.org/projects/armcord/armcord/nl/
2022-06-10 23:22:41 +02:00
Anonymous
00bf23667b
Translated using Weblate (Norwegian Bokmål)
Currently translated at 76.6% (23 of 30 strings)

Translation: ArmCord/ArmCord
Translate-URL: https://hosted.weblate.org/projects/armcord/armcord/nb_NO/
2022-06-10 23:22:41 +02:00
Anonymous
7f524b1559
Translated using Weblate (Italian)
Currently translated at 76.6% (23 of 30 strings)

Translation: ArmCord/ArmCord
Translate-URL: https://hosted.weblate.org/projects/armcord/armcord/it/
2022-06-10 23:22:41 +02:00
Anonymous
478c2da61a
Translated using Weblate (French)
Currently translated at 76.6% (23 of 30 strings)

Translation: ArmCord/ArmCord
Translate-URL: https://hosted.weblate.org/projects/armcord/armcord/fr/
2022-06-10 23:22:40 +02:00
smartfrigde
b43a992027 Tweak translations a bit 2022-06-10 23:22:32 +02:00
Anonymous
b8b1d04d24
Translated using Weblate (Indonesian)
Currently translated at 100.0% (0 of 0 strings)

Translation: ArmCord/ArmCord
Translate-URL: https://hosted.weblate.org/projects/armcord/armcord/id/
2022-06-10 22:38:33 +02:00
Ufal Salman
465a072e67
Added translation using Weblate (Indonesian) 2022-06-10 22:38:33 +02:00
smartfrigde
0f6f650be2 Add 16x16 icon 2022-06-10 22:38:27 +02:00
smartfrigde
a12463877a Add macOS tray icon potential fix 2022-06-10 22:29:43 +02:00
smartfrigde
98f88f4609 Fix icon loading 2022-06-10 20:46:30 +02:00
smartfrigde
81377d3657 Add performance mode 2022-06-10 20:27:37 +02:00
KayoticCarnige
40d743d0e2 Fixed "null" bug
Fixed "null" bug, where on Windows, Discord wouldn't recognize the OS (Only tested onw Windows 10)
2022-06-03 12:05:28 -04:00
smartfrigde
54b1481a4e Update WindowOpenHandler to be much more secure 2022-06-03 15:18:36 +02:00
smartfrigde
12352e3536 Fix icon generating on Debian 2022-06-02 14:28:42 +02:00
smartfrigde
13eb57d17d Add the stable release workflow onto dev 2022-06-02 14:27:29 +02:00
28 changed files with 726 additions and 315 deletions

196
.github/workflows/stable.yml vendored Normal file
View file

@ -0,0 +1,196 @@
name: Release build
on:
push:
branches:
- stable
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: Build
run: npm run build && electron-builder --linux && electron-builder --arm64 --linux && electron-builder --armv7l --linux
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: List all files in the dist directory
run: ls -l dist
- name: Delete unpacked builds
run: rm -rf dist/linux-unpacked && rm -rf dist/linux-arm64-unpacked && rm -rf dist/linux-armv7l-unpacked
- name: Upload artifact
uses: actions/upload-artifact@v2
with:
name: ArmCordLinux
path: dist/
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: Build
run: npm run build && electron-builder --macos
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: List all files in the dist directory
run: ls -l dist
- name: Delete unpacked builds
run: rm -rf dist/macos-unpacked
- name: Upload artifact
uses: actions/upload-artifact@v2
with:
name: ArmCordMac
path: dist/
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: Build
run: npm run build && electron-builder --windows
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Delete unpacked builds
run: Remove-Item -LiteralPath ".\dist\win-unpacked" -Force -Recurse
- name: Upload artifact
uses: actions/upload-artifact@v2
with:
name: ArmCordWindows
path: dist/
release:
runs-on: ubuntu-latest
needs: [build-linux, build-mac, build-windows]
steps:
- uses: actions/download-artifact@v2
with:
name: ArmCordMac
path: macos
- uses: actions/download-artifact@v2
with:
name: ArmCordWindows
path: windows
- uses: actions/download-artifact@v2
with:
name: ArmCordLinux
path: linux
- name: ls
run: ls
- name: Delete unwanted directories
run: rm -rf {linux,macos,windows}/*/
rm -rf {linux,macos,windows}/.icon*
rm -rf {linux,macos,windows}/builder-debug.yml
- name: ls dirs
run: ls linux && ls macos && ls windows
- name: Get some values needed for the release
id: vars
shell: bash
run: |
echo "::set-output name=releaseTag::$(git describe --tags --abbrev=0)"
- uses: dev-drprasad/delete-tag-and-release@v0.2.0
with:
delete_release: true
tag_name: v3.0.7
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Create Release
uses: actions/github-script@v2
with:
github-token: ${{secrets.GITHUB_TOKEN}}
script: |
console.log('environment', process.versions);
const fs = require('fs').promises;
const { repo: { owner, repo }, sha } = context;
console.log({ owner, repo, sha });
const release = await github.repos.createRelease({
owner, repo,
tag_name: process.env.releaseTag,
draft: true,
target_commitish: sha
});
console.log('created release', { release });
for (let file of await fs.readdir('linux')) {
// do whatever filtering you want here, I'm just uploading all the files
console.log('uploading', file);
await github.repos.uploadReleaseAsset({
owner, repo,
release_id: release.data.id,
name: file,
data: await fs.readFile(`./linux/${file}`)
});
}
for (let file of await fs.readdir('windows')) {
// do whatever filtering you want here, I'm just uploading all the files
console.log('uploading', file);
await github.repos.uploadReleaseAsset({
owner, repo,
release_id: release.data.id,
name: file,
data: await fs.readFile(`./windows/${file}`)
});
}
for (let file of await fs.readdir('macos')) {
// do whatever filtering you want here, I'm just uploading all the files
console.log('uploading', file);
await github.repos.uploadReleaseAsset({
owner, repo,
release_id: release.data.id,
name: file,
data: await fs.readFile(`./macos/${file}`)
});
}
env:
releaseTag: ${{ steps.vars.outputs.releaseTag }}

View file

@ -12,17 +12,19 @@
"no": "No", "no": "No",
"next": "Next", "next": "Next",
"setup_question4": "Select a client mod you want to install:", "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.", "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 Discord.",
"settings-theme": "ArmCord Theme:", "settings-theme": "ArmCord theme:",
"settings-theme-glasstron": "Glasstron (experimental)",
"settings-theme-tabs": "Tabs (experimental)",
"settings-theme-default": "Default", "settings-theme-default": "Default",
"settings-theme-native": "Native", "settings-theme-native": "Native",
"settings-tray": "Minimize to tray", "settings-tray": "Minimize to tray",
"settings-patches": "Automatic Patches", "settings-patches": "Automatic Patches",
"settings-channel": "Discord channel:", "settings-channel": "Discord channel:",
"settings-invitewebsocket": "discord.gg support", "settings-invitewebsocket": "Invite Websocket",
"settings-mod": "Client mod:", "settings-mod": "Client mod:",
"settings-prfmMode": "Performance mode:",
"settings-prfmMode-performance": "Performance",
"settings-prfmMode-battery": "Battery",
"settings-none": "None",
"settings-save": "Save settings", "settings-save": "Save settings",
"settings-updater": "Check for updates" "settings-updater": "Check for updates"
} }

30
assets/lang/es-419.json Normal file
View file

@ -0,0 +1,30 @@
{
"loading_screen_start": "Cargando ArmCord…",
"loading_screen_offline": "Parece que no estás conectado a la Internet. Por favor conectate e intentalo de nuevo.",
"loading_screen_update": "Una nueva version de ArmCord está disponible. Por favor actualiza a la última version.",
"setup_question1": "Escoge que tipo de instalación quieres hacer:",
"yes": "Sí",
"setup_question2": "Escoge tu version de Discord:",
"setup_question3": "Dejar que ArmCord se encargue de la instalacion de modificaciones?",
"setup_question1_answer1": "Instalación rápida",
"setup_question1_answer2": "Instalación completa",
"setup_offline": "Parece que no estás conectado a la Internet. Por favor conectate a la Internet e reinicia el instalador de ArmCord.",
"no": "No",
"next": "Siguiente",
"setup_question4": "Selecciona una modificación que te gustaría instalar:",
"setup_question4_clientmodnotice": "Por qué no instalar todas las modificaciones? Tener varias modificaciones a la vez puede causar problemas. Si realmente quieres hacerlo, puedes unirte a nuestro Discord.",
"settings-theme": "Tema de ArmCord:",
"settings-theme-default": "Por Defecto",
"settings-theme-native": "Nativa",
"settings-tray": "Minimizar a la barra de tareas",
"settings-patches": "Automatizar Parches",
"settings-channel": "Version de Discord:",
"settings-invitewebsocket": "Websocket de Invitación",
"settings-mod": "Modificación:",
"settings-prfmMode": "Modo de Rendimiento:",
"settings-prfmMode-performance": "Rendimiento",
"settings-prfmMode-battery": "Batería",
"settings-none": "Ninguna",
"settings-save": "Guardar ajustes",
"settings-updater": "Buscar una actualización"
}

View file

@ -1,6 +1,6 @@
{ {
"loading_screen_start": "Démarrage d'ArmCord…", "loading_screen_start": "Démarrage d'ArmCord…",
"loading_screen_update": "Une nouvelle version de ArmCord est disponible. Veuillez mettre à jour la dernière version.", "loading_screen_update": "Une nouvelle version d'ArmCord est disponible. Veuillez mettre à jour vers la dernière version.",
"setup_question1": "Sélectionnez le type de configuration que vous souhaitez effectuer :", "setup_question1": "Sélectionnez le type de configuration que vous souhaitez effectuer :",
"setup_question1_answer1": "Configuration express", "setup_question1_answer1": "Configuration express",
"setup_question1_answer2": "Configuration complète", "setup_question1_answer2": "Configuration complète",
@ -10,19 +10,21 @@
"no": "Non", "no": "Non",
"next": "Suivant", "next": "Suivant",
"setup_question4": "Sélectionnez le mod client que vous souhaitez installer :", "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.", "setup_question4_clientmodnotice": "Pourquoi pas tous ? Le fait d'avoir plusieurs clients mods en même temps peut causer des problèmes. Si vous voulez vraiment le faire, consultez notre Discord.",
"loading_screen_offline": "Vous semblez être hors ligne. Veuillez vous connecter à internet et réessayer.", "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.", "setup_offline": "Vous semblez être hors ligne. Veuillez vous connecter à internet et redémarrer l'installateur ArmCord.",
"settings-tray": "Minimize to tray", "settings-tray": "Minimize to tray",
"settings-channel": "Discord channel:", "settings-channel": "Discord channel:",
"settings-mod": "Client mod:", "settings-mod": "Client mod:",
"settings-save": "Save settings", "settings-save": "Save settings",
"settings-updater": "Check for updates", "settings-updater": "Check for updates",
"settings-theme": "ArmCord Theme:", "settings-theme": "Thème ArmCord :",
"settings-theme-tabs": "Tabs (experimental)",
"settings-theme-default": "Default", "settings-theme-default": "Default",
"settings-theme-glasstron": "Glasstron (experimental)",
"settings-theme-native": "Native", "settings-theme-native": "Native",
"settings-patches": "Automatic Patches", "settings-patches": "Automatic Patches",
"settings-invitewebsocket": "discord.gg support" "settings-invitewebsocket": "Lien discord.gg",
"settings-prfmMode": "Mode performance :",
"settings-prfmMode-performance": "Performance",
"settings-prfmMode-battery": "Batterie",
"settings-none": "Aucun"
} }

30
assets/lang/id-ID.json Normal file
View file

@ -0,0 +1,30 @@
{
"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_question2": "Choose your Discord channel/instance:",
"setup_offline": "You appear to be offline. Please connect to the Internet and restart the ArmCord setup.",
"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-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",
"settings-prfmMode": "Performance mode:",
"settings-prfmMode-performance": "Performance",
"settings-prfmMode-battery": "Battery",
"settings-none": "None"
}

View file

@ -19,10 +19,12 @@
"settings-updater": "Controlla gli aggiornamenti", "settings-updater": "Controlla gli aggiornamenti",
"settings-mod": "Client mod:", "settings-mod": "Client mod:",
"settings-theme": "ArmCord Theme:", "settings-theme": "ArmCord Theme:",
"settings-theme-glasstron": "Glasstron (experimental)",
"settings-theme-tabs": "Tabs (experimental)",
"settings-theme-default": "Default", "settings-theme-default": "Default",
"settings-theme-native": "Native", "settings-theme-native": "Native",
"settings-patches": "Automatic Patches", "settings-patches": "Automatic Patches",
"settings-invitewebsocket": "discord.gg support" "settings-invitewebsocket": "discord.gg support",
"settings-prfmMode": "Performance mode:",
"settings-prfmMode-performance": "Performance",
"settings-prfmMode-battery": "Battery",
"settings-none": "None"
} }

View file

@ -19,10 +19,12 @@
"settings-save": "Save settings", "settings-save": "Save settings",
"settings-updater": "Check for updates", "settings-updater": "Check for updates",
"settings-theme": "ArmCord Theme:", "settings-theme": "ArmCord Theme:",
"settings-theme-glasstron": "Glasstron (experimental)",
"settings-theme-tabs": "Tabs (experimental)",
"settings-theme-default": "Default", "settings-theme-default": "Default",
"settings-theme-native": "Native", "settings-theme-native": "Native",
"settings-patches": "Automatic Patches", "settings-patches": "Automatic Patches",
"settings-invitewebsocket": "discord.gg support" "settings-invitewebsocket": "discord.gg support",
"settings-prfmMode": "Performance mode:",
"settings-prfmMode-performance": "Performance",
"settings-prfmMode-battery": "Battery",
"settings-none": "None"
} }

View file

@ -20,9 +20,11 @@
"settings-updater": "Check voor updates", "settings-updater": "Check voor updates",
"settings-patches": "Automatische Patches", "settings-patches": "Automatische Patches",
"settings-theme": "ArmCord Thema:", "settings-theme": "ArmCord Thema:",
"settings-theme-glasstron": "Glasstron (experimenteel)",
"settings-theme-tabs": "Tabs (experimenteel)",
"settings-theme-default": "Standaard", "settings-theme-default": "Standaard",
"settings-theme-native": "Native", "settings-theme-native": "Native",
"settings-invitewebsocket": "discord.gg support" "settings-invitewebsocket": "discord.gg support",
"settings-none": "None",
"settings-prfmMode": "Performance mode:",
"settings-prfmMode-performance": "Performance",
"settings-prfmMode-battery": "Battery"
} }

View file

@ -7,7 +7,7 @@
"no": "Nie", "no": "Nie",
"next": "Dalej", "next": "Dalej",
"setup_question4": "Wybierz modyfikację klienta którą chcesz zainstalować:", "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ę.", "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ć naszego Discorda.",
"loading_screen_start": "Ładowanie ArmCord…", "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.", "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_answer1": "Ekspresowa konfiguracja",
@ -19,10 +19,12 @@
"settings-save": "Zapisz ustawienia", "settings-save": "Zapisz ustawienia",
"settings-mod": "Modyfikacja klienta:", "settings-mod": "Modyfikacja klienta:",
"settings-theme": "Motyw ArmCord:", "settings-theme": "Motyw ArmCord:",
"settings-theme-glasstron": "Glasstron (eksperymentalne)",
"settings-theme-tabs": "Karty (eksperymentalne)",
"settings-theme-default": "Domyślny", "settings-theme-default": "Domyślny",
"settings-theme-native": "Natywny", "settings-theme-native": "Natywny",
"settings-patches": "Automatyczne łatki", "settings-patches": "Automatyczne łatki",
"settings-invitewebsocket": "Wsparcie linków discord.gg" "settings-invitewebsocket": "Websocket dla zaproszeń",
"settings-prfmMode": "Tryb wydajności:",
"settings-prfmMode-performance": "Wydajny",
"settings-prfmMode-battery": "Bateria",
"settings-none": "Nic/Brak"
} }

30
assets/lang/th-TH.json Normal file
View file

@ -0,0 +1,30 @@
{
"loading_screen_start": "เริ่มต้น ArmCord…",
"loading_screen_offline": "ดูเหมือนว่าคุณออฟไลน์อยู่ โปรดเชื่อมต่ออินเทอร์เน็ตและลองใหม่อีกครั้ง",
"loading_screen_update": "ArmCord เวอร์ชันใหม่พร้อมใช้งานแล้ว โปรดอัปเดตเป็นเวอร์ชันล่าสุด",
"setup_question1": "เลือกประเภทการติดตั้งที่คุณต้องการ:",
"setup_question1_answer1": "ติดตั้งแบบรวดเร็ว",
"setup_question1_answer2": "การตั้งค่าเต็มรูปแบบ",
"setup_offline": "ดูเหมือนว่าคุณออฟไลน์อยู่ โปรดเชื่อมต่ออินเทอร์เน็ตและลองใหม่อีกครั้ง",
"setup_question2": "เลือกช่อง/อินสแตนส์ Discord:",
"setup_question3": "ต้องการให้ ArmCord จัดการการติดตั้งมอดของไคลเอนต์หรือไม่?",
"yes": "ใช่",
"no": "ไม่",
"next": "ถัดไป",
"setup_question4": "เลือกไคลเอนต์มอดที่ต้องการติดตั้ง:",
"settings-prfmMode-battery": "แบตเตอรี่",
"setup_question4_clientmodnotice": "ทำไมไม่ใช้ทั้งหมดล่ะ? การมีไคลเอนต์มอดหลายตัวพร้อมกันอาจทำให้เกิดปัญหาได้ หากต้องการที่จะทำจริงๆ ให้ไปดูใน Discord ของเรา",
"settings-theme": "ธีม ArmCord:",
"settings-theme-default": "ค่าเริ่มต้น",
"settings-theme-native": "ดั้งเดิม",
"settings-tray": "ย่อลงไปในถาดงาน",
"settings-patches": "แพทช์อัตโนมัติ",
"settings-channel": "ช่อง Discord:",
"settings-invitewebsocket": "ใช้ Websocket สำหรับการเชิญ",
"settings-prfmMode": "โหมดประสิทธิภาพ:",
"settings-prfmMode-performance": "ประสิทธิภาพ",
"settings-mod": "ไคลแอนต์มอด:",
"settings-none": "ไม่มี",
"settings-save": "บันทึกการตั้งค่า",
"settings-updater": "ตรวจหาการอัปเดต"
}

BIN
assets/macos.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
build/icon.icns Normal file

Binary file not shown.

View file

@ -1,6 +1,6 @@
{ {
"name": "ArmCord", "name": "ArmCord",
"version": "3.1.0", "version": "3.0.7",
"description": "ArmCord is a custom client designed to enhance your Discord experience while keeping everything lightweight.", "description": "ArmCord is a custom client designed to enhance your Discord experience while keeping everything lightweight.",
"main": "ts-out/main.js", "main": "ts-out/main.js",
"scripts": { "scripts": {
@ -23,19 +23,20 @@
}, },
"homepage": "https://github.com/armcord/armcord#readme", "homepage": "https://github.com/armcord/armcord#readme",
"devDependencies": { "devDependencies": {
"@types/node": "^17.0.33", "@types/node": "^17.0.42",
"@types/ws": "^8.5.3", "@types/ws": "^8.5.3",
"copyfiles": "^2.4.1", "copyfiles": "^2.4.1",
"electron": "^18.2.4", "electron": "^19.0.4",
"electron-builder": "^23.0.3", "electron-builder": "^23.0.3",
"husky": "^8.0.1", "husky": "^8.0.1",
"prettier": "^2.5.1", "prettier": "^2.7.0",
"typescript": "^4.6.3" "typescript": "^4.7.3"
}, },
"dependencies": { "dependencies": {
"electron-context-menu": "github:ArmCord/electron-context-menu", "electron-context-menu": "github:ArmCord/electron-context-menu",
"os-locale": "^6.0.2",
"v8-compile-cache": "^2.3.0", "v8-compile-cache": "^2.3.0",
"ws": "^8.6.0" "ws": "^8.8.0"
}, },
"build": { "build": {
"appId": "com.smartfridge.armcord", "appId": "com.smartfridge.armcord",
@ -44,6 +45,7 @@
"category": "Network" "category": "Network"
}, },
"linux": { "linux": {
"icon": "build/icon.icns",
"category": "Network", "category": "Network",
"maintainer": "smartfrigde@gmail.com", "maintainer": "smartfrigde@gmail.com",
"target": [ "target": [

View file

@ -1,46 +0,0 @@
.tabs {
display: block;
top: 0;
left: 0;
right: 0;
flex-shrink: 0;
overflow: hidden;
zoom: 1;
box-sizing: border-box;
width: 100%;
clear: both;
height: 30px;
line-height: 30px;
background-color: #202225;
-webkit-app-region: drag;
width: 100%;
user-select: none;
-webkit-user-select: none;
position: fixed;
z-index: 99999;
}
.tabs #tabs-controls-container {
float: left;
width: 150px;
height: 100%;
line-height: 30px;
background-color: #202225;
-webkit-app-region: no-drag;
}
.tabs-buttons {
color: white;
background-color: inherit;
float: left;
border: none;
outline: none;
cursor: pointer;
transition: 0.3s;
font-size: 20px;
}
.tabs-buttons:hover {
background-color: #4e515a;
}
.withFrame-haYltI {
height: 30px !important;
}

View file

@ -12,12 +12,14 @@
<body> <body>
<div class="container"> <div class="container">
<div id="warning" class="hidden"> <div id="warning" class="hidden">
<p>You appear to be offline. Please connect to the internet and restart ArmCord Setup.</p> <p id="setup_offline">
You appear to be offline. Please connect to the internet and restart ArmCord Setup.
</p>
</div> </div>
<div id="setup"> <div id="setup">
<div id="logo" class="hidden"></div> <div id="logo" class="hidden"></div>
<div id="page1" class="hidden"> <div id="page1" class="hidden">
<p>Select the type of setup you want to perform.</p> <p id="setup_question1">Select the type of setup you want to perform.</p>
<div id="buttons"> <div id="buttons">
<button id="express" class="center">Express</button> <button id="express" class="center">Express</button>
<button id="full" class="center">Full</button> <button id="full" class="center">Full</button>
@ -25,7 +27,7 @@
</div> </div>
<div id="page2" class="hidden"> <div id="page2" class="hidden">
<p class="text-center setup-ask">Choose your Discord channel/instance:</p> <p class="text-center setup-ask" id="setup_question2">Choose your Discord channel/instance:</p>
<div class="center"> <div class="center">
<select name="channel" id="channel" class="dropdown-button"> <select name="channel" id="channel" class="dropdown-button">
<option value="stable">Stable</option> <option value="stable">Stable</option>
@ -34,7 +36,9 @@
<option value="foss">Fosscord</option> <option value="foss">Fosscord</option>
</select> </select>
</div> </div>
<p class="text-center setup-ask">Should ArmCord handle client mods installation?</p> <p class="text-center setup-ask" id="setup_question3">
Should ArmCord handle client mods installation?
</p>
<div class="center"> <div class="center">
<select name="csp" id="csp" class="dropdown-button"> <select name="csp" id="csp" class="dropdown-button">
<option value="true">Yes</option> <option value="true">Yes</option>
@ -47,7 +51,7 @@
</div> </div>
<div id="page3" class="hidden"> <div id="page3" class="hidden">
<p class="text-center setup-ask">Select a client mod you want to install:</p> <p class="text-center setup-ask" id="setup_question4">Select a client mod you want to install:</p>
<div class="center"> <div class="center">
<select name="mod" id="mod" class="dropdown-button"> <select name="mod" id="mod" class="dropdown-button">
<option value="cumcord">Cumcord</option> <option value="cumcord">Cumcord</option>
@ -55,9 +59,9 @@
<option value="flicker">Flicker (Heavily WIP)</option> <option value="flicker">Flicker (Heavily WIP)</option>
</select> </select>
</div> </div>
<p class="text-center"> <p class="text-center" id="setup_question4_clientmodnotice">
Why not all of them? Having many client mods at the same time can cause issues. If you really 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 ;) want to do it though, check our Discord ;)
</p> </p>
<div id="buttons"> <div id="buttons">
<button id="next" class="center">Next</button> <button id="next" class="center">Next</button>
@ -65,7 +69,25 @@
</div> </div>
</div> </div>
</div> </div>
<script>
async function loadLang() {
document.getElementById("next").innerHTML = await armcord.getLang("next");
document.getElementById("setup_offline").innerHTML = await armcord.getLang("setup_offline");
document.getElementById("setup_question1").innerHTML = await armcord.getLang("setup_question1");
document.getElementById("express").innerHTML = await armcord.getLang("setup_question1_answer1");
document.getElementById("full").innerHTML = await armcord.getLang("setup_question1_answer2");
document.getElementById("setup_question2").innerHTML = await armcord.getLang("setup_question2");
document.getElementById("setup_question3").innerHTML = await armcord.getLang("setup_question3");
document.getElementById("setup_question4").innerHTML = await armcord.getLang("setup_question4");
document.getElementById("setup_question4_clientmodnotice").innerHTML = await armcord.getLang(
"setup_question4_clientmodnotice"
);
//select stuff1
document.getElementById("csp").options[1].text = await armcord.getLang("no");
document.getElementById("csp").options[0].text = await armcord.getLang("yes");
}
loadLang();
</script>
<script> <script>
document.onload = function () { document.onload = function () {
ipcRenderer.send("win-unmaximize"); ipcRenderer.send("win-unmaximize");
@ -101,7 +123,7 @@
automaticPatches: false, automaticPatches: false,
mods: "cumcord", mods: "cumcord",
inviteWebsocket: true, inviteWebsocket: true,
blurType: "acrylic" performanceMode: "none"
}); });
setTimeout(() => window.armcordinternal.restart(), 5000); setTimeout(() => window.armcordinternal.restart(), 5000);
}); });
@ -130,9 +152,9 @@
autoLaunch: true, autoLaunch: true,
minimizeToTray: true, minimizeToTray: true,
automaticPatches: false, automaticPatches: false,
performanceMode: "none",
mods: options.mod, mods: options.mod,
inviteWebsocket: true, inviteWebsocket: true
blurType: "acrylic"
}); });
setTimeout(() => window.armcordinternal.restart(), 500); setTimeout(() => window.armcordinternal.restart(), 500);
}); });
@ -145,8 +167,8 @@
automaticPatches: false, automaticPatches: false,
autoLaunch: true, autoLaunch: true,
mods: "none", mods: "none",
inviteWebsocket: true, performanceMode: "none",
blurType: "acrylic" inviteWebsocket: true
}); });
setTimeout(() => window.armcordinternal.restart(), 500); setTimeout(() => window.armcordinternal.restart(), 500);
} }

View file

@ -17,52 +17,53 @@
</div> </div>
</body> </body>
<script> <script>
const text = document.getElementById("text-splashscreen"); async function loadLang() {
if (window.navigator.onLine === false) { const text = document.getElementById("text-splashscreen");
text.innerHTML = "You appear to be offline. Please connect to the internet and try again."; if (window.navigator.onLine === false) {
} else { text.innerHTML = await armcord.getLang("loading_screen_offline");
text.innerHTML = "Starting ArmCord...";
if (window.armcord.version === "DEV") {
console.log("Running a development build of ArmCord. Skipping updater.");
} else { } else {
fetch("https://armcord.xyz/latest.json") text.innerHTML = await armcord.getLang("loading_screen_start");
.then((response) => response.json()) if (window.armcord.version === "DEV") {
.then((data) => { console.log("Running a development build of ArmCord. Skipping updater.");
if (data.version !== window.armcord.version) { } else {
var elem = document.createElement("img"); const response = await fetch("https://armcord.xyz/latest.json");
elem.classList.add("logo"); const data = await response.json();
elem.src = "https://armcord.smartfridge.space/update.webp"; if (data.version !== window.armcord.version) {
document.body.prepend(elem); var elem = document.createElement("img");
document.getElementById("splashscreen-armcord").remove(); elem.classList.add("logo");
text.innerHTML = elem.src = "https://armcord.smartfridge.space/update.webp";
"A new version of ArmCord is available. Please update to the latest version."; document.body.prepend(elem);
} else { document.getElementById("splashscreen-armcord").remove();
console.log("ArmCord is up to date."); text.innerHTML = await armcord.getLang("loading_screen_update");
} } else {
}); console.log("ArmCord is up to date.");
} }
setTimeout(() => {
window.armcordinternal.splashEnd();
switch (window.armcord.channel) {
case "stable":
window.location.replace("https://discord.com/app");
break;
case "canary":
window.location.replace("https://canary.discord.com/app");
break;
case "ptb":
window.location.replace("https://ptb.discord.com/app");
break;
case "foss":
window.location.replace("https://dev.fosscord.com/app");
break;
case undefined:
window.location.replace("https://discord.com/app");
break;
default:
window.location.replace("https://discord.com/app");
} }
}, 5000); setTimeout(() => {
window.armcordinternal.splashEnd();
switch (window.armcord.channel) {
case "stable":
window.location.replace("https://discord.com/app");
break;
case "canary":
window.location.replace("https://canary.discord.com/app");
break;
case "ptb":
window.location.replace("https://ptb.discord.com/app");
break;
case "foss":
window.location.replace("https://dev.fosscord.com/app");
break;
case undefined:
window.location.replace("https://discord.com/app");
break;
default:
window.location.replace("https://discord.com/app");
}
}, 5000);
}
} }
loadLang();
</script> </script>
</html> </html>

View file

@ -1,15 +1,18 @@
//ipc stuff //ipc stuff
import {app, ipcMain, shell, desktopCapturer} from "electron"; import {app, ipcMain, shell, desktopCapturer} from "electron";
import {createTabsGuest, mainWindow} from "./window"; import {mainWindow} from "./window";
import {setConfigBulk, getVersion, getConfig} from "./utils"; import {setConfigBulk, getVersion, getConfig, setLang, getLang, getWindowState} from "./utils";
import {customTitlebar, tabs} from "./main"; import {customTitlebar} from "./main";
import {createSettingsWindow} from "./settings/main"; import {createSettingsWindow} from "./settings/main";
export function registerIpc() { export function registerIpc() {
ipcMain.on("get-app-path", (event, arg) => { ipcMain.on("get-app-path", (event, arg) => {
event.reply("app-path", app.getAppPath()); event.reply("app-path", app.getAppPath());
}); });
ipcMain.on("openTab", (event, number: number) => { ipcMain.on("setLang", (event, lang: string) => {
createTabsGuest(number); setLang(lang);
});
ipcMain.handle("getLang", (event, toGet: string) => {
return getLang(toGet);
}); });
ipcMain.on("open-external-link", (event, href: string) => { ipcMain.on("open-external-link", (event, href: string) => {
shell.openExternal(href); shell.openExternal(href);
@ -38,8 +41,22 @@ export function registerIpc() {
ipcMain.on("get-app-version", (event) => { ipcMain.on("get-app-version", (event) => {
event.returnValue = getVersion(); event.returnValue = getVersion();
}); });
ipcMain.on("splashEnd", (event, arg) => { ipcMain.on("splashEnd", async (event, arg) => {
mainWindow.setSize(800, 600); try {
var width = await getWindowState("width") ?? 800;
var height= await getWindowState("height") ?? 600;
var isMaximized = await getWindowState("isMaximized") ?? false;
} catch (e) {
console.log("No window state file found. Fallbacking to default values.")
mainWindow.setSize(800, 600);
}
if (isMaximized) {
mainWindow.setSize(800, 600); //just so the whole thing doesn't cover whole screen
mainWindow.maximize()
} else {
mainWindow.setSize(width, height);
console.log("Not maximized.")
}
}); });
ipcMain.on("restart", (event, arg) => { ipcMain.on("restart", (event, arg) => {
app.relaunch(); app.relaunch();
@ -60,9 +77,6 @@ export function registerIpc() {
ipcMain.on("titlebar", (event, arg) => { ipcMain.on("titlebar", (event, arg) => {
event.returnValue = customTitlebar; event.returnValue = customTitlebar;
}); });
ipcMain.on("tabs", (event, arg) => {
event.returnValue = tabs;
});
ipcMain.on("shouldPatch", async (event, arg) => { ipcMain.on("shouldPatch", async (event, arg) => {
event.returnValue = await getConfig("automaticPatches"); event.returnValue = await getConfig("automaticPatches");
}); });

View file

@ -1,16 +1,15 @@
// Modules to control application life and create native browser window // Modules to control application life and create native browser window
import {app, BrowserWindow, session, dialog} from "electron"; import {app, BrowserWindow, session} from "electron";
import "v8-compile-cache"; import "v8-compile-cache";
import {getConfig, setup, checkIfConfigExists} from "./utils"; import {getConfig, checkIfConfigExists, injectElectronFlags} from "./utils";
import "./extensions/mods"; import "./extensions/mods";
import "./extensions/plugin"; import "./extensions/plugin";
import "./tray"; import "./tray";
import {createCustomWindow, createNativeWindow, createTabsHost} from "./window"; import {createCustomWindow, createNativeWindow} from "./window";
import "./shortcuts"; import "./shortcuts";
export var settings: any; export var settings: any;
export var customTitlebar: boolean; export var customTitlebar: boolean;
export var tabs: boolean;
if (process.platform == "linux") { if (process.platform == "linux") {
if (process.env.$XDG_SESSION_TYPE == "wayland") { if (process.env.$XDG_SESSION_TYPE == "wayland") {
@ -24,7 +23,7 @@ if (process.platform == "linux") {
} }
} }
checkIfConfigExists(); checkIfConfigExists();
injectElectronFlags();
app.whenReady().then(async () => { app.whenReady().then(async () => {
switch (await getConfig("windowStyle")) { switch (await getConfig("windowStyle")) {
case "default": case "default":
@ -37,17 +36,6 @@ app.whenReady().then(async () => {
case "discord": case "discord":
createNativeWindow(); createNativeWindow();
break; break;
case "glasstron":
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: default:
createCustomWindow(); createCustomWindow();
customTitlebar = true; customTitlebar = true;
@ -72,16 +60,8 @@ app.whenReady().then(async () => {
case "native": case "native":
createNativeWindow(); createNativeWindow();
break; break;
case "glasstron": case "discord":
dialog.showErrorBox( createNativeWindow();
"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; break;
default: default:
createCustomWindow(); createCustomWindow();

View file

@ -15,7 +15,11 @@ contextBridge.exposeInMainWorld("armcord", {
}, },
electron: process.versions.electron, electron: process.versions.electron,
channel: ipcRenderer.sendSync("channel"), channel: ipcRenderer.sendSync("channel"),
openTab: (number: number) => ipcRenderer.sendSync("openTab", number), setLang: (lang: string) => ipcRenderer.send("setLang", lang),
getLang: (toGet: string) =>
ipcRenderer.invoke("getLang", toGet).then((result) => {
return result;
}),
version: ipcRenderer.sendSync("get-app-version", "app-version"), version: ipcRenderer.sendSync("get-app-version", "app-version"),
getDisplayMediaSelector: getDisplayMediaSelector, getDisplayMediaSelector: getDisplayMediaSelector,
openSettingsWindow: () => ipcRenderer.send("openSettingsWindow") openSettingsWindow: () => ipcRenderer.send("openSettingsWindow")

View file

@ -4,11 +4,18 @@ import "./patch";
import * as fs from "fs"; import * as fs from "fs";
import * as path from "path"; import * as path from "path";
import {injectTitlebar} from "./titlebar"; import {injectTitlebar} from "./titlebar";
import {sleep, addStyle, injectJS} from "../utils"; import {sleep, addStyle, injectJS, addScript} from "../utils";
import {ipcRenderer} from "electron"; import {ipcRenderer} from "electron";
import {injectTabs} from "./tabs";
var version = ipcRenderer.sendSync("get-app-version", "app-version"); var version = ipcRenderer.sendSync("get-app-version", "app-version");
async function updateLang() {
if (window.location.href.indexOf("setup.html") > -1) {
console.log("Setup, skipping lang update");
} else {
addScript(`function getDiscordLang() {
{const _w=webpackChunkdiscord_app;let lang;_w.push([[Symbol()],{},e=>{for(const k in e.c){const m=e.c[k].exports;const mDef=m?.default&&m.__esModule?m.default:m;if(mDef?._chosenLocale&&!lang)lang=mDef}}]);_w.pop();window.armcord.setLang(lang._chosenLocale);return lang._chosenLocale;void 0}}
getDiscordLang();`);
}
}
declare global { declare global {
interface Window { interface Window {
armcord: any; armcord: any;
@ -21,16 +28,16 @@ const clientMods = {
}; };
console.log("ArmCord"); console.log("ArmCord");
ipcRenderer.on("themeLoader", (event, message) => {
addStyle(message);
});
if (window.location.href.indexOf("splash.html") > -1) { if (window.location.href.indexOf("splash.html") > -1) {
console.log("Skipping titlebar injection and client mod injection."); console.log("Skipping titlebar injection and client mod injection.");
} else { } else {
if (ipcRenderer.sendSync("titlebar")) { if (ipcRenderer.sendSync("titlebar")) {
injectTitlebar(); injectTitlebar();
} }
if (ipcRenderer.sendSync("tabs")) { sleep(5000).then(async () => {
injectTabs();
}
sleep(5000).then(() => {
const cssPath = path.join(__dirname, "../", "/content/css/discord.css"); const cssPath = path.join(__dirname, "../", "/content/css/discord.css");
addStyle(fs.readFileSync(cssPath, "utf8")); addStyle(fs.readFileSync(cssPath, "utf8"));
@ -38,14 +45,17 @@ if (window.location.href.indexOf("splash.html") > -1) {
case "goosemod": case "goosemod":
injectJS(clientMods.goosemod); injectJS(clientMods.goosemod);
console.log("Loading GooseMod..."); console.log("Loading GooseMod...");
await updateLang();
break; break;
case "cumcord": case "cumcord":
injectJS(clientMods.cumcord); injectJS(clientMods.cumcord);
console.log("Loading Cumcord..."); console.log("Loading Cumcord...");
await updateLang();
break; break;
case "flicker": case "flicker":
injectJS(clientMods.flicker); injectJS(clientMods.flicker);
console.log("Loading FlickerMod..."); console.log("Loading FlickerMod...");
await updateLang();
break; break;
} }
}); });

View file

@ -1,26 +0,0 @@
import {addStyle} from "../utils";
import * as fs from "fs";
import * as path from "path";
export function injectTabs() {
document.addEventListener("DOMContentLoaded", function (event) {
var elem = document.createElement("div");
elem.innerHTML = `<nav class="tabs">
<div id="tabs-controls-container">
<button class="tabs-buttons" onclick="armcord.openTab(1)">1</button>
<button class="tabs-buttons" onclick="armcord.openTab(2)">2</button>
<button class="tabs-buttons" onclick="armcord.openTab(3)">3</button>
<button class="tabs-buttons" onclick="armcord.openTab(4)">4</button>
<button class="tabs-buttons" onclick="armcord.openTab(5)">5</button>
<p class="experimental">Experimental</p>
</div>
</nav>`;
elem.classList.add("withFrame-haYltI");
if (document.getElementById("app-mount") == null) {
document.body.appendChild(elem);
} else {
document.getElementById("app-mount")!.prepend(elem);
}
const cssPath = path.join(__dirname, "../", "/content/css/tabs.css");
addStyle(fs.readFileSync(cssPath, "utf8"));
});
}

View file

@ -38,10 +38,8 @@ export function injectTitlebar() {
maximize!.addEventListener("click", () => { maximize!.addEventListener("click", () => {
if (ipcRenderer.sendSync("win-isMaximized") == true) { if (ipcRenderer.sendSync("win-isMaximized") == true) {
ipcRenderer.send("win-unmaximize"); ipcRenderer.send("win-unmaximize");
document.body.removeAttribute("isMaximized");
} else { } else {
ipcRenderer.send("win-maximize"); ipcRenderer.send("win-maximize");
document.body.setAttribute("isMaximized", "");
} }
}); });
@ -54,6 +52,3 @@ export function injectTitlebar() {
}); });
}); });
} }
export function removeTitlebar() {
document.querySelector("#titlebar")!.remove();
}

View file

@ -1,5 +1,5 @@
import {BrowserWindow, shell, ipcMain} from "electron"; import {BrowserWindow, shell, ipcMain} from "electron";
import {getConfig, setConfigBulk, Settings} from "../utils"; import {getConfig, setConfigBulk, Settings, getLang} from "../utils";
import path from "path"; import path from "path";
var settingsWindow: BrowserWindow; var settingsWindow: BrowserWindow;
var instance: number = 0; var instance: number = 0;

View file

@ -2,6 +2,10 @@ import {contextBridge, ipcRenderer} from "electron";
console.log("ArmCord Settings"); console.log("ArmCord Settings");
contextBridge.exposeInMainWorld("settings", { contextBridge.exposeInMainWorld("settings", {
save: (...args: any) => ipcRenderer.send("saveSettings", ...args), save: (...args: any) => ipcRenderer.send("saveSettings", ...args),
getLang: (toGet: string) =>
ipcRenderer.invoke("getLang", toGet).then((result) => {
return result;
}),
get: (toGet: string) => get: (toGet: string) =>
ipcRenderer.invoke("getSetting", toGet).then((result) => { ipcRenderer.invoke("getSetting", toGet).then((result) => {
return result; return result;

View file

@ -14,7 +14,7 @@
<option value="default">Default</option> <option value="default">Default</option>
<option value="native">Native</option> <option value="native">Native</option>
</select> </select>
<p class="header">ArmCord theme:</p> <p class="header" id="settings-theme">ArmCord theme:</p>
</div> </div>
<br /> <br />
<div class="switch"> <div class="switch">
@ -24,19 +24,19 @@
</div> </div>
<br /> <br />
<div class="switch"> <div class="switch">
<label class="header">Minimize to tray</label> <label class="header" id="settings-tray">Minimize to tray</label>
<input class="tgl tgl-light left" id="tray" type="checkbox" /> <input class="tgl tgl-light left" id="tray" type="checkbox" />
<label class="tgl-btn left" for="tray"></label> <label class="tgl-btn left" for="tray"></label>
</div> </div>
<br /> <br />
<div class="switch"> <div class="switch">
<label class="header">Automatic Patches</label> <label class="header" id="settings-patches">Automatic Patches</label>
<input class="tgl tgl-light left" id="patches" type="checkbox" /> <input class="tgl tgl-light left" id="patches" type="checkbox" />
<label class="tgl-btn left" for="patches"></label> <label class="tgl-btn left" for="patches"></label>
</div> </div>
<br /> <br />
<div class="switch"> <div class="switch">
<label class="header">Invite Websocket</label> <label class="header" id="settings-invitewebsocket">Invite Websocket</label>
<input class="tgl tgl-light left" id="websocket" type="checkbox" /> <input class="tgl tgl-light left" id="websocket" type="checkbox" />
<label class="tgl-btn left" for="websocket"></label> <label class="tgl-btn left" for="websocket"></label>
</div> </div>
@ -47,7 +47,7 @@
<option value="ptb">PTB</option> <option value="ptb">PTB</option>
<option value="foss">Fosscord</option> <option value="foss">Fosscord</option>
</select> </select>
<p class="header">Discord channel:</p> <p class="header" id="settings-channel">Discord channel:</p>
</div> </div>
<div class="switch"> <div class="switch">
<select name="mod" id="mod" class="left"> <select name="mod" id="mod" class="left">
@ -56,12 +56,41 @@
<option value="flicker">Flicker</option> <option value="flicker">Flicker</option>
<option value="none">None</option> <option value="none">None</option>
</select> </select>
<p class="header">Client mod:</p> <p class="header" id="settings-mod">Client mod:</p>
</div> </div>
<div class="switch">
<button id="save" class="center">Save settings</button> <select name="prfmMode" id="prfmMode" class="left">
<option value="performance">Performance</option>
<option value="battery">Battery</option>
<option value="none">None</option>
</select>
<p class="header" id="settings-prfmMode">Performance mode:</p>
</div>
<button id="settings-save" class="center">Save settings</button>
</body> </body>
<script>
async function loadLang() {
document.getElementById("settings-save").innerHTML = await settings.getLang("settings-save");
document.getElementById("settings-mod").innerHTML = await settings.getLang("settings-mod");
document.getElementById("settings-channel").innerHTML = await settings.getLang("settings-channel");
document.getElementById("settings-invitewebsocket").innerHTML = await settings.getLang(
"settings-invitewebsocket"
);
document.getElementById("settings-patches").innerHTML = await settings.getLang("settings-patches");
document.getElementById("settings-tray").innerHTML = await settings.getLang("settings-tray");
document.getElementById("settings-theme").innerHTML = await settings.getLang("settings-theme");
//select stuff
document.getElementById("mod").options[3].text = await settings.getLang("settings-none");
document.getElementById("prfmMode").options[2].text = await settings.getLang("settings-none");
document.getElementById("prfmMode").options[1].text = await settings.getLang("settings-prfmMode-battery");
document.getElementById("prfmMode").options[0].text = await settings.getLang(
"settings-prfmMode-performance"
);
document.getElementById("theme").options[1].text = await settings.getLang("settings-theme-native");
document.getElementById("theme").options[0].text = await settings.getLang("settings-theme-default");
}
loadLang();
</script>
<script> <script>
async function loadSettings() { async function loadSettings() {
document.getElementById("csp").checked = await settings.get("armcordCSP"); document.getElementById("csp").checked = await settings.get("armcordCSP");
@ -71,10 +100,10 @@
document.getElementById("mod").value = await settings.get("mods"); document.getElementById("mod").value = await settings.get("mods");
document.getElementById("channel").value = await settings.get("channel"); document.getElementById("channel").value = await settings.get("channel");
document.getElementById("theme").value = await settings.get("windowStyle"); document.getElementById("theme").value = await settings.get("windowStyle");
document.getElementById("prfmMode").value = await settings.get("performanceMode");
} }
loadSettings(); loadSettings();
document.getElementById("save").addEventListener("click", function () { document.getElementById("settings-save").addEventListener("click", function () {
//function saveSettings(windowStyle: string, channelSetting: string, armcordCSPSetting: boolean, minimizeToTray: boolean, automaticPatches: boolean,modsSetting: string, blurType: string)
settings.save({ settings.save({
windowStyle: document.getElementById("theme").value, windowStyle: document.getElementById("theme").value,
channel: document.getElementById("channel").value, channel: document.getElementById("channel").value,
@ -82,8 +111,8 @@
minimizeToTray: document.getElementById("tray").checked, minimizeToTray: document.getElementById("tray").checked,
automaticPatches: document.getElementById("patches").checked, automaticPatches: document.getElementById("patches").checked,
mods: document.getElementById("mod").value, mods: document.getElementById("mod").value,
blurType: "acrylic",
inviteWebsocket: document.getElementById("websocket").checked, inviteWebsocket: document.getElementById("websocket").checked,
performanceMode: document.getElementById("prfmMode").value,
doneSetup: true doneSetup: true
}); });
}); });

View file

@ -1,10 +1,15 @@
import {app, Menu, Tray} from "electron"; import { app, Menu, Tray } from "electron";
import {mainWindow} from "./window"; import { mainWindow } from "./window";
import {getConfig} from "./utils"; import { getConfig, setWindowState } from "./utils";
import * as path from "path"; import * as path from "path";
import {createSettingsWindow} from "./settings/main"; import { createSettingsWindow } from "./settings/main";
import { platform } from "process";
let tray: any = null; let tray: any = null;
let defaultIcon = "ac_plug_colored";
app.whenReady().then(async () => { app.whenReady().then(async () => {
if (platform == "darwin") {
defaultIcon = "macos"
}
if ((await getConfig("windowStyle")) == "discord") { if ((await getConfig("windowStyle")) == "discord") {
tray = new Tray(path.join(__dirname, "../", "/assets/dsc-tray.png")); tray = new Tray(path.join(__dirname, "../", "/assets/dsc-tray.png"));
const contextMenu = Menu.buildFromTemplate([ const contextMenu = Menu.buildFromTemplate([
@ -17,6 +22,12 @@ app.whenReady().then(async () => {
{ {
label: "Quit ArmCord", label: "Quit ArmCord",
click: function () { click: function () {
let [width, height] = mainWindow.getSize()
setWindowState({
width: width,
height: height,
isMaximized: mainWindow.isMaximized()
})
app.quit(); app.quit();
} }
} }
@ -25,7 +36,7 @@ app.whenReady().then(async () => {
tray.setToolTip("Discord"); tray.setToolTip("Discord");
tray.setContextMenu(contextMenu); tray.setContextMenu(contextMenu);
} else { } else {
var trayIcon = (await getConfig("trayIcon")) ?? "ac_plug_colored"; var trayIcon = (await getConfig("trayIcon")) ?? defaultIcon;
tray = new Tray(path.join(__dirname, "../", `/assets/${trayIcon}.png`)); tray = new Tray(path.join(__dirname, "../", `/assets/${trayIcon}.png`));
const contextMenu = Menu.buildFromTemplate([ const contextMenu = Menu.buildFromTemplate([
{ {
@ -59,6 +70,12 @@ app.whenReady().then(async () => {
{ {
label: "Quit ArmCord", label: "Quit ArmCord",
click: function () { click: function () {
let [width, height] = mainWindow.getSize()
setWindowState({
width: width,
height: height,
isMaximized: mainWindow.isMaximized()
})
app.quit(); app.quit();
} }
} }

View file

@ -1,6 +1,7 @@
import * as fs from "fs"; import * as fs from "fs";
import {app, dialog} from "electron"; import { app, dialog } from "electron";
import path from "path"; import path from "path";
import { defaultMaxListeners } from "events";
export var firstRun: boolean; export var firstRun: boolean;
export var isSetup: boolean; export var isSetup: boolean;
export var contentPath: string; export var contentPath: string;
@ -41,7 +42,7 @@ export function setup() {
minimizeToTray: true, minimizeToTray: true,
automaticPatches: false, automaticPatches: false,
mods: "cumcord", mods: "cumcord",
blurType: "acrylic", performanceMode: "none",
inviteWebsocket: true, inviteWebsocket: true,
doneSetup: false doneSetup: false
}; };
@ -52,7 +53,7 @@ export function setup() {
export function getVersion() { export function getVersion() {
//to-do better way of doing this //to-do better way of doing this
return "3.1.0"; return "3.0.7";
} }
export async function injectJS(inject: string) { export async function injectJS(inject: string) {
const js = await (await fetch(`${inject}`)).text(); const js = await (await fetch(`${inject}`)).text();
@ -63,7 +64,111 @@ export async function injectJS(inject: string) {
document.body.appendChild(el); document.body.appendChild(el);
} }
export async function injectElectronFlags() {
// MIT License
// Copyright (c) 2022 GooseNest
// 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.
const presets = {
performance: `--enable-gpu-rasterization --enable-zero-copy --ignore-gpu-blocklist --enable-hardware-overlays=single-fullscreen,single-on-top,underlay --enable-features=EnableDrDc,CanvasOopRasterization,BackForwardCache:TimeToLiveInBackForwardCacheInSeconds/300/should_ignore_blocklists/true/enable_same_site/true,ThrottleDisplayNoneAndVisibilityHiddenCrossOriginIframes,UseSkiaRenderer,WebAssemblyLazyCompilation --disable-features=Vulkan --force_high_performance_gpu`, // Performance
battery: "--enable-features=TurnOffStreamingMediaCachingOnBattery --force_low_power_gpu" // Known to have better battery life for Chromium?
};
switch (await getConfig("performanceMode")) {
case "performance":
console.log("Performance mode enabled");
app.commandLine.appendSwitch(presets.performance);
break;
case "battery":
console.log("Battery mode enabled");
app.commandLine.appendSwitch(presets.battery);
break;
default:
console.log("No performance modes set");
}
}
export async function setLang(language: string) {
const userDataPath = app.getPath("userData");
const storagePath = path.join(userDataPath, "/storage/");
const langConfigFile = storagePath + "lang.json";
if (!fs.existsSync(langConfigFile)) {
fs.writeFileSync(langConfigFile, "{}", "utf-8");
}
let rawdata = fs.readFileSync(langConfigFile, "utf-8");
let parsed = JSON.parse(rawdata);
parsed["lang"] = language;
let toSave = JSON.stringify(parsed);
fs.writeFileSync(langConfigFile, toSave, "utf-8");
}
var language: string;
export async function getLang(object: string) {
if (language == undefined) {
try {
const userDataPath = app.getPath("userData");
const storagePath = path.join(userDataPath, "/storage/");
const langConfigFile = storagePath + "lang.json";
let rawdata = fs.readFileSync(langConfigFile, "utf-8");
let parsed = JSON.parse(rawdata);
language = parsed["lang"];
} catch (e) {
console.log("Language config file doesn't exist. Fallback to English.")
language = "en-US"
}
}
if (language.length == 2) {
language = language + "-" + language.toUpperCase();
}
var langPath = path.join(__dirname, "../", "/assets/lang/" + language + ".json");
if (!fs.existsSync(langPath)) {
langPath = path.join(__dirname, "../", "/assets/lang/en-US.json");
}
let rawdata = fs.readFileSync(langPath, "utf-8");
let parsed = JSON.parse(rawdata);
return parsed[object];
}
//ArmCord Window State manager
export interface WindowState {
width: number;
height: number;
isMaximized: boolean;
}
export async function setWindowState(object: WindowState) {
const userDataPath = app.getPath("userData");
const storagePath = path.join(userDataPath, "/storage/");
const saveFile = storagePath + "window.json";
if (!fs.existsSync(saveFile)) {
fs.writeFileSync(saveFile, "{}", "utf-8");
}
let toSave = JSON.stringify(object);
fs.writeFileSync(saveFile, toSave, "utf-8");
}
export async function getWindowState(object: string) {
const userDataPath = app.getPath("userData");
const storagePath = path.join(userDataPath, "/storage/");
const settingsFile = storagePath + "window.json";
let rawdata = fs.readFileSync(settingsFile, "utf-8");
let returndata = JSON.parse(rawdata);
console.log(object + ": " + returndata[object]);
return returndata[object];
}
//ArmCord Settings/Storage manager //ArmCord Settings/Storage manager
export interface Settings { export interface Settings {
@ -73,7 +178,7 @@ export interface Settings {
minimizeToTray: boolean; minimizeToTray: boolean;
automaticPatches: boolean; automaticPatches: boolean;
mods: string; mods: string;
blurType: string; performanceMode: string;
inviteWebsocket: boolean; inviteWebsocket: boolean;
doneSetup: boolean; doneSetup: boolean;
} }

View file

@ -2,17 +2,18 @@
// I had to add most of the window creation code here to split both into seperete functions // 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 // 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. // I'm sorry for this mess but I'm not sure how to fix it.
import {BrowserWindow, shell, app, ipcMain, dialog, clipboard} from "electron"; import { BrowserWindow, shell, app, dialog } from "electron";
import path from "path"; import path from "path";
import {checkIfConfigIsBroken, firstRun, getConfig, contentPath, isSetup} from "./utils"; import { checkIfConfigIsBroken, firstRun, getConfig, contentPath, isSetup, setConfig, setLang, setWindowState } from "./utils";
import {registerIpc} from "./ipc"; import { registerIpc } from "./ipc";
import * as fs from "fs";
import startServer from "./socket"; import startServer from "./socket";
import contextMenu from "electron-context-menu"; import contextMenu from "electron-context-menu";
import os from "os"; import os from "os";
export var icon: string; export var icon: string;
export let mainWindow: BrowserWindow; export let mainWindow: BrowserWindow;
export let inviteWindow: BrowserWindow; export let inviteWindow: BrowserWindow;
let guestWindows: BrowserWindow[] = []; var osType = os.type()
contextMenu({ contextMenu({
showSaveImageAs: true, showSaveImageAs: true,
@ -21,18 +22,82 @@ contextMenu({
}); });
async function doAfterDefiningTheWindow() { async function doAfterDefiningTheWindow() {
var ignoreProtocolWarning = await getConfig("ignoreProtocolWarning");
checkIfConfigIsBroken(); checkIfConfigIsBroken();
registerIpc(); registerIpc();
mainWindow.webContents.userAgent = `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}) => { // A little sloppy but it works :p
shell.openExternal(url); if (osType == 'Windows_NT') {
return {action: "deny"}; osType = "Windows " + os.release().split('.')[0] + " (" + os.release() + ")";
}
mainWindow.webContents.userAgent = `Mozilla/5.0 (X11; ${osType} ${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 }) => {
if (url.startsWith("https:" || url.startsWith("http:") || url.startsWith("mailto:"))) {
shell.openExternal(url);
} else {
if (ignoreProtocolWarning) {
shell.openExternal(url);
} else {
const options = {
type: "question",
buttons: ["Yes, please", "No, I don't"],
defaultId: 1,
title: url,
message: `Do you want to open ${url}?`,
detail: "This url was detected to not use normal browser protocols. It could mean that this url leads to a local program on your computer. Please check if you recognise it, before proceeding!",
checkboxLabel: "Remember my answer and ignore this warning for future sessions",
checkboxChecked: false
};
dialog.showMessageBox(mainWindow, options).then(({ response, checkboxChecked }) => {
console.log(response, checkboxChecked);
if (checkboxChecked) {
if (response == 0) {
setConfig("ignoreProtocolWarning", true);
} else {
setConfig("ignoreProtocolWarning", false);
}
}
if (response == 0) {
shell.openExternal(url);
} else {
return;
}
});
}
}
return { action: "deny" };
}); });
mainWindow.webContents.session.webRequest.onBeforeRequest((details, callback) => { mainWindow.webContents.session.webRequest.onBeforeRequest((details, callback) => {
if (/api\/v\d\/science$/g.test(details.url)) return callback({cancel: true}); if (/api\/v\d\/science$/g.test(details.url)) return callback({ cancel: true });
return callback({}); return callback({});
}); });
const userDataPath = app.getPath("userData");
const themesFolder = userDataPath + "/themes/";
if (!fs.existsSync(themesFolder)) {
fs.mkdirSync(themesFolder);
console.log("Created missing theme folder");
}
mainWindow.webContents.on('did-finish-load', () => {
fs.readdirSync(themesFolder).forEach((file) => {
try {
const manifest = fs.readFileSync(`${themesFolder}/${file}/manifest.json`, "utf8");
var themeFile = JSON.parse(manifest);
mainWindow.webContents.send("themeLoader", fs.readFileSync(`${themesFolder}/${file}/${themeFile.theme}`, "utf-8"))
console.log(`%cLoaded ${themeFile.name} made by ${themeFile.author}`, "color:red");
} catch (err) {
console.error(err);
}
});
});
mainWindow.on("close", async (e) => { mainWindow.on("close", async (e) => {
let [width, height] = mainWindow.getSize()
setWindowState({
width: width,
height: height,
isMaximized: mainWindow.isMaximized()
})
if (await getConfig("minimizeToTray")) { if (await getConfig("minimizeToTray")) {
e.preventDefault(); e.preventDefault();
mainWindow.hide(); mainWindow.hide();
@ -41,14 +106,20 @@ async function doAfterDefiningTheWindow() {
app.quit(); app.quit();
} }
}); });
mainWindow.on('maximize', () => {
mainWindow.webContents.executeJavaScript(`document.body.setAttribute("isMaximized", "");`)
})
mainWindow.on('unmaximize', () => {
mainWindow.webContents.executeJavaScript(`document.body.removeAttribute("isMaximized");`)
})
console.log(contentPath); console.log(contentPath);
if ((await getConfig("inviteWebsocket")) == true) { if ((await getConfig("inviteWebsocket")) == true) {
startServer(); startServer();
} }
try { try {
mainWindow.loadFile(contentPath); mainWindow.loadFile(contentPath);
if (isSetup) { if (isSetup) {
await setLang(Intl.DateTimeFormat().resolvedOptions().locale)
mainWindow.setSize(390, 470); mainWindow.setSize(390, 470);
} }
} catch (e) { } catch (e) {
@ -58,6 +129,7 @@ async function doAfterDefiningTheWindow() {
console.log(process.platform); console.log(process.platform);
if (process.platform === "win32") { if (process.platform === "win32") {
if (firstRun) { if (firstRun) {
await setLang(Intl.DateTimeFormat().resolvedOptions().locale)
mainWindow.setSize(390, 470); mainWindow.setSize(390, 470);
mainWindow.loadURL(`file://${__dirname}/content/setup.html`); mainWindow.loadURL(`file://${__dirname}/content/setup.html`);
} else { } else {
@ -65,6 +137,7 @@ async function doAfterDefiningTheWindow() {
} }
} else { } else {
if (firstRun) { if (firstRun) {
await setLang(Intl.DateTimeFormat().resolvedOptions().locale)
mainWindow.setSize(390, 470); mainWindow.setSize(390, 470);
mainWindow.loadURL(`file://${__dirname}/ts-out/content/setup.html`); mainWindow.loadURL(`file://${__dirname}/ts-out/content/setup.html`);
} else { } else {
@ -79,7 +152,7 @@ export function createCustomWindow() {
height: 350, height: 350,
title: "ArmCord", title: "ArmCord",
darkTheme: true, darkTheme: true,
icon: path.join(__dirname, "/assets/icon_transparent.png"), icon: path.join(__dirname, "../", "/assets/ac_icon_transparent.png"),
frame: false, frame: false,
autoHideMenuBar: true, autoHideMenuBar: true,
webPreferences: { webPreferences: {
@ -95,7 +168,7 @@ export function createNativeWindow() {
height: 350, height: 350,
title: "ArmCord", title: "ArmCord",
darkTheme: true, darkTheme: true,
icon: path.join(__dirname, "/assets/icon_transparent.png"), icon: path.join(__dirname, "../", "/assets/ac_icon_transparent.png"),
frame: true, frame: true,
autoHideMenuBar: true, autoHideMenuBar: true,
webPreferences: { webPreferences: {
@ -106,84 +179,13 @@ export function createNativeWindow() {
doAfterDefiningTheWindow(); 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,
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")
}
});
doAfterDefiningTheWindow();
}
export function createTabsGuest(number: number) {
console.log(guestWindows);
if (guestWindows[number] !== undefined || null) {
try {
console.log("Showing Guest Window " + number);
mainWindow.hide();
guestWindows[number].show();
mainWindow = guestWindows[number];
} catch (e) {
console.error(e);
}
} else {
console.log("Creating Guest Window " + number);
mainWindow.hide();
guestWindows[number] = new BrowserWindow({
width: 800,
height: 600,
title: "ArmCord Guest Window " + number,
darkTheme: true,
icon: path.join(__dirname, "/assets/icon_transparent.png"),
frame: true,
autoHideMenuBar: true,
webPreferences: {
preload: path.join(__dirname, "preload/preload.js")
}
});
mainWindow = guestWindows[number];
ipcMain.on("tab" + number, (event) => {
event.returnValue = true; //return true so we know the tab exists
});
guestWindows[number].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
guestWindows[number].webContents.setWindowOpenHandler(({url}) => {
shell.openExternal(url);
return {action: "deny"};
});
guestWindows[number].webContents.session.webRequest.onBeforeRequest(
(details: {url: string}, callback: (arg0: {cancel?: boolean}) => any) => {
if (/api\/v\d\/science$/g.test(details.url)) return callback({cancel: true});
return callback({});
}
);
guestWindows[number].loadURL("https://discord.com/app");
}
}
export function createInviteWindow() { export function createInviteWindow() {
inviteWindow = new BrowserWindow({ inviteWindow = new BrowserWindow({
width: 800, width: 800,
height: 600, height: 600,
title: "ArmCord Invite Manager", title: "ArmCord Invite Manager",
darkTheme: true, darkTheme: true,
icon: path.join(__dirname, "/assets/icon_transparent.png"), icon: path.join(__dirname, "../", "/assets/ac_icon_transparent.png"),
frame: true, frame: true,
autoHideMenuBar: true, autoHideMenuBar: true,
webPreferences: { webPreferences: {