Compare commits

...

152 Commits

Author SHA1 Message Date
JeanOUINA 39fc7f2893
Merge pull request #356 from SomeAspy/patch-1
Please do this if your gonna ban people for asking support
2021-10-09 12:47:51 +02:00
Aiden dc3e90125f
Please do this if your gonna ban people for asking support 2021-10-07 17:20:57 -04:00
smartfridge 8ab6645d2c
Merge pull request #324 from SethFalco/chores
EditorConfig + Add Nowegian to Desktop File + Minor Edits
2021-08-25 23:35:51 +02:00
Seth Falco c746a6da1a
minor updates to EmojiModule 2021-08-11 23:31:10 +02:00
Seth Falco b2ffdc088c
i18n: add norwegian comment to desktop file 2021-08-11 23:05:15 +02:00
Seth Falco aee1584dbf
chore: add editorconfig 2021-08-11 23:04:48 +02:00
smartfridge 2d4f4aae41 v0.1.9 2021-07-28 21:58:04 +02:00
JeanOUINA 3c4c7de386
fix bdd not loading 2021-07-15 15:43:46 +02:00
JeanOUINA c4b8a0e03a
who the fuck forgot that equal sign 2021-07-15 15:29:51 +02:00
smartfridge ab207632c1
Merge pull request #297 from Lightcord/development-hell
Merge Development hell
2021-07-03 21:22:06 +02:00
smartfridge 2a68e23cb1 Update changelog 2021-07-03 21:18:57 +02:00
smartfridge ae8c0d5057 Change LightcordBD logo to actual Lightcord logo 2021-07-03 20:45:54 +02:00
smartfridge 47bfd2f279 LightcordApi npm audit fix 2021-07-03 19:50:50 +02:00
smartfridge 241ef227d5 remove ustom-electron-titlebar as it's not used 2021-07-03 18:59:32 +02:00
smartfridge 29c84c8d62 npm audit fix 2021-07-03 18:50:21 +02:00
smartfridge 9484cc93da
Merge pull request #296 from GermanBread/master
add chromeos to readme
2021-07-03 12:21:25 +02:00
GermanBread 9b5c6d3404
add chromeos 2021-07-03 09:50:25 +02:00
smartfridge f3d728ee94 Update package-lock.json 2021-06-18 17:44:31 +02:00
smartfridge abb6aa200f v0.1.7 2021-06-16 20:59:17 +02:00
smartfridge 2bd69b87f6
Merge pull request #288 from smartfrigde/master
0.1.7 😳
2021-06-16 20:53:54 +02:00
smartfridge 596eaec377 Downgrade the version lmfao 2021-06-16 20:53:06 +02:00
smartfridge 32c8bb4349 v0.1.8 2021-06-16 20:36:17 +02:00
smartfridge e77736b60a Update build.yml 2021-06-16 20:36:03 +02:00
smartfridge f2963f63c6 v0.1.7 2021-06-16 20:19:40 +02:00
smartfridge 799790d883 Add CI build 2021-06-16 20:08:04 +02:00
smartfridge e0aa930989 Merge branch 'Lightcord:master' into master 2021-06-16 19:25:24 +02:00
smartfridge c3afe9e275 Correct badges in chat 2021-06-16 19:20:33 +02:00
smartfridge c6bc14a1d7 BandageBD Naming --> LightcordBD 2021-06-16 19:07:12 +02:00
smartfridge 8d7bcfd360 Add some tweaks to Plugin Scanner 2021-06-16 19:00:09 +02:00
smartfridge 00cd1482a4
Merge pull request #287 from smartfrigde/master
Update Lightcord Dev Badge id's
2021-06-16 18:46:10 +02:00
smartfridge 807f0e9003 Update Lightcord Dev Badge id's 2021-06-16 18:44:11 +02:00
Phorcys 0fd8bc047a
Merge pull request #275 from smartfrigde/master
Fix Lightcord (account info, npm audit fix, few readme changes)
smar frodge
2021-06-09 22:20:10 +02:00
smartfridge f4165abb77 oui oui changelog 2021-06-09 19:54:45 +02:00
smartfridge fd0a8e70c4 Change BBD invites, names and bump version to 0.1.6 2021-06-09 19:47:45 +02:00
smartfridge ad7edf74fa Fix account info 2021-06-09 18:43:58 +02:00
smartfridge f38c008d08 npm audit fix 2021-06-09 18:34:18 +02:00
smartfridge f913227278 Merge branch 'Lightcord:master' into master 2021-06-09 18:12:18 +02:00
JeanOUINA dde7969281
Merge pull request #261 from T-O-R-U-S/patch-1
Stop using elif chains, you twats.
2021-06-06 20:59:53 +02:00
smartfridge a016df59ca
Update README.md 2021-05-23 15:54:12 +02:00
JeanOUINA e442cc12d4
Merge pull request #251 from smartfrigde/master
Update BetterDiscord Modules to last possible version
2021-05-17 22:38:19 +02:00
T•Ø•R•Ü•S 11aad62169
Stop using elif chains, you twats. 2021-05-15 08:19:47 +04:00
JeanOUINA 17044e4a6d
Merge pull request #260 from radiden/master
Fix Copy selector button being appended under reaction buttons
2021-05-13 04:46:44 +02:00
radiden bf55c1f586 Fix Copy selector button being appended under reaction buttons 2021-05-13 00:23:17 +02:00
JeanOUINA b0ee318ebc
Merge pull request #255 from GermanBread/master
Finalise installer change
2021-05-03 23:51:03 +02:00
GermanBread ad88cee4ef update README and remove LULI 2021-05-03 23:30:59 +02:00
JeanOUINA 7a007f353d
Merge pull request #254 from GermanBread/master
Provide more assistance during install
2021-05-03 23:01:15 +02:00
GermanBread de58a38d72 Finalise 2021-05-03 22:30:20 +02:00
GermanBread fb5031fe21 install instructions 2021-05-03 22:24:28 +02:00
GermanBread c702b50953 smol change
commit spam
lol?
2021-05-03 22:09:11 +02:00
GermanBread 52f16d89a6 Remove newline... 2021-05-03 22:06:13 +02:00
GermanBread 68ebd08205 Useful stuff 2021-05-03 22:04:05 +02:00
smartfridge 2b383f3c3c
Update package-lock.json 2021-04-29 20:53:55 +02:00
smartfridge 2fd574ad3a
Update package-lock.json 2021-04-29 20:51:53 +02:00
smartfridge 7505dca0a5
Update package-lock.json 2021-04-29 20:49:51 +02:00
smartfridge 7f68bd891a
Update package-lock.json 2021-04-29 20:45:15 +02:00
smartfridge 7b6091b23d
Update package-lock.json 2021-04-29 20:41:48 +02:00
smartfridge 41edb9d34b
Fix typo 2021-04-29 17:45:18 +02:00
smartfridge 4e892d5750 Update BetterDiscord Modules 2021-04-29 17:19:47 +02:00
JeanOUINA f150671a83
fix compile 2021-04-29 16:41:11 +02:00
JeanOUINA ee4e1a5ba5
remove cross-spawn 2021-04-29 16:21:11 +02:00
JeanOUINA 0367814ebe
remove cross-spawn 2021-04-29 15:56:42 +02:00
JeanOUINA 0bd5d289d4
Merge pull request #250 from smartfrigde/patch-1
Fixed typo
2021-04-29 15:30:50 +02:00
smartfridge db148799bf
Fixed typo 2021-04-29 13:05:23 +02:00
JeanOUINA 81bbd98ce1
Merge pull request #249 from pryme-svg/master
make install script posix compliant
2021-04-25 23:42:59 +02:00
pryme-svg 28f36377a4
root user check posix compliance 2021-04-25 11:56:42 -07:00
pryme-svg c288113a2d
remove bash from readme 2021-04-25 11:32:33 -07:00
pryme-svg f00adbde43
make install script posix compliant 2021-04-25 11:25:04 -07:00
JeanOUINA 33bcb72dec
Merge pull request #247 from GermanBread/master
Helpful commit message
2021-04-19 11:13:32 +02:00
GermanBread 3a07a9e447 sussy 2021-04-19 11:12:42 +02:00
GermanBread 7876ff7c36 Whe the installer is sus 2021-04-19 11:10:01 +02:00
JeanOUINA dc8c0e1115
Merge pull request #239 from GermanBread/master
Change stuff in installer (good)
sex
2021-04-12 21:05:51 +02:00
GermanBread 12e846d3c5 You guys changed got me in the habit of writing useless commit messages. 2021-04-12 21:02:45 +02:00
JeanOUINA 1b61e57a05
shorten npm command 2021-03-30 16:57:04 +02:00
JeanOUINA 55192f0704
Merge pull request #231 from GermanBread/master
Clean up the messy README
2021-03-30 16:55:11 +02:00
GermanBread f559f18f2c e? 2021-03-30 16:45:08 +02:00
GermanBread 9fc40d8fdc Finishing touches 2021-03-30 16:44:05 +02:00
GermanBread df88426a50 Change "Lightcord" and "Summary" to "About" 2021-03-30 16:40:54 +02:00
GermanBread ce8eaceaf0 make README even more readable 2021-03-30 16:40:00 +02:00
GermanBread 1b049fe5fc Make README more readable 2021-03-30 16:38:43 +02:00
JeanOUINA d56e032e8f
Merge pull request #226 from GermanBread/master
fish bad, none of my homies use fish
2021-03-24 20:07:26 +01:00
GermanBread f9e53c302c
make it 2 2021-03-24 20:07:16 +01:00
GermanBread a1e60f1fb4
let me just remove this one line 2021-03-24 20:06:33 +01:00
GermanBread cc20787b56 Of course the obligatory warning about fish 2021-03-24 20:03:45 +01:00
GermanBread 1adf5937eb Change /bin/sh to /bin/bash because /bin/sh is a symlink to the current shell and fish users break this script. 2021-03-24 20:03:19 +01:00
JeanOUINA 7303d84f25
Update README.md 2021-03-22 08:17:13 +01:00
JeanOUINA 0d12af06ae
Merge pull request #223 from sitiom/patch-1 2021-03-22 08:12:25 +01:00
sitiom c799c1bca2
Add reference to scoop installation in Windows 2021-03-22 11:11:38 +08:00
JeanOUINA 0436ac7cad
Merge pull request #220 from GermanBread/master
Remove "remove this script" promp
2021-03-19 17:14:47 +01:00
GermanBread ff01ee4d8f And of course remove the prompt to delete the script. Because I'd never forget to do stuff like this. 2021-03-19 17:11:59 +01:00
JeanOUINA 11ad151da2
Merge pull request #219 from GermanBread/master
make install easier
2021-03-19 17:09:35 +01:00
GermanBread b91abe1034 make wget redundant 2021-03-19 17:04:01 +01:00
JeanOUINA 49118eaac0
Merge pull request #211 from steanne/master 2021-03-11 07:20:10 +01:00
steanne 0156020cf4
Update README.md 2021-03-10 16:04:18 -05:00
steanne 48168b5fea
Update README.md 2021-03-10 16:00:18 -05:00
Not Thomiz 6bd9c0a767 package.json missing ? 2021-03-10 00:44:25 +01:00
Not Thomiz c10c2991ab package lok 2021-03-09 23:23:33 +01:00
Jean Ouina 09c8fd3964 fuck me, all my homies hate me 2021-03-09 22:57:21 +01:00
Jean Ouina cd3a8d6117 should work now 2021-03-09 22:20:38 +01:00
Jean Ouina 8fa4c05999 tabs fix !??!?!??? what ? 😳 2021-03-09 20:14:58 +01:00
Jean Ouina bcddf7fbcc Merge branch 'master' of https://github.com/Lightcord/Lightcord 2021-03-09 20:03:42 +01:00
Jean Ouina 0f94f85df0 whoops 2021-03-09 20:00:34 +01:00
Jean Ouina d6ff8c90ab lightcord broken + fix + sex 🤪 2021-03-09 19:59:22 +01:00
JeanOUINA bf6df0151d
Merge pull request #184 from GermanBread/patch-1
Script mainenance
2021-02-13 17:54:27 +01:00
GermanBread 7bb7859626
It wouldn't be a good merge if I forgot some unnecessary stuff
I also made wget and unzip quiet
2021-02-13 16:26:51 +01:00
GermanBread 975ea61e05
Check for unzip 2021-02-13 16:22:36 +01:00
JeanOUINA 4ef8285ec5
Merge pull request #177 from TecCheck/master
Fix #173
2021-02-07 11:37:30 +01:00
TecCheck 9014b09b96
Fix #173 2021-02-05 09:30:20 +01:00
JeanOUINA 2a525cdf7b
Merge pull request #163 from GermanBread/master
Tweak NixOS error message
2021-01-18 19:48:18 +01:00
GermanBread f2066a0389
Tweak NixOS error message
Fixed incorrect variable name
Clarified instructions
2021-01-18 15:37:02 +01:00
JeanOUINA 37ceddc09c
Merge pull request #159 from GermanBread/master
Add fallback URLs to install script
2021-01-15 16:47:28 +01:00
GermanBread 3187618385 Add fallback URLs 2021-01-15 14:30:19 +01:00
Phorcys 50a73a2c68
Merge pull request #157 from GermanBread/master
Usual install script update
2021-01-13 11:57:33 +01:00
GermanBread 87487ddf82 fix .desktop 2021-01-12 22:38:32 +01:00
GermanBread dbe8fb132b - Reliability improvements
- NixOS warning
2021-01-12 22:29:51 +01:00
JeanOUINA 986d1cb4ed
Merge pull request #149 from GermanBread/master
e
2021-01-05 22:13:34 +01:00
GermanBread 730aadd304 fix double sudo 2021-01-05 22:12:30 +00:00
GermanBread e26cdc08a5 Supress removal messages of local .desktop files 2021-01-05 19:48:19 +00:00
GermanBread 3667b284b3 Fix broken wget 2021-01-05 19:42:02 +00:00
GermanBread 91fb2bfb2f Clarification 2021-01-05 19:40:50 +00:00
GermanBread 396c62af5b Reliability improvements 2021-01-05 19:32:11 +00:00
GermanBread d7bbd596a4 Fix missing command elevations 2021-01-05 19:00:36 +00:00
GermanBread 50954dfe8e Fix README ... 2021-01-05 17:44:53 +00:00
GermanBread b157b1c7af Change README accordingly 2021-01-05 17:40:32 +00:00
GermanBread 33361757d0 Merge install scripts into one 2021-01-05 17:40:21 +00:00
Jean Ouina 58f0390112 fuck btoa all my homies hate btoa 2021-01-01 13:32:18 +01:00
JeanOUINA 3df98827aa
Merge pull request #146 from Janastinou/patch-1
e
2021-01-01 02:07:22 +01:00
Janastinou df4b99dfea
Update licence 2020 to 2021 2021-01-01 01:48:41 +01:00
JeanOUINA 0c1de17a5b
Merge pull request #141 from saltedcoffii/patch-1
Fix small typo
2020-12-20 07:07:50 +01:00
saltedcoffii f574c6e17f
Fix small typo
Change "AUR helped" to "AUR helper"
2020-12-19 21:22:37 -08:00
Jean Ouina dae02359ee Partially update discord 2020-12-12 11:56:28 +01:00
JeanOUINA 75bc92dc78
Merge pull request #131 from pryme-svg/master
Fixes #130
2020-12-08 16:56:48 +01:00
pryme-svg 3920151bfe
Try to catch 2020-12-07 20:20:31 -08:00
Jean Ouina 33722854ff Fix for linux aur (or at least should) 2020-12-05 20:46:37 +01:00
Jean Ouina 73092e32f3 e 2020-12-05 07:22:21 +01:00
JeanOUINA ab24f99514
Merge pull request #126 from pryme-svg/master
minor fixes and add keep function
2020-12-04 22:51:12 +01:00
pryme-svg b4dcd629fd minor fixes 2020-12-04 13:48:27 -08:00
JeanOUINA 5256d50651
Merge pull request #125 from Lightcord/dependabot/npm_and_yarn/LightcordApi/highlight.js-10.4.1
Bump highlight.js from 10.4.0 to 10.4.1 in /LightcordApi
2020-12-04 22:10:18 +01:00
dependabot[bot] 2c8304bb5f
Bump highlight.js from 10.4.0 to 10.4.1 in /LightcordApi
Bumps [highlight.js](https://github.com/highlightjs/highlight.js) from 10.4.0 to 10.4.1.
- [Release notes](https://github.com/highlightjs/highlight.js/releases)
- [Changelog](https://github.com/highlightjs/highlight.js/blob/master/CHANGES.md)
- [Commits](https://github.com/highlightjs/highlight.js/compare/10.4.0...10.4.1)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-04 21:08:18 +00:00
JeanOUINA 78088c69d5
Merge pull request #124 from GermanBread/GermanBread-Clarifation
Clarify the install instructions
Fixes #120
2020-12-04 22:04:40 +01:00
UnsignedBool 0a1eba997c
Clarify the install instructions
- Slightly improved formatting
- Inform the user that running something as root isn't always a good idea
2020-12-04 22:00:59 +01:00
JeanOUINA f4c321ec5a
Merge pull request #121 from SomeAspy/patch-1
Cleaning
2020-12-04 16:42:30 +01:00
Aiden Baker 5ce2e142b8
Cleaning
Added and removed a few things, made it look nicer in my opinion. also fixed spelling and grammar.
2020-12-03 13:46:53 -05:00
JeanOUINA 58f6628ce3
Merge pull request #112 from Lightcord/dependabot/npm_and_yarn/LightcordApi/highlight.js-10.4.0
Bump highlight.js from 10.1.1 to 10.4.0 in /LightcordApi
2020-11-25 13:32:31 +01:00
dependabot[bot] 66d0ea65f5
Bump highlight.js from 10.1.1 to 10.4.0 in /LightcordApi
Bumps [highlight.js](https://github.com/highlightjs/highlight.js) from 10.1.1 to 10.4.0.
- [Release notes](https://github.com/highlightjs/highlight.js/releases)
- [Changelog](https://github.com/highlightjs/highlight.js/blob/master/CHANGES.md)
- [Commits](https://github.com/highlightjs/highlight.js/compare/10.1.1...10.4.0)

Signed-off-by: dependabot[bot] <support@github.com>
2020-11-24 23:35:10 +00:00
JeanOUINA a2b3513418
Merge pull request #104 from pryme-svg/patch-1
broke command
2020-11-08 17:16:12 +01:00
pryme-svg 42aca04707
Update README.md 2020-11-08 08:05:05 -08:00
JeanOUINA 7512a31faf
Merge pull request #102 from GermanBread/patch-2
add an option to delete the script after use
2020-11-08 13:31:27 +01:00
JeanOUINA bdeca75c27
Merge pull request #103 from GermanBread/patch-1
fix formatting in README
2020-11-08 13:31:11 +01:00
GermanBread 00f5de8ae4
fix formatting in README 2020-11-08 13:30:09 +01:00
GermanBread 3ea9d9e777
add an option to delete the script after use
prevents clogging of the hard drive
2020-11-08 13:28:02 +01:00
JeanOUINA cdfe7449a2
Merge pull request #101 from GermanBread/patch-1
shorten install script command
2020-11-08 13:23:46 +01:00
GermanBread 4b7e0cc08f
shorten install script command 2020-11-08 12:55:06 +01:00
208 changed files with 32913 additions and 11495 deletions

23
.editorconfig Normal file
View File

@ -0,0 +1,23 @@
root = true
[*]
indent_style = space
indent_size = 4
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
curly_bracket_next_line = false
spaces_around_operators = true
[*.{js,ts}]
quote_type = double
[*.{markdown,md}]
trim_trailing_whitespace = false
[*.tsv]
indent_style = tab
[*.yml]
indent_size = 2

32
.github/workflows/build.yml vendored Normal file
View File

@ -0,0 +1,32 @@
name: Build/release
on: push
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: 12
- run: npm run devInstall
- run: npm run compile
- 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 }}
# 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') }}

View File

@ -13,39 +13,6 @@ Lightcord does not own the code at https://github.com/rauenzi/BetterDiscordApp.
BandagedBD (Bandaged BetterDiscord) is a fork of the original [BetterDiscord](https://github.com/Jiiks/BetterDiscordApp) by Jiiks. This has a number of improvements over the original. The original version has been unmaintained hence this fork existing. There have been attempts to rewrite the original that I have been and will continue to be involved in, but in the meantime I will continue to maintain and improve BBD.
# Installation
## Auto Installers
### Windows
Grab the `exe` file from [here](https://github.com/rauenzi/BetterDiscordApp/releases/latest/download/BandagedBD_Windows.exe).
### macOS/OS X
Grab the `zip` file from [here](https://github.com/rauenzi/BetterDiscordApp/releases/latest/download/BandagedBD_Mac.zip).
### Linux
See this [gist](https://gist.github.com/ObserverOfTime/d7e60eb9aa7fe837545c8cb77cf31172).
## Manual Installation
### Windows
1. Download and extract this: https://github.com/rauenzi/BetterDiscordApp/archive/injector.zip
2. Rename `BetterDiscordApp-injector` to `app`.
3. Go to `%localappdata%\Discord\`, and locate the directory with the largest version number (e.g. `app-0.0.307`).
4. Within `app-0.0.307` navigate to `resources`.
5. If an `app` folder already exists inside `resources`, delete it.
6. Move the `app` folder (the one you downloaded and renamed) inside of `resources`.
7. Fully quit Discord and restart it.
### macOS/OS X
1. Download and extract this: https://github.com/rauenzi/BetterDiscordApp/archive/injector.zip
2. Rename `BetterDiscordApp-injector` to `app`.
3. Go to `/Applications/`, right click `Discord.app` and select `Show Package Contents`.
4. Within `Discord.app` navigate to `Contents` -> `Resources`.
5. If an `app` folder already exists inside `Resources`, delete it.
6. Move the `app` folder (the one you downloaded and renamed) inside of `Resources`.
7. Fully quit Discord and restart it.
# FAQ
### What is this?
@ -60,109 +27,3 @@ In our support servers we have channels with lists of official plugins and theme
There are two: [The main server](https://discord.gg/0Tmfo5ZbORCRqbAd), and [the backup](https://discord.gg/2HScm8j).
# Supporters
These people have all subscribed to the `True Supporter` tier on Patreon to support BandagedBD.
<table>
<tr>
<td align="center">
<img src="https://cdn.discordapp.com/avatars/196098063092154368/90f1a7202955dac7a6c685cca3181ab1.webp" width="100px;" alt="Kraken"/><br />
<strong>Kraken</strong><br />
</td>
<td align="center">
<img src="https://cdn.discordapp.com/attachments/585514483699417089/585552300354043915/34959069_500_500.jpg" width="100px;" alt="SPHHAX"/><br />
<a href="http://sphh.ax/" target="_blank" rel="noreferrer noopener"><strong>SPHHAX</strong></a><br />
</td>
<td align="center">
<img src="https://cdn.discordapp.com/attachments/622954403262889995/622957122765848587/5364774.jpg" width="100px;" alt="DefCon42"/><br />
<a href="https://twitter.com/def_con42" target="_blank" rel="noreferrer noopener"><strong>DefCon42</strong></a><br />
</td>
<td align="center">
<img src="https://cdn.discordapp.com/avatars/629231564261425163/a_36cc7d2940b4ffb8a660b1076ab2087f.webp" width="100px;" alt="Justxn"/><br />
<strong>Justxn</strong><br />
</td>
<td align="center">
<img src="https://cdn.discordapp.com/attachments/682750073448169513/682763113296429087/definitely_not_the_dick_police.png" width="100px;" alt="monkey"/><br />
<a href="https://heartunderbla.de" target="_blank" rel="noreferrer noopener"><strong>monkey</strong></a><br />
</td>
<td align="center">
<img src="https://avatars3.githubusercontent.com/u/20338746?s=460&u=d9ebab4f6f0f5221390bca1eaf8f191acd275afe&v=4" width="100px;" alt="Gibbu"/><br />
<a href="https://github.com/Gibbu" target="_blank" rel="noreferrer noopener"><strong>Gibbu</strong></a>
</td>
<td align="center">
<img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/25717114/c100599e58174499b44b4307c26f9312/1.jpeg" width="100px;" alt="Orekieh"/><br />
<strong>Orekieh</strong>
</td>
</tr>
</table>
# Bandagers
These people have all subscribed to the `Bandager` tier on Patreon to support BandagedBD.
<table>
<tr>
<td align="center">
<img src="https://cdn.discordapp.com/avatars/332199319169925120/4709f8f0c9cb7ababd85459bf71848b9.png" width="50px;" alt="William JCM"/><br />
<a href="https://github.com/williamjcm" target="_blank" rel="noreferrer noopener"><strong>William JCM</strong></a>
</td>
<td align="center">
<img src="https://avatars0.githubusercontent.com/u/24623601" width="50px;" alt="NFLD99"/><br />
<a href="https://github.com/NFLD99" target="_blank" rel="noreferrer noopener"><strong>NFLD99</strong></a>
</td>
<td align="center">
<img src="https://i.postimg.cc/5NVxqMnb/Cute-Squid-Circle.png" width="50px;" alt="Tenuit"/><br />
<strong>Tenuit</strong>
</td>
</tr>
</table>
# Donors
These people have either donated or subscribed to the most basic patron tier to support BandagedBD.
<table>
<tr>
<td align="center">
<img src="https://cdn.discordapp.com/avatars/284122164582416385/ebaa1b63191ce70e48ae24f32f452773.webp" width="25px;" /><br />
<strong>aetheryx</strong>
</td>
<td align="center">
<img src="https://cdn.discordapp.com/avatars/216782345779281921/d4b651b606f108cd2f96a19af68f942f.png" width="25px;" /><br />
<strong>JBeauDee</strong>
</td>
<td align="center">
<img src="https://cdn.discordapp.com/avatars/261673576216789004/31d590fb92329e270a6225a13d500c1d.png" width="25px;" /><br />
<strong>vantiss</strong>
</td>
<td align="center">
<img src="https://cdn.discordapp.com/avatars/122204411962327043/7f44a9b036b9e2691f4e81d9e34a78b4.webp" width="25px;" /><br />
<strong>xstefen</strong>
</td>
<td align="center">
<img src="https://cdn.discordapp.com/avatars/219400174869413888/7c88015869990ba97b614b1ac784f8e8.png" width="25px;" /><br />
<strong>『Sorey』</strong>
</td>
<td align="center">
<img src="https://cdn.discordapp.com/avatars/95263213842608128/5024b83e1bff3096d7fc93e8de09d582.gif" width="25px;" /><br />
<strong>LiVeR</strong>
</td>
<td align="center">
<img src="https://cdn.discordapp.com/avatars/144458450192171008/13a3e66d73d216974504b8aad257b7b4.png" width="25px;" /><br />
<strong>SweetLilyCake</strong>
</td>
<td align="center">
<img src="https://cdn.discordapp.com/avatars/398951709336010793/eb6f63eb2f3a5102fb900e60d1a26cdc.png" width="25px;" /><br />
<strong>GameKuchen</strong>
</td>
<td align="center">
<img src="https://i.imgur.com/qrWcKfH.png" width="25px;" /><br />
<strong>Lozo</strong>
</td>
<td align="center">
<img src="https://media.discordapp.net/attachments/575576868166828032/692136786893340752/pfp.gif" width="25px;" /><br />
<strong>Akira</strong>
</td>
</tr>
</table>

View File

@ -7,17 +7,20 @@ function minify(){
console.log(`\x1b[33mMinifying...\x1b[0m`)
const css = fs.readFileSync(path.join(__dirname, "./src/styles/index.css"), "utf-8")
fs.writeFileSync(path.join(__dirname, "./dist/style.css"), css)
const output = new CleanCSS({
sourceMap: true
}).minify(css)
if(output.errors.length > 0){
console.error("\x1b[31m"+output.errors.join("\n")+"\x1b[0m")
}
if(output.warnings.length > 0){
console.warn("\x1b[33m"+output.warnings.join("\n")+"\x1b[0m")
}
fs.writeFileSync(path.join(__dirname, "./dist/style.min.css"), output.styles+"\n/*# sourceMappingURL=style.min.css.map */")
fs.writeFileSync(path.join(__dirname, "./dist/style.min.css.map"), output.sourceMap)
fs.writeFileSync(path.join(__dirname, "./dist/style.min.css.map"), output.sourceMap.toString())
console.log(`\x1b[32mMinified in ${(Date.now() - start)}ms. Minified by ${Math.floor(output.stats.efficiency*100)}%\x1b[0m`)
}
module.exports.minify = minify

File diff suppressed because it is too large Load Diff

View File

@ -3,17 +3,19 @@ export const currentDiscordVersion = (window.DiscordNative && window.DiscordNati
export const minSupportedVersion = "0.3.0";
export const bbdVersion = "0.3.5";
export const bbdChangelog = {
description: "Big things are coming.",
changes: [
{
title: "Bug Fixes",
type: "fixed",
items: [
"Some fixes related to showing modals in the `BdApi`.",
"Fixed the open folder buttons for plugins and themes"
]
}
]
description: "Security updates and more!",
changes: [
{
title: "Bug Fixes & More.",
type: "fixed",
items: [
"Updated various dependencies.",
"Added badges to new devs.",
"Change BandageBD naming inside Lightcord to LightcordBD",
"New release system that allows us to spend more time on actually developing rather than compiling packages ;)",
],
},
],
};
export const settings = {

View File

@ -1,6 +1,6 @@
export default () => {
const v2Loader = document.createElement("div");
v2Loader.className = "bd-loaderv2";
v2Loader.title = "BandagedBD is loading...";
v2Loader.title = "LightcordBD is loading...";
document.body.appendChild(v2Loader);
};

View File

@ -1,4 +1,12 @@
import {pluginCookie, themeCookie, bdplugins, bdthemes, settingsCookie, settings} from "../0globals";
import {
pluginCookie,
themeCookie,
bdplugins,
bdthemes,
settingsCookie,
settings,
bdEmotes,
} from "../0globals";
import mainCore from "./core";
import Utils from "./utils";
import BDV2 from "./v2";
@ -9,67 +17,96 @@ import settingsPanel from "./settingsPanel";
import DOM from "./domtools";
const BdApi = {
get React() { return BDV2.React; },
get ReactDOM() { return BDV2.ReactDom; },
get ReactComponent() {return BDV2.ReactComponent;},
get WindowConfigFile() {return Utils.WindowConfigFile;},
get settings() {return settings;},
get emotes() {return null}, // deprecated, deleted all emotes from betterdiscord.
get screenWidth() { return Math.max(document.documentElement.clientWidth, window.innerWidth || 0); },
get screenHeight() { return Math.max(document.documentElement.clientHeight, window.innerHeight || 0); }
get React() {
return BDV2.React;
},
get ReactDOM() {
return BDV2.ReactDom;
},
get ReactComponent() {
return BDV2.ReactComponent;
},
get WindowConfigFile() {
return Utils.WindowConfigFile;
},
get settings() {
return settings;
},
get emotes() {
return bdEmotes;
},
get screenWidth() {
return Math.max(
document.documentElement.clientWidth,
window.innerWidth || 0
);
},
get screenHeight() {
return Math.max(
document.documentElement.clientHeight,
window.innerHeight || 0
);
},
};
BdApi.getAllWindowPreferences = function() {
return Utils.getAllWindowPreferences();
BdApi.getAllWindowPreferences = function () {
return Utils.getAllWindowPreferences();
};
BdApi.getWindowPreference = function(key) {
return Utils.getWindowPreference(key);
BdApi.getWindowPreference = function (key) {
return Utils.getWindowPreference(key);
};
BdApi.setWindowPreference = function(key, value) {
return Utils.setWindowPreference(key, value);
BdApi.setWindowPreference = function (key, value) {
return Utils.setWindowPreference(key, value);
};
//Inject CSS to document head
//id = id of element
//css = custom css
BdApi.injectCSS = function (id, css) {
DOM.addStyle(DOM.escapeID(id), css);
DOM.addStyle(DOM.escapeID(id), css);
};
//Clear css/remove any element
//id = id of element
BdApi.clearCSS = function (id) {
DOM.removeStyle(DOM.escapeID(id));
DOM.removeStyle(DOM.escapeID(id));
};
//Inject CSS to document head
//id = id of element
//css = custom css
BdApi.linkJS = function (id, url) {
DOM.addScript(DOM.escapeID(id), url);
DOM.addScript(DOM.escapeID(id), url);
};
//Clear css/remove any element
//id = id of element
BdApi.unlinkJS = function (id) {
DOM.removeScript(DOM.escapeID(id));
DOM.removeScript(DOM.escapeID(id));
};
//Get another plugin
//name = name of plugin
BdApi.getPlugin = function (name) {
if (bdplugins.hasOwnProperty(name)) {
return bdplugins[name].plugin;
}
return null;
Utils.warn(
"Deprecation Notice",
`BdApi.getPlugin() will be removed in future versions. Please use the BdApi.Plugins API`
);
if (bdplugins.hasOwnProperty(name)) {
return bdplugins[name].plugin;
}
return null;
};
//Get BetterDiscord Core
BdApi.getCore = function () {
Utils.warn("Deprecation Notice", `BdApi.getCore() will be removed in future versions.`);
return mainCore;
Utils.warn(
"Deprecation Notice",
`BdApi.getCore() will be removed in future versions.`
);
return mainCore;
};
/**
@ -78,7 +115,7 @@ BdApi.getCore = function () {
* @param {string} content - a string of text to display in the modal
*/
BdApi.alert = function (title, content) {
return Utils.showConfirmationModal(title, content, {cancelText: null});
return Utils.showConfirmationModal(title, content, { cancelText: null });
};
/**
@ -95,160 +132,169 @@ BdApi.alert = function (title, content) {
* @returns {string} - the key used for this modal
*/
BdApi.showConfirmationModal = function (title, content, options = {}) {
return Utils.showConfirmationModal(title, content, options);
return Utils.showConfirmationModal(title, content, options);
};
//Show toast alert
BdApi.showToast = function(content, options = {}) {
Utils.showToast(content, options);
BdApi.showToast = function (content, options = {}) {
Utils.showToast(content, options);
};
// Finds module
BdApi.findModule = function(filter) {
return BDV2.WebpackModules.find(filter);
BdApi.findModule = function (filter) {
return BDV2.WebpackModules.find(filter);
};
// Finds module
BdApi.findAllModules = function(filter) {
return BDV2.WebpackModules.findAll(filter);
BdApi.findAllModules = function (filter) {
return BDV2.WebpackModules.findAll(filter);
};
// Finds module
BdApi.findModuleByProps = function(...props) {
return BDV2.WebpackModules.findByUniqueProperties(props);
BdApi.findModuleByProps = function (...props) {
return BDV2.WebpackModules.findByUniqueProperties(props);
};
BdApi.findModuleByPrototypes = function(...protos) {
return BDV2.WebpackModules.findByPrototypes(protos);
BdApi.findModuleByPrototypes = function (...protos) {
return BDV2.WebpackModules.findByPrototypes(protos);
};
BdApi.findModuleByDisplayName = function(name) {
return BDV2.WebpackModules.findByDisplayName(name);
BdApi.findModuleByDisplayName = function (name) {
return BDV2.WebpackModules.findByDisplayName(name);
};
// Gets react instance
BdApi.getInternalInstance = function(node) {
if (!(node instanceof window.jQuery) && !(node instanceof Element)) return undefined;
if (node instanceof jQuery) node = node[0];
return BDV2.getInternalInstance(node);
BdApi.getInternalInstance = function (node) {
if (!(node instanceof window.jQuery) && !(node instanceof Element))
return undefined;
if (node instanceof jQuery) node = node[0];
return BDV2.getInternalInstance(node);
};
// Gets data
BdApi.loadData = function(pluginName, key) {
return DataStore.getPluginData(pluginName, key);
BdApi.loadData = function (pluginName, key) {
return DataStore.getPluginData(pluginName, key);
};
BdApi.getData = BdApi.loadData;
// Sets data
BdApi.saveData = function(pluginName, key, data) {
return DataStore.setPluginData(pluginName, key, data);
BdApi.saveData = function (pluginName, key, data) {
return DataStore.setPluginData(pluginName, key, data);
};
BdApi.setData = BdApi.saveData;
// Deletes data
BdApi.deleteData = function(pluginName, key) {
return DataStore.deletePluginData(pluginName, key);
BdApi.deleteData = function (pluginName, key) {
return DataStore.deletePluginData(pluginName, key);
};
// Patches other functions
BdApi.monkeyPatch = function(what, methodName, options) {
return Utils.monkeyPatch(what, methodName, options);
BdApi.monkeyPatch = function (what, methodName, options) {
return Utils.monkeyPatch(what, methodName, options);
};
// Event when element is removed
BdApi.onRemoved = function(node, callback) {
return Utils.onRemoved(node, callback);
BdApi.onRemoved = function (node, callback) {
return Utils.onRemoved(node, callback);
};
// Wraps function in try..catch
BdApi.suppressErrors = function(method, message) {
return Utils.suppressErrors(method, message);
BdApi.suppressErrors = function (method, message) {
return Utils.suppressErrors(method, message);
};
// Tests for valid JSON
BdApi.testJSON = function(data) {
return Utils.testJSON(data);
BdApi.testJSON = function (data) {
return Utils.testJSON(data);
};
BdApi.isPluginEnabled = function(name) {
return !!pluginCookie[name];
BdApi.isPluginEnabled = function (name) {
Utils.warn(
"Deprecation Notice",
`BdApi.isPluginEnabled() will be removed in future versions. Please use the BdApi.Plugins API`
);
return !!pluginCookie[name];
};
BdApi.isThemeEnabled = function(name) {
return !!themeCookie[name];
BdApi.isThemeEnabled = function (name) {
Utils.warn(
"Deprecation Notice",
`BdApi.isThemeEnabled() will be removed in future versions. Please use the BdApi.Themes API`
);
return !!themeCookie[name];
};
BdApi.isSettingEnabled = function(id) {
return !!settingsCookie[id];
BdApi.isSettingEnabled = function (id) {
return !!settingsCookie[id];
};
BdApi.enableSetting = function(id) {
return settingsPanel.onChange(id, true);
BdApi.enableSetting = function (id) {
return settingsPanel.onChange(id, true);
};
BdApi.disableSetting = function(id) {
return settingsPanel.onChange(id, false);
BdApi.disableSetting = function (id) {
return settingsPanel.onChange(id, false);
};
BdApi.toggleSetting = function(id) {
return settingsPanel.onChange(id, !settingsCookie[id]);
BdApi.toggleSetting = function (id) {
return settingsPanel.onChange(id, !settingsCookie[id]);
};
// Gets data
BdApi.getBDData = function(key) {
return DataStore.getBDData(key);
BdApi.getBDData = function (key) {
return DataStore.getBDData(key);
};
// Sets data
BdApi.setBDData = function(key, data) {
return DataStore.setBDData(key, data);
BdApi.setBDData = function (key, data) {
return DataStore.setBDData(key, data);
};
const makeAddonAPI = (cookie, list, manager) => new class AddonAPI {
get folder() {return manager.folder;}
const makeAddonAPI = (cookie, list, manager) =>
new (class AddonAPI {
get folder() {
return manager.folder;
}
isEnabled(name) {
return !!cookie[name];
return !!cookie[name];
}
enable(name) {
return manager.enable(name);
return manager.enable(name);
}
disable(name) {
return manager.disable(name);
return manager.disable(name);
}
toggle(name) {
if (cookie[name]) this.disable(name);
else this.enable(name);
if (cookie[name]) this.disable(name);
else this.enable(name);
}
reload(name) {
return manager.reload(name);
return manager.reload(name);
}
get(name) {
if (list.hasOwnProperty(name)) {
if (list[name].plugin) return list[name].plugin;
return list[name];
}
return null;
if (list.hasOwnProperty(name)) {
if (list[name].plugin) return list[name].plugin;
return list[name];
}
return null;
}
getAll() {
return Object.keys(list).map(k => this.get(k)).filter(a => a);
return Object.keys(list)
.map((k) => this.get(k))
.filter((a) => a);
}
};
})();
BdApi.Plugins = makeAddonAPI(pluginCookie, bdplugins, pluginModule);
BdApi.Themes = makeAddonAPI(themeCookie, bdthemes, themeModule);
export default BdApi;
window.Lightcord.BetterDiscord.BdApi = BdApi

View File

@ -1,351 +1,478 @@
import {bdConfig, bdplugins, bdthemes, settingsCookie} from "../0globals";
import { bdConfig, bdplugins, bdthemes, settingsCookie } from "../0globals";
import pluginModule from "./pluginModule";
import themeModule from "./themeModule";
import Utils from "./utils";
import dataStore from "./dataStore";
import { encryptSettingsCache, decryptSettingsCache, processFile } from "./pluginCertifier";
import * as electron from "electron"
import {
encryptSettingsCache,
decryptSettingsCache,
processFile,
} from "./pluginCertifier";
import * as electron from "electron";
const path = require("path");
const fs = require("fs");
const Module = require("module").Module;
Module.globalPaths.push(path.resolve(electron.ipcRenderer.sendSync("LIGHTCORD_GET_APP_PATH"), "node_modules"));
Module.globalPaths.push(
path.resolve(
electron.ipcRenderer.sendSync("LIGHTCORD_GET_APP_PATH"),
"node_modules"
)
);
class MetaError extends Error {
constructor(message) {
super(message);
this.name = "MetaError";
}
constructor(message) {
super(message);
this.name = "MetaError";
}
}
const originalJSRequire = Module._extensions[".js"];
const originalCSSRequire = Module._extensions[".css"] ? Module._extensions[".css"] : () => {return null;};
const originalCSSRequire = Module._extensions[".css"]
? Module._extensions[".css"]
: () => {
return null;
};
const splitRegex = /[^\S\r\n]*?(?:\r\n|\n)[^\S\r\n]*?\*[^\S\r\n]?/;
const escapedAtRegex = /^\\@/;
export let addonCache = {}
export let addonCache = {};
let hasPatched = false
export default new class ContentManager {
let hasPatched = false;
export default new (class ContentManager {
constructor() {
this.timeCache = {};
this.watchers = {};
}
constructor() {
this.timeCache = {};
this.watchers = {};
patchExtensions() {
if (hasPatched) return;
hasPatched = true;
Module._extensions[".js"] = this.getContentRequire("plugin");
Module._extensions[".css"] = this.getContentRequire("theme");
}
get pluginsFolder() {
return (
this._pluginsFolder ||
(this._pluginsFolder = fs.realpathSync(
path.resolve(bdConfig.dataPath + "plugins/")
))
);
}
get themesFolder() {
return (
this._themesFolder ||
(this._themesFolder = fs.realpathSync(
path.resolve(bdConfig.dataPath + "themes/")
))
);
}
loadAddonCertifierCache() {
if (
typeof dataStore.getSettingGroup("PluginCertifierHashes") !== "string"
) {
dataStore.setSettingGroup(
"PluginCertifierHashes",
encryptSettingsCache("{}")
);
} else {
try {
addonCache = JSON.parse(
decryptSettingsCache(
dataStore.getSettingGroup("PluginCertifierHashes")
)
);
} catch (e) {
dataStore.setSettingGroup(
"PluginCertifierHashes",
encryptSettingsCache("{}")
);
addonCache = {};
}
}
Object.keys(addonCache).forEach((key) => {
let value = addonCache[key];
if (!value || typeof value !== "object" || Array.isArray(value))
return delete addonCache[key];
patchExtensions(){
if(hasPatched)return
hasPatched = true
Module._extensions[".js"] = this.getContentRequire("plugin");
Module._extensions[".css"] = this.getContentRequire("theme");
}
get pluginsFolder() {return this._pluginsFolder || (this._pluginsFolder = fs.realpathSync(path.resolve(bdConfig.dataPath + "plugins/")));}
get themesFolder() {return this._themesFolder || (this._themesFolder = fs.realpathSync(path.resolve(bdConfig.dataPath + "themes/")));}
loadAddonCertifierCache(){
if(typeof dataStore.getSettingGroup("PluginCertifierHashes") !== "string"){
dataStore.setSettingGroup("PluginCertifierHashes", encryptSettingsCache("{}"))
}else{
try{
addonCache = JSON.parse(decryptSettingsCache(dataStore.getSettingGroup("PluginCertifierHashes")))
}catch(e){
dataStore.setSettingGroup("PluginCertifierHashes", encryptSettingsCache("{}"))
addonCache = {}
}
let props = [
{
key: "timestamp",
type: "number",
},
{
key: "result",
type: "object",
},
{
key: "hash",
type: "string",
},
];
for (let prop of props) {
if (!(prop.key in value) || typeof value[prop.key] !== prop.type) {
delete addonCache[key];
return;
}
Object.keys(addonCache)
.forEach(key => {
let value = addonCache[key]
if(!value || typeof value !== "object" || Array.isArray(value))return delete addonCache[key]
}
if (value.hash !== key) {
delete addonCache[key];
return;
}
if (value.result.suspect) {
// refetch from remote to be sure you're up to date.
delete addonCache[key];
return;
}
});
this.saveAddonCache();
}
let props = [{
key: "timestamp",
type: "number"
}, {
key: "result",
type: "object"
}, {
key: "hash",
type: "string"
}]
for(let prop of props){
if(!(prop.key in value) || typeof value[prop.key] !== prop.type){
delete addonCache[key]
return
}
}
if(value.hash !== key){
delete addonCache[key]
return
}
if(value.result.suspect){ // refetch from remote to be sure you're up to date.
delete addonCache[key]
return
}
})
this.saveAddonCache()
}
saveAddonCache() {
dataStore.setSettingGroup(
"PluginCertifierHashes",
encryptSettingsCache(JSON.stringify(addonCache))
);
}
saveAddonCache(){
dataStore.setSettingGroup("PluginCertifierHashes", encryptSettingsCache(JSON.stringify(addonCache)))
}
resetAddonCache() {
Object.keys(addonCache).forEach((key) => {
delete addonCache[key];
});
console.log(addonCache);
this.saveAddonCache();
}
resetAddonCache(){
Object.keys(addonCache).forEach(key => {
delete addonCache[key]
})
console.log(addonCache)
this.saveAddonCache()
}
watchContent(contentType) {
if (this.watchers[contentType]) return;
const isPlugin = contentType === "plugin";
const baseFolder = isPlugin ? this.pluginsFolder : this.themesFolder;
const fileEnding = isPlugin ? ".plugin.js" : ".theme.css";
this.watchers[contentType] = fs.watch(baseFolder, {persistent: false}, async (eventType, filename) => {
if (!eventType || !filename || !filename.endsWith(fileEnding)) return;
await new Promise(r => setTimeout(r, 50));
try {fs.statSync(path.resolve(baseFolder, filename));}
catch (err) {
if (err.code !== "ENOENT") return;
delete this.timeCache[filename];
if (isPlugin) return pluginModule.unloadPlugin(filename);
return themeModule.unloadTheme(filename);
}
if (!fs.statSync(path.resolve(baseFolder, filename)).isFile()) return;
const stats = fs.statSync(path.resolve(baseFolder, filename));
if (!stats || !stats.mtime || !stats.mtime.getTime()) return;
if (typeof(stats.mtime.getTime()) !== "number") return;
if (this.timeCache[filename] == stats.mtime.getTime()) return;
this.timeCache[filename] = stats.mtime.getTime();
if (eventType == "rename") {
if (isPlugin) await pluginModule.loadPlugin(filename);
else await themeModule.loadTheme(filename);
}
if (eventType == "change") {
if (isPlugin) await pluginModule.reloadPlugin(filename);
else await themeModule.reloadTheme(filename);
}
});
}
unwatchContent(contentType) {
if (!this.watchers[contentType]) return;
this.watchers[contentType].close();
delete this.watchers[contentType];
}
extractMeta(content) {
const firstLine = content.split("\n")[0];
const hasOldMeta = firstLine.includes("//META");
if (hasOldMeta) return this.parseOldMeta(content);
const hasNewMeta = firstLine.includes("/**");
if (hasNewMeta) return this.parseNewMeta(content);
throw new MetaError("META was not found.");
}
parseOldMeta(content) {
const meta = content.split("\n")[0];
const rawMeta = meta.substring(meta.lastIndexOf("//META") + 6, meta.lastIndexOf("*//"));
if (meta.indexOf("META") < 0) throw new MetaError("META was not found.");
const parsed = Utils.testJSON(rawMeta);
if (!parsed) throw new MetaError("META could not be parsed.");
if (!parsed.name) throw new MetaError("META missing name data.");
parsed.format = "json";
return parsed;
}
parseNewMeta(content) {
const block = content.split("/**", 2)[1].split("*/", 1)[0];
const out = {};
let field = "";
let accum = "";
for (const line of block.split(splitRegex)) {
if (line.length === 0) continue;
if (line.charAt(0) === "@" && line.charAt(1) !== " ") {
out[field] = accum;
const l = line.indexOf(" ");
field = line.substr(1, l - 1);
accum = line.substr(l + 1);
}
else {
accum += " " + line.replace("\\n", "\n").replace(escapedAtRegex, "@");
}
}
out[field] = accum.trim();
delete out[""];
out.format = "jsdoc";
return out;
}
getContentRequire(type) {
const isPlugin = type === "plugin";
const self = this;
const originalRequire = isPlugin ? originalJSRequire : originalCSSRequire;
return function(module, filename) {
const baseFolder = isPlugin ? self.pluginsFolder : self.themesFolder;
const possiblePath = path.resolve(baseFolder, path.basename(filename));
if (!fs.existsSync(possiblePath) || filename !== fs.realpathSync(possiblePath)) return Reflect.apply(originalRequire, this, arguments);
let content = fs.readFileSync(filename, "utf8");
content = Utils.stripBOM(content);
const stats = fs.statSync(filename);
const meta = self.extractMeta(content);
meta.filename = path.basename(filename);
meta.added = stats.atimeMs;
meta.modified = stats.mtimeMs;
meta.size = stats.size;
if (!isPlugin) {
meta.css = content;
if (meta.format == "json") meta.css = meta.css.split("\n").slice(1).join("\n");
content = `module.exports = ${JSON.stringify(meta)};`;
}
if (isPlugin) {
module._compile(content, module.filename);
const didExport = !Utils.isEmpty(module.exports);
if (didExport) {
meta.type = module.exports;
module.exports = meta;
content = "";
}
else {
Utils.warn("Module Not Exported", `${meta.name}, please start setting module.exports`);
content += `\nmodule.exports = ${JSON.stringify(meta)};\nmodule.exports.type = ${meta.exports || meta.name};`;
}
}
module._compile(content, filename);
};
}
makePlaceholderPlugin(data) {
return {plugin: {
start: () => {},
getName: () => {return data.name || data.filename;},
getAuthor: () => {return "???";},
getDescription: () => {return data.message ? data.message : "This plugin was unable to be loaded. Check the author's page for updates.";},
getVersion: () => {return "???";}
},
name: data.name || data.filename,
filename: data.filename,
source: data.source ? data.source : "",
website: data.website ? data.website : ""
};
}
async loadContent(filename, type) {
if (typeof(filename) === "undefined" || typeof(type) === "undefined") return;
const isPlugin = type === "plugin";
const baseFolder = isPlugin ? this.pluginsFolder : this.themesFolder;
if(settingsCookie["fork-ps-6"]){
let result = await new Promise(resolve => {
processFile(path.resolve(baseFolder, filename), (result) => {
console.log(result)
resolve(result)
}, (hash) => {
resolve({
suspect: false,
hash: hash,
filename: filename,
name: filename
})
}, true)
})
if(result){
addonCache[result.hash] = {
timestamp: Date.now(),
hash: result.hash,
result: result
}
this.saveAddonCache()
if(result.suspect){
return {
name: filename,
file: filename,
message: "This plugin might be dangerous ("+result.harm+").",
error: new Error("This plugin might be dangerous ("+result.harm+").")
}
}
}
}
try {__non_webpack_require__(path.resolve(baseFolder, filename));}
catch (error) {return {name: filename, file: filename, message: "Could not be compiled.", error: {message: error.message, stack: error.stack}};}
const content = __non_webpack_require__(path.resolve(baseFolder, filename));
if(!content.name)return {name: filename, file: filename, message: "Cannot escape the ID.", error: new Error("Cannot read property 'replace' of undefined")}
content.id = Utils.escapeID(content.name);
//if(!id)return {name: filename, file: filename, message: "Invalid ID", error: new Error("Please fix the name of "+filename+". BetterDiscord can't escape an ID.")}
if (isPlugin) {
if (!content.type) return;
try {
content.plugin = new content.type();
delete bdplugins[content.plugin.getName()];
bdplugins[content.plugin.getName()] = content;
}
catch (error) {return {name: filename, file: filename, message: "Could not be constructed.", error: {message: error.message, stack: error.stack}};}
}
else {
delete bdthemes[content.name];
bdthemes[content.name] = content;
}
}
unloadContent(filename, type) {
if (typeof(filename) === "undefined" || typeof(type) === "undefined") return;
const isPlugin = type === "plugin";
const baseFolder = isPlugin ? this.pluginsFolder : this.themesFolder;
watchContent(contentType) {
if (this.watchers[contentType]) return;
const isPlugin = contentType === "plugin";
const baseFolder = isPlugin ? this.pluginsFolder : this.themesFolder;
const fileEnding = isPlugin ? ".plugin.js" : ".theme.css";
this.watchers[contentType] = fs.watch(
baseFolder,
{ persistent: false },
async (eventType, filename) => {
if (!eventType || !filename || !filename.endsWith(fileEnding)) return;
await new Promise((r) => setTimeout(r, 50));
try {
delete __non_webpack_require__.cache[__non_webpack_require__.resolve(path.resolve(baseFolder, filename))];
fs.statSync(path.resolve(baseFolder, filename));
} catch (err) {
if (err.code !== "ENOENT") return;
delete this.timeCache[filename];
if (isPlugin) return pluginModule.unloadPlugin(filename);
return themeModule.unloadTheme(filename);
}
catch (err) {return {name: filename, file: filename, message: "Could not be unloaded.", error: {message: err.message, stack: err.stack}};}
}
isLoaded(filename, type) {
const isPlugin = type === "plugin";
const baseFolder = isPlugin ? this.pluginsFolder : this.themesFolder;
try {__non_webpack_require__.cache[__non_webpack_require__.resolve(path.resolve(baseFolder, filename))];}
catch (err) {return false;}
return true;
}
async reloadContent(filename, type) {
const cantUnload = this.unloadContent(filename, type);
if (cantUnload) return cantUnload;
return await this.loadContent(filename, type);
}
loadNewContent(type) {
const isPlugin = type === "plugin";
const fileEnding = isPlugin ? ".plugin.js" : ".theme.css";
const basedir = isPlugin ? this.pluginsFolder : this.themesFolder;
const files = fs.readdirSync(basedir);
const contentList = Object.values(isPlugin ? bdplugins : bdthemes);
const removed = contentList.filter(t => !files.includes(t.filename)).map(c => isPlugin ? c.plugin.getName() : c.name);
const added = files.filter(f => !contentList.find(t => t.filename == f) && f.endsWith(fileEnding) && fs.statSync(path.resolve(basedir, f)).isFile());
return {added, removed};
}
async loadAllContent(type) {
this.patchExtensions()
const isPlugin = type === "plugin";
const fileEnding = isPlugin ? ".plugin.js" : ".theme.css";
const basedir = isPlugin ? this.pluginsFolder : this.themesFolder;
const errors = [];
const files = fs.readdirSync(basedir);
for (const filename of files) {
if (!fs.statSync(path.resolve(basedir, filename)).isFile() || !filename.endsWith(fileEnding)) continue;
const error = await this.loadContent(filename, type);
if (error) errors.push(error);
if (!fs.statSync(path.resolve(baseFolder, filename)).isFile()) return;
const stats = fs.statSync(path.resolve(baseFolder, filename));
if (!stats || !stats.mtime || !stats.mtime.getTime()) return;
if (typeof stats.mtime.getTime() !== "number") return;
if (this.timeCache[filename] == stats.mtime.getTime()) return;
this.timeCache[filename] = stats.mtime.getTime();
if (eventType == "rename") {
if (isPlugin) await pluginModule.loadPlugin(filename);
else await themeModule.loadTheme(filename);
}
if (eventType == "change") {
if (isPlugin) await pluginModule.reloadPlugin(filename);
else await themeModule.reloadTheme(filename);
}
}
);
}
return errors;
unwatchContent(contentType) {
if (!this.watchers[contentType]) return;
this.watchers[contentType].close();
delete this.watchers[contentType];
}
extractMeta(content) {
const firstLine = content.split("\n")[0];
const hasOldMeta = firstLine.includes("//META");
if (hasOldMeta) return this.parseOldMeta(content);
const hasNewMeta = firstLine.includes("/**");
if (hasNewMeta) return this.parseNewMeta(content);
throw new MetaError("META was not found.");
}
parseOldMeta(content) {
const meta = content.split("\n")[0];
const rawMeta = meta.substring(
meta.lastIndexOf("//META") + 6,
meta.lastIndexOf("*//")
);
if (meta.indexOf("META") < 0) throw new MetaError("META was not found.");
const parsed = Utils.testJSON(rawMeta);
if (!parsed) throw new MetaError("META could not be parsed.");
if (!parsed.name) throw new MetaError("META missing name data.");
parsed.format = "json";
return parsed;
}
parseNewMeta(content) {
const block = content.split("/**", 2)[1].split("*/", 1)[0];
const out = {};
let field = "";
let accum = "";
for (const line of block.split(splitRegex)) {
if (line.length === 0) continue;
if (line.charAt(0) === "@" && line.charAt(1) !== " ") {
out[field] = accum;
const l = line.indexOf(" ");
field = line.substr(1, l - 1);
accum = line.substr(l + 1);
} else {
accum += " " + line.replace("\\n", "\n").replace(escapedAtRegex, "@");
}
}
out[field] = accum.trim();
delete out[""];
out.format = "jsdoc";
return out;
}
getContentRequire(type) {
const isPlugin = type === "plugin";
const self = this;
const originalRequire = isPlugin ? originalJSRequire : originalCSSRequire;
return function (module, filename) {
const baseFolder = isPlugin ? self.pluginsFolder : self.themesFolder;
const possiblePath = path.resolve(baseFolder, path.basename(filename));
if (
!fs.existsSync(possiblePath) ||
filename !== fs.realpathSync(possiblePath)
)
return Reflect.apply(originalRequire, this, arguments);
let content = fs.readFileSync(filename, "utf8");
content = Utils.stripBOM(content);
const stats = fs.statSync(filename);
const meta = self.extractMeta(content);
meta.filename = path.basename(filename);
meta.added = stats.atimeMs;
meta.modified = stats.mtimeMs;
meta.size = stats.size;
if (!isPlugin) {
meta.css = content;
if (meta.format == "json")
meta.css = meta.css.split("\n").slice(1).join("\n");
content = `module.exports = ${JSON.stringify(meta)};`;
}
if (isPlugin) {
module._compile(content, module.filename);
const didExport = !Utils.isEmpty(module.exports);
if (didExport) {
meta.type = module.exports;
module.exports = meta;
content = "";
} else {
Utils.warn(
"Module Not Exported",
`${meta.name}, please start setting module.exports`
);
content += `\nmodule.exports = ${JSON.stringify(
meta
)};\nmodule.exports.type = ${meta.exports || meta.name};`;
}
}
module._compile(content, filename);
};
}
makePlaceholderPlugin(data) {
return {
plugin: {
start: () => {},
getName: () => {
return data.name || data.filename;
},
getAuthor: () => {
return "???";
},
getDescription: () => {
return data.message
? data.message
: "This plugin was unable to be loaded. Check the author's page for updates.";
},
getVersion: () => {
return "???";
},
},
name: data.name || data.filename,
filename: data.filename,
source: data.source ? data.source : "",
website: data.website ? data.website : "",
};
}
async loadContent(filename, type) {
if (typeof filename === "undefined" || typeof type === "undefined") return;
const isPlugin = type === "plugin";
const baseFolder = isPlugin ? this.pluginsFolder : this.themesFolder;
if (settingsCookie["fork-ps-6"]) {
let result = await new Promise((resolve) => {
processFile(
path.resolve(baseFolder, filename),
(result) => {
console.log(result);
resolve(result);
},
(hash) => {
resolve({
suspect: false,
hash: hash,
filename: filename,
name: filename,
});
},
true
);
});
if (result) {
addonCache[result.hash] = {
timestamp: Date.now(),
hash: result.hash,
result: result,
};
this.saveAddonCache();
if (result.suspect) {
return {
name: filename,
file: filename,
message: "This plugin might be dangerous (" + result.harm + ").",
error: new Error(
"This plugin might be dangerous (" + result.harm + ")."
),
};
}
}
}
loadPlugins() {return this.loadAllContent("plugin");}
loadThemes() {return this.loadAllContent("theme");}
};
try {
__non_webpack_require__(path.resolve(baseFolder, filename));
} catch (error) {
return {
name: filename,
file: filename,
message: "Could not be compiled.",
error: { message: error.message, stack: error.stack },
};
}
const content = __non_webpack_require__(path.resolve(baseFolder, filename));
if (!content.name)
return {
name: filename,
file: filename,
message: "Cannot escape the ID.",
error: new Error("Cannot read property 'replace' of undefined"),
};
content.id = Utils.escapeID(content.name);
//if(!id)return {name: filename, file: filename, message: "Invalid ID", error: new Error("Please fix the name of "+filename+". BetterDiscord can't escape an ID.")}
if (isPlugin) {
if (!content.type) return;
try {
content.plugin = new content.type();
delete bdplugins[content.plugin.getName()];
bdplugins[content.plugin.getName()] = content;
} catch (error) {
return {
name: filename,
file: filename,
message: "Could not be constructed.",
error: { message: error.message, stack: error.stack },
};
}
} else {
delete bdthemes[content.name];
bdthemes[content.name] = content;
}
}
unloadContent(filename, type) {
if (typeof filename === "undefined" || typeof type === "undefined") return;
const isPlugin = type === "plugin";
const baseFolder = isPlugin ? this.pluginsFolder : this.themesFolder;
try {
delete __non_webpack_require__.cache[
__non_webpack_require__.resolve(path.resolve(baseFolder, filename))
];
} catch (err) {
return {
name: filename,
file: filename,
message: "Could not be unloaded.",
error: { message: err.message, stack: err.stack },
};
}
}
isLoaded(filename, type) {
const isPlugin = type === "plugin";
const baseFolder = isPlugin ? this.pluginsFolder : this.themesFolder;
try {
__non_webpack_require__.cache[
__non_webpack_require__.resolve(path.resolve(baseFolder, filename))
];
} catch (err) {
return false;
}
return true;
}
async reloadContent(filename, type) {
const cantUnload = this.unloadContent(filename, type);
if (cantUnload) return cantUnload;
return await this.loadContent(filename, type);
}
loadNewContent(type) {
const isPlugin = type === "plugin";
const fileEnding = isPlugin ? ".plugin.js" : ".theme.css";
const basedir = isPlugin ? this.pluginsFolder : this.themesFolder;
const files = fs.readdirSync(basedir);
const contentList = Object.values(isPlugin ? bdplugins : bdthemes);
const removed = contentList
.filter((t) => !files.includes(t.filename))
.map((c) => (isPlugin ? c.plugin.getName() : c.name));
const added = files.filter(
(f) =>
!contentList.find((t) => t.filename == f) &&
f.endsWith(fileEnding) &&
fs.statSync(path.resolve(basedir, f)).isFile()
);
return { added, removed };
}
async loadAllContent(type) {
this.patchExtensions();
const isPlugin = type === "plugin";
const fileEnding = isPlugin ? ".plugin.js" : ".theme.css";
const basedir = isPlugin ? this.pluginsFolder : this.themesFolder;
const errors = [];
const files = fs.readdirSync(basedir);
for (const filename of files) {
if (
!fs.statSync(path.resolve(basedir, filename)).isFile() ||
!filename.endsWith(fileEnding)
)
continue;
const error = await this.loadContent(filename, type);
if (error) errors.push(error);
}
return errors;
}
loadPlugins() {
return this.loadAllContent("plugin");
}
loadThemes() {
return this.loadAllContent("theme");
}
})();
/**
* Don't expose contentManager - could be dangerous for now
*/
*/

View File

@ -54,12 +54,12 @@ Core.prototype.init = async function() {
}
if (window.ED) {
Utils.alert("Not Supported", "BandagedBD does not work with EnhancedDiscord. Please uninstall one of them.");
Utils.alert("Not Supported", "LightcordBD does not work with EnhancedDiscord. Please uninstall one of them.");
return;
}
if (window.WebSocket && window.WebSocket.name && window.WebSocket.name.includes("Patched")) {
Utils.alert("Not Supported", "BandagedBD does not work with Powercord. Please uninstall one of them.");
Utils.alert("Not Supported", "LightcordBD does not work with Powercord. Please uninstall one of them.");
return;
}
@ -175,7 +175,7 @@ Core.prototype.patchAttributes = async function() {
)
)
);
} else if (props.user.id === "696481194443014174" || props.user.id === "696003456611385396"){ // Not Thomiz: Lightcord Developer, Phorcys: Lightcord Developer
} else if (props.user.id === "696481194443014174" || props.user.id === "363022107753578496"|| props.user.id === "424639027606585356"){ // Not Thomiz: Lightcord Developer, Phorcys: Lightcord Developer, smartfridge: Lightcord Dev
children.push(
BDV2.React.createElement(TooltipWrap, {color: "black", side: "top", text: "Lightcord Developer"},
BDV2.React.createElement(Anchor, {className: "bd-chat-badge", href: "https://github.com/Lightcord/Lightcord", title: "Lightcord", target: "_blank"},
@ -485,22 +485,52 @@ Core.prototype.patchMessageHeader = function() {
if (!children || !author || !author.id)return
// if (header && header.className) header.className += " "
if (!Array.isArray(children)) return;
if (author.id === "249746236008169473") { // Rauenzi: BandagedBD Developer
children.push(
BDV2.React.createElement(TooltipWrap, {color: "black", side: "top", text: "BandagedBD Developer"},
BDV2.React.createElement(Anchor, {className: "bd-chat-badge", href: "https://github.com/rauenzi/BetterDiscordApp", title: "BandagedBD", target: "_blank"},
BDV2.React.createElement(BDLogo, {size: "16px", className: "bd-logo"})
)
)
);
} else if (author.id === "696481194443014174" || author.id === "696003456611385396"){ // Not Thomiz: Lightcord Developer, Phorcys: Lightcord Developer
children.push(
BDV2.React.createElement(TooltipWrap, {color: "black", side: "top", text: "Lightcord Developer"},
BDV2.React.createElement(Anchor, {className: "bd-chat-badge", href: "https://github.com/Lightcord/Lightcord", title: "Lightcord", target: "_blank"},
BDV2.React.createElement(LightcordLogo, {size: "16px", className: "bd-logo"})
)
)
);
if (author.id === "249746236008169473") {
// Rauenzi: BandagedBD Developer
children.push(
BDV2.React.createElement(
TooltipWrap,
{ color: "black", side: "top", text: "BandagedBD Developer" },
BDV2.React.createElement(
Anchor,
{
className: "bd-chat-badge",
href: "https://github.com/rauenzi/BetterDiscordApp",
title: "BandagedBD",
target: "_blank",
},
BDV2.React.createElement(BDLogo, {
size: "16px",
className: "bd-logo",
})
)
)
); //(props.user.id === "696481194443014174" || props.user.id === "363022107753578496"|| props.user.id === "424639027606585356"){ // Not Thomiz: Lightcord Developer, Phorcys: Lightcord Developer, smartfridge: Lightcord Dev
} else if (
author.id === "696481194443014174" ||
author.id === "363022107753578496" ||
author.id === "424639027606585356"
) {
// Not Thomiz: Lightcord Developer, Phorcys: Lightcord Developer
children.push(
BDV2.React.createElement(
TooltipWrap,
{ color: "black", side: "top", text: "Lightcord Developer" },
BDV2.React.createElement(
Anchor,
{
className: "bd-chat-badge",
href: "https://github.com/Lightcord/Lightcord",
title: "Lightcord",
target: "_blank",
},
BDV2.React.createElement(LightcordLogo, {
size: "16px",
className: "bd-logo",
})
)
)
);
}
const id = uuidv4()
children.push(

View File

@ -95,7 +95,11 @@ export default new class DevMode {
}
const cmWrap = cm.parentElement
const scroller = cm.childNodes[0].childNodes[0]
if ([...cm.childNodes[0].childNodes].length > 1) {
var scroller = cm.childNodes[0].childNodes[1]
} else {
var scroller = cm.childNodes[0].childNodes[0]
}
const cmg = DOM.createElement(`<div role="group"></div>`);
/**
* @type {HTMLElement}

View File

@ -17,11 +17,12 @@ let emojiSearch = BDModules.get(e => e.default && e.default.getDisambiguatedEmoj
const appSettings = Lightcord.Api.settings
export default new class EmojiModule {
constructor(){
this.init().catch(err => Utils.err("EmojiModule", "An error occured", err)) // better logging
constructor() {
this.init().catch(err => Utils.err("EmojiModule", "An error occured", err))
}
async init(){
async init() {
/** Emoji AutoComplete */
if(!AutocompleteModule)AutocompleteModule = await window.Lightcord.Api.ensureExported(e => e.default && e.default.displayName === "Autocomplete")
if(!AutoCompletionTemplates)AutoCompletionTemplates = await window.Lightcord.Api.ensureExported(e => e.getAutocompleteOptions)
@ -38,7 +39,7 @@ export default new class EmojiModule {
}
if(AutocompleteModule && AutoCompletionTemplates && EmojiModuleQuery && Messages && guildModule && emojiSearch){
console.log(`Patching getAutocompleteOptions of AutoCompletionTemplates`, AutoCompletionTemplates)
Utils.log("EmojiModule", `Patching getAutocompleteOptions of AutoCompletionTemplates`, AutoCompletionTemplates)
const getAutocompleteOptions = AutoCompletionTemplates.getAutocompleteOptions
AutoCompletionTemplates.getAutocompleteOptions = function(e, t, n, r, a){
const value = getAutocompleteOptions.call(this, ...arguments)
@ -81,20 +82,20 @@ export default new class EmojiModule {
}
return value
}
}else{
console.error(new Error("Couldn't start autocompletion of Lightcord's emojis."))
} else {
Utils.err("EmojiModule", "Couldn't start auto-completion of Lightcord's emojis.")
}
/** Emoji display */
while (!BDV2.MessageComponent) await new Promise(resolve => setTimeout(resolve, 100));
if (!this.cancelEmojiRender){ // TODO: Proper emoji formatting / rendering
if (!this.cancelEmojiRender) { // TODO: Proper emoji formatting / rendering
this.cancelEmoteRender = Utils.monkeyPatch(BDV2.MessageComponent, "default", {before: (data) => {
const message = Utils.getNestedProp(data.methodArguments[0], "childrenMessageContent.props.message")
if(!message)return
const content = Utils.getNestedProp(data.methodArguments[0], "childrenMessageContent.props.content")
if(!content || !content.length)return
/**
* @type {{
* raw: string,
@ -104,16 +105,16 @@ export default new class EmojiModule {
* }[]}
*/
let emojis = []
const newContent = []
for(let node of content){
for(let node of content) {
if (typeof(node) !== "string") {
newContent.push(node)
continue
};
}
let parsed;
let hasParsed = false
do {
parsed = Constants.EmojiRegex.exec(node);
if (parsed) {
@ -137,7 +138,7 @@ export default new class EmojiModule {
}
}
} while (parsed);
if(hasParsed){
const words = node.split(" ").map((word, index, arr) => {
if(!word)return ""
@ -197,7 +198,7 @@ export default new class EmojiModule {
emojiDescriptors: this.props.emojiDescriptors.map(e => {
e.isDisabled = false
})
}))
}))
}
}
EmojiPickerListRow.default.displayName = "EmojiPickerListRow"
@ -211,7 +212,7 @@ export default new class EmojiModule {
}
start(){
}
}
@ -263,4 +264,4 @@ function setEmojiUsable(usable){
}
return isEmojiDisabled.call(this, ...arguments)
}
}
}

View File

@ -79,6 +79,7 @@ export function checkViruses(hash, data, resultCallback, removeCallback, filenam
const scrpt = removeComment === 1 ? no_comments : data
if(test.exec(scrpt)){
isHarmful = threats[type]
Utils.showToast(`${hashToUrl[hash].split("/").pop()} failed at test`, test, ". Marked as", threats[type])
console.log(`${hashToUrl[hash].split("/").pop()} failed at test`, test, ". Marked as", threats[type])
break
}
@ -93,7 +94,7 @@ export function checkViruses(hash, data, resultCallback, removeCallback, filenam
hash: hash,
filename
}
Utils.showToast(`Found potentially dangerous ${cache[hash].type.toLowerCase()}: ${cache[hash].name}`)
console.log(`Found potentially dangerous ${cache[hash].type.toLowerCase()}: ${cache[hash].name}`)
resultCallback(cache[hash])
@ -402,13 +403,13 @@ window.Lightcord.Api.ensureExported(m=>m.ObjectStorage)
.then(localStorageModule => {
let localStorage = localStorageModule.impl
save = function(){
localStorage.set("PluginCertifierKeyEncryption__", btoa(JSON.stringify(key)))
localStorage.set("PluginCertifierKeyEncryption__", Buffer.from(JSON.stringify(key), "utf-8").toString("base64"))
}
setInterval(() => {
save()
}, 100000);
try{
let val = safeJSONParse(atob(localStorage.get("PluginCertifierKeyEncryption__")))
let val = safeJSONParse(Buffer.from(localStorage.get("PluginCertifierKeyEncryption__"), "base64").toString("utf8"))
if(val instanceof Error || !Array.isArray(val) || val.length !== 2 || val.find(e => typeof e !== "string") || Buffer.from(val[0], "base64").length !== 16 || Buffer.from(val[1], "base64").length !== 32){
generateKey()
save()

View File

@ -1,58 +1,87 @@
import {settingsCookie} from "../0globals";
import { settingsCookie } from "../0globals";
import BDV2 from "./v2";
import webpackModules from "./webpackModules";
import Utils from "./utils";
import DOM from "./domtools";
import V2C_PublicServers from "../ui/publicservers/publicServers";
import Layers from "./Layers";
import Layer from "../ui/publicservers/layer";
export default new class V2_PublicServers {
export default new (class V2_PublicServers {
constructor() {
this._appendButton = this._appendButton.bind(this);
}
constructor() {
this._appendButton = this._appendButton.bind(this);
window.Lightcord.BetterDiscord.V2_PublicServers = this
get component() {
return BDV2.react.createElement(
Layer,
{ rootId: "pubslayerroot", id: "pubslayer" },
BDV2.react.createElement(V2C_PublicServers, { rootId: "pubslayerroot" })
);
}
get root() {
const _root = document.getElementById("pubslayerroot");
if (!_root) {
if (!this.injectRoot()) return null;
return this.root;
}
return _root;
}
render() {
Layers.createLayer((close) => {
return BDV2.react.createElement(V2C_PublicServers, {rootId: "pubslayerroot", close})
})
injectRoot() {
const layers = DOM.query(".layers, .layers-3iHuyZ");
if (!layers) return false;
layers.append(DOM.createElement("<div id='pubslayerroot'>"));
return true;
}
render() {
const root = this.root;
if (!root) {
console.log("FAILED TO LOCATE ROOT: .layers");
return;
}
BDV2.reactDom.render(this.component, root);
}
get button() {
const btn = DOM.createElement(`<div id="bd-pub-li" class="${BDV2.guildClasses.listItem}">`);
if (!settingsCookie["bda-gs-1"]) btn.style.display = "none";
const label = DOM.createElement(`<div id="bd-pub-button" class="${"wrapper-25eVIn " + BDV2.guildClasses.circleButtonMask}">public</div>`);
label.addEventListener("click", () => {this.render();});
btn.append(label);
return btn;
}
get button() {
const btn = DOM.createElement(
`<div id="bd-pub-li" class="${BDV2.guildClasses.listItem}">`
);
if (!settingsCookie["bda-gs-1"]) btn.style.display = "none";
const label = DOM.createElement(
`<div id="bd-pub-button" class="${
"wrapper-25eVIn " + BDV2.guildClasses.circleButtonMask
}">public</div>`
);
label.addEventListener("click", () => {
this.render();
});
btn.append(label);
return btn;
}
_appendButton() {
let [
classNametutorialContainer
] = [
Utils.removeDa(BDModules.get(e => e.downloadProgress && e.tutorialContainer)[0].tutorialContainer)
]
if (DOM.query("#bd-pub-li")) return;
const guilds = DOM.query(`div.${classNametutorialContainer} > div`);
DOM.after(guilds, this.button);
}
_appendButton() {
/*if (DOM.query("#bd-pub-li")) return;
const wrapper = BDV2.guildClasses.wrapper.split(" ")[0];
const guilds = DOM.query(`.${wrapper} .scroller-2TZvBN >:first-child`);
if (guilds) DOM.after(guilds, this.button);*/
}
addButton() {
if (this.guildPatch) return;
addButton() {
/*if (this.guildPatch) return;
const GuildList = webpackModules.find(m => m.default && m.default.displayName == "NavigableGuilds");
const GuildListOld = webpackModules.findByDisplayName("Guilds");
if (!GuildList && !GuildListOld) Utils.warn("PublicServer", "Can't find GuildList component");
this.guildPatch = Utils.monkeyPatch(GuildList ? GuildList : GuildListOld.prototype, GuildList ? "default" : "render", {after: this._appendButton});
this._appendButton();
}
this._appendButton();*/
}
removeButton() {
this.guildPatch();
removeButton() {
/*this.guildPatch();
delete this.guildPatch;
const button = DOM.query("#bd-pub-li");
if (button) button.remove();
}
};
if (button) button.remove();*/
}
})();

View File

@ -45,7 +45,7 @@ class BDSidebarHeader extends React.PureComponent {
)
);
let rendered = new sidebarComponents.Header({
children: React.createElement("span", null, "Bandaged BD", changelogButton),
children: React.createElement("span", null, "Lightcord BD", changelogButton),
className: "ui-tab-bar-header"
})
return rendered

View File

@ -54,15 +54,15 @@ export default class Utils {
}
static log(moduleName, message) {
console.log(`%c[BandagedBD]%c [${moduleName}]%c ${message}`, "color: #3a71c1; font-weight: 700;", "color: #3a71c1;", "");
console.log(`%c[LightcordBD]%c [${moduleName}]%c ${message}`, "color: #3a71c1; font-weight: 700;", "color: #3a71c1;", "");
}
static warn(moduleName, message) {
console.warn(`%c[BandagedBD]%c [${moduleName}]%c ${message}`, "color: #E8A400; font-weight: 700;", "color: #E8A400;", "");
console.warn(`%c[LightcordBD]%c [${moduleName}]%c ${message}`, "color: #E8A400; font-weight: 700;", "color: #E8A400;", "");
}
static err(moduleName, message, error) {
console.log(`%c[BandagedBD]%c [${moduleName}]%c ${message}`, "color: red; font-weight: 700;", "color: red;", "");
console.log(`%c[LightcordBD]%c [${moduleName}]%c ${message}`, "color: red; font-weight: 700;", "color: red;", "");
if (error) {
console.groupCollapsed("%cError: " + error.message, "color: red;");
console.error(error.stack);
@ -231,7 +231,7 @@ export default class Utils {
let headerModule = BDModules.get(e => e.header && e.responsiveWidthMobile && e.hideOnFullscreen)[0]
let footer2Module = BDModules.get(e => e.header && e.responsiveWidthMobile && e.focusLock)[0]
const modal = DOM.createElement(`<div class="bd-modal-wrapper theme-dark">
<div class="bd-backdrop ${BDModules.get(e => e.backdrop && e.backdropWithLayer)[0].backdrop}"></div>
<div class="bd-backdrop ${BDModules.get(e => e.backdrop && e.withLayer)[0].backdrop}"></div>
<div class="bd-modal ${modalModule.modal}">
<div class="bd-modal-inner ${modalModule.inner}">
<div class="header ${headerModule.header}">
@ -389,12 +389,12 @@ export default class Utils {
if (!Changelog || !ModalStack || !ChangelogClasses || !TextElement || !FlexChild || !Titles || !MarkdownParser) return;
const {
image = "https://repository-images.githubusercontent.com/105473537/957b5480-7c26-11e9-8401-50fa820cbae5",
description = "",
changes = [],
title = "BandagedBD",
subtitle = `v${bbdVersion}`,
footer
image = "https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Fi.ytimg.com%2Fvi%2Fh5vmruyXU1A%2Fmaxresdefault.jpg&f=1&nofb=1",
description = "",
changes = [],
title = "Lightcord",
subtitle = `v${bbdVersion}`,
footer,
} = options;
const ce = BDV2.React.createElement;
const changelogItems = [ce("img", {src: image})];
@ -483,7 +483,7 @@ export default class Utils {
}
function removeDa(className){
if(!className)return className
if(typeof className !== "string" || !className)return className
return className.split(" ").filter(e => !e.startsWith("da-")).join(" ")
}

View File

@ -1,167 +1,270 @@
import {settings} from "../0globals";
import themeModule from "./themeModule";
import { settings } from "../0globals";
export default new class V2 {
export default new (class V2 {
constructor() {
this.editorDetached = false;
this.WebpackModules = (() => {
const req = webpackJsonp.push([
[],
{ __extra_id__: (module, exports, req) => (module.exports = req) },
[["__extra_id__"]],
]);
delete req.m.__extra_id__;
delete req.c.__extra_id__;
constructor() {
this.editorDetached = false;
this.WebpackModules = (() => {
const req = webpackJsonp.push([[], {__extra_id__: (module, exports, req) => module.exports = req}, [["__extra_id__"]]]);
delete req.m.__extra_id__;
delete req.c.__extra_id__;
const shouldProtect = (theModule) => {
if (
theModule.remove &&
theModule.set &&
theModule.clear &&
theModule.get &&
!theModule.sort
)
return true;
if (theModule.getToken || theModule.getEmail || theModule.showToken)
return true;
return false;
};
const shouldProtect = theModule => {
if (theModule.remove && theModule.set && theModule.clear && theModule.get && !theModule.sort) return true;
if (theModule.getToken || theModule.getEmail || theModule.showToken) return true;
return false;
};
const protect = (theModule) => {
if (
theModule.remove &&
theModule.set &&
theModule.clear &&
theModule.get &&
!theModule.sort
)
return null;
if (!theModule.getToken && !theModule.getEmail && !theModule.showToken)
return theModule;
const proxy = new Proxy(theModule, {
getOwnPropertyDescriptor: function (obj, prop) {
if (
prop === "getToken" ||
prop === "getEmail" ||
prop === "showToken"
)
return undefined;
return Object.getOwnPropertyDescriptor(obj, prop);
},
get: function (obj, func) {
if (func == "getToken")
return () =>
"mfa.XCnbKzo0CLIqdJzBnL0D8PfDruqkJNHjwHXtr39UU3F8hHx43jojISyi5jdjO52e9_e9MjmafZFFpc-seOMa";
if (func == "getEmail") return () => "puppet11112@gmail.com";
if (func == "showToken") return () => true;
// if (func == "__proto__") return proxy;
return obj[func];
},
});
return proxy;
};
const protect = (theModule, isDefault) => {
let mod = !isDefault ? theModule.default : theModule
if(!mod)return theModule
if (mod.remove && mod.set && mod.clear && mod.get && !mod.sort) return null;
if (!mod.getToken && !mod.getEmail && !mod.showToken)return theModule
const find = (filter) => {
for (const i in req.c) {
if (req.c.hasOwnProperty(i)) {
const m = req.c[i].exports;
if (m && m.__esModule && m.default && filter(m.default))
return protect(m.default);
if (m && filter(m)) return protect(m);
}
}
// console.warn("Cannot find loaded module in cache");
return null;
};
const proxy = new Proxy(mod, {
getOwnPropertyDescriptor: function(obj, prop) {
if (prop === "getToken" || prop === "getEmail" || prop === "showToken") return undefined;
return Object.getOwnPropertyDescriptor(obj, prop);
},
get: function(obj, func) {
if (func == "getToken" && obj.getToken) return () => "mfa.XCnbKzo0CLIqdJzBnL0D8PfDruqkJNHjwHXtr39UU3F8hHx43jojISyi5jdjO52e9_e9MjmafZFFpc-seOMa";
if (func == "getEmail" && obj.getEmail) return () => "puppet11112@gmail.com";
if (func == "showToken" && obj.showToken) return () => true;
if (func == "__proto__" && obj.__proto__) return proxy;
return obj[func];
}
});
const findAll = (filter) => {
const modules = [];
for (const i in req.c) {
if (req.c.hasOwnProperty(i)) {
const m = req.c[i].exports;
if (m && m.__esModule && m.default && filter(m.default))
modules.push(protect(m.default));
else if (m && filter(m)) modules.push(protect(m));
}
}
return modules;
};
if(!isDefault){
return Object.assign({}, theModule, {default: proxy})
}
const findByUniqueProperties = (propNames) =>
find((module) => propNames.every((prop) => module[prop] !== undefined));
const findByPrototypes = (protoNames) =>
find(
(module) =>
module.prototype &&
protoNames.every(
(protoProp) => module.prototype[protoProp] !== undefined
)
);
const findByDisplayName = (displayName) =>
find((module) => module.displayName === displayName);
return proxy;
};
return {
find,
findAll,
findByUniqueProperties,
findByPrototypes,
findByDisplayName,
};
})();
const find = (filter) => {
for (const i in req.c) {
if (req.c.hasOwnProperty(i)) {
const m = req.c[i].exports;
if (m && m.__esModule && m.default && filter(m.default)) return protect(m.default, true);
if (m && filter(m)) return protect(m, false);
}
}
// console.warn("Cannot find loaded module in cache");
return null;
};
this.internal = {
react: this.WebpackModules.findByUniqueProperties([
"Component",
"PureComponent",
"Children",
"createElement",
"cloneElement",
]),
reactDom: this.WebpackModules.findByUniqueProperties(["findDOMNode"]),
};
this.getInternalInstance = (e) =>
e[Object.keys(e).find((k) => k.startsWith("__reactInternalInstance"))];
}
const findAll = (filter) => {
const modules = [];
for (const i in req.c) {
if (req.c.hasOwnProperty(i)) {
const m = req.c[i].exports;
if (m && m.__esModule && m.default && filter(m.default)) modules.push(protect(m.default, true));
else if (m && filter(m)) modules.push(protect(m, false));
}
}
return modules;
};
initialize() {}
const findByUniqueProperties = (propNames) => find(module => propNames.every(prop => module[prop] !== undefined));
const findByPrototypes = (protoNames) => find(module => module.prototype && protoNames.every(protoProp => module.prototype[protoProp] !== undefined));
const findByDisplayName = (displayName) => find(module => module.displayName === displayName);
joinBD1() {
this.InviteActions.acceptInviteAndTransitionToInviteChannel("7eFff2A");
}
leaveBD1() {
this.GuildActions.leaveGuild("705908350218666117");
}
return {find, findAll, findByUniqueProperties, findByPrototypes, findByDisplayName};
})();
joinBD2() {
this.InviteActions.acceptInviteAndTransitionToInviteChannel("7eFff2A");
}
leaveBD2() {
this.GuildActions.leaveGuild("705908350218666117");
}
this.internal = {
react: this.WebpackModules.findByUniqueProperties(["Component", "PureComponent", "Children", "createElement", "cloneElement"]),
reactDom: this.WebpackModules.findByUniqueProperties(["findDOMNode"])
};
this.getInternalInstance = e => e[Object.keys(e).find(k => k.startsWith("__reactInternalInstance"))];
window.Lightcord.BetterDiscord.V2 = this
}
get react() {
return this.internal.react;
}
get React() {
return this.internal.react;
}
get reactDom() {
return this.internal.reactDom;
}
get ReactDom() {
return this.internal.reactDom;
}
get reactComponent() {
return this.internal.react.Component;
}
get ReactComponent() {
return this.internal.react.Component;
}
initialize() {
get anchorClasses() {
return (
this.WebpackModules.findByUniqueProperties([
"anchorUnderlineOnHover",
]) || {
anchor: "anchor-3Z-8Bb",
anchorUnderlineOnHover: "anchorUnderlineOnHover-2ESHQB",
}
);
}
get slateEditorClasses() {
return this.WebpackModules.findByUniqueProperties(["slateTextArea"]);
}
get messageClasses() {
return this.WebpackModules.findByUniqueProperties([
"message",
"containerCozy",
]);
}
get guildClasses() {
const guildsWrapper = this.WebpackModules.findByUniqueProperties([
"wrapper",
"unreadMentionsBar",
]);
const guilds = this.WebpackModules.findByUniqueProperties([
"guildsError",
"selected",
]);
const pill = this.WebpackModules.findByUniqueProperties(["blobContainer"]);
return Object.assign({}, guildsWrapper, guilds, pill);
}
}
get MessageContentComponent() {
return this.WebpackModules.find(
(m) => m.defaultProps && m.defaultProps.hasOwnProperty("disableButtons")
);
}
get MessageComponent() {
return this.WebpackModules.find(
(m) =>
m.default && m.default.toString().search("childrenRepliedMessage") > -1
);
}
get TimeFormatter() {
return this.WebpackModules.findByUniqueProperties(["dateFormat"]);
}
get TooltipWrapper() {
return this.WebpackModules.findByDisplayName("Tooltip");
}
get NativeModule() {
return this.WebpackModules.findByUniqueProperties(["setBadge"]);
}
get InviteActions() {
return this.WebpackModules.findByUniqueProperties(["acceptInvite"]);
}
get GuildActions() {
return this.WebpackModules.findByUniqueProperties(["leaveGuild"]);
}
get Tooltips() {
return this.WebpackModules.find(
(m) =>
m.hide &&
m.show &&
!m.search &&
!m.submit &&
!m.search &&
!m.activateRagingDemon &&
!m.dismiss
);
}
get KeyGenerator() {
return this.WebpackModules.find(
(m) => m.toString && /"binary"/.test(m.toString())
);
}
get LayerStack() {
return this.WebpackModules.findByUniqueProperties(["popLayer"]);
}
get UserStore() {
return this.WebpackModules.findByUniqueProperties(["getCurrentUser"]);
}
get ChannelStore() {
return this.WebpackModules.findByUniqueProperties(["getChannel"]);
}
get ChannelActions() {
return this.WebpackModules.findByUniqueProperties(["openPrivateChannel"]);
}
get PrivateChannelActions() {
return this.WebpackModules.findByUniqueProperties(["selectPrivateChannel"]);
}
joinBD1() {this.InviteActions.acceptInviteAndTransitionToInviteChannel("0Tmfo5ZbORCRqbAd");}
leaveBD1() {this.GuildActions.leaveGuild("86004744966914048");}
openDM(userId) {
const selfId = this.UserStore.getCurrentUser().id;
if (selfId == userId) return;
const privateChannelId = this.ChannelStore.getDMFromUserId(userId);
if (privateChannelId)
return this.PrivateChannelActions.selectPrivateChannel(privateChannelId);
this.ChannelActions.openPrivateChannel(selfId, userId);
}
joinBD2() {this.InviteActions.acceptInviteAndTransitionToInviteChannel("2HScm8j");}
leaveBD2() {this.GuildActions.leaveGuild("280806472928198656");}
joinLC() {this.InviteActions.acceptInviteAndTransitionToInviteChannel("7eFff2A");}
leaveLC() {this.GuildActions.leaveGuild("705908350218666117");}
/**
* @type {typeof React}
*/
get react() {return this.internal.react;}
/**
* @type {typeof React}
*/
get React() {return this.internal.react;}
/**
* @type {typeof import("react-dom")}
*/
get reactDom() {return this.internal.reactDom;}
/**
* @type {typeof import("react-dom")}
*/
get ReactDom() {return this.internal.reactDom;}
/**
* @type {typeof React.Component}
*/
get reactComponent() {return this.internal.react.Component;}
/**
* @type {typeof React.Component}
*/
get ReactComponent() {return this.internal.react.Component;}
get anchorClasses() {return this.WebpackModules.findByUniqueProperties(["anchorUnderlineOnHover"]) || {anchor: "anchor-3Z-8Bb", anchorUnderlineOnHover: "anchorUnderlineOnHover-2ESHQB"};}
get slateEditorClasses() {return this.WebpackModules.findByUniqueProperties(["slateTextArea"]);}
get messageClasses() {return this.WebpackModules.findByUniqueProperties(["message", "containerCozy"]);}
get guildClasses() {
const guildsWrapper = BDModules.get(e => e.wrapper && e.unreadMentionsBar)[0];
const guilds = BDModules.get(e => e.guildsError && e.selected)[0]
const pill = BDModules.get(e => e.blobContainer)[0]
return Object.assign({}, guildsWrapper, guilds, pill);
}
get MessageContentComponent() {return this.WebpackModules.find(m => m.defaultProps && m.defaultProps.hasOwnProperty("disableButtons"));}
get MessageComponent() {return this.WebpackModules.find(m => m.default && m.default.displayName && m.default.displayName == "Message");}
get TimeFormatter() {return this.WebpackModules.findByUniqueProperties(["dateFormat"]);}
get TooltipWrapper() {return this.WebpackModules.findByDisplayName("Tooltip");}
get NativeModule() {return this.WebpackModules.findByUniqueProperties(["setBadge"]);}
get InviteActions() {return this.WebpackModules.findByUniqueProperties(["acceptInvite"]);}
get GuildActions() {return this.WebpackModules.findByUniqueProperties(["leaveGuild"]);}
get Tooltips() {return this.WebpackModules.find(m => m.hide && m.show && !m.search && !m.submit && !m.search && !m.activateRagingDemon && !m.dismiss);}
get KeyGenerator() {return this.WebpackModules.find(m => m.toString && /"binary"/.test(m.toString()));}
get LayerStack() {return this.WebpackModules.findByUniqueProperties(["popLayer"]);}
get UserStore() {return this.WebpackModules.findByUniqueProperties(["getCurrentUser"]);}
get ChannelStore() {return this.WebpackModules.findByUniqueProperties(["getChannel"]);}
get ChannelActions() {return this.WebpackModules.findByUniqueProperties(["openPrivateChannel"]);}
get PrivateChannelActions() {return this.WebpackModules.findByUniqueProperties(["selectPrivateChannel"]);}
openDM(userId) {
const selfId = this.UserStore.getCurrentUser().id;
if (selfId == userId) return;
const privateChannelId = this.ChannelStore.getDMFromUserId(userId);
if (privateChannelId) return this.PrivateChannelActions.selectPrivateChannel(privateChannelId);
this.ChannelActions.openPrivateChannel(selfId, userId);
}
parseSettings(cat) {
return Object.keys(settings).reduce((arr, key) => {
const setting = settings[key];
if (setting.cat === cat && setting.implemented && !setting.hidden) {
setting.text = key;
arr.push(setting);
} return arr;
}, []);
}
};
parseSettings(cat) {
return Object.keys(settings).reduce((arr, key) => {
const setting = settings[key];
if (setting.cat === cat && setting.implemented && !setting.hidden) {
setting.text = key;
arr.push(setting);
}
return arr;
}, []);
}
})();

File diff suppressed because one or more lines are too long

View File

@ -66,24 +66,12 @@ export default class V2C_AccountInfos extends React.Component {
*/
const createdAt = user.createdAt
let avatarURL = user.avatarURL
if(user.avatar && user.avatar.startsWith("a_")){
avatarURL = user.getAvatarURL("gif")
}
if(avatarURL.startsWith("/")){
avatarURL = "https://discord.com"+avatarURL
}
if(avatarURL.endsWith("?size=128")){
avatarURL = avatarURL.replace("?size=128", "?size=4096")
}
return `+ Username: ${user.username}
+ Discriminator: ${user.discriminator}
+ Tag: ${user.tag}
+ ID: ${user.id}
+ Avatar: ${user.avatar}
+ Avatar URL: ${avatarURL}
+ Creation Date: ${(createdAt.getDate()).toString().padStart(2, "0")}/${(createdAt.getMonth()+1).toString().padStart(2, "0")}/${(createdAt.getFullYear()).toString().padStart(2, "0")} ${createdAt.getHours().toString().padStart(2, "0")}h ${createdAt.getMinutes().toString().padStart(2, "0")}min ${createdAt.getSeconds()}s
+ Flags: ${user.flags}
+ Has Nitro: ${user.hasPremiumSubscription ? "Yes" : "No"}

View File

@ -52,9 +52,6 @@ export default class V2C_PluginCard extends BDV2.reactComponent {
componentDidUpdate() {
if (!this.state.settings) return;
if (typeof this.settingsPanel === "object") {
this.refs.settingspanel.appendChild(this.settingsPanel);
}
if (!settingsCookie["fork-ps-3"]) return;
setImmediate(() => {
@ -97,15 +94,28 @@ export default class V2C_PluginCard extends BDV2.reactComponent {
try { this.settingsPanel = this.props.addon.plugin.getSettingsPanel(); }
catch (err) { Utils.err("Plugins", "Unable to get settings panel for " + this.name + ".", err); }
let settingPanel
if(typeof this.settingsPanel === "object"){
if(this.settingsPanel instanceof Node){
settingPanel = BDV2.react.createElement("div", {id: `plugin-settings-${this.name}`, className: "plugin-settings", ref: (elem) => {
elem.appendChild(this.settingsPanel)
}})
}else{
settingPanel = BDV2.react.createElement("div", {id: `plugin-settings-${this.name}`, className: "plugin-settings"},
this.settingsPanel)
}
}else if(typeof this.settingsPanel === "string"){
settingPanel = BDV2.react.createElement("div", {id: `plugin-settings-${this.name}`, className: "plugin-settings", dangerouslySetInnerHTML: {__html: this.settingsPanel}})
}
return BDV2.react.createElement("div", {className: "bd-card bd-addon-card settings-open ui-switch-item", ref: "cardNode"},
BDV2.react.createElement("div", {style: {"float": "right", "cursor": "pointer"}, onClick: () => {
this.refs.settingspanel.innerHTML = "";
this.setState({settings: false});
this.setState({
settings: false
});
}},
BDV2.react.createElement(XSvg, null)
),
typeof this.settingsPanel === "object" && BDV2.react.createElement("div", {id: `plugin-settings-${this.name}`, className: "plugin-settings", ref: "settingspanel"}),
typeof this.settingsPanel !== "object" && BDV2.react.createElement("div", {id: `plugin-settings-${this.name}`, className: "plugin-settings", ref: "settingspanel", dangerouslySetInnerHTML: {__html: this.settingsPanel}})
settingPanel
);
}
@ -239,4 +249,4 @@ Object.defineProperty(V2C_PluginCard.prototype, "render", {
configurable: false,
set: function() {console.warn("Addon policy for plugins #5 https://github.com/rauenzi/BetterDiscordApp/wiki/Addon-Policies#plugins");},
get: () => originalRender
});
});

View File

@ -0,0 +1,87 @@
import {settingsCookie} from "../0globals";
import quickEmoteMenu from "../modules/quickEmoteMenu";
import BDV2 from "../modules/v2";
export default class BDEmote extends BDV2.reactComponent {
constructor(props) {
super(props);
const isFav = quickEmoteMenu && quickEmoteMenu.favoriteEmotes && quickEmoteMenu.favoriteEmotes[this.label] ? true : false;
this.state = {
shouldAnimate: !this.animateOnHover,
isFavorite: isFav
};
this.onMouseEnter = this.onMouseEnter.bind(this);
this.onMouseLeave = this.onMouseLeave.bind(this);
this.onClick = this.onClick.bind(this);
}
get animateOnHover() {
return settingsCookie["fork-es-2"];
}
get label() {
return this.props.modifier ? `${this.props.name}:${this.props.modifier}` : this.props.name;
}
get modifierClass() {
return this.props.modifier ? ` emote${this.props.modifier}` : "";
}
onMouseEnter() {
if (!this.state.shouldAnimate && this.animateOnHover) this.setState({shouldAnimate: true});
if (!this.state.isFavorite && quickEmoteMenu.favoriteEmotes[this.label]) this.setState({isFavorite: true});
else if (this.state.isFavorite && !quickEmoteMenu.favoriteEmotes[this.label]) this.setState({isFavorite: false});
}
onMouseLeave() {
if (this.state.shouldAnimate && this.animateOnHover) this.setState({shouldAnimate: false});
}
onClick(e) {
if (this.props.onClick) this.props.onClick(e);
}
render() {
return BDV2.react.createElement(BDV2.TooltipWrapper, {
color: "black",
position: "top",
text: this.label,
delay: 750
},
(childProps) => {
return BDV2.react.createElement("div", Object.assign({
className: "emotewrapper" + (this.props.jumboable ? " jumboable" : ""),
onMouseEnter: this.onMouseEnter,
onMouseLeave: this.onMouseLeave,
onClick: this.onClick
}, childProps),
BDV2.react.createElement("img", {
draggable: false,
className: "emote" + this.modifierClass + (this.props.jumboable ? " jumboable" : "") + (!this.state.shouldAnimate ? " stop-animation" : ""),
dataModifier: this.props.modifier,
alt: this.label,
src: this.props.url
}),
BDV2.react.createElement("input", {
className: "fav" + (this.state.isFavorite ? " active" : ""),
title: "Favorite!",
type: "button",
onClick: (e) => {
e.preventDefault();
e.stopPropagation();
if (this.state.isFavorite) {
delete quickEmoteMenu.favoriteEmotes[this.label];
quickEmoteMenu.updateFavorites();
}
else {
quickEmoteMenu.favorite(this.label, this.props.url);
}
this.setState({isFavorite: !this.state.isFavorite});
}
})
);
});
}
}

View File

@ -6,7 +6,8 @@ export default class BDErrorBoundary extends BDV2.reactComponent {
this.state = {hasError: false};
}
componentDidCatch() {
componentDidCatch(error, errorStack) {
console.log(error, errorStack)
this.setState({hasError: true});
}

View File

@ -0,0 +1,89 @@
import BDV2 from "../../modules/v2";
import DOM from "../../modules/domtools";
export default class V2C_Layer extends BDV2.reactComponent {
constructor(props) {
super(props);
this.keyupListener = this.keyupListener.bind(this);
}
keyupListener(e) {
if (e.which === 27) {
BDV2.reactDom.unmountComponentAtNode(this.refs.root.parentNode);
}
}
componentDidMount() {
window.addEventListener("keyup", this.keyupListener);
const thisNode = DOM.query(`#${this.props.id}`);
DOM.animate({
duration: 200,
update: function(progress) {
thisNode.style.transform = `scale(${1.1 - 0.1 * progress}) translateZ(0px)`;
thisNode.style.opacity = progress;
if (progress == 1) {
setImmediate(() => {
thisNode.style.transform = "";
thisNode.style.opacity = "";
});
}
}
});
}
componentWillUnmount() {
window.removeEventListener("keyup", this.keyupListener);
const thisNode = DOM.query(`#${this.props.id}`);
DOM.animate({
duration: 200,
update: function(progress) {
thisNode.style.transform = `scale(${1.1 - 0.1 * (1 - progress)}) translateZ(0px)`;
thisNode.style.opacity = 1 - progress;
if (progress == 1) {
setImmediate(() => {
thisNode.remove();
});
}
}
});
const layer = DOM.query(".publicServersOpen");
layer.classList.remove("publicServersOpen");
DOM.animate({
duration: 200,
update: function(progress) {
layer.style.transform = `scale(${0.07 * progress + 0.93}) translateZ(0px)`;
layer.style.opacity = progress;
if (progress == 1) {
setImmediate(() => {
layer.style.transform = "";
layer.style.opacity = "";
});
}
}
});
}
componentWillMount() {
const layer = DOM.query("[class*=\"layer-\"]");
layer.classList.add("publicServersOpen");
DOM.animate({
duration: 200,
update: function(progress) {
layer.style.transform = `scale(${0.07 * (1 - progress) + 0.93}) translateZ(0px)`;
layer.style.opacity = 1 - progress;
}
});
}
render() {
return BDV2.react.createElement(
"div",
{className: "layer bd-layer layer-3QrUeG", id: this.props.id, ref: "root", style: {opacity: 0, transform: "scale(1.1) translateZ(0px)"}},
this.props.children
);
}
}

View File

@ -167,8 +167,8 @@ export default class V2C_PublicServers extends BDV2.reactComponent {
};
const server2 = {
name: "Lightcord",
online: "100+",
members: "300+",
online: "500+",
members: "1200+",
categories: ["community", "programming", "support"],
description: "Official Lightcord server for support etc",
identifier: "705908350218666117",

View File

@ -0,0 +1,32 @@
import BDV2 from "../../modules/v2";
import Scroller from "../scroller";
export default class V2C_SidebarView extends BDV2.reactComponent {
constructor(props) {
super(props);
}
render() {
const {sidebar, content, tools} = this.props.children;
return BDV2.react.createElement(
"div",
{className: "standardSidebarView-3F1I7i ui-standard-sidebar-view"},
BDV2.react.createElement(
"div",
{className: "sidebarRegion-VFTUkN sidebar-region"},
BDV2.react.createElement(Scroller, {key: "sidebarScroller", ref: "sidebarScroller", sidebar: true, fade: sidebar.fade || true, dark: sidebar.dark || true}, sidebar.component)
),
BDV2.react.createElement("div", {className: "contentRegion-3nDuYy content-region"},
BDV2.react.createElement("div", {className: "contentTransitionWrap-3hqOEW content-transition-wrap"},
BDV2.react.createElement("div", {className: "scroller-2FKFPG firefoxFixScrollFlex-cnI2ix contentRegionScroller-26nc1e content-region-scroller scroller", ref: "contentScroller"},
BDV2.react.createElement("div", {className: "contentColumn-2hrIYH contentColumnDefault-1VQkGM content-column default"}, content.component),
tools.component
)
)
)
);
}
}

View File

@ -0,0 +1,24 @@
import {settingsCookie} from "../0globals";
import BDV2 from "../modules/v2";
import SettingsTitle from "./settingsTitle";
import Switch from "./switch";
export default class V2C_SettingsGroup extends BDV2.reactComponent {
constructor(props) {
super(props);
}
render() {
const {title, settings, button} = this.props;
const buttonComponent = button ? BDV2.react.createElement("button", {key: "title-button", className: "bd-pfbtn", onClick: button.onClick}, button.title) : null;
return [BDV2.react.createElement(SettingsTitle, {text: title}),
buttonComponent,
settings.map(setting => {
return BDV2.react.createElement(Switch, {id: setting.id, key: setting.id, data: setting, checked: settingsCookie[setting.id], onChange: (id, checked) => {
this.props.onChange(id, checked);
}});
})];
}
}

View File

@ -0,0 +1,77 @@
import BDV2 from "../modules/v2";
import TabBarSeparator from "./tabBarSeparator";
import TabBarHeader from "./tabBarHeader";
import TabBarItem from "./tabBarItem";
export default class V2C_SideBar extends BDV2.reactComponent {
constructor(props) {
super(props);
const si = document.querySelector("[class*=side-] > [class*=selected]");
if (si) this.scn = si.className;
const ns = document.querySelector("[class*=side-] > [class*='item-']:not([class*=selected])");
if (ns) this.nscn = ns.className;
const tabs = document.querySelectorAll("[class*='side-'] > [class*='item-']");
for (const element of tabs) {
element.addEventListener("click", () => {
this.setState({
selected: null
});
});
}
this.setInitialState();
this.onClick = this.onClick.bind(this);
this.setSelected = this.setSelected.bind(this);
}
setInitialState() {
const self = this;
self.state = {
selected: null,
items: self.props.items
};
const initialSelection = self.props.items.find(item => {
return item.selected;
});
if (initialSelection) {
self.state.selected = initialSelection.id;
}
}
render() {
const self = this;
const {headerText} = self.props;
const {items, selected} = self.state;
return BDV2.react.createElement(
"div",
null,
BDV2.react.createElement(TabBarSeparator, null),
BDV2.react.createElement(TabBarHeader, {text: headerText, button: this.props.headerButton}),
items.map(item => {
const {id, text} = item;
return BDV2.react.createElement(TabBarItem, {key: id, selected: selected === id, text: text, id: id, onClick: self.onClick});
})
);
}
setSelected(e) {
e.target.className = this.scn;
}
onClick(id) {
const si = document.querySelector("[class*=side] > [class*=selected]");
if (si) {
si.removeEventListener("click", this.setSelected);
si.addEventListener("click", this.setSelected);
si.className = this.nscn;
}
this.setState({selected: null});
this.setState({selected: id});
if (this.props.onClick) this.props.onClick(id);
}
}

View File

@ -107,7 +107,7 @@ export default class EmulatedTooltip {
/** Container where the tooltip will be appended. */
get container() {
return document.querySelector("."+Utils.removeDa(BDModules.get(e => e.popouts)[0].popouts)+" ~ ."+Utils.removeDa(BDModules.get(e => e.layerContainer)[0].layerContainer));
return document.querySelector("."+Utils.removeDa(BDModules.get(e => typeof e.popouts === "string")[0].popouts)+" ~ ."+Utils.removeDa(BDModules.get(e => typeof e.layerContainer === "string")[0].layerContainer));
}
/** Boolean representing if the tooltip will fit on screen above the element */
get canShowAbove() { return this.node.getBoundingClientRect().top - this.element.offsetHeight >= 0; }

View File

@ -66,10 +66,10 @@ module.exports = {
optimization: {
minimizer: [
new TerserPlugin({
sourceMap: true,
terserOptions: {
compress: {drop_debugger:false}
},
sourceMap: true
})
]
}

View File

@ -1,8 +1,373 @@
{
"name": "discord.js-lightcord",
"version": "11.6.4",
"lockfileVersion": 1,
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "discord.js-lightcord",
"version": "11.6.4",
"license": "ISC",
"dependencies": {
"@discordjs/collection": "0.1.5"
},
"devDependencies": {
"ts-loader": "^7.0.5",
"typescript": "^3.9.5"
}
},
"node_modules/@discordjs/collection": {
"version": "0.1.5",
"resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-0.1.5.tgz",
"integrity": "sha512-CU1q0UXQUpFNzNB7gufgoisDHP7n+T3tkqTsp3MNUkVJ5+hS3BCvME8uCXAUFlz+6T2FbTCu75A+yQ7HMKqRKw=="
},
"node_modules/ansi-styles": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
"dev": true,
"dependencies": {
"color-convert": "^1.9.0"
},
"engines": {
"node": ">=4"
}
},
"node_modules/big.js": {
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
"integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==",
"dev": true,
"engines": {
"node": "*"
}
},
"node_modules/braces": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
"dev": true,
"dependencies": {
"fill-range": "^7.0.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/chalk": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
"dev": true,
"dependencies": {
"ansi-styles": "^3.2.1",
"escape-string-regexp": "^1.0.5",
"supports-color": "^5.3.0"
},
"engines": {
"node": ">=4"
}
},
"node_modules/color-convert": {
"version": "1.9.3",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
"dev": true,
"dependencies": {
"color-name": "1.1.3"
}
},
"node_modules/color-name": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
"dev": true
},
"node_modules/core-util-is": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
"dev": true
},
"node_modules/emojis-list": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz",
"integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==",
"dev": true,
"engines": {
"node": ">= 4"
}
},
"node_modules/enhanced-resolve": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.2.0.tgz",
"integrity": "sha512-S7eiFb/erugyd1rLb6mQ3Vuq+EXHv5cpCkNqqIkYkBgN2QdFnyCZzFBleqwGEx4lgNGYij81BWnCrFNK7vxvjQ==",
"dev": true,
"dependencies": {
"graceful-fs": "^4.1.2",
"memory-fs": "^0.5.0",
"tapable": "^1.0.0"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/errno": {
"version": "0.1.7",
"resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz",
"integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==",
"dev": true,
"dependencies": {
"prr": "~1.0.1"
},
"bin": {
"errno": "cli.js"
}
},
"node_modules/escape-string-regexp": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
"dev": true,
"engines": {
"node": ">=0.8.0"
}
},
"node_modules/fill-range": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
"dev": true,
"dependencies": {
"to-regex-range": "^5.0.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/graceful-fs": {
"version": "4.2.4",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz",
"integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==",
"dev": true
},
"node_modules/has-flag": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
"dev": true,
"engines": {
"node": ">=4"
}
},
"node_modules/inherits": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
"dev": true
},
"node_modules/is-number": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
"dev": true,
"engines": {
"node": ">=0.12.0"
}
},
"node_modules/isarray": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
"dev": true
},
"node_modules/json5": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
"integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
"dev": true,
"dependencies": {
"minimist": "^1.2.0"
},
"bin": {
"json5": "lib/cli.js"
}
},
"node_modules/loader-utils": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz",
"integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==",
"dev": true,
"dependencies": {
"big.js": "^5.2.2",
"emojis-list": "^3.0.0",
"json5": "^1.0.1"
},
"engines": {
"node": ">=4.0.0"
}
},
"node_modules/memory-fs": {
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz",
"integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==",
"dev": true,
"dependencies": {
"errno": "^0.1.3",
"readable-stream": "^2.0.1"
},
"engines": {
"node": ">=4.3.0 <5.0.0 || >=5.10"
}
},
"node_modules/micromatch": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz",
"integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==",
"dev": true,
"dependencies": {
"braces": "^3.0.1",
"picomatch": "^2.0.5"
},
"engines": {
"node": ">=8"
}
},
"node_modules/minimist": {
"version": "1.2.5",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
"dev": true
},
"node_modules/picomatch": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz",
"integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==",
"dev": true,
"engines": {
"node": ">=8.6"
}
},
"node_modules/process-nextick-args": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
"dev": true
},
"node_modules/prr": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz",
"integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=",
"dev": true
},
"node_modules/readable-stream": {
"version": "2.3.7",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
"integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
"dev": true,
"dependencies": {
"core-util-is": "~1.0.0",
"inherits": "~2.0.3",
"isarray": "~1.0.0",
"process-nextick-args": "~2.0.0",
"safe-buffer": "~5.1.1",
"string_decoder": "~1.1.1",
"util-deprecate": "~1.0.1"
}
},
"node_modules/safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
"dev": true
},
"node_modules/semver": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
"dev": true,
"bin": {
"semver": "bin/semver.js"
}
},
"node_modules/string_decoder": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
"dev": true,
"dependencies": {
"safe-buffer": "~5.1.0"
}
},
"node_modules/supports-color": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
"dev": true,
"dependencies": {
"has-flag": "^3.0.0"
},
"engines": {
"node": ">=4"
}
},
"node_modules/tapable": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz",
"integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==",
"dev": true,
"engines": {
"node": ">=6"
}
},
"node_modules/to-regex-range": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
"dev": true,
"dependencies": {
"is-number": "^7.0.0"
},
"engines": {
"node": ">=8.0"
}
},
"node_modules/ts-loader": {
"version": "7.0.5",
"resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-7.0.5.tgz",
"integrity": "sha512-zXypEIT6k3oTc+OZNx/cqElrsbBtYqDknf48OZos0NQ3RTt045fBIU8RRSu+suObBzYB355aIPGOe/3kj9h7Ig==",
"dev": true,
"dependencies": {
"chalk": "^2.3.0",
"enhanced-resolve": "^4.0.0",
"loader-utils": "^1.0.2",
"micromatch": "^4.0.0",
"semver": "^6.0.0"
},
"engines": {
"node": ">=10.0.0"
}
},
"node_modules/typescript": {
"version": "3.9.5",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.5.tgz",
"integrity": "sha512-hSAifV3k+i6lEoCJ2k6R2Z/rp/H3+8sdmcn5NrS3/3kE7+RyZXm9aqvxWqjEXHAd8b0pShatpcdMTvEdvAJltQ==",
"dev": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
},
"engines": {
"node": ">=4.2.0"
}
},
"node_modules/util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
"dev": true
}
},
"dependencies": {
"@discordjs/collection": {
"version": "0.1.5",

View File

@ -13,7 +13,7 @@
"@discordjs/collection": "0.1.5"
},
"devDependencies": {
"typescript": "^3.9.5",
"ts-loader": "^7.0.5"
"ts-loader": "^7.0.5",
"typescript": "^3.9.5"
}
}

View File

@ -92,7 +92,7 @@ export default class Permissions extends BitField {
* - `MANAGE_WEBHOOKS`
* - `MANAGE_EMOJIS`
* @type {Object}
* @see {@link https://discordapp.com/developers/docs/topics/permissions}
* @see {@link https://discord.com/developers/docs/topics/permissions}
*/
static FLAGS:{
CREATE_INSTANT_INVITE: number,

View File

@ -1,6 +1,6 @@
MIT License
Copyright (c) 2020 JeanOUINA
Copyright (c) 2021 JeanOUINA
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@ -1,6 +1,8 @@
[Desktop Entry]
Name=Lightcord
StartupWMClass=lightcord
Comment[fr_FR]=Un client Discord simple et personalisable
Comment[no]=En enkel - tilpassbar - Discord klient
Comment=A simple - customizable - Discord Client
Exec=/opt/Lightcord/Lightcord
Icon=lightcord

File diff suppressed because it is too large Load Diff

View File

@ -47,7 +47,7 @@ export default class Tabs extends React.Component<TabsProps, {
return (<div className="lc-tabWrapper" style={this.props.style}>
<div className="lc-tabnav" style={{flex: "0 1 auto"}}>
{this.tabs.map(tab => {
return React.createElement(Tab, {TabContainer: this, title: tab.label, id: tab.id, key: btoa(tab.label+":"+tab.id)})
return React.createElement(Tab, {TabContainer: this, title: tab.label, id: tab.id, key: Buffer.from(tab.label+":"+tab.id, "utf8").toString("base64")})
})}
</div>
<div className="lc-tab">

View File

@ -1,177 +0,0 @@
#!/bin/bash
# Original script by https://github.com/GermanBread
if [[ $TERM == dumb ]]; then
exit;
fi
if [[ $(whoami) != "root" ]] ; then
printf "[$(tput setaf 9 && tput blink)PANIC$(tput sgr0)] $(tput setaf 9)This script needs to run as root$(tput sgr0)\n";
exit;
fi
tput setaf 208
cat << "EOF"
_ _ _ _ _
| | (_)__ _| |_| |_ __ ___ _ _ __| |
| |__| / _` | ' \ _/ _/ _ \ '_/ _` |
|____|_\__, |_||_\__\__\___/_| \__,_|
|___/
Linux Installer and Updater
EOF
tput sgr0
printf "[$(tput setaf 12 && tput blink)INFO$(tput sgr0)] $(tput setaf 12)This script depends on unzip! Install that package first!$(tput sgr0)\n";
printf "Please select\n";
printf "1: Install Lightcord\n";
printf "2: Uninstall Lightcord\n";
printf "3: Update Lightcord\n"
printf "\n";
#Repeat only if the user hasn't entered an integer...
while ! [[ $selection =~ ^[0-9]+$ ]];
do
read selection;
#if the entered value was not an integer, show this
if ! [[ $selection =~ ^[0-9]+$ ]]; then
sleep 1;
printf "$(tput setaf 9)Please try again$(tput sgr0)\n";
printf "1: Install Lightcord\n";
printf "2: Uninstall Lightcord\n";
printf "3: Update Lightcord\n"
printf "\n";
fi
done
case $selection in
1)
printf "[$(tput setaf 12 && tput blink)INFO$(tput sgr0)] $(tput setaf 12)Installing Lightcord$(tput sgr0)\n";
printf "[$(tput setaf 12 && tput blink)INFO$(tput sgr0)] $(tput setaf 7)Downloading Lightcord zip to $(pwd && tput sgr0)\n";
rm -rf Lightcord.*;
rm -rf Lightcord;
rm -rf lightcord-linux-x64.*;
wget https://lightcord.org/api/v1/gh/releases/Lightcord/Lightcord/dev/lightcord-linux-x64.zip;
printf "[$(tput setaf 12 && tput blink)INFO$(tput sgr0)] $(tput setaf 7)Unzipping$(tput sgr0)\n";
unzip lightcord-linux-x64.zip -d Lightcord;
printf "[$(tput setaf 12 && tput blink)INFO$(tput sgr0)] $(tput setaf 7)Deleting zip$(tput sgr0)\n";
rm lightcord-linux-x64.zip;
prev_pwd = pwd;
printf "[$(tput setaf 12 && tput blink)INFO$(tput sgr0)] $(tput setaf 7)Changing directory into $(pwd)/Lightcord$(tput sgr0)\n";
cd Lightcord;
printf "[$(tput setaf 12 && tput blink)INFO$(tput sgr0)] $(tput setaf 7)Giving $(pwd)/lightcord executable execute permissions$(tput sgr0)\n";
chmod +x ./lightcord;
printf "[$(tput setaf 12 && tput blink)INFO$(tput sgr0)] $(tput setaf 7)Changing directory into ${prev_pwd}$(tput sgr0)\n";
cd ..;
printf "[$(tput setaf 12 && tput blink)INFO$(tput sgr0)] $(tput setaf 7)Moving $(pwd)/Lightcord folder to /opt$(tput sgr0)\n";
mv Lightcord/ /opt/;
printf "[$(tput setaf 12 && tput blink)INFO$(tput sgr0)] $(tput setaf 7)Deleting $(pwd)/Lightcord folder$(tput sgr0)\n";
rm Lightcord/;
printf "[$(tput setaf 12 && tput blink)INFO$(tput sgr0)] $(tput setaf 7)Downloading lightcord.svg icon to $(pwd && tput sgr0)\n";
wget https://raw.githubusercontent.com/Lightcord/LightcordLogos/master/lightcord/lightcord.svg;
printf "[$(tput setaf 12 && tput blink)INFO$(tput sgr0)] $(tput setaf 7)Moving $(pwd)/lightcord.svg file to /usr/share/pixmaps$(tput sgr0)\n";
mv lightcord.svg /usr/share/pixmaps;
printf "[$(tput setaf 12 && tput blink)INFO$(tput sgr0)] $(tput setaf 7)Generating and moving Lightcord.desktop file to /usr/share/Lightcord.desktop$(tput sgr0)\n";
rm -rf /usr/share/applications/Lightcord.desktop
echo -e "[Desktop Entry]\nName=Lightcord\nComment[fr_FR]=Un client Discord simple et personalisable\nComment=A simple - customizable - Discord Client\nExec=/opt/Lightcord/lightcord\nIcon=lightcord\nTerminal=false\nType=Application\nCategories=Network;InstantMessaging;P2P;" >> /usr/share/applications/Lightcord.desktop
printf "[$(tput setaf 12 && tput blink)INFO$(tput sgr0)] $(tput setaf 7)Giving /usr/share/Lightcord.desktop execute permissions$(tput sgr0)\n";
chmod +x /usr/share/applications/Lightcord.desktop;
printf "[$(tput setaf 12 && tput blink)INFO$(tput sgr0)] $(tput setaf 7)Cleaning up$(tput sgr0)\n";
rm -rf Lightcord.*;
rm -rf Lightcord;
rm -rf lightcord-linux-x64.*;
printf "[$(tput setaf 10 && tput blink)FINISH$(tput sgr0)] Installation complete\n";
;;
2)
printf "[$(tput setaf 12 && tput blink)INFO$(tput sgr0)] $(tput setaf 12)Uninstalling Lightcord$(tput sgr0)\n";
printf "[$(tput setaf 12 && tput blink)INFO$(tput sgr0)] $(tput setaf 12)Deleting /opt/Lightcord$(tput sgr0)\n";
rm -r /opt/Lightcord;
printf "[$(tput setaf 12 && tput blink)INFO$(tput sgr0)] $(tput setaf 12)Deleting /usr/share/pixmaps/lightcord.svg$(tput sgr0)\n";
rm /usr/share/pixmaps/lightcord.svg;
printf "[$(tput setaf 12 && tput blink)INFO$(tput sgr0)] $(tput setaf 12)Deleting /usr/share/Lightcord.desktop$(tput sgr0)\n";
rm /usr/share/applications/Lightcord.desktop;
printf "[$(tput setaf 12 && tput blink)INFO$(tput sgr0)] $(tput setaf 12)Deleting /home/*/.local/share/applications/Lightcord.desktop$(tput sgr0)\n";
rm -f /home/*/.local/share/applications/Lightcord.desktop;
printf "[$(tput setaf 10 && tput blink)FINISH$(tput sgr0)] Uninstall complete\n";
;;
3)
#Uninstall
printf "[$(tput setaf 12 && tput blink)INFO$(tput sgr0)] $(tput setaf 12)Updating Lightcord$(tput sgr0)\n";
printf "[$(tput setaf 12 && tput blink)INFO$(tput sgr0)] $(tput setaf 12)Deleting /opt/Lightcord$(tput sgr0)\n";
rm -r /opt/Lightcord;
#Install
printf "[$(tput setaf 12 && tput blink)INFO$(tput sgr0)] $(tput setaf 7)Downloading Lightcord zip to $(pwd && tput sgr0)\n";
rm -rf Lightcord.*;
rm -rf Lightcord;
rm -rf lightcord-linux-x64.*;
wget https://lightcord.org/api/v1/gh/releases/Lightcord/Lightcord/dev/lightcord-linux-x64.zip;
printf "[$(tput setaf 12 && tput blink)INFO$(tput sgr0)] $(tput setaf 7)Unzipping$(tput sgr0)\n";
unzip lightcord-linux-x64.zip -d Lightcord;
printf "[$(tput setaf 12 && tput blink)INFO$(tput sgr0)] $(tput setaf 7)Deleting zip$(tput sgr0)\n";
rm lightcord-linux-x64.zip;
prev_pwd = pwd;
printf "[$(tput setaf 12 && tput blink)INFO$(tput sgr0)] $(tput setaf 7)Changing directory into $(pwd)/Lightcord$(tput sgr0)\n";
cd Lightcord;
printf "[$(tput setaf 12 && tput blink)INFO$(tput sgr0)] $(tput setaf 7)Giving $(pwd)/lightcord executable execute permissions$(tput sgr0)\n";
chmod +x ./lightcord;
printf "[$(tput setaf 12 && tput blink)INFO$(tput sgr0)] $(tput setaf 7)Changing directory into ${prev_pwd}$(tput sgr0)\n";
cd ..;
printf "[$(tput setaf 12 && tput blink)INFO$(tput sgr0)] $(tput setaf 7)Moving $(pwd)/Lightcord folder to /opt$(tput sgr0)\n";
mv Lightcord/ /opt/;
printf "[$(tput setaf 12 && tput blink)INFO$(tput sgr0)] $(tput setaf 7)Deleting $(pwd)/Lightcord folder$(tput sgr0)\n";
rm Lightcord/;
printf "[$(tput setaf 12 && tput blink)INFO$(tput sgr0)] $(tput setaf 7)Cleaning up$(tput sgr0)\n";
rm -rf Lightcord.*;
rm -rf Lightcord;
rm -rf lightcord-linux-x64.*;
printf "[$(tput setaf 10 && tput blink)FINISH$(tput sgr0)] Update complete\n";
;;
# 4)
# printf "Please select\n";
# printf "1: \"/opt/Lightcord/Lightcord not found\"\n";
# printf "2: None of the above\n"
# printf "\n";
#
# #Repeat only if the user hasn't entered an integer...
# while ! [[ $troubleshooting_selection =~ ^[0-9]+$ ]];
# do
# read troubleshooting_selection;
# #if the entered value was not an integer, show this
# if ! [[ $troubleshooting_selection =~ ^[0-9]+$ ]]; then
# sleep 1;
# printf "$(tput setaf 9)Please try again$(tput sgr0)\n";
# printf "1: \"/opt/Lightcord/Lightcord not found\"\n";
# printf "2: None of the above\n"
# printf "\n";
# fi
# done
#
# case $troubleshooting_selection in
# 1)
# printf "[$(tput setaf 12 && tput blink)INFO$(tput sgr0)] $(tput setaf 7)Modifying /usr/share/applications/Lightcord.desktop$(tput sgr0)\n";
# sed -i 's/Lightcord\/Lightcord/Lightcord\/lightcord/' /usr/share/applications/Lightcord.desktop > /dev/null 2>&1;
# sed -i 's/Lightcord\/Lightcord/Lightcord\/lightcord/' /home/*/.local/share/applications/Lightcord.desktop > /dev/null 2>&1;
# printf "[$(tput setaf 10 && tput blink)FINISH$(tput sgr0)] Done\n";
# ;;
#
# 2)
# printf "[$(tput setaf 12 && tput blink)INFO$(tput sgr0)] $(tput setaf 15)Visit the official server for support: https://discord.gg/7eFff2A$(tput sgr0)\n";
# ;;
#
# *)
# printf "[$(tput setaf 12 && tput blink)INFO$(tput sgr0)] $(tput setaf 12)Exiting troubleshooting$(tput sgr0)\n";
# ;;
# esac
# ;;
#
*)
printf "[$(tput setaf 12 && tput blink)INFO$(tput sgr0)] $(tput setaf 12)Exiting script$(tput sgr0)\n";
;;
esac

155
README.md
View File

@ -4,113 +4,76 @@
[![HitCount](http://hits.dwyl.com/Lightcord/Lightcord.svg)](http://hits.dwyl.com/Lightcord/Lightcord)
<br />
[![PayPal](https://img.shields.io/badge/donate-PayPal-blue?logo=PayPal&style=flat-square)](https://paypal.me/jenwina)
[![BTC](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/phorcysed/cryptodonate/master/badges/bitcoin.json&style=flat-square)](https://unixkeys.github.io/cryptodonate/btc.html?address=14hL2fPS2ASoe8Hcif87EqCS5AGHrepGKp&note=https://github.com/phorcysed)
[![CDN](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/phorcysed/cryptodonate/master/badges/cdn.json&style=flat-square)](https://unixkeys.github.io/cryptodonate/cdn.html?address=CbdW3pR4HBWJ6wyc1JeNXP4L2fh8QiL85v&note=https://github.com/phorcysed)
[![BCH](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/phorcysed/cryptodonate/master/badges/bitcoincash.json&style=flat-square)](https://unixkeys.github.io/cryptodonate/bch.html?address=qzqwhfyvkl324fue86r55q656nftfmxkhsn6qugenq&note=https://github.com/phorcysed)
[![XMR](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/phorcysed/cryptodonate/master/badges/monero.json&style=flat-square)](https://unixkeys.github.io/cryptodonate/xmr.html?address=42pGf1KHHpqaifJd3TtWSdcTmhGVwFp24cGxDoqaYLQJ6rH4pM7KqtUdTpoyxHScDTSJpPA2Bnv19b1bs2uPXgSMH2KYkwj&note=https://github.com/phorcysed)
[![ETH](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/phorcysed/cryptodonate/master/badges/ethereum.json&style=flat-square)](https://unixkeys.github.io/cryptodonate/eth.html?address=0xEFE45F22Ee844bf2Ba0E4d853FA0bC8c028fAfFe&note=https://github.com/phorcysed)
[![LTC](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/phorcysed/cryptodonate/master/badges/litecoin.json&style=flat-square)](https://unixkeys.github.io/cryptodonate/ltc.html?address=LNTmfMjHJgTHaB7rj8ZuWWuU1XkP2YeGCA&note=https://github.com/phorcysed)
---
# Lightcord
A simple - customizable - Discord Client
[![BTC](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/papycochon/cryptodonate/master/badges/bitcoin.json&style=flat-square)](https://papycochon.github.io/cryptodonate/btc.html?address=14hL2fPS2ASoe8Hcif87EqCS5AGHrepGKp&note=https://github.com/Lightcord/Lightcord)
[![CDN](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/papycochon/cryptodonate/master/badges/cdn.json&style=flat-square)](https://papycochon.github.io/cryptodonate/cdn.html?address=CbdW3pR4HBWJ6wyc1JeNXP4L2fh8QiL85v&note=https://github.com/Lightcord/Lightcord)
[![BCH](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/papycochon/cryptodonate/master/badges/bitcoincash.json&style=flat-square)](https://papycochon.github.io/cryptodonate/bch.html?address=qzqwhfyvkl324fue86r55q656nftfmxkhsn6qugenq&note=https://github.com/Lightcord/Lightcord)
[![XMR](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/papycochon/cryptodonate/master/badges/monero.json&style=flat-square)](https://papycochon.github.io/cryptodonate/xmr.html?address=42pGf1KHHpqaifJd3TtWSdcTmhGVwFp24cGxDoqaYLQJ6rH4pM7KqtUdTpoyxHScDTSJpPA2Bnv19b1bs2uPXgSMH2KYkwj&note=https://github.com/Lightcord/Lightcord)
[![ETH](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/papycochon/cryptodonate/master/badges/ethereum.json&style=flat-square)](https://papycochon.github.io/cryptodonate/eth.html?address=0xEFE45F22Ee844bf2Ba0E4d853FA0bC8c028fAfFe&note=https://github.com/Lightcord/Lightcord)
[![LTC](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/papycochob/cryptodonate/master/badges/litecoin.json&style=flat-square)](https://papycochon.github.io/cryptodonate/ltc.html?address=LNTmfMjHJgTHaB7rj8ZuWWuU1XkP2YeGCA&note=https://github.com/Lightcord/Lightcord)
# Lightcord has been abandoned and no longer receives support or updates!
# About
## What's this ?
[Lightcord](https://lightcord.org) is a simple and customizable client for Discord.
It includes [BandagedBD](https://github.com/rauenzi/BetterDiscordApp), [Glasstron](https://github.com/AryToNeX/Glasstron) and a [discord.js-like api](https://github.com/Lightcord/Lightcord/tree/master/DiscordJS).
## Informations
Lightcord doesn't *patch* Discord with it's content. If it was, Discord could update itself and break the patch. That's why Lightcord is a standalone Discord client. Just grab the latest release version you need, and launch it !
# Features
## Installing
You can download a release from the [releases tab](https://github.com/Lightcord/Lightcord/releases).
* **Standalone client** - Lightcord is built to be standalone i.e. it will not break on Discord updates!
* **BetterDiscord built in** - Use almost any BetterDiscord plugin or theme!
* **Easy custom rich presence** - Our method of doing this ensures you won't get banned!
* **Made for Privacy** - Lightcord automatically blocks Discord's trackers and blurs your email, keeping your data safe!
* **Free Emotes** - Send any emote to other Lightcord users!
* **Token Login** - (user/bot) [Make **server** calls with bots]
* **AdBlock** - Automatically block bots and ads in your DMs!
* **Always On Top** - Lightcord will always be shown in front of any other windows!
* **Experiments** - Access Discord's hidden experiments with a single click!
* **Tabs** - Have multiple tabs open to do more!
* **HypeSquad Housing** - Easily change your HypeSquad house, no test required!
* **Badges** - Important people like the developers have special badges to make sure you know who is who!
## Running from source
Prequeresites: Node.js, NPM
## Planned Features
Lightcord is no longer updated
# Installing
## Windows
You can install Lightcord with [scoop](https://github.com/lukesampson/scoop).
```powershell
scoop bucket add extras
scoop install lightcord
```
Alternatively, download the installer from the [releases tab](https://github.com/Lightcord/Lightcord/releases).
## Linux (and ChromeOS)
[This part has moved!](https://github.com/Lightcord/lc-installer-linux)
# Running From Source
Prerequisites: [Node.js](https://nodejs.org/en/) and NPM
To run from source, follow these instructions:
```sh
```bash
git clone https://github.com/Lightcord/Lightcord
cd Lightcord
npm run devInstall
npm test
```
*You will have to do that everytime you pull/clone*
<br/>
Lightcord will launch next. You can see you have done it right by looking at the icon.
*You will have to do that every time you pull/clone*
Lightcord will then launch. If you see the Lightcord icon, you're good to go!
![icon](https://github.com/Lightcord/Lightcord/blob/master/imagery/68747470733a2f2f692e696d6775722e636f6d2f72486e73504e4f2e706e67.png?raw=true)
<br />
Then everytime you want to launch it just type in
```sh
npm run run
Any time you want to launch, just run:
```bash
npm start
```
*You can install on GNU/Linux with our install script or the AUR*
## AUR (unofficial)
You need to install the `base-devel` and `git` packages first
**For compilation** https://aur.archlinux.org/packages/lightcord-git/
`git clone https://aur.archlinux.org/lightcord-git.git && cd lightcord-git && makepkg -si`
**For precomiled binaries** https://aur.archlinux.org/packages/lightcord-bin/
`git clone https://aur.archlinux.org/lightcord-bin.git && cd lightcord-bin && makepkg -si`
**For AppImage**
`git clone https://aur.archlinux.org/lightcord-appimage.git && cd lightcord-appimage && makepkg -si`
An AUR helped such as `yay` can also be used
## Other linux distribution
You can also install it via this install script. It will automatically :
- Download the latest Lightcord stable release from the official dev server.
- Extract its file, and rename it to a more conventional ¨Lightcord¨ folder.
- Install the Lightcord files in /opt/.
- Add execution rights to the Lightcord executable to be able to launch it.
- Download an apropriate .desktop file and install it in /usr/share/applications.
- Add executions rights to the .desktop file to be able to launch Lightcord from it.
- Download the Lightcord icon in an .svg format, and will install it in /usr/share/pixmaps.
## One-liner install script
**For installation**
*Please install the "unzip" package before executing this script as this script depends on it.*
- Run `rm -f Lightcord_installer.sh && wget https://raw.githubusercontent.com/Lightcord/Lightcord/master/Lightcord_installer.sh && clear && sudo bash Lightcord_installer.sh && rm -f Lightcord_installer.sh`
**For AppImage**
- Run `wget https://raw.githubusercontent.com/Lightcord/Lightcord/master/appimage_installer.sh && bash appimage_install.sh`
## Features
* **BetterDiscord** Themes/Plugins
* **Native** Custom RPC (No ban chance)
* Blocking Discord's **trackers**
* **Free emotes** (normal emotes) to use everywhere for Lightcord users
* **Login with token** (user/bot) [Make **server** calls with bots]
* DM Adverts blocker (**AdBlock**) [Even in embeds]
* File certification/approval (tells you if a **file is safe or not**)
* Prevent **malicious** plugins [File scanner]
* **Always-On-Top** feature (great to chat while coding)
* Hide sensitive informations (blurry e-mail)
* Great scripting API
* Account information section
* Developer mode / experiments (get discord features before anyone else without updating)
* Experimental tabs
* Select your HypeSquad (manually/without doing the quizz)
* Badges (Lightcord owners have badges so you know who to trust)
### Soon
* Username history
* Custom BetterDiscord location (custom themes/plugins location) [more portability]
## BetterDiscord
BetterDiscord (BandagedBD) is already installed (modified version).
You can go into your settings to manage plugins.
Because it's more painful than anything else, global emotes are not supported on Lightcord. They have been removed.
The freeze caused by the emotes downloading at startup was annoying. So we removed them.
## Plugins & Themes
Plugins and themes are not in the standard BetterDiscord folder. They have been moved because betterdiscord supports only stable, ptb and canary release. Using the same directory could cause problems with settings.
They are located in `%AppData%/Lightcord_BD`. This is the main folder for BetterDiscord.

View File

@ -1,97 +0,0 @@
#!/bin/bash
# Original script by https://github.com/GermanBread
appimage='https://lightcord.org/api/gh/releases/Lightcord/Lightcord/dev/lightcord-linux-x86_64.AppImage'
icon='https://raw.githubusercontent.com/Lightcord/Lightcord/master/discord.png'
if [[ $TERM == dumb ]]; then
exit;
fi
if [[ $(whoami) = "root" ]] ; then
printf "[$(tput setaf 9 && tput blink)PANIC$(tput sgr0)] $(tput setaf 9)Do not run this script as root!$(tput sgr0)\n";
exit;
fi
tput setaf 208
cat << "EOF"
_ _ _ _ _
| | (_)__ _| |_| |_ __ ___ _ _ __| |
| |__| / _` | ' \ _/ _/ _ \ '_/ _` |
|____|_\__, |_||_\__\__\___/_| \__,_|
|___/
AppImage Installer and Updater
EOF
tput sgr0
printf "Please select\n";
printf "1: Install Lightcord\n";
printf "2: Uninstall Lightcord\n";
printf "3: Update Lightcord\n"
printf "\n";
while ! [[ $selection =~ ^[0-9]+$ ]];
do
read selection;
#if the entered value was not an integer, show this
if ! [[ $selection =~ ^[0-9]+$ ]]; then
sleep 1;
printf "$(tput setaf 9)Please try again$(tput sgr0)\n";
printf "1: Install Lightcord\n";
printf "2: Uninstall Lightcord\n";
printf "3: Update Lightcord\n"
printf "\n";
fi
done
case $selection in
1)
printf "[$(tput setaf 12 && tput blink)INFO$(tput sgr0)] $(tput setaf 12)Installing Lightcord$(tput sgr0)\n";
printf "[$(tput setaf 12 && tput blink)INFO$(tput sgr0)] $(tput setaf 7)Downloading Lightcord$(tput sgr0)\n";
wget -O lightcord.AppImage $appimage;
printf "[$(tput setaf 12 && tput blink)INFO$(tput sgr0)] $(tput setaf 7)Downloading Icon$(tput sgr0)\n";
wget -O lightcord.png $icon;
printf "[$(tput setaf 12 && tput blink)INFO$(tput sgr0)] $(tput setaf 7)Moving Lightcord AppImage to ~/.lightcord$(tput sgr0)\n";
mkdir -p ~/.lightcord;
mv lightcord.AppImage ~/.lightcord;
printf "[$(tput setaf 12 && tput blink)INFO$(tput sgr0)] $(tput setaf 7)Setting Executable Permissions$(tput sgr0)\n";
chmod +x ~/.lightcord/lightcord.AppImage ;
printf "[$(tput setaf 12 && tput blink)INFO$(tput sgr0)] $(tput setaf 7)Installing Icon$(tput sgr0)\n";
mv lightcord.png ~/.local/share/icons/hicolor/512x512/apps;
printf "[$(tput setaf 12 && tput blink)INFO$(tput sgr0)] $(tput setaf 7)Installing Desktop File$(tput sgr0)\n";
echo -e "[Desktop Entry]\nName=Lightcord\nComment[fr_FR]=Un client Discord simple et personalisable\nComment=A simple - customizable - Discord Client\nExec=${HOME}/.lightcord/lightcord.AppImage\nIcon=lightcord\nTerminal=false\nType=Application\nCategories=Network;InstantMessaging;P2P;" >> ~/.local/share/applications/lightcord.desktop;
;;
2)
printf "[$(tput setaf 12 && tput blink)INFO$(tput sgr0)] $(tput setaf 12)Deleting Lightcord AppImage$(tput sgr0)\n";
rm -rf ~/.lightcord;
printf "[$(tput setaf 12 && tput blink)INFO$(tput sgr0)] $(tput setaf 12)Deleting Icon$(tput sgr0)\n";
rm ~/.local/share/icons/hicolor/512x512/apps/lightcord.png;
printf "[$(tput setaf 12 && tput blink)INFO$(tput sgr0)] $(tput setaf 12)Deleting Desktop File$(tput sgr0)\n";
rm ~/.local/share/applications/lightcord.desktop;
printf "[$(tput setaf 10 && tput blink)FINISH$(tput sgr0)] Uninstall complete\n";
;;
3)
#Uninstall
printf "[$(tput setaf 12 && tput blink)INFO$(tput sgr0)] $(tput setaf 12)Updating Lightcord$(tput sgr0)\n";
printf "[$(tput setaf 12 && tput blink)INFO$(tput sgr0)] $(tput setaf 12)Deleting Lightcord AppImage$(tput sgr0)\n";
rm -f ~/.lightcord/lightcord.AppImage;
#Install
printf "[$(tput setaf 12 && tput blink)INFO$(tput sgr0)] $(tput setaf 7)Downloading Lightcord$(tput sgr0)\n";
wget -O lightcord.AppImage $appimage;
printf "[$(tput setaf 12 && tput blink)INFO$(tput sgr0)] $(tput setaf 7)Moving Lightcord AppImage to ~/.lightcord$(tput sgr0)\n";
mkdir -p ~/.lightcord;
mv lightcord.AppImage ~/.lightcord;
printf "[$(tput setaf 12 && tput blink)INFO$(tput sgr0)] $(tput setaf 7)Setting Executable Permissions$(tput sgr0)\n";
chmod +x ~/.lightcord/lightcord.AppImage ;
printf "[$(tput setaf 10 && tput blink)FINISH$(tput sgr0)] Update complete\n";
;;
*)
printf "[$(tput setaf 12 && tput blink)INFO$(tput sgr0)] $(tput setaf 12)Exiting script$(tput sgr0)\n";
;;
esac

View File

@ -35,9 +35,9 @@ linux:
- target: zip
arch:
- x64
# - target: AppImage
# arch:
# - x64
- target: AppImage
arch:
- x64
icon: discord.png
files:
- "**/*"
@ -50,7 +50,7 @@ linux:
- "**/*_linux.node"
- "**/*.so.4"
mac:
artifactName: ${name}-darwin-${arch}.${ext}
artifactName: ${name}-darwin-x64.${ext}
target:
- target: zip
arch:

View File

@ -1,83 +0,0 @@
.theme-dark {
--header-primary: #fff;
--header-secondary: #b9bbbe;
--text-normal: #dcddde;
--text-muted: #72767d;
--text-link: #00b0f4;
--channels-default: #8e9297;
--interactive-normal: #b9bbbe;
--interactive-hover: #dcddde;
--interactive-active: #fff;
--interactive-muted: #4f545c;
--background-primary: #36393f;
--background-secondary: #2f3136;
--background-secondary-alt: #292b2f;
--background-tertiary: #202225;
--background-accent: #4f545c;
--background-floating: #18191c;
--background-mobile-primary: #36393f;
--background-mobile-secondary: #2f3136;
--background-modifier-hover: rgba(79,84,92,0.16);
--background-modifier-active: rgba(79,84,92,0.24);
--background-modifier-selected: rgba(79,84,92,0.32);
--background-modifier-accent: hsla(0,0%,100%,0.06);
--background-mentioned: rgba(250,166,26,0.05);
--background-mentioned-hover: rgba(250,166,26,0.08);
--background-message-hover: rgba(4,4,5,0.07);
--elevation-stroke: 0 0 0 1px rgba(4,4,5,0.15);
--elevation-low: 0 1px 0 rgba(4,4,5,0.2),0 1.5px 0 rgba(6,6,7,0.05),0 2px 0 rgba(4,4,5,0.05);
--elevation-medium: 0 4px 4px rgba(0,0,0,0.16);
--elevation-high: 0 8px 16px rgba(0,0,0,0.24);
--logo-primary: #fff;
--focus-primary: #00b0f4;
--guild-header-text-shadow: 0 1px 1px rgba(0,0,0,0.4);
--channeltextarea-background: #40444b;
--activity-card-background: #202225;
--textbox-markdown-syntax: #8e9297;
--deprecated-card-bg: rgba(32,34,37,0.6);
--deprecated-card-editable-bg: rgba(32,34,37,0.3);
--deprecated-store-bg: #36393f;
--deprecated-quickswitcher-input-background: #72767d;
--deprecated-quickswitcher-input-placeholder: hsla(0,0%,100%,0.3);
--deprecated-text-input-bg: rgba(0,0,0,0.1);
--deprecated-text-input-border: rgba(0,0,0,0.3);
--deprecated-text-input-border-hover: #040405;
--deprecated-text-input-border-disabled: #202225;
--deprecated-text-input-prefix: #dcddde;
}
::placeholder, body, button, input, select, textarea {
font-family: Whitney,Helvetica Neue,Helvetica,Arial,sans-serif;
text-rendering: optimizeLegibility;
}.appMount, body {
background-color: var(--background-tertiary);
text-rendering: optimizeLegibility;
}body{
color: var(--text-normal)
}.center{
text-align: center;
}.marginBottom20{
margin-bottom: 20px;
}.button {
position: absolute;
top: 200px;
padding-right: 12.5px;
padding-top: 14px;
background-color: #7289da;
color: #fff;
font-size: 20px;
font-weight: 600;
border-radius: 3px;
justify-content: center;
align-items: center;
padding-bottom: 14px;
padding-left: 12.5px;
display: inline;
}.button:hover{
background-color: #697ec4;
cursor: pointer;
}.button-yes{
left: 100px;
}.button-no{
left: 300px;
}

View File

@ -1,25 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title></title>
<link rel="stylesheet" href="lightcord://index.css">
</head>
<body class="theme-dark">
<div class="appMount">
<div class="marginBottom20">
</div>
<h2 class="center">
Would you like to use Lightcord's network features ?
</h2>
<div class="marginBottom20"></div>
<div class="marginBottom20"></div>
<div class="buttonContainer">
<div class="button button-yes">Yes I do !</div>
<div class="button button-no">No, thanks</div>
</div>
</div>
</body>
</html>

View File

@ -1,63 +0,0 @@
const electron = require("electron").remote
const fetch = require("node-fetch").default
const currentWindow = electron.getCurrentWindow()
currentWindow.webContents.on("dom-ready", () => {
const customTitlebar = require('custom-electron-titlebar')
new customTitlebar.Titlebar({
backgroundColor: customTitlebar.Color.fromHex('#2f3136'),
"drag": true,
minimizable: false,
maximizable: false,
closeable: true,
menu: electron.Menu.buildFromTemplate([])
});
function resetAppMount(){
document.querySelector("body > div.container-after-titlebar > div").remove()
const appMount = document.createElement("div")
appMount.className = "appMount"
document.querySelector("body > div.container-after-titlebar").appendChild(appMount)
}
document.querySelector("body > div.container-after-titlebar > div > div.buttonContainer > div.button.button-yes").addEventListener("click", (ev) => {// should we move location ? or go trough a webview ?
resetAppMount()
const webview = document.createElement("webview")
webview.id = "discordauth"
webview.src = "https://discord.com/api/oauth2/authorize?client_id=711416957718757418&redirect_uri=http%3A%2F%2Flightcord.electron%2Flogin%2Fcallback&response_type=code&scope=identify"
webview.style.width = "500ox"
webview.style.height = "520px"
webview.addEventListener('did-stop-loading', () => {
console.log("Webview loaded")
electron.webContents.fromId(webview.getWebContentsId()).on("will-navigate", (e, url) => {
console.log(url)
if(url.startsWith("http://lightcord.electron/login/callback?error=")){ // used denied / error.
e.preventDefault()
currentWindow.close()
return
}else if(url.startsWith("http://lightcord.electron/login/callback?code=")){ // yay we got the code
const query = url.split("?")[1]
e.preventDefault()
webview.remove()
resetAppMount()
document.querySelector("body > div.container-after-titlebar > div").innerHTML = '<h2 class="center">Loading...</h2>'
fetch("https://lightcord.org/auth/callback?"+query)
.then(async res => {
if(res.status !== 200){ // error
currentWindow.close()
return
}
const resp = await res.text()
console.debug(resp)
window.location.href = "lightcord://login/callback?auth="+resp
})
}
})
})
document.querySelector("body > div.container-after-titlebar > div").appendChild(webview)
})
document.querySelector("body > div.container-after-titlebar > div > div.buttonContainer > div.button.button-no").addEventListener("click", (ev) => {
currentWindow.close()
})
})

View File

@ -7,7 +7,7 @@ const electron = require("electron")
const fetch = require("node-fetch").default
const uuid = require("uuid/v4")
const isPackaged = __filename.includes("app.asar")
const isPackaged = electron.remote.app.isPackaged
const events = exports.events = new EventEmitter()
const logger = exports.logger = new Logger("Lightcord")
@ -20,9 +20,11 @@ const localStorage = window.localStorage
const UserAgent = electron.ipcRenderer.sendSync("LIGHTCORD_GET_USER_AGENT").replace(/lightcord\/[^ ]+/g, "discord/"+require("../discord_native/renderer/app").getVersion())
electron.ipcRenderer.sendSync("LIGHTCORD_SET_USER_AGENT", UserAgent)
exports.init = function(){
exports.init = function({
isTab
}){
if(hasInit == true){
console.warn(new Error("Lightcord has already inited."))
console.warn(new Error("Lightcord has already started."))
return
}
formatLogger.log("The app is", isPackaged ? "packaged." : "not packaged.")
@ -33,6 +35,7 @@ exports.init = function(){
try{
if(!global.webpackJsonp)return
if(isTab && !hasReplacedLocalstorage){
console.log("Replacing localStorage...")
hasReplacedLocalstorage = true
const localstr = require("localstorage-polyfill")
Object.defineProperty(window, "localStorage", {
@ -66,10 +69,10 @@ async function privateInit(){
ModuleLoader.get(e => e.getCurrentHub)[0].getCurrentHub().getClient().getOptions().enabled = false
// setting react in require cache
const React = ModuleLoader.get(e => !["Component", "PureComponent", "Children", "createElement", "cloneElement"].find(k => !e[k]))[0]
const React = await ensureExported(e => !["Component", "PureComponent", "Children", "createElement", "cloneElement"].find(k => !e[k]))
window.React = React
const ReactDOM = ModuleLoader.get(e => e.findDOMNode)[0]
const ReactDOM = await ensureExported(e => e.findDOMNode)
window.ReactDOM = ReactDOM
//stop here if betterdiscord is disabled.
@ -108,7 +111,7 @@ async function privateInit(){
// fix notifications here
let dispatcher = ModuleLoader.get(m=>m.Dispatcher&&m.default&&m.default.dispatch)[0].default
dispatcher.subscribe("USER_SETTINGS_UPDATE", (data) => {
DiscordNative.ipc.send("UPDATE_THEME", data.settings.theme)
ipcRenderer.send("DISCORD_UPDATE_THEME", data.settings.theme)
})
let constants = ModuleLoader.get(m=>m.API_HOST)[0]
@ -153,11 +156,12 @@ async function privateInit(){
return
}
let createSoundOriginal = ModuleLoader.get((e) => e.createSound)[0].createSound
ModuleLoader.get((e) => e.createSound)[0].createSound = function(sound){
let soundModule = await ensureExported((e) => e.createSound)
let createSound = soundModule.createSound
soundModule.createSound = function(sound){
let isCalling = sound === "call_ringing_beat" || sound === "call_ringing"
if(isCalling){
let returned = createSoundOriginal.call(this, ...arguments)
let returned = createSound.call(this, ...arguments)
Object.defineProperty(returned, "name", {
get(){
return window.Lightcord.Settings.callRingingBeat ? "call_ringing_beat" : "call_ringing"
@ -169,7 +173,7 @@ async function privateInit(){
})
return returned
}else{
return createSoundOriginal(...arguments)
return createSound(...arguments)
}
}
@ -187,7 +191,7 @@ async function privateInit(){
return undefined
}
window.$ = window.jQuery = require("./jquery.min.js")
window.$ = window.jQuery = require("./jquery-3.6.0.slim.min.js")
require("./ace.js")
installReactDevtools()
@ -305,7 +309,7 @@ async function privateInit(){
})
dispatcher.subscribe("USER_SETTINGS_UPDATE", (data) => {
DiscordNative.ipc.send("UPDATE_THEME", data.settings.theme)
ipcRenderer.send("DISCORD_UPDATE_THEME", data.settings.theme)
})
require(formatMinified("lightcordapi/js/main{min}.js"))
@ -1171,7 +1175,7 @@ function installReactDevtools(){
require.extensions[".css"] = (m, filename) => {
let content = fs.readFileSync(filename, "binary")
let style = document.createElement("style")
style.id = btoa(filename)
style.id = Buffer.from(filename, "utf8").toString("base64")
style.innerHTML = content
document.head.appendChild(style)
m.exports = {

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,4 +1,4 @@
const ipcRenderer = require("../discord_native/renderer/ipc")
const ipcRenderer = require("electron").ipcRenderer
if(process.platform === "win32"){
@ -98,5 +98,5 @@ let settingStore
ensureExported((e => e.default && e.default.theme))
.then(themeStore => {
settingStore = themeStore
ipcRenderer.send("UPDATE_THEME", themeStore.default.theme)
ipcRenderer.send("DISCORD_UPDATE_THEME", themeStore.default.theme)
}).catch(console.error)

View File

@ -1,4 +1,4 @@
'use strict';
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
@ -6,11 +6,11 @@ Object.defineProperty(exports, "__esModule", {
exports.getEnableHardwareAcceleration = getEnableHardwareAcceleration;
exports.setEnableHardwareAcceleration = setEnableHardwareAcceleration;
var _electron = require('electron');
var _electron = require("electron");
var _appSettings = require('./appSettings');
var _appSettings = require("./appSettings");
const settings = _appSettings.getSettings();
const settings = (0, _appSettings.getSettings)();
function getEnableHardwareAcceleration() {
// TODO: This should probably a constant
@ -22,5 +22,6 @@ function setEnableHardwareAcceleration(enableHardwareAcceleration) {
settings.save();
_electron.app.relaunch();
_electron.app.exit(0);
}

View File

@ -1,31 +1,29 @@
'use strict';
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.hasInit = undefined;
exports.init = init;
exports.hasInit = void 0;
var _electron = require('electron');
var _electron = require("electron");
var _utils = require('./utils');
var _utils = require("./utils");
var _mainScreen = require('./mainScreen');
var _mainScreen = require("./mainScreen");
var _ipcMain = require('./ipcMain');
var _ipcMain2 = _interopRequireDefault(_ipcMain);
var _ipcMain = _interopRequireDefault(require("./ipcMain"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
let hasInit = exports.hasInit = false;
let hasInit = false;
exports.hasInit = hasInit;
let lastIndex;
let appIcons;
/**
* Used on Windows to set the taskbar icon
*/
function init() {
// Only init on win32 platforms
if (process.platform !== 'win32') return;
@ -34,26 +32,27 @@ function init() {
console.warn('appBadge: Has already init! Cancelling init.');
return;
}
exports.hasInit = hasInit = true;
exports.hasInit = hasInit = true;
lastIndex = null;
appIcons = [];
const resourcePath = `app/images/badges`;
for (let i = 1; i <= 11; i++) {
appIcons.push(_utils.exposeModuleResource(resourcePath, `badge-${i}.ico`));
appIcons.push((0, _utils.exposeModuleResource)(resourcePath, `badge-${i}.ico`));
}
_ipcMain2.default.on('APP_BADGE_SET', (_event, count) => setAppBadge(count));
_ipcMain.default.on('APP_BADGE_SET', (_event, count) => setAppBadge(count));
}
function setAppBadge(count) {
const win = _electron.BrowserWindow.fromId((0, _mainScreen.getMainWindowId)());
const { index, description } = getOverlayIconData(count);
const {
index,
description
} = getOverlayIconData(count); // Prevent setting a new icon when the icon is the same
// Prevent setting a new icon when the icon is the same
if (lastIndex !== index) {
if (index == null) {
win.setOverlayIcon(null, description);
@ -64,32 +63,36 @@ function setAppBadge(count) {
lastIndex = index;
}
}
/*
* -1 is bullet
* 0 is nothing
* 1-9 is a number badge
* 10+ is `9+`
*/
function getOverlayIconData(count) {
// Unread message badge
if (count === -1) {
return {
index: 10, // this.appIcons.length - 1
index: 10,
// this.appIcons.length - 1
description: `Unread messages`
};
}
} // Clear overlay icon
// Clear overlay icon
if (count === 0) {
return {
index: null, // null is used to clear the overlay icon
index: null,
// null is used to clear the overlay icon
description: 'No Notifications'
};
}
} // Notification badge
// Notification badge
const index = Math.max(1, Math.min(count, 10)) - 1; // arrays are 0 based
return {
index,
description: `${index} notifications`

View File

@ -1,4 +1,4 @@
'use strict';
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
@ -6,16 +6,14 @@ Object.defineProperty(exports, "__esModule", {
exports.init = init;
exports.getFeatures = getFeatures;
var _FeatureFlags = require('../common/FeatureFlags');
var _FeatureFlags2 = _interopRequireDefault(_FeatureFlags);
var _FeatureFlags = _interopRequireDefault(require("../common/FeatureFlags"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
let features;
function init() {
features = new _FeatureFlags2.default();
features = new _FeatureFlags.default();
}
function getFeatures() {

View File

@ -1,3 +1,3 @@
'use strict';
"use strict";
module.exports = require('./bootstrapModules').appSettings;

View File

@ -1,44 +1,54 @@
'use strict';
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _electron = require('electron');
var _electron = require("electron");
var _Constants = require('../Constants');
var _securityUtils = require("../../common/securityUtils");
var Constants = _interopRequireWildcard(_Constants);
var Constants = _interopRequireWildcard(require("../Constants"));
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
const { MenuEvents } = Constants;
const SEPARATOR = { type: 'separator' };
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
const {
MenuEvents
} = Constants;
const SEPARATOR = {
type: 'separator'
};
function getWindow() {
let window = _electron.BrowserWindow.getFocusedWindow();
if (!window) {
const windowList = _electron.BrowserWindow.getAllWindows();
if (windowList && windowList[0]) {
window = windowList[0];
window.show();
window.focus();
}
}
return window;
}
exports.default = [{
var _default = [{
label: 'Lightcord',
submenu: [{
label: 'About Lightcord',
label: 'About Discord',
selector: 'orderFrontStandardAboutPanel:'
}, {
label: 'Check for Updates...',
click: () => _electron.app.emit(MenuEvents.CHECK_FOR_UPDATES)
}, {
label: 'Acknowledgements',
click: () => _electron.shell.openExternal('https://discord.com/acknowledgements')
click: () => (0, _securityUtils.saferShellOpenExternal)('https://discord.com/acknowledgements')
}, SEPARATOR, {
label: 'Preferences',
click: () => _electron.app.emit(MenuEvents.OPEN_SETTINGS),
@ -89,6 +99,7 @@ exports.default = [{
label: 'Reload',
click: () => {
const window = getWindow();
if (window) {
window.webContents.reloadIgnoringCache();
}
@ -98,6 +109,7 @@ exports.default = [{
label: 'Toggle Full Screen',
click: () => {
const window = getWindow();
if (window) {
window.setFullScreen(!window.isFullScreen());
}
@ -109,6 +121,7 @@ exports.default = [{
label: 'Toggle Developer Tools',
click: () => {
const window = getWindow();
if (window) {
window.toggleDevTools();
}
@ -128,7 +141,14 @@ exports.default = [{
}, {
label: 'Close',
accelerator: 'Command+W',
selector: 'hide:'
click: (_, window) => {
// Main window
if (window == null || window.windowKey == null) {
_electron.Menu.sendActionToFirstResponder('hide:');
} else {
window.close();
}
}
}, SEPARATOR, {
label: 'Bring All to Front',
selector: 'arrangeInFront:'
@ -136,8 +156,9 @@ exports.default = [{
}, {
label: 'Help',
submenu: [{
label: 'Lightcord Help',
label: 'Discord Help',
click: () => _electron.app.emit(MenuEvents.OPEN_HELP)
}]
}];
exports.default = _default;
module.exports = exports.default;

View File

@ -1,12 +1,13 @@
'use strict';
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _electron = require('electron');
exports.default = void 0;
const menu = require('./' + process.platform);
exports.default = menu
var _default = menu
exports.default = _default;
module.exports = exports.default;

View File

@ -1,21 +1,25 @@
'use strict';
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _electron = require('electron');
var _electron = require("electron");
var _Constants = require('../Constants');
var Constants = _interopRequireWildcard(require("../Constants"));
var Constants = _interopRequireWildcard(_Constants);
function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
const { MenuEvents } = Constants;
const SEPARATOR = { type: 'separator' };
exports.default = [{
const {
MenuEvents
} = Constants;
const SEPARATOR = {
type: 'separator'
};
var _default = [{
label: '&File',
submenu: [{
label: '&Options',
@ -71,8 +75,9 @@ exports.default = [{
label: 'Check for Updates',
click: () => _electron.app.emit(MenuEvents.CHECK_FOR_UPDATES)
}, SEPARATOR, {
label: 'Lightcord Help',
label: 'Discord Help',
click: () => _electron.app.emit(MenuEvents.OPEN_HELP)
}]
}];
exports.default = _default;
module.exports = exports.default;

View File

@ -1,21 +1,25 @@
'use strict';
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _electron = require('electron');
var _electron = require("electron");
var _Constants = require('../Constants');
var Constants = _interopRequireWildcard(require("../Constants"));
var Constants = _interopRequireWildcard(_Constants);
function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
const { MenuEvents } = Constants;
const SEPARATOR = { type: 'separator' };
exports.default = [{
const {
MenuEvents
} = Constants;
const SEPARATOR = {
type: 'separator'
};
var _default = [{
label: '&File',
submenu: [{
label: '&Options',
@ -50,8 +54,9 @@ exports.default = [{
label: 'Check for Updates',
click: () => _electron.app.emit(MenuEvents.CHECK_FOR_UPDATES)
}, SEPARATOR, {
label: 'Lightcord Help',
label: 'Discord Help',
click: () => _electron.app.emit(MenuEvents.OPEN_HELP)
}]
}];
exports.default = _default;
module.exports = exports.default;

View File

@ -1,3 +1,3 @@
'use strict';
"use strict";
module.exports = require('./bootstrapModules').autoStart;

View File

@ -6,8 +6,10 @@ exports.init = function (bootstrapModules) {
if (hasInit) {
throw new Error(`bootstrapModules has already init`);
}
for (const mod of Object.keys(bootstrapModules)) {
exports[mod] = bootstrapModules[mod];
}
hasInit = true;
};

View File

@ -1,3 +1,3 @@
'use strict';
"use strict";
module.exports = require('./bootstrapModules').buildInfo;

View File

@ -0,0 +1,5 @@
"use strict";
const bootstrapCrashReporterSetup = require('./bootstrapModules').crashReporterSetup;
module.exports = bootstrapCrashReporterSetup != null ? bootstrapCrashReporterSetup : require('../common/crashReporterSetup');

View File

@ -1,17 +1,11 @@
'use strict';
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
"use strict";
const electron = require('electron');
const { ACCESSIBILITY_GET_ENABLED } = require('../common/constants').IPCEvents;
const {
ACCESSIBILITY_GET_ENABLED
} = require('../common/constants').IPCEvents;
electron.ipcMain.handle(ACCESSIBILITY_GET_ENABLED, (() => {
var _ref = _asyncToGenerator(function* (_) {
return electron.app.accessibilitySupportEnabled;
});
return function (_x) {
return _ref.apply(this, arguments);
};
})());
electron.ipcMain.handle(ACCESSIBILITY_GET_ENABLED, async _ => {
return electron.app.accessibilitySupportEnabled;
});

View File

@ -1,12 +1,11 @@
'use strict';
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.injectBuildInfo = injectBuildInfo;
exports.injectModuleUpdater = injectModuleUpdater;
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
exports.injectUpdater = injectUpdater;
const electron = require('electron');
@ -25,6 +24,7 @@ const {
let injectedBuildInfo = null;
let injectedModuleUpdater = null;
let injectedUpdater = null;
function injectBuildInfo(buildInfo) {
injectedBuildInfo = buildInfo;
@ -34,110 +34,67 @@ function injectModuleUpdater(moduleUpdater) {
injectedModuleUpdater = moduleUpdater;
}
function injectUpdater(updater) {
injectedUpdater = updater;
}
electron.ipcMain.on(APP_GET_RELEASE_CHANNEL_SYNC, event => {
event.returnValue = injectedBuildInfo.releaseChannel;
});
electron.ipcMain.on(APP_GET_HOST_VERSION_SYNC, event => {
// hardcode because Discord could identify Lightcord or could simply bug.
if(process.platform === "darwin")
event.returnValue = "0.0.259";
else if(process.platform === "linux")
event.returnValue = "0.0.12";
else
event.returnValue = "0.0.308"; //electron.app.getVersion();
event.returnValue = electron.app.getVersion();
});
electron.ipcMain.handle(APP_GET_MODULE_VERSIONS, (() => {
var _ref = _asyncToGenerator(function* (_) {
const versions = {};
const installed = injectedModuleUpdater != null ? injectedModuleUpdater.getInstalled() : {};
for (const name of Object.keys(installed)) {
versions[name] = installed[name].installedVersion;
}
return versions;
});
async function newUpdaterGetModuleVersions(updater) {
// eslint-disable-next-line camelcase
return (await updater.queryCurrentVersions()).current_modules;
}
return function (_x) {
return _ref.apply(this, arguments);
};
})());
electron.ipcMain.handle(APP_GET_MODULE_VERSIONS, async _ => {
var _injectedUpdater;
electron.ipcMain.handle(APP_GET_PATH, (() => {
var _ref2 = _asyncToGenerator(function* (_, path) {
return electron.app.getPath(path);
});
const newUpdater = (_injectedUpdater = injectedUpdater) === null || _injectedUpdater === void 0 ? void 0 : _injectedUpdater.getUpdater();
return function (_x2, _x3) {
return _ref2.apply(this, arguments);
};
})());
if (newUpdater != null) {
return newUpdaterGetModuleVersions(newUpdater);
}
electron.ipcMain.handle(APP_SET_BADGE_COUNT, (() => {
var _ref3 = _asyncToGenerator(function* (_, count) {
electron.app.setBadgeCount(count);
});
const versions = {};
const installed = injectedModuleUpdater != null ? injectedModuleUpdater.getInstalled() : {};
return function (_x4, _x5) {
return _ref3.apply(this, arguments);
};
})());
for (const name of Object.keys(installed)) {
versions[name] = installed[name].installedVersion;
}
electron.ipcMain.handle(APP_DOCK_SET_BADGE, (() => {
var _ref4 = _asyncToGenerator(function* (_, badge) {
if (electron.app.dock != null) {
electron.app.dock.setBadge(badge);
}
});
return function (_x6, _x7) {
return _ref4.apply(this, arguments);
};
})());
electron.ipcMain.handle(APP_DOCK_BOUNCE, (() => {
var _ref5 = _asyncToGenerator(function* (_, type) {
if (electron.app.dock != null) {
return electron.app.dock.bounce(type);
} else {
return -1;
}
});
return function (_x8, _x9) {
return _ref5.apply(this, arguments);
};
})());
electron.ipcMain.handle(APP_DOCK_CANCEL_BOUNCE, (() => {
var _ref6 = _asyncToGenerator(function* (_, id) {
if (electron.app.dock != null) {
electron.app.dock.cancelBounce(id);
}
});
return function (_x10, _x11) {
return _ref6.apply(this, arguments);
};
})());
electron.ipcMain.handle(APP_RELAUNCH, (() => {
var _ref7 = _asyncToGenerator(function* (_) {
electron.app.relaunch();
electron.app.exit(0);
});
return function (_x12) {
return _ref7.apply(this, arguments);
};
})());
electron.ipcMain.handle(APP_GET_DEFAULT_DOUBLE_CLICK_ACTION, (() => {
var _ref8 = _asyncToGenerator(function* (_) {
return electron.systemPreferences.getUserDefault('AppleActionOnDoubleClick', 'string');
});
return function (_x13) {
return _ref8.apply(this, arguments);
};
})());
return versions;
});
electron.ipcMain.handle(APP_GET_PATH, async (_, path) => {
return electron.app.getPath(path);
});
electron.ipcMain.handle(APP_SET_BADGE_COUNT, async (_, count) => {
electron.app.setBadgeCount(count);
});
electron.ipcMain.handle(APP_DOCK_SET_BADGE, async (_, badge) => {
if (electron.app.dock != null) {
electron.app.dock.setBadge(badge);
}
});
electron.ipcMain.handle(APP_DOCK_BOUNCE, async (_, type) => {
if (electron.app.dock != null) {
return electron.app.dock.bounce(type);
} else {
return -1;
}
});
electron.ipcMain.handle(APP_DOCK_CANCEL_BOUNCE, async (_, id) => {
if (electron.app.dock != null) {
electron.app.dock.cancelBounce(id);
}
});
electron.ipcMain.handle(APP_RELAUNCH, async _ => {
electron.app.relaunch();
electron.app.exit(0);
});
electron.ipcMain.handle(APP_GET_DEFAULT_DOUBLE_CLICK_ACTION, async _ => {
return electron.systemPreferences.getUserDefault('AppleActionOnDoubleClick', 'string');
});

View File

@ -1,37 +1,19 @@
'use strict';
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
"use strict";
const electron = require('electron');
const { CLIPBOARD_COPY, CLIPBOARD_CUT, CLIPBOARD_PASTE } = require('../common/constants').IPCEvents;
const {
CLIPBOARD_COPY,
CLIPBOARD_CUT,
CLIPBOARD_PASTE
} = require('../common/constants').IPCEvents;
electron.ipcMain.handle(CLIPBOARD_COPY, (() => {
var _ref = _asyncToGenerator(function* (_) {
electron.webContents.getFocusedWebContents().copy();
});
return function (_x) {
return _ref.apply(this, arguments);
};
})());
electron.ipcMain.handle(CLIPBOARD_CUT, (() => {
var _ref2 = _asyncToGenerator(function* (_) {
electron.webContents.getFocusedWebContents().cut();
});
return function (_x2) {
return _ref2.apply(this, arguments);
};
})());
electron.ipcMain.handle(CLIPBOARD_PASTE, (() => {
var _ref3 = _asyncToGenerator(function* (_) {
electron.webContents.getFocusedWebContents().paste();
});
return function (_x3) {
return _ref3.apply(this, arguments);
};
})());
electron.ipcMain.handle(CLIPBOARD_COPY, async _ => {
electron.webContents.getFocusedWebContents().copy();
});
electron.ipcMain.handle(CLIPBOARD_CUT, async _ => {
electron.webContents.getFocusedWebContents().cut();
});
electron.ipcMain.handle(CLIPBOARD_PASTE, async _ => {
electron.webContents.getFocusedWebContents().paste();
});

View File

@ -0,0 +1,28 @@
"use strict";
const electron = require('electron');
const {
CONSTANTS_GET
} = require('../common/constants').IPCEvents;
const {
APP_NAME,
APP_ID,
API_ENDPOINT,
UPDATE_ENDPOINT
} = require('../../Constants');
const exposedConstants = {
APP_NAME,
APP_ID,
API_ENDPOINT,
UPDATE_ENDPOINT
};
electron.ipcMain.handle(CONSTANTS_GET, async (_, name) => {
if (!exposedConstants.hasOwnProperty(name)) {
return undefined;
}
return exposedConstants[name];
});

View File

@ -1,77 +1,38 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.injectBuildInfo = injectBuildInfo;
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
"use strict";
const electron = require('electron');
const lodash = require('lodash');
const childProcess = require('child_process');
const { getElectronMajorVersion, flatten, reconcileCrashReporterMetadata } = require('../common/utility');
const { CRASH_REPORTER_UPDATE_METADATA } = require('../common/constants').IPCEvents;
const {
reconcileCrashReporterMetadata
} = require('../../../common/crashReporterUtils');
const metadata = exports.metadata = {};
const {
getElectronMajorVersion
} = require('../../../common/processUtils');
function injectBuildInfo(buildInfo) {
metadata['channel'] = buildInfo.releaseChannel;
const sentryMetadata = metadata['sentry'] != null ? metadata['sentry'] : {};
sentryMetadata['environment'] = buildInfo.releaseChannel;
sentryMetadata['release'] = buildInfo.version;
metadata['sentry'] = sentryMetadata;
}
const {
metadata
} = require('../../crashReporterSetup');
if (process.platform === 'linux') {
const XDG_CURRENT_DESKTOP = process.env.XDG_CURRENT_DESKTOP || 'unknown';
const GDMSESSION = process.env.GDMSESSION || 'unknown';
metadata['wm'] = `${XDG_CURRENT_DESKTOP},${GDMSESSION}`;
try {
metadata['distro'] = childProcess.execFileSync('lsb_release', ['-ds'], { timeout: 100, maxBuffer: 512, encoding: 'utf-8' }).trim();
} catch (_) {} // just in case lsb_release doesn't exist
}
const {
CRASH_REPORTER_UPDATE_METADATA
} = require('../common/constants').IPCEvents;
function getCrashReporterArgs(metadata) {
// NB: we need to flatten the metadata because modern electron caps metadata values at 127 bytes,
// which our sentry subobject can easily exceed.
let flat_metadata = flatten(metadata);
electron.ipcMain.handle(CRASH_REPORTER_UPDATE_METADATA, async (_, additional_metadata) => {
const final_metadata = lodash.defaultsDeep({}, metadata, additional_metadata || {});
const result = {
metadata: final_metadata
}; // In Electron 9 we only start the crashReporter once and let reconcileCrashReporterMetadata
// do the work of keeping `extra` up-to-date. Prior to this we would simply start crashReporter
// again to apply new metadata as well as pass the full arguments back to the renderer so it
// could do similarly.
return {
productName: 'Discord',
companyName: 'Discord Inc.',
submitURL: 'https://sentry.io/api/146342/minidump/?sentry_key=384ce4413de74fe0be270abe03b2b35a',
uploadToServer: false,
ignoreSystemCrashHandler: false,
extra: flat_metadata
};
}
if (getElectronMajorVersion() < 9) {
const args = getCrashReporterArgs(final_metadata);
result.args = args;
}
//electron.crashReporter.start(getCrashReporterArgs(metadata));
electron.ipcMain.handle(CRASH_REPORTER_UPDATE_METADATA, (() => {
var _ref = _asyncToGenerator(function* (_, additional_metadata) {
const final_metadata = lodash.defaultsDeep({}, metadata, additional_metadata || {});
const result = {
metadata: final_metadata
};
// In Electron 9 we only start the crashReporter once and let reconcileCrashReporterMetadata
// do the work of keeping `extra` up-to-date. Prior to this we would simply start crashReporter
// again to apply new metadata as well as pass the full arguments back to the renderer so it
// could do similarly.
if (getElectronMajorVersion() < 9) {
const args = getCrashReporterArgs(final_metadata);
//electron.crashReporter.start(args);
result.args = args;
}
reconcileCrashReporterMetadata(electron.crashReporter, final_metadata);
return result;
});
return function (_x, _x2) {
return _ref.apply(this, arguments);
};
})());
return result;
});

View File

@ -1,12 +1,15 @@
'use strict';
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.injectFeaturesBackend = injectFeaturesBackend;
const electron = require('electron');
const { FEATURES_GET_BROWSER_FEATURES } = require('../common/constants').IPCEvents;
const {
FEATURES_GET_BROWSER_FEATURES
} = require('../common/constants').IPCEvents;
let injectedFeatures = null;

View File

@ -1,52 +1,27 @@
'use strict';
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
"use strict";
const electron = require('electron');
const {
FILE_MANAGER_GET_MODULE_PATH,
FILE_MANAGER_GET_MODULE_DATA_PATH_SYNC,
FILE_MANAGER_SHOW_SAVE_DIALOG,
FILE_MANAGER_SHOW_OPEN_DIALOG,
FILE_MANAGER_SHOW_ITEM_IN_FOLDER
} = require('../common/constants').IPCEvents;
electron.ipcMain.handle(FILE_MANAGER_GET_MODULE_PATH, (() => {
var _ref = _asyncToGenerator(function* (_) {
return global.modulePath;
});
return function (_x) {
return _ref.apply(this, arguments);
};
})());
electron.ipcMain.handle(FILE_MANAGER_SHOW_SAVE_DIALOG, (() => {
var _ref2 = _asyncToGenerator(function* (_, dialogOptions) {
return yield electron.dialog.showSaveDialog(dialogOptions);
});
return function (_x2, _x3) {
return _ref2.apply(this, arguments);
};
})());
electron.ipcMain.handle(FILE_MANAGER_SHOW_OPEN_DIALOG, (() => {
var _ref3 = _asyncToGenerator(function* (_, dialogOptions) {
return yield electron.dialog.showOpenDialog(dialogOptions);
});
return function (_x4, _x5) {
return _ref3.apply(this, arguments);
};
})());
electron.ipcMain.handle(FILE_MANAGER_SHOW_ITEM_IN_FOLDER, (() => {
var _ref4 = _asyncToGenerator(function* (_, path) {
electron.shell.showItemInFolder(path);
});
return function (_x6, _x7) {
return _ref4.apply(this, arguments);
};
})());
electron.ipcMain.handle(FILE_MANAGER_GET_MODULE_PATH, async _ => {
return global.moduleDataPath || global.modulePath;
});
electron.ipcMain.handle(FILE_MANAGER_SHOW_SAVE_DIALOG, async (_, dialogOptions) => {
return await electron.dialog.showSaveDialog(dialogOptions);
});
electron.ipcMain.handle(FILE_MANAGER_SHOW_OPEN_DIALOG, async (_, dialogOptions) => {
return await electron.dialog.showOpenDialog(dialogOptions);
});
electron.ipcMain.handle(FILE_MANAGER_SHOW_ITEM_IN_FOLDER, async (_, path) => {
electron.shell.showItemInFolder(path);
});
electron.ipcMain.on(FILE_MANAGER_GET_MODULE_DATA_PATH_SYNC, event => {
event.returnValue = global.moduleDataPath || global.modulePath;
});

View File

@ -1,12 +1,10 @@
'use strict';
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.injectGpuSettingsBackend = injectGpuSettingsBackend;
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
const electron = require('electron');
const {
@ -20,18 +18,11 @@ function injectGpuSettingsBackend(gpuSettings) {
injectedGpuSettings = gpuSettings;
}
electron.ipcMain.handle(GPU_SETTINGS_SET_ENABLE_HWACCEL, (() => {
var _ref = _asyncToGenerator(function* (_, enable) {
if (injectedGpuSettings) {
injectedGpuSettings.setEnableHardwareAcceleration(enable);
}
});
return function (_x, _x2) {
return _ref.apply(this, arguments);
};
})());
electron.ipcMain.handle(GPU_SETTINGS_SET_ENABLE_HWACCEL, async (_, enable) => {
if (injectedGpuSettings) {
injectedGpuSettings.setEnableHardwareAcceleration(enable);
}
});
electron.ipcMain.on(GPU_SETTINGS_GET_ENABLE_HWACCEL_SYNC, event => {
event.returnValue = injectedGpuSettings != null ? injectedGpuSettings.getEnableHardwareAcceleration() : false;
});

View File

@ -1,23 +1,41 @@
'use strict';
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.injectModuleUpdater = injectModuleUpdater;
exports.injectUpdater = injectUpdater;
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
const childProcess = require('child_process');
const electron = require('electron');
const { once } = require('events');
const { NATIVE_MODULES_GET_PATHS, NATIVE_MODULES_INSTALL } = require('../common/constants').IPCEvents;
const {
once
} = require('events');
const path = require('path');
const process = require('process');
const {
NATIVE_MODULES_GET_PATHS,
NATIVE_MODULES_INSTALL,
NATIVE_MODULES_FINISH_UPDATER_BOOTSTRAP,
NATIVE_MODULES_GET_HAS_NEW_UPDATER
} = require('../common/constants').IPCEvents;
let injectedModuleUpdater = null;
let injectedUpdater = null;
function injectModuleUpdater(moduleUpdater) {
injectedModuleUpdater = moduleUpdater;
}
function injectUpdater(updater) {
injectedUpdater = updater;
}
electron.ipcMain.on(NATIVE_MODULES_GET_PATHS, event => {
event.returnValue = {
mainAppDirname: global.mainAppDirname,
@ -25,33 +43,72 @@ electron.ipcMain.on(NATIVE_MODULES_GET_PATHS, event => {
};
});
electron.ipcMain.handle(NATIVE_MODULES_INSTALL, (() => {
var _ref = _asyncToGenerator(function* (_, moduleName) {
const updater = injectedModuleUpdater;
if (!updater) {
throw new Error('Module updater is not available!');
}
async function newUpdaterInstall(updater, moduleName) {
try {
await updater.installModule(moduleName);
await updater.commitModules();
} catch (e) {
throw new Error(`Failed to install ${moduleName}: ${e}`);
}
}
const waitForInstall = new Promise(function (resolve, reject) {
let installedHandler = function (installedModuleEvent) {
if (installedModuleEvent.name === moduleName) {
updater.events.removeListener(updater.INSTALLED_MODULE, installedHandler);
if (installedModuleEvent.succeeded) {
resolve();
} else {
reject(new Error(`Failed to install ${moduleName}`));
}
electron.ipcMain.handle(NATIVE_MODULES_INSTALL, async (_, moduleName) => {
var _injectedUpdater;
const newUpdater = (_injectedUpdater = injectedUpdater) === null || _injectedUpdater === void 0 ? void 0 : _injectedUpdater.getUpdater();
if (newUpdater != null) {
return newUpdaterInstall(newUpdater, moduleName);
}
const updater = injectedModuleUpdater;
if (!updater) {
throw new Error('Module updater is not available!');
}
const waitForInstall = new Promise((resolve, reject) => {
const installedHandler = installedModuleEvent => {
if (installedModuleEvent.name === moduleName) {
updater.events.removeListener(updater.INSTALLED_MODULE, installedHandler);
if (installedModuleEvent.succeeded) {
resolve();
} else {
reject(new Error(`Failed to install ${moduleName}`));
}
};
}
};
updater.events.on(updater.INSTALLED_MODULE, installedHandler);
});
updater.install(moduleName, false);
yield waitForInstall;
updater.events.on(updater.INSTALLED_MODULE, installedHandler);
});
updater.install(moduleName, false);
await waitForInstall;
});
electron.ipcMain.on(NATIVE_MODULES_GET_HAS_NEW_UPDATER, event => {
var _injectedUpdater2;
return function (_x, _x2) {
return _ref.apply(this, arguments);
};
})());
event.returnValue = ((_injectedUpdater2 = injectedUpdater) === null || _injectedUpdater2 === void 0 ? void 0 : _injectedUpdater2.getUpdater()) != null;
}); // This endpoint is a bit special in the sense that it's exposed from
// discord_updater_bootstrap instead of discord_desktop_core. The reason for
// this is so that a malicious app can't pass in an arbitrary version number to
// launch.
electron.ipcMain.on(NATIVE_MODULES_FINISH_UPDATER_BOOTSTRAP, async (_, [major, minor, revision]) => {
// TODO(eiz): This code is currently duplicated between the updater and here
// due to bootstrapping reasons. I'd like to not have it be that way.
if (typeof major !== 'number' || typeof minor !== 'number' || typeof revision !== 'number') {
throw new Error('You tried.');
}
const hostVersionStr = `${major}.${minor}.${revision}`;
const hostExePath = path.join(path.dirname(process.execPath), '..', `app-${hostVersionStr}`, path.basename(process.execPath));
electron.app.once('will-quit', () => {
childProcess.spawn(hostExePath, [], {
detached: true,
stdio: 'inherit'
});
});
console.log(`Restarting from ${path.resolve(process.execPath)} to ${path.resolve(hostExePath)}`);
electron.app.quit();
});

View File

@ -1,6 +1,4 @@
'use strict';
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
"use strict";
const electron = require('electron');
@ -12,19 +10,14 @@ const {
POWER_MONITOR_GET_SYSTEM_IDLE_TIME
} = require('../common/constants').IPCEvents;
electron.ipcMain.handle(POWER_MONITOR_GET_SYSTEM_IDLE_TIME, (() => {
var _ref = _asyncToGenerator(function* (_) {
return electron.powerMonitor.getSystemIdleTime() * 1000;
});
return function (_x) {
return _ref.apply(this, arguments);
};
})());
electron.ipcMain.handle(POWER_MONITOR_GET_SYSTEM_IDLE_TIME, async _ => {
return electron.powerMonitor.getSystemIdleTime() * 1000;
});
function sendToAllWindows(channel) {
electron.BrowserWindow.getAllWindows().forEach(win => {
const contents = win.webContents;
if (contents != null) {
contents.send(channel);
}
@ -34,15 +27,12 @@ function sendToAllWindows(channel) {
electron.powerMonitor.on('resume', () => {
sendToAllWindows(POWER_MONITOR_RESUME);
});
electron.powerMonitor.on('suspend', () => {
sendToAllWindows(POWER_MONITOR_SUSPEND);
});
electron.powerMonitor.on('lock-screen', () => {
sendToAllWindows(POWER_MONITOR_LOCK_SCREEN);
});
electron.powerMonitor.on('unlock-screen', () => {
sendToAllWindows(POWER_MONITOR_UNLOCK_SCREEN);
});

View File

@ -1,6 +1,4 @@
'use strict';
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
"use strict";
const electron = require('electron');
@ -11,40 +9,20 @@ const {
} = require('../common/constants').IPCEvents;
const powerSaveBlockerIds = new Set();
electron.ipcMain.handle(POWER_SAVE_BLOCKER_BLOCK_DISPLAY_SLEEP, (() => {
var _ref = _asyncToGenerator(function* (_) {
const newId = electron.powerSaveBlocker.start('prevent-display-sleep');
powerSaveBlockerIds.add(newId);
return newId;
});
return function (_x) {
return _ref.apply(this, arguments);
};
})());
electron.ipcMain.handle(POWER_SAVE_BLOCKER_UNBLOCK_DISPLAY_SLEEP, (() => {
var _ref2 = _asyncToGenerator(function* (_, id) {
electron.ipcMain.handle(POWER_SAVE_BLOCKER_BLOCK_DISPLAY_SLEEP, async _ => {
const newId = electron.powerSaveBlocker.start('prevent-display-sleep');
powerSaveBlockerIds.add(newId);
return newId;
});
electron.ipcMain.handle(POWER_SAVE_BLOCKER_UNBLOCK_DISPLAY_SLEEP, async (_, id) => {
electron.powerSaveBlocker.stop(id);
powerSaveBlockerIds.delete(id);
});
electron.ipcMain.handle(POWER_SAVE_BLOCKER_CLEANUP_DISPLAY_SLEEP, async _ => {
// cleanup all previous sleeps
for (const id of powerSaveBlockerIds) {
electron.powerSaveBlocker.stop(id);
powerSaveBlockerIds.delete(id);
});
}
return function (_x2, _x3) {
return _ref2.apply(this, arguments);
};
})());
electron.ipcMain.handle(POWER_SAVE_BLOCKER_CLEANUP_DISPLAY_SLEEP, (() => {
var _ref3 = _asyncToGenerator(function* (_) {
// cleanup all previous sleeps
for (const id of powerSaveBlockerIds) {
electron.powerSaveBlocker.stop(id);
}
powerSaveBlockerIds.clear();
});
return function (_x4) {
return _ref3.apply(this, arguments);
};
})());
powerSaveBlockerIds.clear();
});

View File

@ -1,8 +1,7 @@
'use strict';
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
"use strict";
const electron = require('electron');
const process = require('process');
const {
@ -14,62 +13,29 @@ const {
PROCESS_UTILS_GET_MAIN_ARGV_SYNC
} = require('../common/constants').IPCEvents;
electron.ipcMain.handle(PROCESS_UTILS_GET_CPU_USAGE, (() => {
var _ref = _asyncToGenerator(function* (_) {
let totalProcessorUsagePercent = 0.0;
for (const processMetric of electron.app.getAppMetrics()) {
totalProcessorUsagePercent += processMetric.cpu.percentCPUUsage;
}
return totalProcessorUsagePercent;
});
electron.ipcMain.handle(PROCESS_UTILS_GET_CPU_USAGE, async _ => {
let totalProcessorUsagePercent = 0.0;
return function (_x) {
return _ref.apply(this, arguments);
};
})());
electron.ipcMain.handle(PROCESS_UTILS_GET_MEMORY_INFO, (() => {
var _ref2 = _asyncToGenerator(function* (_) {
return process.getProcessMemoryInfo();
});
return function (_x2) {
return _ref2.apply(this, arguments);
};
})());
electron.ipcMain.handle(PROCESS_UTILS_FLUSH_DNS_CACHE, (() => {
var _ref3 = _asyncToGenerator(function* (_) {
const defaultSession = electron.session.defaultSession;
if (!defaultSession || !defaultSession.clearHostResolverCache) return;
defaultSession.clearHostResolverCache();
});
return function (_x3) {
return _ref3.apply(this, arguments);
};
})());
electron.ipcMain.handle(PROCESS_UTILS_FLUSH_COOKIES, (() => {
var _ref4 = _asyncToGenerator(function* (_) {
return electron.session.defaultSession.cookies.flushStore();
});
return function (_x4) {
return _ref4.apply(this, arguments);
};
})());
electron.ipcMain.handle(PROCESS_UTILS_FLUSH_STORAGE_DATA, (() => {
var _ref5 = _asyncToGenerator(function* (_) {
electron.session.defaultSession.flushStorageData();
});
return function (_x5) {
return _ref5.apply(this, arguments);
};
})());
for (const processMetric of electron.app.getAppMetrics()) {
totalProcessorUsagePercent += processMetric.cpu.percentCPUUsage;
}
return totalProcessorUsagePercent;
});
electron.ipcMain.handle(PROCESS_UTILS_GET_MEMORY_INFO, async _ => {
return process.getProcessMemoryInfo();
});
electron.ipcMain.handle(PROCESS_UTILS_FLUSH_DNS_CACHE, async _ => {
const defaultSession = electron.session.defaultSession;
if (!defaultSession || !defaultSession.clearHostResolverCache) return;
defaultSession.clearHostResolverCache();
});
electron.ipcMain.handle(PROCESS_UTILS_FLUSH_COOKIES, async _ => {
return electron.session.defaultSession.cookies.flushStore();
});
electron.ipcMain.handle(PROCESS_UTILS_FLUSH_STORAGE_DATA, async _ => {
electron.session.defaultSession.flushStorageData();
});
electron.ipcMain.on(PROCESS_UTILS_GET_MAIN_ARGV_SYNC, event => {
event.returnValue = process.argv;
});

View File

@ -1,12 +1,17 @@
'use strict';
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.injectSettingsBackend = injectSettingsBackend;
const electron = require('electron');
const { SETTINGS_GET, SETTINGS_SET, SETTINGS_GET_SYNC } = require('../common/constants').IPCEvents;
const {
SETTINGS_GET,
SETTINGS_SET,
SETTINGS_GET_SYNC
} = require('../common/constants').IPCEvents;
let injectedSettings = null;
@ -26,13 +31,11 @@ electron.ipcMain.handle(SETTINGS_GET, (_, name, defaultValue) => {
const settings = getSettings();
return settings.get(name, defaultValue);
});
electron.ipcMain.handle(SETTINGS_SET, (_, name, value) => {
const settings = getSettings();
settings.set(name, value);
settings.save();
});
electron.ipcMain.on(SETTINGS_GET_SYNC, (event, name, defaultValue) => {
const settings = getSettings();
event.returnValue = settings.get(name, defaultValue);

View File

@ -1,6 +1,4 @@
'use strict';
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
"use strict";
const electron = require('electron');
@ -12,64 +10,36 @@ const {
} = require('../common/constants').IPCEvents;
let _learnedWords = new Set();
let _hasLoadedLearnedWords = false;
electron.ipcMain.handle(SPELLCHECK_REPLACE_MISSPELLING, async (event, correction) => {
event.sender.replaceMisspelling(correction);
});
electron.ipcMain.handle(SPELLCHECK_GET_AVAILABLE_DICTIONARIES, async _ => {
return electron.session.defaultSession.availableSpellCheckerLanguages;
});
electron.ipcMain.handle(SPELLCHECK_SET_LOCALE, async (_, locale) => {
electron.session.defaultSession.setSpellCheckerLanguages([locale]);
});
electron.ipcMain.handle(SPELLCHECK_SET_LEARNED_WORDS, async (_, newLearnedWords) => {
const session = electron.session.defaultSession;
electron.ipcMain.handle(SPELLCHECK_REPLACE_MISSPELLING, (() => {
var _ref = _asyncToGenerator(function* (event, correction) {
event.sender.replaceMisspelling(correction);
});
if (!_hasLoadedLearnedWords) {
const dictionaryContents = await session.listWordsInSpellCheckerDictionary();
_learnedWords = new Set(dictionaryContents);
_hasLoadedLearnedWords = true;
}
return function (_x, _x2) {
return _ref.apply(this, arguments);
};
})());
electron.ipcMain.handle(SPELLCHECK_GET_AVAILABLE_DICTIONARIES, (() => {
var _ref2 = _asyncToGenerator(function* (_) {
return electron.session.defaultSession.availableSpellCheckerLanguages;
});
return function (_x3) {
return _ref2.apply(this, arguments);
};
})());
electron.ipcMain.handle(SPELLCHECK_SET_LOCALE, (() => {
var _ref3 = _asyncToGenerator(function* (_, locale) {
electron.session.defaultSession.setSpellCheckerLanguages([locale]);
});
return function (_x4, _x5) {
return _ref3.apply(this, arguments);
};
})());
electron.ipcMain.handle(SPELLCHECK_SET_LEARNED_WORDS, (() => {
var _ref4 = _asyncToGenerator(function* (_, newLearnedWords) {
const session = electron.session.defaultSession;
if (!_hasLoadedLearnedWords) {
const dictionaryContents = yield session.listWordsInSpellCheckerDictionary();
_learnedWords = new Set(dictionaryContents);
_hasLoadedLearnedWords = true;
_learnedWords.forEach(word => {
if (!newLearnedWords.has(word)) {
session.removeWordFromSpellCheckerDictionary(word);
}
_learnedWords.forEach(function (word) {
if (!newLearnedWords.has(word)) {
session.removeWordFromSpellCheckerDictionary(word);
}
});
newLearnedWords.forEach(function (word) {
if (!_learnedWords.has(word)) {
session.addWordToSpellCheckerDictionary(word);
}
});
_learnedWords = new Set(newLearnedWords);
});
return function (_x6, _x7) {
return _ref4.apply(this, arguments);
};
})());
newLearnedWords.forEach(word => {
if (!_learnedWords.has(word)) {
session.addWordToSpellCheckerDictionary(word);
}
});
_learnedWords = new Set(newLearnedWords);
});

View File

@ -0,0 +1,76 @@
"use strict";
var _electron = _interopRequireDefault(require("electron"));
var _fs = _interopRequireDefault(require("fs"));
var _path = _interopRequireDefault(require("path"));
var _appFeatures = require("../../appFeatures");
var paths = _interopRequireWildcard(require("../../paths"));
var _constants = require("../common/constants");
function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
const {
USER_DATA_CACHE_SAVE,
USER_DATA_CACHE_GET,
USER_DATA_CACHE_DELETE
} = _constants.IPCEvents;
const features = (0, _appFeatures.getFeatures)();
function getCachePath() {
return _path.default.join(paths.getUserData(), 'userDataCache.json');
}
function getMigratedPath() {
return _path.default.join(paths.getUserData(), 'domainMigrated');
}
function cacheUserData(userData) {
_fs.default.writeFile(getCachePath(), userData, e => {
if (e) {
console.warn('Failed updating user data cache with error: ', e);
}
});
}
function getCachedUserData() {
try {
return JSON.parse(_fs.default.readFileSync(getCachePath()));
} catch (_err) {}
return null;
}
function deleteCachedUserData() {
try {
_fs.default.unlinkSync(getCachePath());
_fs.default.writeFile(getMigratedPath(), '', e => {
if (e) {
console.warn('Failed to create domainMigrated file with error: ', e);
}
});
} catch (_err) {}
}
_electron.default.ipcMain.handle(USER_DATA_CACHE_GET, () => {
return getCachedUserData();
});
_electron.default.ipcMain.on(USER_DATA_CACHE_SAVE, (_event, userData) => {
cacheUserData(userData);
});
_electron.default.ipcMain.on(USER_DATA_CACHE_DELETE, _event => {
deleteCachedUserData();
});
features.declareSupported('user_data_cache');

View File

@ -1,13 +1,12 @@
'use strict';
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.injectGetWindow = injectGetWindow;
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
const electron = require('electron');
const process = require('process');
const {
@ -33,154 +32,73 @@ function injectGetWindow(getWindow) {
injectedGetWindow = getWindow;
}
electron.ipcMain.handle(WINDOW_FLASH_FRAME, (() => {
var _ref = _asyncToGenerator(function* (_, flag) {
const currentWindow = injectedGetWindow();
if (currentWindow == null || currentWindow.flashFrame == null) return;
currentWindow.flashFrame(!currentWindow.isFocused() && flag);
});
electron.ipcMain.handle(WINDOW_FLASH_FRAME, async (_, flag) => {
const currentWindow = injectedGetWindow();
if (currentWindow == null || currentWindow.flashFrame == null) return;
currentWindow.flashFrame(!currentWindow.isFocused() && flag);
});
electron.ipcMain.handle(WINDOW_MINIMIZE, async (_, key) => {
const win = injectedGetWindow(key);
if (win == null) return;
win.minimize();
});
electron.ipcMain.handle(WINDOW_RESTORE, async (_, key) => {
const win = injectedGetWindow(key);
if (win == null) return;
win.restore();
});
electron.ipcMain.handle(WINDOW_MAXIMIZE, async (_, key) => {
const win = injectedGetWindow(key);
if (win == null) return;
return function (_x, _x2) {
return _ref.apply(this, arguments);
};
})());
if (win.isMaximized()) {
win.unmaximize();
} else {
win.maximize();
}
});
electron.ipcMain.handle(WINDOW_FOCUS, async (_, key) => {
const win = injectedGetWindow(key);
if (win == null) return;
win.show();
});
electron.ipcMain.handle(WINDOW_SET_ALWAYS_ON_TOP, async (_, key, enabled) => {
const win = injectedGetWindow(key);
if (win == null) return;
win.setAlwaysOnTop(enabled);
});
electron.ipcMain.handle(WINDOW_IS_ALWAYS_ON_TOP, async (_, key) => {
const win = injectedGetWindow(key);
if (win == null) return false;
return win.isAlwaysOnTop();
});
electron.ipcMain.handle(WINDOW_BLUR, async (_, key) => {
const win = injectedGetWindow(key);
electron.ipcMain.handle(WINDOW_MINIMIZE, (() => {
var _ref2 = _asyncToGenerator(function* (_, key) {
if (win != null && !win.isDestroyed()) {
win.blur();
}
});
electron.ipcMain.handle(WINDOW_SET_PROGRESS_BAR, async (_, key, progress) => {
const win = injectedGetWindow(key);
if (win == null) return;
win.setProgressBar(progress);
});
electron.ipcMain.handle(WINDOW_TOGGLE_FULLSCREEN, async (_, key) => {
const currentWindow = injectedGetWindow(key);
currentWindow.setFullScreen(!currentWindow.isFullScreen());
});
electron.ipcMain.handle(WINDOW_CLOSE, async (_, key) => {
if (key == null && process.platform === 'darwin') {
electron.Menu.sendActionToFirstResponder('hide:');
} else {
const win = injectedGetWindow(key);
if (win == null) return;
win.minimize();
});
return function (_x3, _x4) {
return _ref2.apply(this, arguments);
};
})());
electron.ipcMain.handle(WINDOW_RESTORE, (() => {
var _ref3 = _asyncToGenerator(function* (_, key) {
const win = injectedGetWindow(key);
if (win == null) return;
win.restore();
});
return function (_x5, _x6) {
return _ref3.apply(this, arguments);
};
})());
electron.ipcMain.handle(WINDOW_MAXIMIZE, (() => {
var _ref4 = _asyncToGenerator(function* (_, key) {
const win = injectedGetWindow(key);
if (win == null) return;
if (win.isMaximized()) {
win.unmaximize();
} else {
win.maximize();
}
});
return function (_x7, _x8) {
return _ref4.apply(this, arguments);
};
})());
electron.ipcMain.handle(WINDOW_FOCUS, (() => {
var _ref5 = _asyncToGenerator(function* (_, key) {
const win = injectedGetWindow(key);
if (win == null) return;
win.show();
});
return function (_x9, _x10) {
return _ref5.apply(this, arguments);
};
})());
electron.ipcMain.handle(WINDOW_SET_ALWAYS_ON_TOP, (() => {
var _ref6 = _asyncToGenerator(function* (_, key, enabled) {
const win = injectedGetWindow(key);
if (win == null) return;
win.setAlwaysOnTop(enabled);
});
return function (_x11, _x12, _x13) {
return _ref6.apply(this, arguments);
};
})());
electron.ipcMain.handle(WINDOW_IS_ALWAYS_ON_TOP, (() => {
var _ref7 = _asyncToGenerator(function* (_, key) {
const win = injectedGetWindow(key);
if (win == null) return false;
return win.isAlwaysOnTop();
});
return function (_x14, _x15) {
return _ref7.apply(this, arguments);
};
})());
electron.ipcMain.handle(WINDOW_BLUR, (() => {
var _ref8 = _asyncToGenerator(function* (_, key) {
const win = injectedGetWindow(key);
if (win != null && !win.isDestroyed()) {
win.blur();
}
});
return function (_x16, _x17) {
return _ref8.apply(this, arguments);
};
})());
electron.ipcMain.handle(WINDOW_SET_PROGRESS_BAR, (() => {
var _ref9 = _asyncToGenerator(function* (_, key, progress) {
const win = injectedGetWindow(key);
if (win == null) return;
win.setProgressBar(progress);
});
return function (_x18, _x19, _x20) {
return _ref9.apply(this, arguments);
};
})());
electron.ipcMain.handle(WINDOW_TOGGLE_FULLSCREEN, (() => {
var _ref10 = _asyncToGenerator(function* (_, key) {
const currentWindow = injectedGetWindow(key);
currentWindow.setFullScreen(!currentWindow.isFullScreen());
});
return function (_x21, _x22) {
return _ref10.apply(this, arguments);
};
})());
electron.ipcMain.handle(WINDOW_CLOSE, (() => {
var _ref11 = _asyncToGenerator(function* (_, key) {
if (key == null && process.platform === 'darwin') {
electron.Menu.sendActionToFirstResponder('hide:');
} else {
const win = injectedGetWindow(key);
if (win == null) return;
win.close();
}
});
return function (_x23, _x24) {
return _ref11.apply(this, arguments);
};
})());
electron.ipcMain.handle(WINDOW_SET_BACKGROUND_THROTTLING, (() => {
var _ref12 = _asyncToGenerator(function* (_, enabled) {
const win = injectedGetWindow();
if (win == null) return;
win.webContents.setBackgroundThrottling(enabled);
});
return function (_x25, _x26) {
return _ref12.apply(this, arguments);
};
})());
win.close();
}
});
electron.ipcMain.handle(WINDOW_SET_BACKGROUND_THROTTLING, async (_, enabled) => {
const win = injectedGetWindow();
if (win == null) return;
win.webContents.setBackgroundThrottling(enabled);
});

View File

@ -4,6 +4,8 @@ Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getDiscordIPCEvent = getDiscordIPCEvent;
exports.IPCEvents = void 0;
function sanitizeIPCEvents(events) {
for (const key of Object.keys(events)) {
events[key] = getDiscordIPCEvent(key);
@ -16,9 +18,9 @@ function getDiscordIPCEvent(ev) {
return `DISCORD_${ev}`;
}
const IPCEvents = exports.IPCEvents = sanitizeIPCEvents({
const IPCEvents = sanitizeIPCEvents({
ACCESSIBILITY_GET_ENABLED: null,
APP_BADGE_SET: null,
APP_GET_RELEASE_CHANNEL_SYNC: null,
APP_GET_HOST_VERSION_SYNC: null,
APP_GET_MODULE_VERSIONS: null,
@ -29,26 +31,28 @@ const IPCEvents = exports.IPCEvents = sanitizeIPCEvents({
APP_DOCK_CANCEL_BOUNCE: null,
APP_RELAUNCH: null,
APP_GET_DEFAULT_DOUBLE_CLICK_ACTION: null,
CLIPBOARD_COPY: null,
CLIPBOARD_CUT: null,
CLIPBOARD_PASTE: null,
CHECK_FOR_UPDATES: null,
CONSTANTS_GET: null,
CRASH_REPORTER_UPDATE_METADATA: null,
FEATURES_GET_BROWSER_FEATURES: null,
FILE_MANAGER_GET_MODULE_PATH: null,
FILE_MANAGER_GET_MODULE_DATA_PATH_SYNC: null,
FILE_MANAGER_SHOW_SAVE_DIALOG: null,
FILE_MANAGER_SHOW_OPEN_DIALOG: null,
FILE_MANAGER_SHOW_ITEM_IN_FOLDER: null,
GPU_SETTINGS_SET_ENABLE_HWACCEL: null,
GPU_SETTINGS_GET_ENABLE_HWACCEL_SYNC: null,
NATIVE_MODULES_GET_PATHS: null,
NATIVE_MODULES_INSTALL: null,
NATIVE_MODULES_FINISH_UPDATER_BOOTSTRAP: null,
NATIVE_MODULES_GET_HAS_NEW_UPDATER: null,
NOTIFICATION_CLOSE: null,
NOTIFICATION_SHOW: null,
NOTIFICATIONS_CLEAR: null,
OPEN_EXTERNAL_URL: null,
POWER_MONITOR_RESUME: null,
POWER_MONITOR_SUSPEND: null,
POWER_MONITOR_LOCK_SCREEN: null,
@ -57,24 +61,33 @@ const IPCEvents = exports.IPCEvents = sanitizeIPCEvents({
POWER_SAVE_BLOCKER_BLOCK_DISPLAY_SLEEP: null,
POWER_SAVE_BLOCKER_UNBLOCK_DISPLAY_SLEEP: null,
POWER_SAVE_BLOCKER_CLEANUP_DISPLAY_SLEEP: null,
PROCESS_UTILS_GET_CPU_USAGE: null,
PROCESS_UTILS_GET_MEMORY_INFO: null,
PROCESS_UTILS_FLUSH_DNS_CACHE: null,
PROCESS_UTILS_FLUSH_COOKIES: null,
PROCESS_UTILS_FLUSH_STORAGE_DATA: null,
PROCESS_UTILS_GET_MAIN_ARGV_SYNC: null,
QUIT_AND_INSTALL: null,
SETTINGS_GET: null,
SETTINGS_SET: null,
SETTINGS_GET_SYNC: null,
SETTINGS_UPDATE_BACKGROUND_COLOR: null,
SPELLCHECK_RESULT: null,
SPELLCHECK_REPLACE_MISSPELLING: null,
SPELLCHECK_GET_AVAILABLE_DICTIONARIES: null,
SPELLCHECK_SET_LOCALE: null,
SPELLCHECK_SET_LEARNED_WORDS: null,
SYSTEM_TRAY_SET_ICON: null,
SYSTEM_TRAY_SET_APPLICATIONS: null,
TOGGLE_MINIMIZE_TO_TRAY: null,
TOGGLE_OPEN_ON_STARTUP: null,
TOGGLE_START_MINIMIZED: null,
UPDATE_OPEN_ON_STARTUP: null,
UPDATER_HISTORY_QUERY_AND_TRUNCATE: null,
UPDATED_QUOTES: null,
USER_DATA_CACHE_DELETE: null,
USER_DATA_CACHE_GET: null,
USER_DATA_CACHE_SAVE: null,
WINDOW_BLUR: null,
WINDOW_CLOSE: null,
WINDOW_FOCUS: null,
@ -89,4 +102,5 @@ const IPCEvents = exports.IPCEvents = sanitizeIPCEvents({
WINDOW_SET_ALWAYS_ON_TOP: null,
WINDOW_DEVTOOLS_OPENED: null,
WINDOW_DEVTOOLS_CLOSED: null
});
});
exports.IPCEvents = IPCEvents;

View File

@ -1,20 +1,14 @@
'use strict';
let isAccessibilitySupportEnabled = (() => {
var _ref = _asyncToGenerator(function* () {
return electron.ipcRenderer.invoke(ACCESSIBILITY_GET_ENABLED);
});
return function isAccessibilitySupportEnabled() {
return _ref.apply(this, arguments);
};
})();
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
"use strict";
const electron = require('electron');
const { ACCESSIBILITY_GET_ENABLED } = require('../common/constants').IPCEvents;
const {
ACCESSIBILITY_GET_ENABLED
} = require('../common/constants').IPCEvents;
async function isAccessibilitySupportEnabled() {
return electron.ipcRenderer.invoke(ACCESSIBILITY_GET_ENABLED);
}
module.exports = {
isAccessibilitySupportEnabled

View File

@ -1,85 +1,9 @@
'use strict';
let getPath = (() => {
var _ref2 = _asyncToGenerator(function* (path) {
if (!allowedAppPaths.has(path)) {
throw new Error(`${path} is not an allowed app path`);
}
return electron.ipcRenderer.invoke(APP_GET_PATH, path);
});
return function getPath(_x2) {
return _ref2.apply(this, arguments);
};
})();
let setBadgeCount = (() => {
var _ref3 = _asyncToGenerator(function* (count) {
electron.ipcRenderer.invoke(APP_SET_BADGE_COUNT, count);
});
return function setBadgeCount(_x3) {
return _ref3.apply(this, arguments);
};
})();
let dockSetBadge = (() => {
var _ref4 = _asyncToGenerator(function* (badge) {
electron.ipcRenderer.invoke(APP_DOCK_SET_BADGE, badge);
});
return function dockSetBadge(_x4) {
return _ref4.apply(this, arguments);
};
})();
let dockBounce = (() => {
var _ref5 = _asyncToGenerator(function* (type) {
return electron.ipcRenderer.invoke(APP_DOCK_BOUNCE, type);
});
return function dockBounce(_x5) {
return _ref5.apply(this, arguments);
};
})();
let dockCancelBounce = (() => {
var _ref6 = _asyncToGenerator(function* (id) {
electron.ipcRenderer.invoke(APP_DOCK_CANCEL_BOUNCE, id);
});
return function dockCancelBounce(_x6) {
return _ref6.apply(this, arguments);
};
})();
let relaunch = (() => {
var _ref7 = _asyncToGenerator(function* () {
electron.ipcRenderer.invoke(APP_RELAUNCH);
});
return function relaunch() {
return _ref7.apply(this, arguments);
};
})();
let getDefaultDoubleClickAction = (() => {
var _ref8 = _asyncToGenerator(function* () {
return electron.ipcRenderer.invoke(APP_GET_DEFAULT_DOUBLE_CLICK_ACTION);
});
return function getDefaultDoubleClickAction() {
return _ref8.apply(this, arguments);
};
})();
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
"use strict";
const electron = require('electron');
const { UpdaterEvents } = require('../../Constants');
const allowedAppPaths = new Set(['home', 'appData', 'desktop', 'documents', 'downloads']);
const allowedAppPaths = new Set(['home', 'appData', 'desktop', 'documents', 'downloads', 'crashDumps']);
const {
APP_GET_RELEASE_CHANNEL_SYNC,
APP_GET_HOST_VERSION_SYNC,
@ -96,20 +20,12 @@ const {
let releaseChannel = electron.ipcRenderer.sendSync(APP_GET_RELEASE_CHANNEL_SYNC);
let hostVersion = electron.ipcRenderer.sendSync(APP_GET_HOST_VERSION_SYNC);
let moduleVersions = {};
electron.ipcRenderer.invoke(APP_GET_MODULE_VERSIONS).then(versions => {
moduleVersions = versions;
});
electron.ipcRenderer.on('DISCORD_MODULE_INSTALLED', (() => {
var _ref = _asyncToGenerator(function* (_) {
moduleVersions = yield electron.ipcRenderer.invoke(APP_GET_MODULE_VERSIONS);
});
return function (_x) {
return _ref.apply(this, arguments);
};
})());
electron.ipcRenderer.on('DISCORD_MODULE_INSTALLED', async _ => {
moduleVersions = await electron.ipcRenderer.invoke(APP_GET_MODULE_VERSIONS);
});
function getReleaseChannel() {
return releaseChannel;
@ -123,6 +39,59 @@ function getModuleVersions() {
return moduleVersions;
}
async function getPath(path) {
if (!allowedAppPaths.has(path)) {
throw new Error(`${path} is not an allowed app path`);
}
return electron.ipcRenderer.invoke(APP_GET_PATH, path);
}
async function setBadgeCount(count) {
electron.ipcRenderer.invoke(APP_SET_BADGE_COUNT, count);
}
async function dockSetBadge(badge) {
electron.ipcRenderer.invoke(APP_DOCK_SET_BADGE, badge);
}
async function dockBounce(type) {
return electron.ipcRenderer.invoke(APP_DOCK_BOUNCE, type);
}
async function dockCancelBounce(id) {
electron.ipcRenderer.invoke(APP_DOCK_CANCEL_BOUNCE, id);
}
async function relaunch() {
electron.ipcRenderer.invoke(APP_RELAUNCH);
}
async function getDefaultDoubleClickAction() {
return electron.ipcRenderer.invoke(APP_GET_DEFAULT_DOUBLE_CLICK_ACTION);
}
function registerUserInteractionHandler(elementId, eventType, callback) {
const element = document.getElementById(elementId);
if (element == null) {
throw new Error(`Element with id '${elementId}' was not found`);
}
function handleUserInteraction(ev) {
if (!ev.isTrusted) {
return;
}
callback(ev);
}
element.addEventListener(eventType, handleUserInteraction);
return () => {
element.removeEventListener(eventType, handleUserInteraction);
};
}
module.exports = {
getReleaseChannel,
getVersion,
@ -135,5 +104,6 @@ module.exports = {
cancelBounce: dockCancelBounce
},
relaunch,
getDefaultDoubleClickAction
getDefaultDoubleClickAction,
registerUserInteractionHandler
};

View File

@ -1,9 +1,14 @@
'use strict';
"use strict";
const electron = require('electron');
const invariant = require('invariant');
const { CLIPBOARD_COPY, CLIPBOARD_CUT, CLIPBOARD_PASTE } = require('../common/constants').IPCEvents;
const {
CLIPBOARD_COPY,
CLIPBOARD_CUT,
CLIPBOARD_PASTE
} = require('../common/constants').IPCEvents;
function copy(text) {
if (text) {
@ -15,9 +20,11 @@ function copy(text) {
function copyImage(imageArrayBuffer, imageSrc) {
invariant(imageArrayBuffer != null, 'Image data is empty');
const nativeImg = electron.nativeImage.createFromBuffer(imageArrayBuffer);
electron.clipboard.write({ html: `<img src="${imageSrc}">`, image: nativeImg });
electron.clipboard.write({
html: `<img src="${imageSrc}">`,
image: nativeImg
});
}
function cut() {

View File

@ -1,33 +1,33 @@
'use strict';
let updateCrashReporter = (() => {
var _ref = _asyncToGenerator(function* (additional_metadata) {
const result = yield electron.ipcRenderer.invoke(CRASH_REPORTER_UPDATE_METADATA, additional_metadata);
// Calling crashReporter.start from a renderer process was deprecated in Electron 9.
if (getElectronMajorVersion() < 9) {
//electron.crashReporter.start(result.args);
}
metadata = result.metadata || {};
reconcileCrashReporterMetadata(electron.crashReporter, metadata);
});
return function updateCrashReporter(_x) {
return _ref.apply(this, arguments);
};
})();
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
"use strict";
const electron = require('electron');
const { getElectronMajorVersion, reconcileCrashReporterMetadata } = require('../common/utility');
const { CRASH_REPORTER_UPDATE_METADATA } = require('../common/constants').IPCEvents;
const {
reconcileCrashReporterMetadata
} = require('../../../common/crashReporterUtils');
const {
getElectronMajorVersion
} = require('../../../common/processUtils');
const {
CRASH_REPORTER_UPDATE_METADATA
} = require('../common/constants').IPCEvents;
let metadata = {};
updateCrashReporter(metadata);
async function updateCrashReporter(additional_metadata) {
const result = await electron.ipcRenderer.invoke(CRASH_REPORTER_UPDATE_METADATA, additional_metadata); // Calling crashReporter.start from a renderer process was deprecated in Electron 9.
if (getElectronMajorVersion() < 9) {
electron.crashReporter.start(result.args);
}
metadata = result.metadata || {};
reconcileCrashReporterMetadata(electron.crashReporter, metadata);
}
function getMetadata() {
return metadata;
}

View File

@ -1,4 +1,4 @@
'use strict';
"use strict";
const electron = require('electron');

View File

@ -1,8 +1,10 @@
'use strict';
"use strict";
const electron = require('electron');
const { FEATURES_GET_BROWSER_FEATURES } = require('../common/constants').IPCEvents;
const {
FEATURES_GET_BROWSER_FEATURES
} = require('../common/constants').IPCEvents;
let supportedFeatures = new Set(electron.ipcRenderer.sendSync(FEATURES_GET_BROWSER_FEATURES));

View File

@ -1,192 +1,167 @@
'use strict';
let saveWithDialog = (() => {
var _ref = _asyncToGenerator(function* (fileContents, fileName, filePath) {
if (INVALID_FILENAME_CHAR_REGEX.test(fileName)) {
throw new Error(`fileName has invalid characters`);
}
const defaultPath = filePath != null ? path.join(os.homedir(), filePath, fileName) : path.join(os.homedir(), fileName);
const writeFileToDisk = function (selectedFileName) {
selectedFileName && fs.writeFileSync(selectedFileName, fileContents);
};
const results = yield electron.ipcRenderer.invoke(FILE_MANAGER_SHOW_SAVE_DIALOG, { defaultPath });
if (results && results.filePath) {
fs.writeFileSync(results.filePath, fileContents);
}
});
return function saveWithDialog(_x, _x2, _x3) {
return _ref.apply(this, arguments);
};
})();
let showOpenDialog = (() => {
var _ref2 = _asyncToGenerator(function* (dialogOptions) {
const results = yield electron.ipcRenderer.invoke(FILE_MANAGER_SHOW_OPEN_DIALOG, dialogOptions);
return results.filePaths;
});
return function showOpenDialog(_x4) {
return _ref2.apply(this, arguments);
};
})();
let orderedFiles = (() => {
var _ref3 = _asyncToGenerator(function* (folder) {
try {
const filenames = yield readdir(folder);
const times = yield getTimes(filenames.map(function (filename) {
return path.join(folder, filename);
}));
return times.filter(function (result) {
return result.status === 'fulfilled';
}).map(function (result) {
return result.value;
}).sort(function (a, b) {
return b.mtime.getTime() - a.mtime.getTime();
}).map(function (a) {
return a.filename;
});
} catch (err) {
return [];
}
});
return function orderedFiles(_x5) {
return _ref3.apply(this, arguments);
};
})();
let readLogFiles = (() => {
var _ref4 = _asyncToGenerator(function* (maxSize, makeFile) {
const modulePath = yield getModulePath();
const webrtcLog0 = path.join(modulePath, 'discord_voice', 'discord-webrtc_0');
const webrtcLog1 = path.join(modulePath, 'discord_voice', 'discord-webrtc_1');
const webrtcLog2 = path.join(modulePath, 'discord_voice', 'discord-last-webrtc_0');
const webrtcLog3 = path.join(modulePath, 'discord_voice', 'discord-last-webrtc_1');
const hookLog = path.join(modulePath, 'discord_hook', 'hook.log');
const audioState = path.join(modulePath, 'discord_voice', 'audio_state.json');
const filesToUpload = [webrtcLog0, webrtcLog1, webrtcLog2, webrtcLog3, hookLog, audioState];
const crashFolder = process.platform === 'win32' ? path.join(os.tmpdir(), 'Discord Crashes', 'reports') : path.join(os.tmpdir(), 'Discord Crashes', 'completed');
const crashFiles = yield orderedFiles(crashFolder);
if (crashFiles.length > 0) {
filesToUpload.push(crashFiles[0]);
}
const files = yield readFiles(filesToUpload, maxSize, function (data, filename) {
return makeFile(data, filename, 'application/octet-stream');
});
return files.filter(function (result) {
return result.status === 'fulfilled';
}).map(function (result) {
return result.value;
});
});
return function readLogFiles(_x6, _x7) {
return _ref4.apply(this, arguments);
};
})();
let showItemInFolder = (() => {
var _ref5 = _asyncToGenerator(function* (path) {
electron.ipcRenderer.invoke(FILE_MANAGER_SHOW_ITEM_IN_FOLDER, path);
});
return function showItemInFolder(_x8) {
return _ref5.apply(this, arguments);
};
})();
let openFiles = (() => {
var _ref6 = _asyncToGenerator(function* (dialogOptions, maxSize, makeFile) {
const filenames = yield showOpenDialog(dialogOptions);
if (filenames == null) {
return;
}
const files = yield readFiles(filenames, maxSize, makeFile);
files.forEach(function (result) {
if (result.status === 'rejected') {
throw result.reason;
}
});
return files.map(function (result) {
return result.value;
});
});
return function openFiles(_x9, _x10, _x11) {
return _ref6.apply(this, arguments);
};
})();
let getModulePath = (() => {
var _ref7 = _asyncToGenerator(function* () {
return electron.ipcRenderer.invoke(FILE_MANAGER_GET_MODULE_PATH);
});
return function getModulePath() {
return _ref7.apply(this, arguments);
};
})();
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
"use strict";
const electron = require('electron');
const fs = require('fs');
const os = require('os');
const path = require('path');
const originalFs = require('original-fs');
const util = require('util');
const {
getPath
} = require('./app');
const {
getElectronMajorVersion
} = require('../../../common/processUtils');
const {
FILE_MANAGER_GET_MODULE_PATH,
FILE_MANAGER_GET_MODULE_DATA_PATH_SYNC,
FILE_MANAGER_SHOW_SAVE_DIALOG,
FILE_MANAGER_SHOW_OPEN_DIALOG,
FILE_MANAGER_SHOW_ITEM_IN_FOLDER
} = require('../common/constants').IPCEvents;
const INVALID_FILENAME_CHAR_REGEX = /[^a-zA-Z0-9-_.]/g;
const readdir = util.promisify(originalFs.readdir);
async function saveWithDialog(fileContents, fileName) {
if (INVALID_FILENAME_CHAR_REGEX.test(fileName)) {
throw new Error('fileName has invalid characters');
}
const defaultPath = path.join((await getPath('downloads')), fileName);
const results = await electron.ipcRenderer.invoke(FILE_MANAGER_SHOW_SAVE_DIALOG, {
defaultPath
});
if (results && results.filePath) {
fs.writeFileSync(results.filePath, fileContents);
}
}
async function showOpenDialog({
filters,
properties
}) {
const results = await electron.ipcRenderer.invoke(FILE_MANAGER_SHOW_OPEN_DIALOG, {
filters,
properties
});
return results.filePaths;
}
function getTimes(filenames) {
return Promise.allSettled(filenames.map(filename => new Promise((resolve, reject) => {
originalFs.stat(filename, (err, stats) => {
if (err) {
return reject(err);
}
if (!stats.isFile()) {
return reject(new Error('Not a file'));
}
return resolve({ filename, mtime: stats.mtime });
return resolve({
filename,
mtime: stats.mtime
});
});
})));
}
function readFiles(filenames, maxSize, makeFile) {
async function orderedFiles(folder) {
try {
const filenames = await readdir(folder);
const times = await getTimes(filenames.map(filename => path.join(folder, filename)));
return times.filter(result => result.status === 'fulfilled').map(result => result.value).sort((a, b) => b.mtime.getTime() - a.mtime.getTime()).map(a => a.filename);
} catch (err) {
return [];
}
}
async function readLogFiles(maxSize) {
const modulePath = await getModulePath();
const webrtcLog0 = path.join(modulePath, 'discord_voice', 'discord-webrtc_0');
const webrtcLog1 = path.join(modulePath, 'discord_voice', 'discord-webrtc_1');
const webrtcLog2 = path.join(modulePath, 'discord_voice', 'discord-last-webrtc_0');
const webrtcLog3 = path.join(modulePath, 'discord_voice', 'discord-last-webrtc_1');
const hookLog = path.join(modulePath, 'discord_hook', 'hook.log');
const audioState = path.join(modulePath, 'discord_voice', 'audio_state.json');
const filesToUpload = [webrtcLog0, webrtcLog1, webrtcLog2, webrtcLog3, hookLog, audioState]; // Electron 9 changes crash folder location
const crashBaseFolder = getElectronMajorVersion() < 9 ? path.join(os.tmpdir(), 'Discord Crashes') : await getPath('crashDumps');
const crashFolder = process.platform === 'win32' ? path.join(crashBaseFolder, 'reports') : path.join(crashBaseFolder, 'completed');
const crashFiles = await orderedFiles(crashFolder);
if (crashFiles.length > 0) {
filesToUpload.push(crashFiles[0]);
}
const files = await readFiles(filesToUpload, maxSize);
return files.filter(result => result.status === 'fulfilled').map(result => result.value);
}
async function showItemInFolder(path) {
electron.ipcRenderer.invoke(FILE_MANAGER_SHOW_ITEM_IN_FOLDER, path);
}
async function openFiles(dialogOptions, maxSize) {
const filenames = await showOpenDialog(dialogOptions);
if (filenames == null) {
return;
}
const files = await readFiles(filenames, maxSize);
files.forEach(result => {
if (result.status === 'rejected') {
throw result.reason;
}
});
return files.map(result => result.value);
}
function readFiles(filenames, maxSize) {
return Promise.allSettled(filenames.map(filename => new Promise((resolve, reject) => {
originalFs.stat(filename, (err, stats) => {
if (err) return reject(err);
if (stats.size > maxSize) {
const err = new Error('upload too large');
// used to help determine why openFiles failed
err.code = 'ETOOLARGE';
return reject(err);
// Used to help determine why openFiles failed.
// Cannot use an error here because context bridge will remove the code field.
// eslint-disable-next-line prefer-promise-reject-errors
return reject({
code: 'ETOOLARGE',
message: 'upload too large'
});
}
originalFs.readFile(filename, (err, data) => {
if (err) return reject(err);
return resolve(makeFile(data.buffer, path.basename(filename)));
return resolve({
data: data.buffer,
filename: path.basename(filename)
});
});
});
})));
}
async function getModulePath() {
return electron.ipcRenderer.invoke(FILE_MANAGER_GET_MODULE_PATH);
}
function getModuleDataPathSync() {
return electron.ipcRenderer.sendSync(FILE_MANAGER_GET_MODULE_DATA_PATH_SYNC);
}
module.exports = {
readLogFiles,
saveWithDialog,
@ -194,6 +169,7 @@ module.exports = {
showOpenDialog,
showItemInFolder,
getModulePath,
getModuleDataPathSync,
extname: path.extname,
basename: path.basename,
dirname: path.dirname,

View File

@ -1,20 +1,11 @@
'use strict';
let setEnableHardwareAcceleration = (() => {
var _ref = _asyncToGenerator(function* (enable) {
electron.ipcRenderer.invoke(GPU_SETTINGS_SET_ENABLE_HWACCEL, enable);
});
return function setEnableHardwareAcceleration(_x) {
return _ref.apply(this, arguments);
};
})();
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
"use strict";
const electron = require('electron');
const { GPU_SETTINGS_SET_ENABLE_HWACCEL, GPU_SETTINGS_GET_ENABLE_HWACCEL_SYNC } = require('../common/constants').IPCEvents;
const {
GPU_SETTINGS_SET_ENABLE_HWACCEL,
GPU_SETTINGS_GET_ENABLE_HWACCEL_SYNC
} = require('../common/constants').IPCEvents;
const hardwareAccelerationEnabled = electron.ipcRenderer.sendSync(GPU_SETTINGS_GET_ENABLE_HWACCEL_SYNC);
@ -22,6 +13,10 @@ function getEnableHardwareAcceleration() {
return hardwareAccelerationEnabled;
}
async function setEnableHardwareAcceleration(enable) {
electron.ipcRenderer.invoke(GPU_SETTINGS_SET_ENABLE_HWACCEL, enable);
}
module.exports = {
getEnableHardwareAcceleration,
setEnableHardwareAcceleration

View File

@ -1,11 +1,26 @@
'use strict';
"use strict";
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
const electron = require('electron');
const http = require('http');
const https = require('https');
function makeChunkedRequest(route, chunks, options, callback) {
const {
CONSTANTS_GET
} = require('../common/constants').IPCEvents;
async function getAPIEndpoint() {
const apiEndpoint = await electron.ipcRenderer.invoke(CONSTANTS_GET, 'API_ENDPOINT');
if (apiEndpoint == null || apiEndpoint === '') {
return null;
}
return apiEndpoint;
}
async function makeChunkedRequest(route, chunks, options) {
/**
* Given an array of chunks, make a slow request, only writing chunks
* after a specified amount of time
@ -18,62 +33,79 @@ function makeChunkedRequest(route, chunks, options, callback) {
* token: the token to make an authorized request from
* chunks: chunked body of the request to upload
*/
const { method, chunkInterval, token, contentType } = options;
const {
method,
chunkInterval,
token,
contentType
} = options;
let httpModule = http;
if (route.startsWith('https')) {
httpModule = https;
} // we will force the URL to hit only API_ENDPOINT
const apiEndpoint = await getAPIEndpoint();
if (apiEndpoint == null) {
throw new Error('missing api endpoint setting');
}
const requestPromise = new Promise((() => {
var _ref = _asyncToGenerator(function* (resolve, reject) {
let writeTimeout;
const req = httpModule.request(route, {
method,
headers: {
authorization: token,
'Content-Type': contentType,
'Content-Length': Buffer.byteLength(chunks.join(''))
}
}, function (res) {
let responseData = '';
res.setEncoding('utf8');
res.on('data', function (chunk) {
responseData += chunk;
});
const apiEndpointUrl = new URL(apiEndpoint);
const url = new URL(route, apiEndpoint);
url.protocol = apiEndpointUrl.protocol;
url.host = apiEndpointUrl.host;
res.on('end', function () {
resolve({ status: res.statusCode, body: responseData });
if (!url.pathname.startsWith(apiEndpointUrl.pathname)) {
url.pathname = `${apiEndpointUrl.pathname}${url.pathname}`;
}
return new Promise(async (resolve, reject) => {
let writeTimeout;
const req = httpModule.request(url.toString(), {
method,
headers: {
authorization: token,
'Content-Type': contentType,
'Content-Length': Buffer.byteLength(chunks.join(''))
}
}, res => {
let responseData = '';
res.setEncoding('utf8');
res.on('data', chunk => {
responseData += chunk;
});
res.on('end', () => {
resolve({
status: res.statusCode,
body: responseData
});
});
req.on('error', function (e) {
if (writeTimeout != null) {
clearTimeout(writeTimeout);
}
reject(e);
});
for (let i = 0; i < chunks.length; i++) {
yield new Promise(function (resolve) {
req.write(chunks[i], function () {
writeTimeout = setTimeout(resolve, chunkInterval);
});
});
});
req.on('error', e => {
if (writeTimeout != null) {
clearTimeout(writeTimeout);
}
req.end();
reject(e);
});
return function (_x, _x2) {
return _ref.apply(this, arguments);
};
})());
for (let i = 0; i < chunks.length; i++) {
await new Promise(resolve => {
req.write(chunks[i], () => {
writeTimeout = setTimeout(resolve, chunkInterval);
});
});
}
requestPromise.then(body => callback(null, body)).catch(callback);
req.end();
});
}
module.exports = {
makeChunkedRequest
getAPIEndpoint,
makeChunkedRequest: function (route, chunks, options, callback) {
makeChunkedRequest(route, chunks, options).then(body => callback(null, body)).catch(err => callback(err));
}
};

View File

@ -1,18 +1,29 @@
'use strict';
"use strict";
const electron = require('electron');
const { getDiscordIPCEvent } = require('../common/constants');
const ipcRenderer = electron.ipcRenderer;
const {
getDiscordIPCEvent,
IPCEvents
} = require('../common/constants');
const ipcRenderer = electron.ipcRenderer; // Sending ipc directly from the renderer is considered deprecated.
// App still sends a few, so we whitelist those.
const RENDERER_IPC_WHITELIST = [IPCEvents.APP_BADGE_SET, IPCEvents.CHECK_FOR_UPDATES, IPCEvents.NOTIFICATION_CLOSE, IPCEvents.NOTIFICATION_SHOW, IPCEvents.NOTIFICATIONS_CLEAR, IPCEvents.OPEN_EXTERNAL_URL, IPCEvents.QUIT_AND_INSTALL, IPCEvents.SETTINGS_UPDATE_BACKGROUND_COLOR, IPCEvents.SYSTEM_TRAY_SET_ICON, IPCEvents.SYSTEM_TRAY_SET_APPLICATIONS, IPCEvents.TOGGLE_MINIMIZE_TO_TRAY, IPCEvents.TOGGLE_OPEN_ON_STARTUP, IPCEvents.TOGGLE_START_MINIMIZED, IPCEvents.UPDATE_OPEN_ON_STARTUP, IPCEvents.UPDATER_HISTORY_QUERY_AND_TRUNCATE, IPCEvents.UPDATED_QUOTES];
function send(ev, ...args) {
const event = getDiscordIPCEvent(ev)
ipcRenderer.send(event, ...args);
const prefixedEvent = getDiscordIPCEvent(ev);
if (!RENDERER_IPC_WHITELIST.includes(prefixedEvent)) {
throw new Error('cannot send this event');
}
ipcRenderer.send(prefixedEvent, ...args);
}
function on(ev, callback) {
const event = getDiscordIPCEvent(ev)
ipcRenderer.on(event, callback);
ipcRenderer.on(getDiscordIPCEvent(ev), callback);
}
module.exports = {

View File

@ -1,69 +1,59 @@
'use strict';
let ensureModule = (() => {
var _ref = _asyncToGenerator(function* (name) {
let modulePromise = modulePromises[name];
if (modulePromise == null) {
modulePromise = electron.ipcRenderer.invoke(NATIVE_MODULES_INSTALL, name);
}
return modulePromise;
});
return function ensureModule(_x) {
return _ref.apply(this, arguments);
};
})();
// TODO: remove this sandboxing when we turn contextIsolation on
// sandbox this function in a new context, else it's susceptible to prototype attacks
// - RegExp.prototype.test = () => true
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
"use strict";
const electron = require('electron');
const vm = require('vm');
const { NATIVE_MODULES_GET_PATHS, NATIVE_MODULES_INSTALL } = require('../common/constants').IPCEvents;
const {
NATIVE_MODULES_GET_PATHS,
NATIVE_MODULES_INSTALL,
NATIVE_MODULES_GET_HAS_NEW_UPDATER
} = require('../common/constants').IPCEvents;
const modulePromises = {};
function getSanitizedModulePaths() {
let sanitizedModulePaths = [];
const { mainAppDirname, browserModulePaths } = electron.ipcRenderer.sendSync(NATIVE_MODULES_GET_PATHS);
const {
mainAppDirname,
browserModulePaths
} = electron.ipcRenderer.sendSync(NATIVE_MODULES_GET_PATHS);
browserModulePaths.forEach(modulePath => {
if (!modulePath.includes('app.asar')) {
if (!modulePath.includes('electron.asar')) {
sanitizedModulePaths.push(modulePath);
}
});
const rendererModulePaths = require('module')._nodeModulePaths(mainAppDirname);
sanitizedModulePaths = sanitizedModulePaths.concat(rendererModulePaths.slice(0, 2));
sanitizedModulePaths = sanitizedModulePaths.concat(rendererModulePaths.slice(0, 2));
return sanitizedModulePaths;
}
const context = vm.createContext(Object.create(null));
const _requireModule = vm.runInContext(`
function requireModule(localRequire, name) {
if (!/^discord_[a-z0-9_-]+$/.test(name) && name !== 'erlpack') {
throw new Error('"' + String(name) + '" is not a whitelisted native module');
}
return localRequire(name);
function getHasNewUpdater() {
return electron.ipcRenderer.sendSync(NATIVE_MODULES_GET_HAS_NEW_UPDATER);
}
async function ensureModule(name) {
let modulePromise = modulePromises[name];
if (modulePromise == null) {
modulePromise = electron.ipcRenderer.invoke(NATIVE_MODULES_INSTALL, name);
}
requireModule
`, context);
await modulePromise;
module.paths = getSanitizedModulePaths();
}
function requireModule(name) {
return _requireModule((id) => {
return require("../../../../../"+id)
}, name);
if (!/^discord_[a-z0-9_-]+$/.test(name) && name !== 'erlpack') {
throw new Error('"' + String(name) + '" is not a whitelisted native module');
}
return require("../../../../../"+name);
}
module.paths = getSanitizedModulePaths();
module.exports = {
ensureModule,
requireModule
requireModule,
canBootstrapNewUpdater: !getHasNewUpdater()
};

View File

@ -1,9 +1,11 @@
'use strict';
"use strict";
const os = require('os');
const process = require('process');
let arch = os.arch();
if (process.platform === 'win32' && process.env['PROCESSOR_ARCHITEW6432'] != null) {
arch = 'x64';
}

View File

@ -1,18 +1,7 @@
'use strict';
let getSystemIdleTimeMs = (() => {
var _ref = _asyncToGenerator(function* () {
return electron.ipcRenderer.invoke(POWER_MONITOR_GET_SYSTEM_IDLE_TIME);
});
return function getSystemIdleTimeMs() {
return _ref.apply(this, arguments);
};
})();
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
"use strict";
const electron = require('electron');
const EventEmitter = require('events');
const {
@ -24,19 +13,15 @@ const {
} = require('../common/constants').IPCEvents;
const events = new EventEmitter();
electron.ipcRenderer.on(POWER_MONITOR_RESUME, () => {
events.emit('resume');
});
electron.ipcRenderer.on(POWER_MONITOR_SUSPEND, () => {
events.emit('suspend');
});
electron.ipcRenderer.on(POWER_MONITOR_LOCK_SCREEN, () => {
events.emit('lock-screen');
});
electron.ipcRenderer.on(POWER_MONITOR_UNLOCK_SCREEN, () => {
events.emit('unlock-screen');
});
@ -53,6 +38,10 @@ function removeAllListeners() {
events.removeAllListeners.apply(events, arguments);
}
async function getSystemIdleTimeMs() {
return electron.ipcRenderer.invoke(POWER_MONITOR_GET_SYSTEM_IDLE_TIME);
}
module.exports = {
on,
removeListener,

View File

@ -1,36 +1,4 @@
'use strict';
let blockDisplaySleep = (() => {
var _ref = _asyncToGenerator(function* () {
return electron.ipcRenderer.invoke(POWER_SAVE_BLOCKER_BLOCK_DISPLAY_SLEEP);
});
return function blockDisplaySleep() {
return _ref.apply(this, arguments);
};
})();
let unblockDisplaySleep = (() => {
var _ref2 = _asyncToGenerator(function* (id) {
return electron.ipcRenderer.invoke(POWER_SAVE_BLOCKER_UNBLOCK_DISPLAY_SLEEP, id);
});
return function unblockDisplaySleep(_x) {
return _ref2.apply(this, arguments);
};
})();
let cleanupDisplaySleep = (() => {
var _ref3 = _asyncToGenerator(function* () {
return electron.ipcRenderer.invoke(POWER_SAVE_BLOCKER_CLEANUP_DISPLAY_SLEEP);
});
return function cleanupDisplaySleep() {
return _ref3.apply(this, arguments);
};
})();
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
"use strict";
const electron = require('electron');
@ -40,6 +8,18 @@ const {
POWER_SAVE_BLOCKER_CLEANUP_DISPLAY_SLEEP
} = require('../common/constants').IPCEvents;
async function blockDisplaySleep() {
return electron.ipcRenderer.invoke(POWER_SAVE_BLOCKER_BLOCK_DISPLAY_SLEEP);
}
async function unblockDisplaySleep(id) {
return electron.ipcRenderer.invoke(POWER_SAVE_BLOCKER_UNBLOCK_DISPLAY_SLEEP, id);
}
async function cleanupDisplaySleep() {
return electron.ipcRenderer.invoke(POWER_SAVE_BLOCKER_CLEANUP_DISPLAY_SLEEP);
}
module.exports = {
blockDisplaySleep,
unblockDisplaySleep,

View File

@ -1,9 +1,10 @@
'use strict';
"use strict";
const electron = require('electron');
const process = require('process');
const env = process.env;
const process = require('process');
const env = process.env;
module.exports = {
platform: process.platform,
arch: process.arch,

View File

@ -1,58 +1,7 @@
'use strict';
let flushDNSCache = (() => {
var _ref = _asyncToGenerator(function* () {
electron.ipcRenderer.invoke(PROCESS_UTILS_FLUSH_DNS_CACHE);
});
return function flushDNSCache() {
return _ref.apply(this, arguments);
};
})();
let flushCookies = (() => {
var _ref2 = _asyncToGenerator(function* (callback) {
try {
yield electron.ipcRenderer.invoke(PROCESS_UTILS_FLUSH_COOKIES);
callback();
} catch (err) {
callback(err);
}
});
return function flushCookies(_x) {
return _ref2.apply(this, arguments);
};
})();
let flushStorageData = (() => {
var _ref3 = _asyncToGenerator(function* (callback) {
try {
yield electron.ipcRenderer.invoke(PROCESS_UTILS_FLUSH_STORAGE_DATA);
callback();
} catch (err) {
callback(err);
}
});
return function flushStorageData(_x2) {
return _ref3.apply(this, arguments);
};
})();
let purgeMemory = (() => {
var _ref4 = _asyncToGenerator(function* () {
electron.webFrame.clearCache();
});
return function purgeMemory() {
return _ref4.apply(this, arguments);
};
})();
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
"use strict";
const electron = require('electron');
const process = require('process');
const {
@ -63,23 +12,47 @@ const {
PROCESS_UTILS_FLUSH_STORAGE_DATA,
PROCESS_UTILS_GET_MAIN_ARGV_SYNC
} = require('../common/constants').IPCEvents;
const CPU_USAGE_GATHER_INTERVAL = 1000;
const MEMORY_USAGE_GATHER_INTERVAL = 5000;
const mainArgv = electron.ipcRenderer.sendSync(PROCESS_UTILS_GET_MAIN_ARGV_SYNC);
let totalProcessorUsagePercent = 0;
let totalMemoryUsageKB = 0;
setInterval(() => {
electron.ipcRenderer.invoke(PROCESS_UTILS_GET_CPU_USAGE).then(usage => totalProcessorUsagePercent = usage);
}, CPU_USAGE_GATHER_INTERVAL);
setInterval(() => {
Promise.all([process.getProcessMemoryInfo(), electron.ipcRenderer.invoke(PROCESS_UTILS_GET_MEMORY_INFO)].map(x => x.catch(() => 0))).then(usages => {
totalMemoryUsageKB = usages.reduce((total, usage) => total + usage.private, 0);
});
}, MEMORY_USAGE_GATHER_INTERVAL);
async function flushDNSCache() {
electron.ipcRenderer.invoke(PROCESS_UTILS_FLUSH_DNS_CACHE);
}
async function flushCookies(callback) {
try {
await electron.ipcRenderer.invoke(PROCESS_UTILS_FLUSH_COOKIES);
callback();
} catch (err) {
callback(err);
}
}
async function flushStorageData(callback) {
try {
await electron.ipcRenderer.invoke(PROCESS_UTILS_FLUSH_STORAGE_DATA);
callback();
} catch (err) {
callback(err);
}
}
async function purgeMemory() {
electron.webFrame.clearCache();
}
function getCurrentCPUUsagePercent() {
return totalProcessorUsagePercent;
}

View File

@ -1,30 +1,28 @@
'use strict';
let get = (() => {
var _ref = _asyncToGenerator(function* (name, defaultValue) {
return electron.ipcRenderer.invoke(SETTINGS_GET, name, defaultValue);
});
return function get(_x, _x2) {
return _ref.apply(this, arguments);
};
})();
let set = (() => {
var _ref2 = _asyncToGenerator(function* (name, value) {
return electron.ipcRenderer.invoke(SETTINGS_SET, name, value);
});
return function set(_x3, _x4) {
return _ref2.apply(this, arguments);
};
})();
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
"use strict";
const electron = require('electron');
const { SETTINGS_GET, SETTINGS_SET, SETTINGS_GET_SYNC } = require('../common/constants').IPCEvents;
const {
SETTINGS_GET,
SETTINGS_SET,
SETTINGS_GET_SYNC
} = require('../common/constants').IPCEvents; // Updating app settings directly from the renderer is considered deprecated.
// Voice still sets a few options, so we whitelist those.
const RENDERER_SET_WHITELIST = ['audioSubsystem', 'useLegacyAudioDevice', 'debugLogging'];
async function get(name, defaultValue) {
return electron.ipcRenderer.invoke(SETTINGS_GET, name, defaultValue);
}
async function set(name, value) {
if (!RENDERER_SET_WHITELIST.includes(name)) {
throw new Error('cannot set this setting key');
}
return electron.ipcRenderer.invoke(SETTINGS_SET, name, value);
}
function getSync(name, defaultValue) {
return electron.ipcRenderer.sendSync(SETTINGS_GET_SYNC, name, defaultValue);

View File

@ -1,10 +1,12 @@
'use strict';
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
"use strict";
const electron = require('electron');
const EventEmitter = require('events');
const { getElectronMajorVersion } = require('../common/utility');
const {
getElectronMajorVersion
} = require('../../../common/processUtils');
const {
SPELLCHECK_RESULT,
@ -15,87 +17,23 @@ const {
} = require('../common/constants').IPCEvents;
if (getElectronMajorVersion() < 8) {
let setSpellCheckProvider = (() => {
var _ref = _asyncToGenerator(function* (locale, autoCorrectWord, provider) {
const asyncProvider = {
spellCheck: function (words, callback) {
return callback(words.filter(function (word) {
return !provider.spellCheck(word);
}));
}
};
electron.webFrame.setSpellCheckProvider(locale, asyncProvider);
});
return function setSpellCheckProvider(_x, _x2, _x3) {
return _ref.apply(this, arguments);
async function setSpellCheckProvider(locale, autoCorrectWord, provider) {
const asyncProvider = {
spellCheck: (words, callback) => callback(words.filter(word => !provider.spellCheck(word)))
};
})();
electron.webFrame.setSpellCheckProvider(locale, asyncProvider);
}
let replaceMisspelling = (() => {
var _ref2 = _asyncToGenerator(function* (word) {
electron.ipcRenderer.invoke(SPELLCHECK_REPLACE_MISSPELLING, word);
});
return function replaceMisspelling(_x4) {
return _ref2.apply(this, arguments);
};
})();
async function replaceMisspelling(word) {
electron.ipcRenderer.invoke(SPELLCHECK_REPLACE_MISSPELLING, word);
}
module.exports = {
setSpellCheckProvider,
replaceMisspelling
};
} else {
let getAvailableDictionaries = (() => {
var _ref3 = _asyncToGenerator(function* () {
return electron.ipcRenderer.invoke(SPELLCHECK_GET_AVAILABLE_DICTIONARIES);
});
return function getAvailableDictionaries() {
return _ref3.apply(this, arguments);
};
})();
let setLocale = (() => {
var _ref4 = _asyncToGenerator(function* (locale) {
let succeeded = true;
try {
yield electron.ipcRenderer.invoke(SPELLCHECK_SET_LOCALE, locale);
} catch (_) {
succeeded = false;
}
return succeeded;
});
return function setLocale(_x5) {
return _ref4.apply(this, arguments);
};
})();
let setLearnedWords = (() => {
var _ref5 = _asyncToGenerator(function* (learnedWords) {
return electron.ipcRenderer.invoke(SPELLCHECK_SET_LEARNED_WORDS, learnedWords);
});
return function setLearnedWords(_x6) {
return _ref5.apply(this, arguments);
};
})();
let replaceMisspelling = (() => {
var _ref6 = _asyncToGenerator(function* (correction) {
return electron.ipcRenderer.invoke(SPELLCHECK_REPLACE_MISSPELLING, correction);
});
return function replaceMisspelling(_x7) {
return _ref6.apply(this, arguments);
};
})();
const events = new EventEmitter();
electron.ipcRenderer.on(SPELLCHECK_RESULT, handleSpellcheckData);
function handleSpellcheckData(_, misspelledWord, dictionarySuggestions) {
@ -110,6 +48,30 @@ if (getElectronMajorVersion() < 8) {
events.removeListener.apply(events, arguments);
}
async function getAvailableDictionaries() {
return electron.ipcRenderer.invoke(SPELLCHECK_GET_AVAILABLE_DICTIONARIES);
}
async function setLocale(locale) {
let succeeded = true;
try {
await electron.ipcRenderer.invoke(SPELLCHECK_SET_LOCALE, locale);
} catch (_) {
succeeded = false;
}
return succeeded;
}
async function setLearnedWords(learnedWords) {
return electron.ipcRenderer.invoke(SPELLCHECK_SET_LEARNED_WORDS, learnedWords);
}
async function replaceMisspelling(correction) {
return electron.ipcRenderer.invoke(SPELLCHECK_REPLACE_MISSPELLING, correction);
}
module.exports = {
on,
removeListener,

View File

@ -0,0 +1,28 @@
"use strict";
const electron = require('electron');
const {
USER_DATA_CACHE_SAVE,
USER_DATA_CACHE_GET,
USER_DATA_CACHE_DELETE
} = require('../common/constants').IPCEvents;
async function getCached() {
const cached = await electron.ipcRenderer.invoke(USER_DATA_CACHE_GET);
return cached;
}
function cacheUserData(userData) {
electron.ipcRenderer.send(USER_DATA_CACHE_SAVE, userData);
}
function deleteCache() {
electron.ipcRenderer.send(USER_DATA_CACHE_DELETE);
}
module.exports = {
getCached,
cacheUserData,
deleteCache
};

View File

@ -1,148 +1,4 @@
'use strict';
let flashFrame = (() => {
var _ref3 = _asyncToGenerator(function* (flag) {
electron.ipcRenderer.invoke(WINDOW_FLASH_FRAME, flag);
});
return function flashFrame(_x3) {
return _ref3.apply(this, arguments);
};
})();
let minimize = (() => {
var _ref4 = _asyncToGenerator(function* (key) {
electron.ipcRenderer.invoke(WINDOW_MINIMIZE, key);
});
return function minimize(_x4) {
return _ref4.apply(this, arguments);
};
})();
let restore = (() => {
var _ref5 = _asyncToGenerator(function* (key) {
electron.ipcRenderer.invoke(WINDOW_RESTORE, key);
});
return function restore(_x5) {
return _ref5.apply(this, arguments);
};
})();
let maximize = (() => {
var _ref6 = _asyncToGenerator(function* (key) {
electron.ipcRenderer.invoke(WINDOW_MAXIMIZE, key);
});
return function maximize(_x6) {
return _ref6.apply(this, arguments);
};
})();
let focus = (() => {
var _ref7 = _asyncToGenerator(function* (_hack, key) {
electron.ipcRenderer.invoke(WINDOW_FOCUS, key);
});
return function focus(_x7, _x8) {
return _ref7.apply(this, arguments);
};
})();
let setAlwaysOnTop = (() => {
var _ref8 = _asyncToGenerator(function* (key, enabled) {
return electron.ipcRenderer.invoke(WINDOW_SET_ALWAYS_ON_TOP, key, enabled);
});
return function setAlwaysOnTop(_x9, _x10) {
return _ref8.apply(this, arguments);
};
})();
let isAlwaysOnTop = (() => {
var _ref9 = _asyncToGenerator(function* (key) {
return electron.ipcRenderer.invoke(WINDOW_IS_ALWAYS_ON_TOP, key);
});
return function isAlwaysOnTop(_x11) {
return _ref9.apply(this, arguments);
};
})();
let blur = (() => {
var _ref10 = _asyncToGenerator(function* (key) {
electron.ipcRenderer.invoke(WINDOW_BLUR, key);
});
return function blur(_x12) {
return _ref10.apply(this, arguments);
};
})();
let setProgressBar = (() => {
var _ref11 = _asyncToGenerator(function* (progress, key) {
electron.ipcRenderer.invoke(WINDOW_SET_PROGRESS_BAR, key, progress);
});
return function setProgressBar(_x13, _x14) {
return _ref11.apply(this, arguments);
};
})();
let fullscreen = (() => {
var _ref12 = _asyncToGenerator(function* (key) {
electron.ipcRenderer.invoke(WINDOW_TOGGLE_FULLSCREEN, key);
});
return function fullscreen(_x15) {
return _ref12.apply(this, arguments);
};
})();
let close = (() => {
var _ref13 = _asyncToGenerator(function* (key) {
electron.ipcRenderer.invoke(WINDOW_CLOSE, key);
});
return function close(_x16) {
return _ref13.apply(this, arguments);
};
})();
let setZoomFactor = (() => {
var _ref14 = _asyncToGenerator(function* (factor) {
if (!electron.webFrame.setZoomFactor) return;
electron.webFrame.setZoomFactor(factor / 100);
});
return function setZoomFactor(_x17) {
return _ref14.apply(this, arguments);
};
})();
let setBackgroundThrottling = (() => {
var _ref15 = _asyncToGenerator(function* (enabled) {
electron.ipcRenderer.invoke(WINDOW_SET_BACKGROUND_THROTTLING, enabled);
});
return function setBackgroundThrottling(_x18) {
return _ref15.apply(this, arguments);
};
})();
let setDevtoolsCallbacks = (() => {
var _ref16 = _asyncToGenerator(function* (onOpened, onClosed) {
devtoolsOpenedCallback = onOpened;
devtoolsClosedCallback = onClosed;
});
return function setDevtoolsCallbacks(_x19, _x20) {
return _ref16.apply(this, arguments);
};
})();
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
"use strict";
const electron = require('electron');
@ -164,31 +20,77 @@ const {
} = require('../common/constants').IPCEvents;
let devtoolsOpenedCallback = () => {};
let devtoolsClosedCallback = () => {};
electron.ipcRenderer.on(WINDOW_DEVTOOLS_OPENED, (() => {
var _ref = _asyncToGenerator(function* (_) {
if (devtoolsOpenedCallback != null) {
devtoolsOpenedCallback();
}
});
electron.ipcRenderer.on(WINDOW_DEVTOOLS_OPENED, async _ => {
if (devtoolsOpenedCallback != null) {
devtoolsOpenedCallback();
}
});
electron.ipcRenderer.on(WINDOW_DEVTOOLS_CLOSED, async _ => {
if (devtoolsOpenedCallback != null) {
devtoolsOpenedCallback();
}
});
return function (_x) {
return _ref.apply(this, arguments);
};
})());
async function flashFrame(flag) {
electron.ipcRenderer.invoke(WINDOW_FLASH_FRAME, flag);
}
electron.ipcRenderer.on(WINDOW_DEVTOOLS_CLOSED, (() => {
var _ref2 = _asyncToGenerator(function* (_) {
if (devtoolsOpenedCallback != null) {
devtoolsOpenedCallback();
}
});
async function minimize(key) {
electron.ipcRenderer.invoke(WINDOW_MINIMIZE, key);
}
return function (_x2) {
return _ref2.apply(this, arguments);
};
})());
async function restore(key) {
electron.ipcRenderer.invoke(WINDOW_RESTORE, key);
}
async function maximize(key) {
electron.ipcRenderer.invoke(WINDOW_MAXIMIZE, key);
}
async function focus(_hack, key) {
electron.ipcRenderer.invoke(WINDOW_FOCUS, key);
}
async function setAlwaysOnTop(key, enabled) {
return electron.ipcRenderer.invoke(WINDOW_SET_ALWAYS_ON_TOP, key, enabled);
}
async function isAlwaysOnTop(key) {
return electron.ipcRenderer.invoke(WINDOW_IS_ALWAYS_ON_TOP, key);
}
async function blur(key) {
electron.ipcRenderer.invoke(WINDOW_BLUR, key);
}
async function setProgressBar(progress, key) {
electron.ipcRenderer.invoke(WINDOW_SET_PROGRESS_BAR, key, progress);
}
async function fullscreen(key) {
electron.ipcRenderer.invoke(WINDOW_TOGGLE_FULLSCREEN, key);
}
async function close(key) {
electron.ipcRenderer.invoke(WINDOW_CLOSE, key);
}
async function setZoomFactor(factor) {
if (!electron.webFrame.setZoomFactor) return;
electron.webFrame.setZoomFactor(factor / 100);
}
async function setBackgroundThrottling(enabled) {
electron.ipcRenderer.invoke(WINDOW_SET_BACKGROUND_THROTTLING, enabled);
}
async function setDevtoolsCallbacks(onOpened, onClosed) {
devtoolsOpenedCallback = onOpened;
devtoolsClosedCallback = onClosed;
}
module.exports = {
flashFrame,

Some files were not shown because too many files have changed in this diff Show More