Compare commits

...

3127 Commits

Author SHA1 Message Date
Alexei Stukov 835cc3134c
Merge pull request #318 from JsSucks/2.0.0-beta.6
beta6
2019-03-16 19:22:45 +02:00
Jiiks 02b30153ee beta6 2019-03-16 19:18:28 +02:00
Alexei Stukov d09dc5a2a5
Merge pull request #315 from Mega-Mewthree/patch-3
Fix #303, Try 3
2019-03-16 19:12:08 +02:00
Mega-Mewthree 98d9a30027
Fix #303, Try 3 2019-03-12 22:11:05 -07:00
Alexei Stukov 5cb4bc15bd
Merge pull request #312 from samuelthomas2774/component-patches
React component patches
2019-03-12 22:44:26 +02:00
Alexei Stukov bb2aba04d5
Missing FileUtils import 2019-03-12 22:40:21 +02:00
Samuel Elliott 82e9b0bd6a
Fix packed plugins 2019-03-12 19:47:55 +00:00
Samuel Elliott 47575d3449
Don’t watch packed themes 2019-03-12 19:22:27 +00:00
Samuel Elliott 32e2582ded
Use the system temporary directory for packed content 2019-03-12 19:10:09 +00:00
Samuel Elliott d58dda6f50
Fix E2EE message button patch 2019-03-12 17:23:56 +00:00
Samuel Elliott 648954d533
Rerender messages when disabling coloured text and fix jumbo Discord emoji in spoilers 2019-03-12 15:59:18 +00:00
Samuel Elliott 4aa38f4582
Move E2EE and emote module to their own directories 2019-03-12 15:27:05 +00:00
Samuel Elliott b3ba1aef13
Render emotes in spoilers 2019-03-11 17:56:29 +00:00
Samuel Elliott 2a6cbd39b7
Remove logging 2019-03-11 16:43:18 +00:00
Samuel Elliott ce5bcb9b85
Patch MessageAccessories instead of ImageWrapper for emotes sent as images 2019-03-10 21:29:17 +00:00
Samuel Elliott 5a3821ad3e
Package installer UploadArea patch 2019-03-10 20:29:55 +00:00
Samuel Elliott fd0032b24c
Autocomplete 2019-03-10 18:12:43 +00:00
Samuel Elliott 226719b36e
Rerender messages after loading emotes 2019-03-10 17:45:20 +00:00
Samuel Elliott fcfee53928
Move all component selectors + filters to ReactAutoPatcher 2019-03-10 16:58:24 +00:00
Samuel Elliott 285ae34b50
Fix component patches 2019-03-10 16:30:13 +00:00
Alexei Stukov a170a97688
Merge pull request #306 from samuelthomas2774/keytar-4.4.1
macOS + Linux keytar + node-sass bindings
2019-03-10 15:30:36 +02:00
Samuel Elliott a770f57b28
Linux keytar + node-sass bindings for Discord Canary 2019-03-10 00:04:02 +00:00
Samuel Elliott 5757fc20c9
macOS keytar + node-sass bindings for Discord Canary 2019-03-09 23:57:29 +00:00
Samuel Elliott 421289f63b
Linux keytar binding 2019-03-09 23:36:47 +00:00
Samuel Elliott ac85316578
.. 2019-03-09 22:02:40 +00:00
Samuel Elliott 08af9be061
Fix guilds wrapper position 2019-03-09 21:55:13 +00:00
Samuel Elliott ead0fbbd1e
Fix extra space on macOS in the plugins and themes panel and use BdMenuItems to add the super secret view 2019-03-09 21:43:41 +00:00
Samuel Elliott dc85a808f8
Fix undefined/storage file 2019-03-09 21:24:01 +00:00
Samuel Elliott aecfa814f9
Fix error Cannot find module ‘core/dist/package.json’ 2019-03-09 20:52:04 +00:00
Samuel Elliott 436f3d3c36
macOS keytar binding 2019-03-09 20:41:40 +00:00
Alexei Stukov 68a8187964
Merge pull request #300 from JsSucks/Jiiks-patch-1
Update issue templates
2019-03-08 21:54:49 +02:00
Alexei Stukov f30e4c12fe
Update issue templates 2019-03-08 21:51:44 +02:00
Alexei Stukov 686514ed1d
Merge pull request #299 from JsSucks/Jiiks-patch-1
Update issue templates
2019-03-08 21:43:50 +02:00
Alexei Stukov d795da1750
Update issue templates 2019-03-08 21:38:52 +02:00
Alexei Stukov 3219ff7c6e
Merge pull request #293 from JsSucks/2.0.0-beta.4
beta 4 to master
2019-03-08 14:11:13 +02:00
Alexei Stukov 33567a2cfd
Merge pull request #292 from JsSucks/updater
Updater
2019-03-08 14:08:07 +02:00
Jiiks 85310bfbff Stop updater thread 2019-03-08 14:00:54 +02:00
Jiiks d1d79a37b7 Start updater and set interval to 30 minutes 2019-03-08 13:58:46 +02:00
Jiiks d95592acc9 Styling and debug view 2019-03-08 13:57:02 +02:00
Jiiks f6a3fb65da v69 bindings 2019-03-08 13:33:52 +02:00
Alexei Stukov 6788cca363
Merge pull request #291 from XeonPowder/patch-1
fixed comma
2019-03-08 00:41:41 +02:00
Lars van der Zande 1fb442e096
fixed comma 2019-03-07 16:30:21 -06:00
Jiiks 6e64ff61c5 Copy csp.json 2019-03-07 23:50:17 +02:00
Jiiks dd8fe68a11 Better 2019-03-07 22:57:07 +02:00
Jiiks a3829089f9 Secrets for devs 2019-03-07 22:54:16 +02:00
Jiiks 174c1ee791 add some secrets 2019-03-07 22:44:29 +02:00
Jiiks b8793fd2b6 Package parsing for production 2019-03-07 21:09:48 +02:00
Jiiks 31986ca3a0 Try to rename first. 2019-03-07 20:22:11 +02:00
Jiiks 10ff740f75 Remove asar external from production 2019-03-07 19:34:32 +02:00
Jiiks 83fbab63c0 add release test script for faster release testing. copy extra files 2019-03-07 19:21:27 +02:00
Jiiks c4670946e6 Use replace to set production 2019-03-07 19:10:08 +02:00
Jiiks e5239d952e Send error event 2019-03-07 14:15:24 +02:00
Jiiks a57783a9d8 add updates available notification 2019-03-07 11:41:32 +02:00
Jiiks 001a6e4fda Functional updater 2019-03-07 11:35:24 +02:00
Jiiks dd621038f9 Reload and restart notifications 2019-03-06 12:57:19 +02:00
Jiiks 288c233447 tar.gz download 2019-03-06 12:11:45 +02:00
Jiiks 399c6e792b Updater ui 2019-03-06 09:29:23 +02:00
Jiiks 0be6facba4 assign old state, some updater checks. 2019-03-06 09:04:03 +02:00
Jiiks dc7247a12d Send updates to client 2019-03-06 08:36:54 +02:00
Jiiks 377c4fd104 Send updater events 2019-03-06 08:19:09 +02:00
Jiiks 252d496dc2 Get release from github, todo use common 2019-03-06 02:57:57 +02:00
Jiiks 83e334c3f8 Getters, debug 2019-03-06 02:16:27 +02:00
Jiiks e72ad10dfc add semver 2019-03-06 02:02:02 +02:00
Jiiks 9ef392c575 test updater 2019-03-05 23:46:42 +02:00
Jiiks 76057efbb7 Remove old updater code 2019-03-05 23:35:39 +02:00
Jiiks dcb121750a Use core version as the main version 2019-03-05 23:30:41 +02:00
Jiiks 13fa769e9e add versions to config 2019-03-05 23:26:17 +02:00
Jiiks 3143991239 Nevet test editor in production 2019-03-05 21:31:40 +02:00
Jiiks 1ae0c5aa4d Never ignore externals in production 2019-03-05 21:31:20 +02:00
Jiiks 5ea39f86f7 add axios to vendor 2019-03-05 21:28:32 +02:00
Jiiks d6a946e096 headers 2019-03-05 21:26:36 +02:00
Jiiks b68c1fbd04 Move csp and add some sources. 2019-03-05 21:02:06 +02:00
Jiiks 07d3629622 axios wrapper base 2019-03-05 20:38:21 +02:00
Jiiks 15daa9acef add axios because it's better 2019-03-05 20:22:26 +02:00
Jiiks 817a4a03b6 add versions to test args and version getters to config 2019-03-05 12:56:19 +02:00
Jiiks e63386e9eb Updater base 2019-03-05 12:53:08 +02:00
Jiiks 402acdfea9 Wrong main 2019-03-05 10:11:45 +02:00
Jiiks b440206d07 add webpack parallel build/watch 2019-03-05 10:07:49 +02:00
Jiiks c7bea4a743 remove csseditor 2019-03-05 09:43:25 +02:00
Jiiks 2528d87b8f beta.4 branch. all future pulls should go to the latest dev branch instead of master. 2019-03-05 08:46:27 +02:00
Alexei Stukov 405d74fada
Merge pull request #290 from JsSucks/Jiiks-patch-1
I like badges
2019-03-05 08:41:27 +02:00
Alexei Stukov b311220132
I like badges 2019-03-05 08:39:11 +02:00
Alexei Stukov 66b47457b1
Merge pull request #289 from JsSucks/snyk-badge
Snyk badge
2019-03-05 08:30:49 +02:00
Alexei Stukov 6e9f9f8bf8
put it in correct place 2019-03-05 07:46:02 +02:00
Alexei Stukov 88a113dc8f
snyk badge 2019-03-05 07:44:13 +02:00
Alexei Stukov a61f860466
Merge pull request #288 from JsSucks/update-versions
Update versions
2019-03-05 07:43:53 +02:00
Jiiks 729a4607bd Use mver for release tag instead. 2019-03-05 07:35:59 +02:00
Jiiks d81dcc9aa2 refresh lock, fix editor production config 2019-03-05 07:32:11 +02:00
Jiiks 1e4f3fa82b semver 2019-03-05 07:25:18 +02:00
Alexei Stukov 150a1d63c4
Merge pull request #287 from JsSucks/deps-and-scripts
Deps and scripts
2019-03-04 20:12:14 +02:00
Jiiks 6b481733b9 editor webpack merge 2019-03-04 20:08:48 +02:00
Jiiks e07b9b1550 bindings 2019-03-04 19:50:34 +02:00
Jiiks 99c2b53ec6 depcopy and configs 2019-03-04 17:02:52 +02:00
Jiiks 2a93e5d2a3 lint 2019-03-04 10:25:00 +02:00
Jiiks 3661207602 switch to babel.config.js 2019-03-04 10:12:42 +02:00
Jiiks 92845728cc command line pls 2019-03-04 10:09:58 +02:00
Jiiks c99753fc8c Use webpack merge to simplify configs 2019-03-04 10:07:32 +02:00
Jiiks 688e6022a0 pls 2019-03-04 09:55:34 +02:00
Jiiks 5408d994be babel config for client 2019-03-04 09:52:25 +02:00
Zack Rauen 003c9766bc remove uglifyjs plugin 2019-03-03 14:47:44 -05:00
Zack Rauen 82e9c257ce Update deps 2019-03-02 22:15:24 -05:00
Jiiks 6167cc7c4b remove installer build 2019-03-01 22:02:06 +02:00
Jiiks 1bacecf8d4 vtc 2019-03-01 22:01:37 +02:00
Jiiks d102686379 vue, vue-color, remove cm, remove csseditor scripts 2019-03-01 21:56:35 +02:00
Jiiks 1160955629 add chokidar 2019-03-01 20:15:30 +02:00
Jiiks e60f765a50 Move bdedit to devdeps 2019-03-01 20:14:33 +02:00
Alexei Stukov d3db696616
Merge pull request #284 from JsSucks/installer-compliance
Installer compliance
2019-02-28 19:25:39 +02:00
Jiiks b8d16c6e4d Load correct editor file 2019-02-28 17:07:53 +02:00
Jiiks b22923d12f editor packaging 2019-02-28 17:00:25 +02:00
Jiiks 1ea307efdd Editor release build 2019-02-28 16:51:45 +02:00
Jiiks d98cff878f uglify editor 2019-02-28 16:47:49 +02:00
Jiiks dd11708f9f return null if no path 2019-02-28 15:20:36 +02:00
Jiiks 665a7818c9 Make sure editor path is set 2019-02-28 15:12:17 +02:00
Jiiks d75b907ae4 ensure user.scss exists 2019-02-28 15:10:34 +02:00
Alexei Stukov f051bc4812
Merge pull request #286 from JsSucks/bdedit
Bdedit
2019-02-28 14:46:48 +02:00
Jiiks 9773f78506 Toasts and name conflict handler 2019-02-28 12:37:57 +02:00
Alexei Stukov f4b7c99c31
Merge pull request #283 from JsSucks/bdedit
Bdedit
2019-02-28 09:51:20 +02:00
Jiiks 97519b2307 lint 2019-02-28 09:48:45 +02:00
Jiiks 806ca5028a auto imports 2019-02-28 09:46:24 +02:00
Jiiks db89e3a1a0 sass doesn't like empty 2019-02-28 09:45:06 +02:00
Jiiks 6030a78b91 Delete and rename handlers 2019-02-28 06:40:33 +02:00
Jiiks 99ec82795c reveal, copy and copypath handlers 2019-02-28 06:05:54 +02:00
Jiiks b1e8b591ba Remove todo 2019-02-27 20:34:31 +02:00
Jiiks ac9e16632d Snippet save/load 2019-02-27 20:34:11 +02:00
Jiiks d8f977b57a Not a dir anymore 2019-02-27 16:43:13 +02:00
Jiiks c3283c47f6 Tons of smol things 2019-02-27 08:10:04 +02:00
Jiiks 2b86f2d741 File watchers 2019-02-27 01:33:23 +02:00
Jiiks 9f6389845a add live update 5 seconds after last change 2019-02-26 22:24:05 +02:00
Jiiks 7489fd0aaf Titlebar buttons fix 2019-02-26 20:30:07 +02:00
Jiiks 7e1c379fd3 Set user.scss caption 2019-02-26 20:19:57 +02:00
Jiiks c0765120e8 Juggle paths and keep user.scss in data 2019-02-26 20:18:33 +02:00
Jiiks 7e10de32cb add new paths and enable snippet import 2019-02-26 19:54:13 +02:00
Jiiks 145d61fe5e Enable importing other files 2019-02-26 18:32:06 +02:00
Jiiks 72b278de6e js should be javascript 2019-02-26 16:33:14 +02:00
Jiiks 5e977e8dc4 Hoist user.scss 2019-02-25 18:05:51 +02:00
Jiiks 109eb31aa5 custom css inject and file saved state 2019-02-25 17:56:56 +02:00
Jiiks 1b6f3005f5 No need to compile if not scss 2019-02-25 13:01:46 +02:00
Jiiks d02f894d4a Style inject 2019-02-25 12:41:22 +02:00
Jiiks 20561e2938 Set type 2019-02-25 12:10:00 +02:00
Jiiks a3724d739b Read files on load at least for now 2019-02-24 21:56:46 +02:00
Jiiks cf1da34e16 add editor file writing 2019-02-24 21:38:33 +02:00
Jiiks 5454950838 add writefile 2019-02-24 21:36:04 +02:00
Jiiks ed7abe3571 Don't need all these prefixes since they're automated 2019-02-24 21:29:54 +02:00
Jiiks b14bf93ef9 remove todo 2019-02-24 21:27:05 +02:00
Jiiks 3436bbe52b add editor test flag 2019-02-24 21:26:52 +02:00
Jiiks 1a26e77dd9 Move editor events to editor 2019-02-24 21:24:37 +02:00
Jiiks da1fc0a2f0 Smol things 2019-02-24 19:57:46 +02:00
Jiiks d1fd5ae881 imodule and base for new editor module in client 2019-02-24 19:46:11 +02:00
Jiiks 8c04e7d2d3 File/snippet saving signals 2019-02-24 18:43:58 +02:00
Jiiks 3fc1adc503 get files/snippets from core 2019-02-24 18:39:28 +02:00
Jiiks 691c9f378a new file/snippet 2019-02-24 18:29:00 +02:00
Jiiks a769385219 Run scripts from editor in Discord window 2019-02-24 16:04:25 +02:00
Jiiks f1f23fa220 Initial BDEdit addition. No logic yet. 2019-02-24 13:03:15 +02:00
Jiiks 99ef0d9f81 add bdedit 2019-02-24 12:28:29 +02:00
Jiiks 5597c485d1 oops 2019-02-24 12:12:13 +02:00
Jiiks 7f08ba27e6 Remove my test script 2019-02-24 12:02:30 +02:00
Jiiks 99614aecdc Fix linter warnings 2019-02-24 11:56:07 +02:00
Alexei Stukov 726db7f0c9
Merge pull request #279 from JsSucks/dnd-patch
Add dnd in non-channels and fix upload failover
2019-02-24 11:46:57 +02:00
Zack Rauen 67c39fd9d9 Add dnd in non-channels and fix upload failover 2019-02-23 09:42:53 -05:00
Jiiks 23d4eb77b2 Fix test mode 2019-02-20 20:13:27 +02:00
Jiiks 124ec078aa only warn if tag is not set 2019-02-20 16:12:56 +02:00
Jiiks e6c9bc447e allow tag to be set with args 2019-02-20 16:10:18 +02:00
Jiiks 7bc4b652fa add child process as external instead of asar 2019-02-20 16:03:03 +02:00
Alexei Stukov 6ab1f5c844
Merge pull request #278 from JsSucks/Jiiks-patch-1
Core version
2019-02-18 15:26:32 +02:00
Alexei Stukov 816ff2ed08
Core version 2019-02-18 15:23:05 +02:00
Jiiks 6ca36ebbb5 Should use core package 2019-02-18 15:21:51 +02:00
Jiiks f511e4556e keep stub 2019-02-18 15:20:44 +02:00
Alexei Stukov 36515432c7
Merge pull request #277 from JsSucks/Jiiks-patch-1
stub should be a file
2019-02-18 15:07:54 +02:00
Alexei Stukov 47782c0168
stub should be a file 2019-02-18 15:03:17 +02:00
Jiiks 3a370f2827 higher compression for core 2019-02-18 15:01:30 +02:00
Jiiks 90f5596cb2 files should be under respective dir 2019-02-18 14:57:00 +02:00
Jiiks 75439a600e stub should be a file 2019-02-18 14:54:27 +02:00
Alexei Stukov f46960fdd0
Merge pull request #276 from JsSucks/Jiiks-patch-1
Installer Test 2
2019-02-18 12:29:38 +02:00
Alexei Stukov f684780842
Installer Test 2 2019-02-18 12:26:29 +02:00
Jiiks 6c8631f1cd TODO editor packaging/renaming 2019-02-18 12:14:38 +02:00
Jiiks 0311602539 update scripts 2019-02-18 12:13:51 +02:00
Jiiks b5e8098d20 Not having asar in externals causes some weird error 2019-02-18 12:03:54 +02:00
Jiiks 111be57b59 release task 2019-02-18 11:42:34 +02:00
Jiiks 76e19c8469 wip script updates 2019-02-18 09:21:28 +02:00
Jiiks ccff016820 init comms module duh 2019-02-17 14:14:07 +02:00
Jiiks 021e282b1c add tests flag back 2019-02-17 12:26:07 +02:00
Jiiks 6699fcc1e7 add base for compatibility 2019-02-17 12:22:13 +02:00
Jiiks f3ea192974 Paths compatibility 2019-02-17 12:18:16 +02:00
Jiiks 9c1a93f4c1 Remove installer scripts, correct sparkplug external 2019-02-17 11:58:45 +02:00
Jiiks 2c23f18e89 New installer compliance 2019-02-17 11:12:12 +02:00
Jiiks c88d2cdae9 paths is an object now 2019-02-17 08:48:41 +02:00
Alexei Stukov 8235e55357
Merge pull request #275 from JsSucks/Jiiks-patch-1
Update releaseinfo.json
2019-02-16 03:43:40 +02:00
Alexei Stukov 754e6bbd72
Update releaseinfo.json 2019-02-16 03:40:17 +02:00
Alexei Stukov e27d8874ef
Merge pull request #274 from JsSucks/lodash-vuln
https://nvd.nist.gov/vuln/detail/CVE-2018-16487
2019-02-10 18:49:32 +02:00
Alexei Stukov c310cc52d5
Merge pull request #267 from BeardDesign1/master
Fixed a bunch of transitions and changed the arrow animation.
2019-02-10 18:47:59 +02:00
Jiiks 073cce825d https://nvd.nist.gov/vuln/detail/CVE-2018-16487 2019-02-10 18:45:57 +02:00
Alexei Stukov a04fb59db7
Merge pull request #273 from JsSucks/Jiiks-patch-1
Create README.MD
2019-02-06 01:53:39 +02:00
Alexei Stukov f8ed871f8e
Create README.MD 2019-02-06 01:50:53 +02:00
Alexei Stukov fae97613d1
Merge pull request #272 from JsSucks/installer-stuff
Installer stuff
2019-02-01 15:07:46 +02:00
Jiiks 27df24f369 Update stub 2019-02-01 15:00:03 +02:00
Jiiks 5bb95f59c0 update installer info 2019-02-01 14:58:50 +02:00
Alexei Stukov bcabaab14c
Merge pull request #271 from JsSucks/Jiiks-patch-1
Create stub.js
2019-02-01 09:20:45 +02:00
Alexei Stukov 033f3472cb
Create stub.js 2019-02-01 09:08:21 +02:00
Alexei Stukov 8fbd75ce94
Merge pull request #270 from JsSucks/Jiiks-patch-1
Update installer.json
2019-01-23 11:41:53 +02:00
Alexei Stukov 3a38b59a4d
Update installer.json 2019-01-23 11:38:57 +02:00
Alexei Stukov c29b659afb
Merge pull request #269 from JsSucks/installer-tests
Create installer.json
2019-01-20 21:31:30 +02:00
Alexei Stukov ece161fac0
Create installer.json 2019-01-20 21:28:12 +02:00
Lilian Tedone b57ab92269 Fixed a bunch of transitions and changed the arrow animation. 2019-01-08 08:41:24 +01:00
Alexei Stukov 5a3aa553cd
Merge pull request #266 from JsSucks/content-browser
Content browser
2018-12-06 11:26:26 +02:00
Jiiks a2f48dd007 lint 2018-12-06 11:23:31 +02:00
Jiiks 4f10f38581 Remote tests 2018-12-06 10:02:07 +02:00
Jiiks ea0dc0c6f1 Do the same for plugins 2018-12-05 10:58:43 +02:00
Jiiks 93f536bf21 Make tags clickable 2018-12-05 08:26:01 +02:00
Jiiks 497ab62ee6 Remove hover scaling 2018-12-05 08:09:15 +02:00
Jiiks 784a14f853 More neutral red 2018-12-05 08:08:52 +02:00
Jiiks 95447dd3f0 Array for sort buttons 2018-12-05 08:07:18 +02:00
Jiiks 2cff8edb59 Sorting by name is useless 2018-12-05 07:15:49 +02:00
Jiiks e4c0796e5e add rating sort 2018-12-05 00:43:40 +02:00
Jiiks e3010fcd43 Functional sorting 2018-12-05 00:40:57 +02:00
Jiiks 08b66d5e5a Functional sort buttons 2018-12-04 23:37:39 +02:00
Jiiks c618956639 flipy 2018-12-04 23:30:11 +02:00
Jiiks c6ddb75630 Remove sort by text 2018-12-04 23:25:49 +02:00
Jiiks 1fd7b97ce6 always have spinner container visible 2018-12-04 23:18:13 +02:00
Jiiks fa5be193ad add chevron to sort buttons and styling 2018-12-04 23:15:16 +02:00
Jiiks 63874c8b4e Sort styling 2018-12-04 23:02:36 +02:00
Jiiks b4dbfcd808 Pagination 2018-12-04 10:48:25 +02:00
Jiiks 7a9b72a33a Initial search 2018-12-04 09:30:49 +02:00
Jiiks 6db34b9cee Server emulator thing 2018-12-04 09:22:04 +02:00
Alexei Stukov ead51ae676
Merge pull request #265 from JsSucks/content-browser
Merge for now
2018-12-02 05:06:02 +02:00
Jiiks 9a77aae56b Lint 2018-12-02 04:13:57 +02:00
Jiiks 3182f28359 Layout and initial sort buttons 2018-12-02 02:23:03 +02:00
Jiiks a274b0c839 Styles 2018-12-02 02:20:16 +02:00
Jiiks 199b9249e4 Layout 2018-12-02 02:18:54 +02:00
Jiiks 08ba649a91 Sort box 2018-12-02 00:40:14 +02:00
Jiiks a0eb43188f add search results text 2018-12-02 00:30:20 +02:00
Jiiks b1bd5190c1 Initial loading logic for packed themes 2018-12-01 03:53:49 +02:00
Jiiks 7fb5c8a378 Theme packer 2018-11-30 22:13:36 +02:00
Jiiks 26b1fad5a4 Move packer to contentmanager 2018-11-30 22:08:05 +02:00
Jiiks f028aefab8 Source button 2018-11-30 21:14:52 +02:00
Jiiks f0d66300c4 Styling 2018-11-29 00:22:04 +02:00
Jiiks 12b291cf0b Temp online plugins, local content body scroller 2018-11-28 09:22:29 +02:00
Jiiks a8f686eb61 only scroll body 2018-11-28 08:50:14 +02:00
Jiiks 98bf4d21ac Load more on scroll 2018-11-26 17:15:26 +02:00
Jiiks d5a82ab2b3 Load more spinner 2018-11-26 17:04:20 +02:00
Jiiks d5d7709c9f Scrollend event 2018-11-26 11:32:22 +02:00
Jiiks cfc197cdc0 add spinner 2018-11-26 11:08:27 +02:00
Jiiks e8cfb840fe Styling 2018-11-26 10:56:35 +02:00
Jiiks f01f4926eb Random timestamps 2018-11-26 10:00:57 +02:00
Jiiks 83a4e0a114 Use moment 2018-11-26 09:55:59 +02:00
Jiiks 4b8a905d2a Dummy theme generation 2018-11-26 09:42:52 +02:00
Alexei Stukov 08ae8dceb5
Merge pull request #264 from JsSucks/emotemodule
Emotemodule
2018-11-26 07:31:53 +02:00
Jiiks ad28e7c638 Childpatch 2018-11-26 07:22:15 +02:00
Jiiks 9ba8047066 Fix MessageContent patch 2018-11-26 07:06:21 +02:00
Alexei Stukov 9ba9ec1556
Merge pull request #263 from JsSucks/package-updates
Package updates
2018-11-26 03:02:38 +02:00
Jiiks ce2658b6e2 electron 2018-11-26 02:56:31 +02:00
Jiiks f3cc033182 deepmerge 2018-11-26 02:54:50 +02:00
Jiiks 7b44d163ca node-sass 2018-11-26 02:53:12 +02:00
Alexei Stukov 72d24a1cb0
Merge pull request #262 from JsSucks/injection-patch
Injection patch
2018-11-26 02:50:34 +02:00
Alexei Stukov c2c520fe27
Merge pull request #260 from samuelthomas2774/electron-4.0.0-beta.7
Node Sass and keytar bindings for Electron 4.0.0 beta.7
2018-11-26 02:45:52 +02:00
Samuel Elliott ad55459649
Indentation 2018-11-25 02:19:10 +00:00
Samuel Elliott dfac3f1825
Add keytar and node-sass bindings from Jiiks 2018-11-25 02:13:14 +00:00
Samuel Elliott adecbf8945
Add Linux Node Sass binding 2018-11-25 02:10:19 +00:00
Samuel Elliott a371fabc70
Add keytar build scripts 2018-11-25 02:01:12 +00:00
Samuel Elliott c04ffdfc24
Working keytar binding for Linux 2018-11-25 01:58:35 +00:00
Samuel Elliott 572721c57f
Fix inject script for Canary on Linux 2018-11-25 01:04:07 +00:00
Samuel Elliott 4af09224d7
Update node-sass build script for Windows 2018-11-24 23:22:50 +00:00
Samuel Elliott 7f1ac9bea0
Update keytar and add bindings for Electron 4.0.0-beta.7 2018-11-24 23:20:25 +00:00
Samuel Elliott ce93b2b4c6
Updated node-sass build script for Electron 4.0.0-beta.7 2018-11-24 23:12:15 +00:00
Samuel Elliott d98ed6649e
Updated inject script (works on macOS and Linux) 2018-11-24 23:11:10 +00:00
Zack Rauen 468422084a fix injection for electron 4.0.0-beta.7 2018-11-24 17:44:28 -05:00
Alexei Stukov 395167aafa
Merge pull request #256 from JsSucks/reactcomponents
Fix for new context wrappers in Discord
2018-11-22 21:57:15 +02:00
Alexei Stukov 803cf59f11
Merge pull request #255 from JsSucks/message-content
Fix MessageContent not being found in multiple builtins
2018-11-22 21:57:00 +02:00
Alexei Stukov 133511aeec
Merge pull request #254 from JsSucks/electron-patch
fix for electron 3.x.x (now in discord canary)
2018-11-22 21:56:44 +02:00
Zack Rauen be024c1bbe quickfix array check 2018-10-10 23:58:16 -04:00
Zack Rauen 6f10c71623 add filter for MessageContent 2018-10-10 23:46:34 -04:00
Zack Rauen adb2430d71 fix for electron 3.x.x 2018-10-10 22:13:32 -04:00
Alexei Stukov 990453cdad
Merge pull request #253 from JsSucks/package-installer
Package installer
2018-08-31 08:36:45 +03:00
Jiiks 7cf69f6993 lint 2018-08-31 08:33:23 +03:00
Jiiks 5822110c87 Package updater fix 2018-08-31 05:16:42 +03:00
Jiiks 669a88c1ff Fix package installer and add remote loader 2018-08-31 05:01:05 +03:00
Jiiks 6a8c77b578 add error display 2018-08-31 00:42:05 +03:00
Jiiks a93d12df03 add support for updating unpacked to packed and packed with different package name 2018-08-30 21:24:09 +03:00
Jiiks 80096c5e71 Styling 2018-08-30 18:34:06 +03:00
Jiiks 307b084214 add success circle 2018-08-30 18:32:06 +03:00
Jiiks 1e0f3b69fb Success modal 2018-08-30 18:30:49 +03:00
Jiiks 550d0d3c40 Move uploadarea patcher to packageinstaller 2018-08-30 17:34:18 +03:00
Jiiks 96f8fe680f add verified text 2018-08-30 09:27:16 +03:00
Jiiks b48adc7a62 red outline file svg for unverified 2018-08-30 09:23:27 +03:00
Jiiks 6db016060b Small things 2018-08-30 09:08:52 +03:00
Jiiks ecb0b3e9d0 Verify step 2018-08-30 07:05:14 +03:00
Jiiks 8c060314da Functional installer/updater. Still needs lots of work. 2018-08-30 05:39:23 +03:00
Jiiks a040a605d4 Version is in info not in config 2018-08-29 23:09:30 +03:00
Jiiks 09fb76d148 Versions should be strings 2018-08-29 23:07:32 +03:00
Jiiks ddda5b3cc1 add checks and lint fixes 2018-08-29 23:02:41 +03:00
Jiiks cff425f916 Package installer & install modal 2018-08-29 06:19:18 +03:00
Jiiks 76d54f0a95 Fix plugin loading for packed plugins 2018-08-28 18:08:56 +03:00
Jiiks 2093c472b5 Move unsafe-content under security 2018-08-27 20:17:07 +03:00
Jiiks 1009c62ea0 duplicate asar external 2018-08-27 19:41:52 +03:00
Jiiks 2cd94fcd5f Remove package plugin button if plugin is already packaged 2018-08-27 19:39:29 +03:00
Jiiks cb35b14311 Remove debugs 2018-08-27 19:37:55 +03:00
Jiiks 6b3cb712c7 Block any nonpacked content by default if unsafe is not allowed 2018-08-27 19:36:06 +03:00
Jiiks cfbafffe46 add option for unsafe content 2018-08-27 19:17:33 +03:00
Jiiks 2913a85368 Packed content loading 2018-08-27 19:16:30 +03:00
Jiiks 5c160d75a6 add a packed test plugin 2018-08-27 17:32:21 +03:00
Jiiks f14b1b71e7 Use asar instead 2018-08-27 17:28:42 +03:00
Jiiks 4e3a56e466 Plugin packager 2018-08-26 22:39:04 +03:00
Alexei Stukov 30716b57e6
Merge pull request #251 from JsSucks/example-plugin
Render example
2018-08-26 17:56:22 +03:00
Jiiks b18559aa5e Rename to render example 2018-08-26 17:38:22 +03:00
Jiiks 6d8ef35bd6 add api's for easy generic components 2018-08-26 17:34:54 +03:00
Jiiks 8146e0e7f2 Make pluginmanager delete all relative modules from cache insted 2018-08-26 05:03:54 +03:00
Jiiks 23b8e2dd76 add and use the relative api 2018-08-26 03:48:23 +03:00
Jiiks e12dc28052 Vuewrap 2018-08-26 01:37:37 +03:00
Jiiks 6538442b0b Correct callback 2018-08-26 01:03:03 +03:00
Jiiks 4a9cc603d2 add vue component 2018-08-26 00:59:07 +03:00
Jiiks d4aa8fb377 Custom element example 2018-08-25 23:29:54 +03:00
Jiiks 977fd80d0c add walkers to pluginapi 2018-08-25 22:34:18 +03:00
Alexei Stukov ad64743874
Merge pull request #250 from JsSucks/builtin-refactor
E2EE Refactor
2018-08-25 19:24:30 +03:00
Jiiks 436c469b1d E2EE refactor for new builtin base 2018-08-25 19:19:19 +03:00
Alexei Stukov 7d05d0c884
Merge pull request #249 from JsSucks/builtin-refactor
Merge for now for e2ee fix.
2018-08-25 18:19:12 +03:00
Jiiks 1afbcacec3 add favourite contextmenu to emote autocomplete 2018-08-25 18:05:17 +03:00
Jiiks 9b5464b9a5 Remove unused imports 2018-08-25 17:45:52 +03:00
Jiiks da8e912a95 Emotemodule refactor to use new builtin base 2018-08-25 17:43:29 +03:00
Jiiks a4cbfd9235 Devtools 2018-08-25 17:03:46 +03:00
Jiiks 5e0c5e39f6 Unused imports 2018-08-25 17:01:37 +03:00
Jiiks e798e3d6e2 Voice Disconnect refactor to use new builtin base 2018-08-25 16:59:24 +03:00
Jiiks 937ab55456 Tracking protection refactor to use new builtin base 2018-08-25 16:58:27 +03:00
Jiiks aa0882c449 Kill clyde refactor to use new builtin base 2018-08-25 16:55:58 +03:00
Jiiks f5b70d5a23 Not much to change here 2018-08-25 16:51:45 +03:00
Jiiks 6d818f40d2 Get Message correctly 2018-08-25 16:50:48 +03:00
Jiiks 6a5f185c80 add some comments and consistent structure 2018-08-25 16:12:33 +03:00
Jiiks 62b7679408 Coloured text refactor to use new builtin base 2018-08-25 16:09:04 +03:00
Jiiks c11aa205a3 Remove unused imports 2018-08-25 16:03:13 +03:00
Jiiks 47af7a5da6 Blocked messages refactor to use new builtin base 2018-08-25 16:02:42 +03:00
Jiiks 89b645b334 24hour refactor to use new builtin base 2018-08-25 15:57:29 +03:00
Alexei Stukov 62c9fe6011
Merge pull request #247 from JsSucks/suggested-changes
Modules to Reflection
2018-08-25 15:51:11 +03:00
Alexei Stukov a45c39ed91
Merge branch 'master' into suggested-changes 2018-08-25 15:24:43 +03:00
Alexei Stukov f35d206044
Merge pull request #245 from samuelthomas2774/e2ee-popout
Add an option to move the E2EE popout over the button
2018-08-25 15:23:20 +03:00
Jiiks f46694f2d0 Use Reflection, deleted any wpm references from plugin api for now 2018-08-24 19:05:27 +03:00
Jiiks 5c493d413b Fix resolver and add helpers to it 2018-08-24 17:42:27 +03:00
Jiiks 32fc655326 camelCase 2018-08-24 15:04:10 +03:00
Jiiks 9cf63c2cfa allow non-array args 2018-08-24 15:03:41 +03:00
Jiiks b59c919733 Simplify names, have modules return byName 2018-08-24 14:17:13 +03:00
Jiiks e66af1e1d2 Export Reflection and put it in _bd 2018-08-24 13:50:59 +03:00
Jiiks f1cf802746 add ui reflection as property 2018-08-24 13:48:03 +03:00
Jiiks d1387f5183 Leave the original intact for now 2018-08-24 13:46:58 +03:00
Jiiks 9190b208eb Move classname stuff to resolver 2018-08-24 13:41:44 +03:00
Jiiks fdd934ae0c Change header 2018-08-24 13:38:21 +03:00
Jiiks b1c8070fc3 add deprecation notice 2018-08-24 13:37:55 +03:00
Jiiks 56753d3614 Move webpackmodules under reflection.modules 2018-08-24 13:35:16 +03:00
Alexei Stukov 66966e6729
Merge pull request #246 from Aphypnise/patch-1
Missing one round bracket, causes gulp build error
2018-08-24 12:59:15 +03:00
Aphypnise 0f7639da6d
Missing one round bracket, causes gulp build error 2018-08-24 03:25:04 +02:00
Samuel Elliott 2a81054f64
Add options for the popout’s position/trigger 2018-08-23 22:16:15 +01:00
Alexei Stukov 22ea3ff2ad
Merge pull request #244 from JsSucks/builtin-base
Builtin base
2018-08-23 22:57:55 +03:00
Jiiks d3e76a1c2d Typo 2018-08-23 22:51:35 +03:00
Jiiks 72326d220e Make builtin base more useful 2018-08-23 22:50:12 +03:00
Samuel Elliott 52dfaf18c1
Open the popout on hover 2018-08-23 20:44:51 +01:00
Samuel Elliott 40acb33bbd
Disable the popout when there’s no key for the channel and it’s not a DM 2018-08-23 20:44:14 +01:00
Samuel Elliott 74d5d3540f
Open the E2EE popout over the button 2018-08-23 20:38:48 +01:00
Alexei Stukov 3ba90705ff
Merge pull request #243 from samuelthomas2774/keytar
Add an option to store the master password in the system keychain
2018-08-23 22:30:57 +03:00
Samuel Elliott 6c14f80791
Fix “Unnecessary 'else' after 'return’” 2018-08-23 20:26:23 +01:00
Samuel Elliott 5fa964ed50
Install libsecret on Travis 2018-08-23 20:21:20 +01:00
Alexei Stukov da28828880
Merge pull request #242 from samuelthomas2774/plugin-api
Plugin API
2018-08-23 22:06:42 +03:00
Samuel Elliott 21c8c6d267
Update gulpfile to copy keytar bindings 2018-08-23 20:00:52 +01:00
Samuel Elliott 5868b4f0f9
Use a different hint on each platform 2018-08-23 19:50:09 +01:00
Samuel Elliott d53afe2538
Add an option to store the master password in the system keychain 2018-08-23 19:40:45 +01:00
Samuel Elliott 96b7e8d859
Add IPC events for keytar 2018-08-23 19:14:21 +01:00
Samuel Elliott 60e42cea07
Lock at v4.2.1 2018-08-23 18:28:30 +01:00
Samuel Elliott 43ec860bfe
Add keytar and bindings 2018-08-23 18:28:11 +01:00
Samuel Elliott 1f971c7490
Add a script to copy the node sass bindings on install 2018-08-23 18:20:34 +01:00
Samuel Elliott 5e7de49999
Update user profile modal badge size 2018-08-23 17:17:00 +01:00
Samuel Elliott 35c1ab93a0
Add Lucario 🌌 V5.0.0#7902 to contributors 2018-08-23 17:11:16 +01:00
Samuel Elliott a85107cc51
Fix GlobalAc.toggle and add it to the plugin API 2018-08-23 16:36:22 +01:00
Samuel Elliott 46dae11085
Use const 2018-08-23 04:02:01 +01:00
Samuel Elliott c885e4ceda
Add notification titles 2018-08-23 03:16:18 +01:00
Samuel Elliott 26bce739d7
Add bd-windowHasFrame and bd-windowIsTransparent classes 2018-08-23 02:54:01 +01:00
Samuel Elliott 3747417865
Register chrome-extension as privileged in the preload script 2018-08-23 02:39:33 +01:00
Samuel Elliott 4c0248ca00
Remove old favourite emotes storage 2018-08-22 23:45:25 +01:00
Samuel Elliott fd9c03ac2f
Update the emote module in the plugin API 2018-08-22 23:44:46 +01:00
Samuel Elliott d11e8d4fe2
Merge remote-tracking branch 'upstream/master' into plugin-api
# Conflicts:
#	client/src/index.js
#	client/src/ui/components/contextmenu/Group.vue
#	client/src/ui/contextmenus.js
2018-08-22 22:16:39 +01:00
Samuel Elliott 56a807f294
Add support for using submenus in submenus 2018-08-22 22:06:42 +01:00
Samuel Elliott cf71f89077
Use the CMGroup component to render sub menus 2018-08-22 21:35:50 +01:00
Samuel Elliott 3ff077ea04
Add BD button context menu 2018-08-22 21:04:08 +01:00
Samuel Elliott 697df8a7fe
Add v-contextmenu directive 2018-08-22 20:58:00 +01:00
Samuel Elliott c2ccfd02da
Move ReactComponent to Vue injector 2018-08-22 20:56:05 +01:00
Alexei Stukov 1e9b1618f1
Merge pull request #241 from JsSucks/emote-stuff
Support more then 10 items in autocomplete with scrolling
2018-08-22 21:49:51 +03:00
Jiiks d92da4b6e4 Support more then 10 items in autocomplete with scrolling 2018-08-22 21:45:32 +03:00
Samuel Elliott 67debca9d9
Add notifications to the plugin API 2018-08-22 19:42:22 +01:00
Samuel Elliott a0bee1846e
Add autocomplete to the plugin API 2018-08-22 19:07:06 +01:00
Samuel Elliott 73192f5762
Load external content after builtin modules 2018-08-22 18:37:39 +01:00
Alexei Stukov a1e32f8b89
Merge pull request #240 from JsSucks/emote-stuff
Emote stuff
2018-08-22 20:28:29 +03:00
Jiiks 2002db7807 bd-autocomplete -> bd-ac 2018-08-22 20:17:43 +03:00
Jiiks 07374ceeee add autocomplete hint text and float right for third title 2018-08-22 20:15:21 +03:00
Samuel Elliott d02be1521d
Fix modal closing animation and add a header slot 2018-08-22 18:02:07 +01:00
Jiiks 5c92f3e3e0 Toggle between favourite and most used 2018-08-22 20:00:00 +03:00
Jiiks 41a5a3a791 add toggle functionality to ac 2018-08-22 19:49:53 +03:00
Samuel Elliott 42a89129d4
Move unloading plugin main script to the plugin manager 2018-08-22 17:44:30 +01:00
Jiiks 2617925cd8 add actype setting 2018-08-22 19:34:26 +03:00
Jiiks 7a0b6e9262 Remove unused imports 2018-08-22 19:32:31 +03:00
Jiiks 3f5c168ffc Move emote autocomplete to it's own module 2018-08-22 19:31:09 +03:00
Jiiks 09d9f50160 z-indexes, shouldn't break any indexing? 2018-08-22 18:54:32 +03:00
Jiiks d274fda428 Save favourites to db 2018-08-22 18:49:20 +03:00
Jiiks 58a2b6714e add id to test cm 2018-08-22 18:39:47 +03:00
Jiiks 4c3659f857 add contextmenu patch removal 2018-08-22 18:39:09 +03:00
Jiiks b8dc9c0d25 No more ugly 2018-08-22 18:33:00 +03:00
Jiiks c4f28a6ac5 Initial favouriting and horrible toggle code fix it Zere 2018-08-22 17:17:37 +03:00
Jiiks 1ab52cb174 Correct targeting 2018-08-22 16:55:25 +03:00
Jiiks f315c8b134 pass target to toggle 2018-08-22 16:38:32 +03:00
Jiiks 8bfac0f6ff add favourite toggle 2018-08-22 16:31:49 +03:00
Samuel Elliott 4bed9f726c
Separate file/directory delete functions 2018-08-22 14:27:06 +01:00
Jiiks 0145492773 Wrap single emotes 2018-08-22 16:20:26 +03:00
Samuel Elliott 2188c22425
Update begin key exchange icon 2018-08-22 13:55:24 +01:00
Jiiks e9c419529d Change singular emote name to detect it in render 2018-08-22 15:50:20 +03:00
Samuel Elliott 6ee647b249
Fix SettingsWrapper padding on macOS 2018-08-22 13:32:10 +01:00
Samuel Elliott 5676435473
Fix channelcategory.channels 2018-08-22 13:23:22 +01:00
Samuel Elliott 8cf28fcaba
Add DiscordContextMenu to the plugin API 2018-08-22 13:19:15 +01:00
Samuel Elliott 237899c91a
Add BdContextMenu to the plugin API 2018-08-22 12:56:27 +01:00
Samuel Elliott 73e4e83ced
Add Maks#3712 to contributors 2018-08-22 12:54:55 +01:00
Alexei Stukov 5b63667bc2
Merge pull request #238 from JsSucks/context-menus
Context menus
2018-08-22 14:29:56 +03:00
Alexei Stukov 00ce5d70c9
Merge pull request #237 from JsSucks/windowpreferences-patch
fix window preferences
2018-08-22 14:29:47 +03:00
Alexei Stukov b3d14d853c
Merge pull request #236 from Maks-s/filetype
Add file functions for FileSetting
2018-08-22 14:29:35 +03:00
Alexei Stukov c1af0c6115
Merge pull request #234 from JsSucks/builtins
Add several builtins
2018-08-22 14:29:18 +03:00
Alexei Stukov f3bb7aac96
Merge pull request #233 from Maks-s/delete-intensifies
Added delete method to plugins / themes
2018-08-22 14:29:06 +03:00
Jiiks cd84f6329a add a test contextmenu item 2018-08-22 12:08:56 +03:00
Jiiks b4fa9c2934 add docs 2018-08-22 12:07:32 +03:00
Jiiks 9db6ddaf98 Make filter optional 2018-08-22 12:06:53 +03:00
Jiiks ed55e060aa Linter warnings 2018-08-22 10:55:18 +03:00
Jiiks bb37b89d35 Discord contextmenu patching 2018-08-22 10:53:20 +03:00
Jiiks 07fc98670c Hide cm when clicked outside 2018-08-22 02:03:18 +03:00
Jiiks 25aecf82a6 Fix chevron position 2018-08-22 01:42:14 +03:00
Jiiks 242fbfaaa7 Match notifications with context menu style 2018-08-22 01:35:46 +03:00
Jiiks ef5a1c223c Get position from passed event|object 2018-08-22 01:27:50 +03:00
Jiiks 8637f176c1 Lint 2018-08-22 00:34:13 +03:00
Jiiks 4c5300be12 Custom context menu 2018-08-22 00:23:08 +03:00
Zack Rauen 1ccd7766bc fix window preferences 2018-08-21 14:05:13 -04:00
Maks-s 9711c99217
Add filetype/read/readBuffer functions to FileSetting 2018-08-21 16:01:37 +02:00
Maks 10f45b6b4c
Fixed stupid errors 2018-08-21 10:09:38 +02:00
Maks 7c44b92bce
Changed path import 2018-08-21 09:57:09 +02:00
Zack Rauen 4784b13c86 proper color mixing, support light theme 2018-08-21 01:50:54 -04:00
Zack Rauen a8c8c017f6 add color intensity option 2018-08-21 01:19:43 -04:00
Zack Rauen c98e4430b1 forgot about midnight case in 24hr 2018-08-21 00:36:57 -04:00
Zack Rauen adf94990c2 add several builtins
- Colored Text
- 24 Hour
- Kill Clyde
- Prevent Blocked Messages
- Voice Disconnect
2018-08-20 23:42:34 -04:00
Maks-s e78021a538
Added delete method to plugins / themes 2018-08-21 02:45:54 +02:00
Alexei Stukov 3c38ecdd97
Merge pull request #232 from JsSucks/minor-things
Minor things
2018-08-20 18:58:06 +03:00
Jiiks 12021fcf15 Lint fix 2018-08-20 18:36:34 +03:00
Jiiks 1031ab3a18 zer-unit 2018-08-20 18:31:08 +03:00
Jiiks e75c575a32 add dummy notif 2018-08-20 18:30:41 +03:00
Jiiks 9c91222fff More styling 2018-08-20 18:23:18 +03:00
Jiiks d0eb2a441a Notification styling 2018-08-20 18:21:34 +03:00
Jiiks 5c6d544562 Use bd green for logger 2018-08-20 17:37:40 +03:00
Jiiks ceca53a75d Update CSS Editor Icon 2018-08-20 17:36:43 +03:00
Jiiks 6eaed063ec Move to bottom right 2018-08-20 17:21:01 +03:00
Jiiks bc5eb1b5f0 button logic 2018-08-20 16:52:26 +03:00
Jiiks 1a11eb6a6b Styling a bit, still uglyish 2018-08-20 16:48:29 +03:00
Jiiks cff67a3b1d Notification styling 2018-08-20 16:40:28 +03:00
Jiiks 3518ac7cb2 add base for notifications. These should be used for things such as "update available" only 2018-08-20 16:23:05 +03:00
Jiiks f2d7ef41da Use full white logo instead of filter 2018-08-20 15:28:31 +03:00
Jiiks 87e0f132d1 add full white small logo 2018-08-20 15:26:19 +03:00
Alexei Stukov 9306018111
Merge pull request #231 from JsSucks/editor-patch
fix module resolving for vscode
2018-08-20 06:42:11 +03:00
Zack Rauen 19d33a44ea fix module resolving for vscode 2018-08-19 22:43:40 -04:00
Alexei Stukov e755b60807
Merge pull request #230 from JsSucks/fix-zeres-crap
No typos
2018-08-20 05:13:18 +03:00
Jiiks f50bcd0785 Massive commit 2018-08-20 05:07:28 +03:00
Jiiks fc6481acae Big commit 2018-08-20 05:05:01 +03:00
Jiiks de0651bb47 Huge commit 2018-08-20 04:02:09 +03:00
Alexei Stukov 358b1e8bf3
Merge pull request #229 from JsSucks/emote-module
Emote module
2018-08-20 03:54:16 +03:00
Jiiks 84b94c614e Typos 2018-08-20 03:48:49 +03:00
Jiiks 3fa848bb5a add some comments 2018-08-20 03:26:56 +03:00
Jiiks 533566fde8 Don't store useless data in db 2018-08-20 03:16:09 +03:00
Jiiks 6ab1adfe5b Use findOne 2018-08-20 02:39:48 +03:00
Jiiks 205dcf6ff1 add findOne to db 2018-08-20 02:38:17 +03:00
Jiiks beaee8764c Persistent most used and favourites 2018-08-20 02:35:51 +03:00
Alexei Stukov d22188ea2a
Merge pull request #228 from JsSucks/emote-module
Emote module
2018-08-20 01:59:43 +03:00
Jiiks 53ef0be7b8 Minor changes 2018-08-20 01:56:57 +03:00
Jiiks e3edb09f38 Remove debugs 2018-08-19 23:16:49 +03:00
Jiiks 316f3c1bb0 Remove debug 2018-08-19 23:15:37 +03:00
Jiiks 6948335ea7 Fix lag and random no reason package change 2018-08-19 23:13:23 +03:00
Jiiks 25decd0514 Correct sort pls 2018-08-19 21:07:14 +03:00
Jiiks a35c75717e Most used emotes, only in memory right now 2018-08-19 21:00:53 +03:00
Jiiks 8d6d3c9e18 Autocomplete 2018-08-19 20:34:32 +03:00
Jiiks 91df5350ad I'll just remove them here 2018-08-17 17:06:38 +03:00
Jiiks 22740fb16c Autocomplete 2018-08-17 17:05:23 +03:00
Jiiks 0316bbc1cd add wrapper for getClassName 2018-08-17 10:40:19 +03:00
Jiiks 8bac53e9be Emote mofule refactoring, vrwrapper and hasOwnProperty treewalk check 2018-08-16 14:33:22 +03:00
Alexei Stukov 42e2569569
Merge pull request #226 from JsSucks/inject
Add inject script
2018-08-16 10:56:32 +03:00
Alexei Stukov dd81201a95
Merge pull request #227 from JsSucks/security-keyexchange
Fix key exchange
2018-08-16 10:55:55 +03:00
Jiiks 805e1ce771 Fix key exchange 2018-08-16 10:53:27 +03:00
Zack Rauen 322badd209 add inject script 2018-08-15 23:01:10 -04:00
Alexei Stukov 8438d32ce9
Merge pull request #225 from JsSucks/refactor-classnames
Refactor classnames, add sasslint, reorganize scss, change some classnames, update eslint rules etc
2018-08-15 13:00:44 +03:00
Jiiks 3446ed2d6b package-lock 2018-08-15 12:52:45 +03:00
Jiiks 6a51834f82 Cleaning and sass-lint 2018-08-15 12:42:43 +03:00
Jiiks 89461244bd Clean a little bit 2018-08-15 10:45:10 +03:00
Jiiks b1847b8c41 bit more 2018-08-15 10:14:45 +03:00
Jiiks 11eed2c89d Make it a bit more readable 2018-08-15 10:10:16 +03:00
Jiiks b971b716bf Update eslint 2018-08-15 09:10:11 +03:00
Jiiks 9f8a1f08be Update eslint rules 2018-08-15 09:01:47 +03:00
Jiiks c1ac349211 all fixed? 2018-08-15 07:13:37 +03:00
Jiiks 1804fcfbe1 Drawer open state 2018-08-15 06:48:59 +03:00
Jiiks 303addae42 Fix badges and add bd-v2 to body 2018-08-15 06:41:44 +03:00
Jiiks 9e80f7b051 Fix bugs caused by automated renaming 2018-08-15 06:33:42 +03:00
Jiiks 0e32d835ef camelCase 2018-08-15 05:03:56 +03:00
Alexei Stukov 462b198895
Merge pull request #223 from JsSucks/security
Security
2018-08-15 02:39:36 +03:00
Jiiks 34e2833555 Disable E2EE if master password is invalid 2018-08-15 02:34:35 +03:00
Alexei Stukov 8b180ea423
Merge pull request #222 from JsSucks/security-treewalk
add findInTree and adjust the render patch
2018-08-14 22:14:38 +03:00
Jiiks a90400c280 Check if we're not in a channel 2018-08-14 15:43:55 +03:00
Jiiks e49a1932f3 Remove debug 2018-08-14 15:37:14 +03:00
Jiiks abf83821d9 Typo exchange 2018-08-14 15:35:50 +03:00
Jiiks 6ed50c4206 TODO 2018-08-14 15:32:49 +03:00
Jiiks edab8dd93b Use MESSAGE_CREATE instead 2018-08-14 15:30:43 +03:00
Jiiks ab03633431 add password option to input modal 2018-08-14 14:49:50 +03:00
Jiiks 67b554c68f add input modal
TODO Option for masked input
2018-08-14 13:50:32 +03:00
Jiiks 68f3a280a5 TODO 2018-08-14 13:29:19 +03:00
Jiiks 5db4f8cf26 Remove debug 2018-08-14 13:27:45 +03:00
Jiiks 3e57d0092a Display user tag in exchange request modal 2018-08-14 13:27:20 +03:00
Jiiks 36408d74ad Change button tooltip 2018-08-14 13:03:47 +03:00
Jiiks 9aa9305755 Check for message state 2018-08-14 13:02:25 +03:00
Jiiks 6f9cdb9dda That obviously wouldn't work 2018-08-14 12:59:37 +03:00
Jiiks 0aa370aeb9 add custom text for confirm modal buttons 2018-08-14 12:57:39 +03:00
Jiiks 27fee8e10c Typo and set preExchangeState 2018-08-14 12:51:57 +03:00
Jiiks ac1e4ad9a2 Move storage outside 2018-08-14 11:16:39 +03:00
Jiiks 73f2fe4fd0 Reset encryptNewMessages to previous state 2018-08-14 11:08:41 +03:00
Jiiks 8b4318c06e Remove logging 2018-08-14 11:06:53 +03:00
Jiiks 7636ea480d Disable encryption for new exchanges 2018-08-14 11:06:02 +03:00
Jiiks 54e5f2149b Suite B 2018-08-14 11:02:29 +03:00
Jiiks b1f0a4247a Make sure we don't send public keys encrypted 2018-08-14 10:44:57 +03:00
Jiiks 8d6cdafc23 Push kvp to db 2018-08-14 10:41:22 +03:00
Jiiks 5711576a0d Semi automated key exchange process 2018-08-14 10:40:33 +03:00
Jiiks 6df9b1e019 add DraftActions 2018-08-14 06:20:02 +03:00
Jiiks c2e7abcfca nodecrypt 2018-08-14 04:21:48 +03:00
Jiiks b6c58f16e7 DiscordApi in data and remove contextmenu thing 2018-08-14 04:19:03 +03:00
Jiiks b47a3c65aa node-crypto 2018-08-14 04:04:57 +03:00
Alexei Stukov 0315d610e0
Merge pull request #216 from Mega-Mewthree/security
E2EE Secure ECDH key exchange for DMs
2018-08-14 04:03:11 +03:00
Zack Rauen 3714e71297 add findInTree 2018-08-13 16:38:13 -04:00
Mega-Mewthree 9f4b0aec6b
Forgot to save stuff. (#8) 2018-08-13 13:23:14 -07:00
Mega-Mewthree 0ea5bc2dcc
Merge pull request #7 from Mega-Mewthree/e2ee-dev
E2ee dev
2018-08-13 13:19:27 -07:00
Mega-Mewthree 64608c7e62 Switched context menu stuff to popover, fixed things. 2018-08-13 13:17:29 -07:00
Mega-Mewthree 2d8c0a5306
Merge pull request #6 from Mega-Mewthree/security
Security
2018-08-13 10:41:20 -07:00
Mega-Mewthree 81c451d31f
Merge branch 'security' into security 2018-08-13 10:35:16 -07:00
Jiiks d04aa313fc CSP Fix. fixes #215 2018-08-13 15:13:59 +03:00
Jiiks 45ab822fba add collection.scss that got lost somewhere somehow 2018-08-13 14:45:38 +03:00
Alexei Stukov c893216874
Merge branch 'master' into security 2018-08-13 14:38:25 +03:00
Alexei Stukov a1a869181b
Merge pull request #214 from samuelthomas2774/settings
Add an option to disable toasts and additional options for collections
2018-08-13 14:37:03 +03:00
Alexei Stukov f5cbd8d491
Merge pull request #220 from JsSucks/security-encrypted-images
Security encrypted images
2018-08-13 14:34:59 +03:00
Alexei Stukov 17917f3257
Merge branch 'security' into security-encrypted-images 2018-08-13 14:27:29 +03:00
Jiiks 19be33b17d Don't use encrypted key for hmac 2018-08-13 12:56:41 +03:00
Jiiks cfcca0d782 Remove debug 2018-08-13 12:35:19 +03:00
Jiiks 5592a8d376 Use security module 2018-08-13 12:33:44 +03:00
Jiiks 0c0ebb2ebb Pseudo needs content 2018-08-13 10:57:32 +03:00
Jiiks d6d78d1e99 Move master init to enabled 2018-08-13 10:45:52 +03:00
Jiiks b6da7019d0 Unused import 2018-08-12 22:12:26 +03:00
Jiiks a123e20b05 Move to Security 2018-08-12 22:11:41 +03:00
Jiiks 856334cf30 TODO 2018-08-12 22:09:34 +03:00
Jiiks 3f5b2afbd5 decrypting should be set to false as well 2018-08-12 22:05:44 +03:00
Jiiks ad35c89d7d Force update on failed auth instead 2018-08-12 21:59:54 +03:00
Jiiks 71a0ce8fb0 Set readyState on failed authentication 2018-08-12 21:58:26 +03:00
Jiiks d53a3b4d64 base classname 2018-08-12 21:56:57 +03:00
Jiiks bd0c66466f Use randomBytes for master encryption 2018-08-12 21:54:57 +03:00
Jiiks 0a751919aa Remove debug 2018-08-12 21:48:15 +03:00
Jiiks cae68947df add bad key handler 2018-08-12 21:46:59 +03:00
Jiiks 2b833b5141 add hmac 2018-08-12 21:43:59 +03:00
Jiiks b24c0ba2f3 Strip base64 prefix to not have static data in encrypted content 2018-08-12 20:57:02 +03:00
Jiiks 3b8126781d Default to channel id 2018-08-12 20:31:30 +03:00
Jiiks a1a63f2c35 Proper doc 2018-08-12 18:37:11 +03:00
Jiiks 334c9f852a Use cache module 2018-08-12 18:10:22 +03:00
Jiiks 17128a889b add cache module 2018-08-12 17:40:26 +03:00
Jiiks d2b99f200b add image plus material icon 2018-08-12 15:58:00 +03:00
Jiiks 5f4a77f2d8 Remove my leak tests 2018-08-12 15:48:26 +03:00
Jiiks 3614997fa9 No need to use this when it's already in the scope 2018-08-12 15:47:20 +03:00
Jiiks 5f76d304f6 Use predefined colours 2018-08-12 15:46:17 +03:00
Jiiks e8688c0ce4 User some colour variables 2018-08-12 15:41:25 +03:00
Jiiks 641a12d640 Move lock icon to images 2018-08-12 15:40:00 +03:00
Jiiks 169741d5a1 Image encryption, decryption, styling and other stuff 2018-08-12 15:39:00 +03:00
Alexei Stukov 4aec2a7ade
Merge pull request #218 from JsSucks/security-patch
fix all mentions in e2ee
2018-08-12 11:01:45 +03:00
Mega-Mewthree ee9cba328f
Merge pull request #5 from Mega-Mewthree/e2ee-dev
E2ee dev
2018-08-11 18:29:38 -07:00
Mega-Mewthree c421be9e91 Fix merge 2018-08-11 18:28:18 -07:00
Mega-Mewthree 7a1768ca87 Merge branch 'e2ee-dev' of https://github.com/Mega-Mewthree/BetterDiscordApp into e2ee-dev 2018-08-11 18:26:37 -07:00
Mega-Mewthree b9e9ab89f7 Rename variables to better describe what they represent. 2018-08-11 18:24:55 -07:00
Mega-Mewthree b9f3c3f4e2
Merge pull request #4 from Mega-Mewthree/e2ee-dev
E2ee dev
2018-08-11 17:24:46 -07:00
Mega-Mewthree dc842b479b
Merge branch 'security' into e2ee-dev 2018-08-11 17:24:22 -07:00
Mega-Mewthree 02e6fb88aa Prevent the context menu from appearing in Group DMs. 2018-08-11 16:37:58 -07:00
Mega-Mewthree c10310af3a Error toast on computeSecret error. 2018-08-11 16:28:34 -07:00
Mega-Mewthree 7e41fe73e7 Secure key exchange for DMs. 2018-08-11 16:21:08 -07:00
Mega-Mewthree c122457565 Style the lock context menu. 2018-08-11 10:11:56 -07:00
Mega-Mewthree 0ea0acfaa5
Merge pull request #3 from JsSucks/security-patch
fix all mentions
2018-08-11 07:55:19 -07:00
Jiiks 866ad8b13b Tons of stuff 2018-08-11 15:29:30 +03:00
Mega-Mewthree c5d4e199fc Very poorly implemented key exchange UI.
PLEASE HELP ME
2018-08-11 00:34:18 -07:00
Mega-Mewthree 1a8946b151 Merge branch 'e2ee-dev' of https://github.com/Mega-Mewthree/BetterDiscordApp into e2ee-dev 2018-08-10 23:06:28 -07:00
Zack Rauen 9c0e19e198 fix all mentions 2018-08-11 01:15:49 -04:00
Alexei Stukov 816f809ca7
Merge pull request #217 from samuelthomas2774/security
Add clicking the status icon to toggle encryption and add an indicator to encrypted messages
2018-08-11 06:00:56 +03:00
Samuel Elliott 32a995f678
Add an encrypted indicator to encrypted messages 2018-08-11 02:58:55 +01:00
Samuel Elliott dac3187866
Add clicking the status icon to toggle encryption 2018-08-11 02:43:02 +01:00
Jiiks 60cdec3ae4 and move everything around just to annoy Zere 2018-08-11 04:33:00 +03:00
Jiiks ed4adf21f4 Maybe encrypt instead 2018-08-11 04:31:57 +03:00
Jiiks a8f0e239cf Who wants to call them directly anyways 2018-08-11 04:31:13 +03:00
Jiiks be1a183e62 Empty prefixes 2018-08-11 04:28:07 +03:00
Jiiks d88cedb614 Security module 2018-08-11 04:27:18 +03:00
Jiiks 9880152290 Message parsing 2018-08-11 03:39:13 +03:00
Jiiks 0a1bd46ca9 Don't prefix everything by default 2018-08-10 21:17:52 +03:00
Jiiks 83ef17d302 Fix button patching 2018-08-10 20:38:02 +03:00
Mega-Mewthree cb6473920f
Update webpack.production.config.js 2018-08-10 10:30:42 -07:00
Mega-Mewthree d8c769433a
Update webpack.config.js 2018-08-10 10:30:16 -07:00
Mega-Mewthree fd7a0f4051
Functions to create an ECDH key exchange
Allows 2 users to securely obtain a shared key for usage with AES.
2018-08-10 09:56:55 -07:00
Mega-Mewthree 7899312e73
Merge pull request #1 from JsSucks/security
Security
2018-08-10 09:39:53 -07:00
Samuel Elliott 784d8223e8
Add a separate build-release task
So you can update the release version without deleting all user data
2018-08-10 15:48:43 +01:00
Samuel Elliott 344a9e6fe5
Fix escape key to close menu 2018-08-10 15:21:33 +01:00
Samuel Elliott 22e78c03e1
Add toasts enabled state to the plugin API 2018-08-10 15:17:57 +01:00
Jiiks b67ca5c42d Set master 2018-08-10 17:04:09 +03:00
Jiiks bdec8b842e Set master key 2018-08-10 17:02:41 +03:00
Jiiks 3bc7c28a97 initial master encrypt 2018-08-10 17:01:07 +03:00
Samuel Elliott a4992e905c
Fix class normaliser also normalising classes of elements outside the passed element 2018-08-10 14:29:31 +01:00
Samuel Elliott c8381eb808
Add disabled, min and max options for collections 2018-08-10 14:23:21 +01:00
Samuel Elliott 0aabc72652
Indentation 2018-08-10 14:22:37 +01:00
Jiiks 3d4204f080 Functional E2EE submitting 2018-08-10 16:22:30 +03:00
Samuel Elliott dc3fed3408
Hide collection setting dividers 2018-08-10 14:11:25 +01:00
Samuel Elliott a12a3c74f4
Hide the button properly 2018-08-10 13:57:27 +01:00
Jiiks 3c83dbe0ff add slight loading animation 2018-08-10 15:44:33 +03:00
Samuel Elliott 4970214324
Add an option to disable toasts 2018-08-10 13:37:47 +01:00
Jiiks a5ae5ad8e9 Warn style 2018-08-10 15:37:14 +03:00
Jiiks 54808f32ea Default to error state 2018-08-10 15:33:48 +03:00
Jiiks 4e4c532813 More styling 2018-08-10 15:33:34 +03:00
Jiiks aac4dba641 Styling 2018-08-10 15:32:04 +03:00
Jiiks 17f1b60a9b E2EE component and material lock icon 2018-08-10 15:30:24 +03:00
Jiiks 2a10191926 E2EE patches 2018-08-10 15:08:21 +03:00
Alexei Stukov 87ec7d8773
Merge pull request #213 from JsSucks/ui
Securekvp
2018-08-10 14:21:00 +03:00
Jiiks e518d4c117 package-lock 2018-08-10 14:18:08 +03:00
Jiiks c4dfc7b11d Remove debugs 2018-08-10 12:50:37 +03:00
Jiiks 0c04c04590 Secure kvp 2018-08-10 12:48:56 +03:00
Alexei Stukov 11b2b16233
Merge pull request #212 from samuelthomas2774/hide-button
Make the hide button setting functional
2018-08-10 02:35:07 +03:00
Alexei Stukov 4c6805510d
Merge pull request #211 from samuelthomas2774/vue-transition
Use Vue’s transition element to transition between menu panels
2018-08-10 02:34:25 +03:00
Samuel Elliott cb01d32e19
Fix position on macOS 2018-08-10 00:00:01 +01:00
Samuel Elliott 89a5bfba20
Make the hide button setting functional 2018-08-09 23:49:10 +01:00
Alexei Stukov 87a2db1745
Merge pull request #210 from JsSucks/drop-area
Add temporary .bd file check on drop
2018-08-10 00:59:14 +03:00
Samuel Elliott 387227cc1f
Use Vue’s transition element to transition between menu panels 2018-08-09 22:50:14 +01:00
Zack Rauen fdb3b308e1 add bd file check for upload drop area 2018-08-09 16:33:31 -04:00
Alexei Stukov b33aff51c1
Merge pull request #207 from JsSucks/normalizer
fix class search in normalizer
2018-08-09 23:29:28 +03:00
Alexei Stukov be09fbb5ac
Merge pull request #209 from JsSucks/settings
Collection setting and other minor things
2018-08-09 23:26:16 +03:00
Jiiks 2b4a804934 Use material icon 2018-08-09 23:21:57 +03:00
Jiiks fcfba41805 Styling and remove default from E2EE 2018-08-09 23:13:38 +03:00
Jiiks d14a06528c else 2018-08-09 23:07:53 +03:00
Alexei Stukov c336c8cb0d
Merge pull request #208 from samuelthomas2774/collection-settings
Extend ArraySetting for collections
2018-08-09 20:33:38 +03:00
Samuel Elliott 755d870a10
Merge remote-tracking branch 'upstream/settings' into collection-settings
# Conflicts:
#	client/src/structs/settings/types/collection.js
#	client/src/ui/components/bd/setting/Collection.vue
2018-08-09 18:27:06 +01:00
Jiiks 4ed301f531 Styling 2018-08-09 20:26:37 +03:00
Jiiks 263fcbe001 Collection fix 2018-08-09 20:22:48 +03:00
Samuel Elliott 883f760292
Extend ArraySetting for collections 2018-08-09 18:22:15 +01:00
Zack Rauen 5af8a2168d fix class search 2018-08-09 11:31:11 -04:00
Jiiks 50badaef2b add collection and make kvp functional 2018-08-09 17:20:06 +03:00
Alexei Stukov 4c20115705
Merge pull request #206 from JsSucks/security
Merge due to changes to core functionality to avoid conflicts
2018-08-09 13:24:00 +03:00
Jiiks e21583eafd add a manager for builtin modules 2018-08-09 13:21:17 +03:00
Jiiks 983763c48d Check for module existence 2018-08-09 13:09:35 +03:00
Jiiks 75ceee5449 Typo 2018-08-09 13:06:20 +03:00
Jiiks 572c57d3a7 add tracking protection 2018-08-09 13:04:19 +03:00
Jiiks 4f98eaf85b Rename to Security and Privacy 2018-08-09 11:40:48 +03:00
Jiiks 44a1c87484 Don't think we need test settings anymore 2018-08-09 11:37:13 +03:00
Jiiks b18dd7c01a KVP Component 2018-08-09 11:30:48 +03:00
Jiiks 356e8f0934 E2EE module base 2018-08-09 10:56:44 +03:00
Alexei Stukov 1288e0361a
Merge pull request #205 from JsSucks/patcher
Update Patcher
2018-08-09 09:07:39 +03:00
Alexei Stukov 8f95ba290a
Merge pull request #204 from JsSucks/normalizer
Fix class normalizer
2018-08-09 09:07:06 +03:00
Zack Rauen 5a603a084f normalize DOM on load 2018-08-09 01:18:49 -04:00
Zack Rauen f144934cd7 use const instead of let 2018-08-09 01:01:32 -04:00
Zack Rauen 9473e419b4 add documentation to patcher 2018-08-09 00:54:35 -04:00
Zack Rauen a081a8fdf9 make patcher more robust + fix collisions 2018-08-09 00:22:10 -04:00
Zack Rauen e660ce6a31 remove redundant array check, fix strings 2018-08-08 23:39:57 -04:00
Zack Rauen 5c7b10299b update normalizer 2018-08-08 23:29:54 -04:00
Jiiks 42957dbb16 add devtool hashes and move them to the top. Pushing to master since it's minor change. 2018-08-07 20:17:34 +03:00
Alexei Stukov c3df892f1c
Merge pull request #203 from JsSucks/devtools
React and Vue devtool modules
2018-08-07 16:12:04 +03:00
Jiiks 26f386ad31 Setting hints for devtools 2018-08-07 16:07:06 +03:00
Jiiks b861280548 Use path.join 2018-08-07 16:02:10 +03:00
Jiiks 9d22293927 Remove listener don't add another one 2018-08-07 13:37:23 +03:00
Jiiks c3d8f4090e try catch missing extension 2018-08-07 13:07:38 +03:00
Jiiks 3f00dba937 Devtool modules 2018-08-07 12:48:50 +03:00
Alexei Stukov 9f00aed4fa
Merge pull request #202 from JsSucks/bdapi
Online theme browser
2018-08-07 07:21:24 +03:00
Jiiks 685d0f4bac Dummy search 2018-08-07 07:17:44 +03:00
Alexei Stukov a805c8f75a
Merge pull request #201 from samuelthomas2774/channel-components
Channel components
2018-08-07 06:16:35 +03:00
Alexei Stukov ce23a39f83
Merge pull request #200 from samuelthomas2774/scheme-icons
Settings scheme icons
2018-08-07 06:15:21 +03:00
Samuel Elliott c0a971a27b
Fix element is not defined 2018-08-07 00:08:13 +01:00
Jiiks 7f567f6e9d Correct padding 2018-08-06 21:45:41 +03:00
Jiiks 865fcee12d Remote card styling 2018-08-06 21:42:09 +03:00
Jiiks 6b3fc39a1d Use dummy themes for now 2018-08-06 21:37:15 +03:00
Jiiks 7b1f36cb9c account-cicle material icon 2018-08-06 21:22:11 +03:00
Jiiks f6f308baa2 Remotecard component for online content 2018-08-06 20:52:10 +03:00
Jiiks e170ed608e online themes loading 2018-08-06 18:14:25 +03:00
Jiiks a432d78953 Structure 2018-08-06 17:05:36 +03:00
Jiiks b369dc31f2 Merge branch 'master' of https://github.com/JsSucks/BetterDiscordApp 2018-08-06 16:11:28 +03:00
Jiiks 778eb0474f Remove not so nice looking border 2018-08-06 16:04:50 +03:00
Jiiks 8c1f196675 New logos 2018-08-06 16:04:49 +03:00
Jiiks e25ac66abf Use bd green, override bdblue with it for now 2018-08-06 16:04:49 +03:00
Alexei Stukov a2a334bdac
Merge pull request #199 from JsSucks/branding
Branding
2018-08-06 15:30:57 +03:00
Jiiks 8331b30d73 Remove not so nice looking border 2018-08-06 15:25:53 +03:00
Jiiks 7083577db2 New logos 2018-08-06 15:23:29 +03:00
Jiiks 1b91c97c24 Use bd green, override bdblue with it for now 2018-08-06 15:17:57 +03:00
Alexei Stukov cca6cdf95d
Merge pull request #198 from JsSucks/bdapi
Connectivity and web api bases
2018-08-06 15:14:21 +03:00
Jiiks 7c02a51a46 Base connectivity stuff 2018-08-06 13:31:49 +03:00
Samuel Elliott 0e34fdaa8d
Fix scheme matching 2018-08-06 10:28:35 +01:00
Samuel Elliott e2f05d9a64
Patch all channel components 2018-08-06 04:48:10 +01:00
Samuel Elliott 13437c56d4
Search all matching elements instead of just the first and don’t fail if a filter function is passed 2018-08-06 04:30:48 +01:00
Samuel Elliott 4b4b3c341f
Update content/scheme icons properly 2018-08-06 02:55:08 +01:00
Samuel Elliott c2f8f5cfab
Use a file for all plugin/theme/scheme icons 2018-08-06 02:48:16 +01:00
Samuel Elliott d4c883a5d7
Add using a file as a scheme icon 2018-08-06 02:45:59 +01:00
Zack 520366c4ac
Merge pull request #191 from samuelthomas2774/discord-api
DiscordAPI, Toasts, Normalizer, Bugfixes, etc.
2018-08-05 15:08:53 -04:00
Samuel Elliott 342b4cddc4
Fix unread mentions indicator position 2018-08-04 00:54:44 +01:00
Samuel Elliott 6ea85341b9
Fix keybind settings not activating 2018-08-03 12:57:30 +01:00
Samuel Elliott 9af8a71e17
Add using a file as a plugin/theme’s icon 2018-08-02 20:24:56 +01:00
Samuel Elliott 33488d716d
Update dependencies 2018-08-01 21:41:45 +01:00
Samuel Elliott a5ff8bbdb6
Fix removing keybind-activated listeners 2018-08-01 21:17:36 +01:00
Samuel Elliott 16bb32b86c
Remove IterableWeakCollections and deactivate keybind settings when possible 2018-08-01 21:08:45 +01:00
Samuel Elliott 8826a7b984
Use an observer to detect new React components 2018-08-01 20:48:09 +01:00
Samuel Elliott 5b419cb8ab
Use ReactComponent.forceUpdateAll to rerender components after patching them 2018-08-01 20:41:53 +01:00
Samuel Elliott db21f4eb13
Fix Guild component selection 2018-08-01 20:40:03 +01:00
Samuel Elliott 3a7ac06ce3
Fix errors when rendering system messages 2018-08-01 20:28:35 +01:00
Samuel Elliott 0c8279311e
Fix Message component selection and add bd-isGuildOwner and bd-isGuildMember classes 2018-08-01 20:18:47 +01:00
Samuel Elliott 331b2b396a
Fix emotes 2018-08-01 19:58:52 +01:00
Samuel Elliott a20473d718
Add a function to force update all instances of a component 2018-08-01 19:31:48 +01:00
Samuel Elliott 1a12430322
Add getting all state nodes to Reflection 2018-08-01 15:50:10 +01:00
Samuel Elliott 7a416c0ff7
Fix MessageGroup component selection 2018-08-01 13:53:59 +01:00
Samuel Elliott 81e392c0f6
Fix request module not found 2018-07-21 23:10:33 +01:00
Samuel Elliott 71c2d3aaad
Fix error with process.binding 2018-07-21 21:03:47 +01:00
Samuel Elliott 19bbd4215c
Fix syntax error at `%` 2018-07-20 21:10:44 +01:00
Samuel Elliott 5301498978 Merge branch 'toasts' into discord-api 2018-07-20 12:04:51 +01:00
Samuel Elliott 1d887967d9
Add an option to add additional classes to toasts 2018-07-20 12:04:16 +01:00
Samuel Elliott a95b97b3c0
Requested changes from JsSucks/BetterDiscordApp#194 2018-07-19 22:21:20 +01:00
Samuel Elliott 007637a557
Merge remote-tracking branch 'upstream/toasts' into toasts
# Conflicts:
#	client/src/modules/pluginapi.js
#	client/src/ui/bdui.js
#	client/src/ui/dom.js
#	client/src/ui/ui.js
#	package-lock.json
#	package.json
2018-07-19 22:03:29 +01:00
Samuel Elliott 6ded1c62e5
Prevent modals from being added to the stack more than once 2018-07-19 00:14:03 +01:00
Samuel Elliott 27f1eec967
Use a counter instead of the current time for modal IDs to avoid duplicates when multiple modals are opened at the same time 2018-07-18 22:17:50 +01:00
Samuel Elliott 821f46481e
Add all Map and Set methods to IterableWeakMap and IterableWeakSet 2018-07-18 21:53:07 +01:00
Samuel Elliott 6b97505f66
Remove unused imports 2018-07-18 20:57:05 +01:00
Samuel Elliott df471161a7
Fix leaks in keybind settings 2018-07-18 20:55:57 +01:00
Samuel Elliott da627f71e5
Add functions to get the values of weak collections 2018-07-18 20:54:58 +01:00
Samuel Elliott 78079588ea Fix Message component selection 2018-07-18 19:18:06 +01:00
Samuel Elliott b4ebd6c08a Always activate keybind settings 2018-07-18 19:18:06 +01:00
Samuel Elliott e6f2f518e6 Properly unbind events for emote autocomplete and dropdowns 2018-07-18 19:18:06 +01:00
Samuel Elliott aff89371e6
Fix all modals closing on escape key press 2018-07-08 13:52:29 +01:00
Samuel Elliott 98a7a71b87
Fix updater incorrectly showing an update is available 2018-07-07 22:05:36 +01:00
Samuel Elliott 98a0717bba
Use webpack named modules and eval source map plugins in development and disable Babel’s debug info 2018-07-07 20:00:15 +01:00
Samuel Elliott 7c8c8a754f
Use request instead of axios 2018-07-07 19:43:17 +01:00
Samuel Elliott ab13e716ad
Fix custom CSS editor 2018-07-07 14:37:23 +01:00
Samuel Elliott f2c31d866d
Add axios export 2018-07-07 14:29:44 +01:00
Samuel Elliott e169206821
Add hosts that serve emotes to the content security policy 2018-07-07 14:26:48 +01:00
Samuel Elliott cd77d659a5
Use axios and http/https to check for updates 2018-07-07 14:23:43 +01:00
Samuel Elliott b6f38a73dc
Add function to get classes and fix emote autocomplete injection 2018-07-07 01:17:26 +01:00
Samuel Elliott c384920275
Add WebpackModules wait functions to the plugin API 2018-07-07 01:10:39 +01:00
Samuel Elliott 097fc9b3e9
Update dependencies 2018-07-05 01:49:40 +01:00
Samuel Elliott b8fbfdee55
Fix Travis 2018-07-05 01:43:05 +01:00
Samuel Elliott 8c0b73625d
Add a settings proxy so settings values can be updated/retrieved like a plain object 2018-07-05 01:39:30 +01:00
Samuel Elliott 55cd75b5f4
Add settings section to edit window options 2018-07-05 01:26:04 +01:00
Samuel Elliott f8f519e882
Add custom window preferences 2018-07-04 19:40:25 +01:00
Samuel Elliott 799dca7e1b
Update to Gulp v4 2018-07-04 18:48:45 +01:00
Samuel Elliott eae1bdf3a6
Fix Utils is not defined 2018-06-26 23:41:39 +01:00
Samuel Elliott ea27259a67
Add common to the ESLint path and fix stats is undefined 2018-06-26 23:39:46 +01:00
Samuel Elliott ebe195f078
Delete old logs on startup 2018-06-26 23:25:43 +01:00
Samuel Elliott e2b68788bd
Add functions to wait for modules to be loaded 2018-06-24 19:56:05 +01:00
Samuel Elliott c8ca4fcfce
Fix friend source flags 2018-06-24 19:50:21 +01:00
Samuel Elliott 2c38433a2b
Add extra classes to messages, channel members and channels 2018-06-24 19:48:45 +01:00
Samuel Elliott ee0b13dab2
Emit events for when webpack modules are loaded 2018-06-23 23:15:45 +01:00
Samuel Elliott 4d2347cf84
Make sure file settings are updated properly when removing items 2018-06-23 22:59:13 +01:00
Samuel Elliott 7cf40a9ee4
Add SettingsWrapper to CommonComponents 2018-06-22 23:57:07 +01:00
Samuel Elliott 70f678119a
Add support for ES6 modules in plugins 2018-06-22 23:55:53 +01:00
Samuel Elliott 0a2b967e36
Fix removing items from file settings 2018-06-22 23:16:42 +01:00
Samuel Elliott a2367299b7
Don’t load emotes unless they’re enabled 2018-06-12 20:56:40 +01:00
Samuel Elliott bbcc36647d
Add class normaliser
Normalises and prefixes all classes with `da-`
2018-06-12 20:56:07 +01:00
Samuel Elliott 906140686f
Fix Utils is not defined 2018-06-10 22:51:52 +01:00
Samuel Elliott cecaf314f9
Fix channel.setNsfw 2018-06-10 22:41:14 +01:00
Samuel Elliott 4a3bb89259
Restore common in main and add note about __non_webpack_require__ 2018-06-10 22:40:46 +01:00
Samuel Elliott d7db836e30
Update DOMObserver
- Changed observer.subscribe function signature - `observer.subscribe(id, filter, callback, type)` is now `id = observer.subscribe(callback, filter, bind, type === 'filter’)`
- Add a function to subscribe to mutations affecting elements matching a query selector
- Some internal changes
2018-06-10 22:35:44 +01:00
Samuel Elliott 1eca4bcec7
Add ReactHelpers and ReactAutoPatcher to global._bd 2018-06-10 22:21:09 +01:00
Samuel Elliott c02052a982
Remove emote.name 2018-06-10 22:20:17 +01:00
Samuel Elliott be841f0426
Add the Manip class as an export of ui/dom.js 2018-06-10 22:17:37 +01:00
Zack Rauen 6c4743d7ed update node-sass 2018-06-10 16:42:56 -04:00
Zack Rauen 726d6cf4b0 gulp v4 instead of node 8 2018-06-10 16:28:55 -04:00
Samuel Elliott 35cedbdbb3
Use a single badge component 2018-06-10 21:28:23 +01:00
Samuel Elliott 17597e2c30
Add Vue wrapper for React 2018-06-10 21:22:01 +01:00
Zack Rauen 1bb705014f friggin travis 2018-06-10 16:00:52 -04:00
Samuel Elliott 204dd76e7b
Use the correct name for the user popout component 2018-05-29 21:59:54 +01:00
Samuel Elliott 3e41a11197
Allow forcefully unloading plugins without reloading Discord 2018-05-29 21:48:58 +01:00
Samuel Elliott 68d4617e46
Use the same format as React.createElement for VueInjector.createReactElement
Allows props to flow down to Vue components cleanly
2018-05-29 21:47:44 +01:00
Samuel Elliott 4654025423
Properly destroy Vue components after they’re unmounted by React 2018-05-29 18:46:08 +01:00
Samuel Elliott 231afa8ed6
Add the option to mount Vue components at the top of the React component 2018-05-29 18:35:40 +01:00
Samuel Elliott c3ff71ff85
Hide the ; before emotes in autocomplete and add the case insensitive flag 2018-05-29 17:00:05 +01:00
Samuel Elliott 0e99b219c1
Move emote autocomplete injector to the emote module 2018-05-29 16:58:57 +01:00
Samuel Elliott 13508b449d
Add some libraries to Vendor 2018-05-29 16:49:37 +01:00
Samuel Elliott e57e1f51ea
Fix getModuleByDisplayName 2018-05-29 15:40:14 +01:00
Samuel Elliott c345ab1419
Indentation 2018-05-29 15:39:32 +01:00
Samuel Elliott bee869340d
Disable errors for __[non_]webpack_require__ 2018-05-28 04:17:38 +01:00
Samuel Elliott 1de4680ded
Use ES6 imports/exports 2018-05-28 01:52:12 +01:00
Samuel Elliott bba1165c77
Wrap Discord’s preload script instead of enabling Node integration 2018-05-28 01:43:25 +01:00
Samuel Elliott a5c7aaab3b
Allow patching arrays 2018-05-21 20:49:21 +01:00
Samuel Elliott 93cd1fd07d
Log proxy targets and handlers instead of the proxy object itself 2018-05-21 19:08:57 +01:00
Samuel Elliott cfaf581ae1
Don’t use Moment.js
Plugins can still use Discord’s Moment.js with WebpackModules
2018-05-21 16:41:41 +01:00
Samuel Elliott 665c1d5fe4
Use local Moment.js instead of Discord’s
Fixes a recursive dependency issue
2018-05-20 00:46:15 +01:00
Samuel Elliott 8d8c1a8080
Add getting webpack modules as properties of the WebpackModules object
`WebpackModules.React` instead of `WebpackModules.getModuleByName('React')`
2018-05-20 00:36:14 +01:00
Samuel Elliott 8827bdb8b0
Fix messages with emotes not being updated when emotes are disabled 2018-05-20 00:27:02 +01:00
Samuel Elliott cd81f925cb
Fix for webpack 4 2018-05-20 00:24:21 +01:00
Samuel Elliott d7f4c651b6
Fix errors 2018-05-15 20:07:34 +01:00
Samuel Elliott f2159f1031
Fix error when unmounting a component 2018-05-15 16:54:22 +01:00
Samuel Elliott 581c94f6b3
Add React wrapper for Vue 2018-05-14 17:56:23 +01:00
Samuel Elliott 9eb8eaa906
Add DOM, DOMObserver and VueInjector to the plugin API 2018-05-14 16:34:40 +01:00
Samuel Elliott 9915ef8b19 Fix for Linux 2018-05-13 16:16:51 +01:00
Zack Rauen 2d784b48f4 add toasts 2018-05-12 23:17:04 -04:00
Samuel Elliott cee2a6ec34
Fix badges not being rendered when jumping to a message without a flash 2018-05-05 11:51:08 +01:00
Samuel Elliott 64e855ab2d
Fix badges not being rendered when jumping to a message 2018-05-05 11:39:56 +01:00
Samuel Elliott 5aa921ae4b
Fix EventsWrapper not unsubscribing from events
Also changed it to use removeListener so it can be used with normal EventEmitters
2018-05-05 11:17:26 +01:00
Samuel Elliott 40a72458e2
Fix Channel component 2018-05-03 19:52:23 +01:00
Samuel Elliott dc2be5c410
Add ReactHelpers to the plugin API 2018-05-03 15:56:07 +01:00
Samuel Elliott 640ec66abc
Some comments and fix updateSystemChannel 2018-04-30 21:12:50 +01:00
Samuel Elliott 3aedcfdd06
Add updating a guild’s icon/splash image from a file 2018-04-30 20:46:55 +01:00
Samuel Elliott 71fe549ee6
Add some permission checks 2018-04-30 20:19:54 +01:00
Samuel Elliott cbe1de98a5
Add updating guilds 2018-04-30 20:18:25 +01:00
Samuel Elliott 5a58c1c6ce
Add updating channel attributes 2018-04-30 19:17:04 +01:00
Samuel Elliott 591d44dee4
Add creating channels 2018-04-30 19:16:06 +01:00
Samuel Elliott 6da58ef6bb
Move Channel.openSettings to GuildChannel.openSettings, rename defaultChannel to isDefaultChannel and add GroupChannel names 2018-04-30 19:14:34 +01:00
Samuel Elliott 85d5de9791
Fix ChannelMember returning wrong component 2018-04-30 19:12:21 +01:00
Samuel Elliott 5ce78f4b32
Update layer classes 2018-04-29 17:56:23 +01:00
Samuel Elliott 2499f8c0ab
Get class names from internal modules 2018-04-29 17:41:12 +01:00
Samuel Elliott 3f2eb1047e
Use top/left to position tooltips/popovers and remove BdMenuItems from global 2018-04-29 17:35:30 +01:00
Samuel Elliott ac79bbb99b
Update classes 2018-04-29 16:30:21 +01:00
Samuel Elliott 1c4fb0b5ea
Rename HTMLUtils to SimpleMarkdown 2018-04-29 02:19:08 +01:00
Samuel Elliott 2e2d0dd6f6
Make some Vue components available to plugins, add highlight.js module and some tidying 2018-04-29 01:57:09 +01:00
Samuel Elliott a6c91d5e27
Add updating a user’s roles 2018-04-28 00:15:17 +01:00
Samuel Elliott 949206738b
Add user notes 2018-04-27 23:51:37 +01:00
Samuel Elliott 4dc715a39a
Patch all components at once instead of waiting for the previous component to be found 2018-04-27 19:05:00 +01:00
Samuel Elliott 36d7554b46
Add user popout data attributes 2018-04-27 19:02:35 +01:00
Samuel Elliott d42e8f66ca
Fix badges not being rendered on update 2018-04-27 17:39:28 +01:00
Samuel Elliott 244b7e5bd1
Move filters to common 2018-04-27 17:33:05 +01:00
Samuel Elliott ca7a7c1f91
Fix injected profile badges being removed 2018-04-27 16:12:46 +01:00
Samuel Elliott 504221ce28
Fix getComponentByRegex and add Filters to the plugin API 2018-04-27 16:06:51 +01:00
Samuel Elliott 1e643b8164
Patch the UserProfileModal component instead of injecting badges when the modal is opened 2018-04-27 16:00:27 +01:00
Samuel Elliott 0944c0708f
Add user profile modal data attributes 2018-04-27 15:53:49 +01:00
Samuel Elliott 17575fc6a1
Add filtering all components to ReactComponents 2018-04-27 15:52:43 +01:00
Samuel Elliott 1354b884b4
Add getting all components to reflection 2018-04-27 15:51:59 +01:00
Samuel Elliott 1ace26b67f
Select the channel when sending messages 2018-04-26 19:52:56 +01:00
Samuel Elliott 117336a6b4
Switch to Node.js v8 for Travis CI builds 2018-04-26 18:35:06 +01:00
Samuel Elliott d1cce95abe
Fix colour picker/dropdown options being hidden when in a drawer 2018-04-26 01:08:14 +01:00
Samuel Elliott 22fbb7b5bd
Fixed favourite emotes array being undefined
https://cdn.discordapp.com/attachments/400734824740028419/438847211325882370/unknown.png
2018-04-26 00:47:42 +01:00
Samuel Elliott 34ebab7c21
Use APIModule directly to edit messages 2018-04-25 23:57:07 +01:00
Samuel Elliott 5e8579e4dc
Use APIModule directly to delete messages 2018-04-25 23:56:10 +01:00
Samuel Elliott 4721f66dab
Comments 2018-04-25 23:54:26 +01:00
Samuel Elliott 02b313f2e6
Add checks for whether the user can delete a message 2018-04-25 23:02:47 +01:00
Samuel Elliott b0ae424adb
Change all properties to camel case 2018-04-25 22:54:41 +01:00
Samuel Elliott 5a6fb990c7
Add sending local bot messages 2018-04-25 13:54:33 +01:00
Samuel Elliott c294df6b26
Fix nickname checks and add changing nicknames programmatically 2018-04-25 13:40:18 +01:00
Samuel Elliott c3e4563aeb
Add multi option radios 2018-04-25 13:21:18 +01:00
Samuel Elliott 525fd3145d Merge branch 'master' into discord-api 2018-04-17 20:17:04 +01:00
Samuel Elliott 32452d918a
Fix guild member methods and set the guild/channel settings window section before opening it 2018-04-15 02:27:01 +01:00
Samuel Elliott e524c50b65
Add opening the user’s profile modal 2018-04-15 02:26:21 +01:00
Samuel Elliott 96952c3fef
Fix guild.owner 2018-04-15 00:54:33 +01:00
Samuel Elliott ad710de008
Fixes and add file header to list 2018-04-14 21:49:16 +01:00
Samuel Elliott 21ff9d200c
Some comments 2018-04-14 19:42:58 +01:00
Samuel Elliott a1c6f5d5fd
Separate messages into their types 2018-04-14 19:13:26 +01:00
Samuel Elliott 6d64d17b7d
Add embeds 2018-04-14 18:43:18 +01:00
Samuel Elliott 695d088f60
Add reactions 2018-04-14 18:08:57 +01:00
Samuel Elliott bcb888100c
Fix development CSS editor build being copied instead of the release build 2018-04-14 17:51:02 +01:00
Samuel Elliott 146e108874
Add file headers 2018-04-14 17:37:41 +01:00
Samuel Elliott 4837a01812
Add guild emojis 2018-04-14 17:24:07 +01:00
Samuel Elliott 48f4837a24
Wrap User instead of extending it 2018-04-14 17:20:17 +01:00
Samuel Elliott 8b320d2f09
More modals 2018-04-14 17:03:39 +01:00
Samuel Elliott ac22b14358
Add opening channel/guild settings window 2018-04-14 17:02:06 +01:00
Samuel Elliott 4d5a403d6d
Add user settings 2018-04-14 17:00:33 +01:00
Samuel Elliott 9dc424cc75
Allow after patches to change the return value 2018-04-14 15:17:02 +01:00
Samuel Elliott 1b75753a3d
Add user status/activity 2018-04-14 15:15:13 +01:00
Samuel Elliott a7b300d233
Check if the member exists before creating a GuildMember 2018-04-14 15:14:31 +01:00
Samuel Elliott 68e42b8b36
Add channel permission overwrites 2018-04-14 14:06:32 +01:00
Samuel Elliott e061d95ae6
Add roles 2018-04-14 14:06:09 +01:00
Alexei Stukov 6b517adbe8
Merge pull request #190 from samuelthomas2774/emote-autocomplete
Emote autocomplete and other fixes
2018-04-14 04:57:01 +03:00
Samuel Elliott 33c0732c08
Store objects in a WeakMap
So comparisons like `DiscordApi.currentUser === DiscordApi.currentUser` can be true
2018-04-14 00:31:09 +01:00
Samuel Elliott f1e0350433
Move data types to separate files and further separate channels based of their type 2018-04-14 00:29:03 +01:00
Samuel Elliott d5f486d1ad
Add shortcut to plugin/theme/extmodule manager content 2018-04-13 19:50:31 +01:00
Samuel Elliott 7fb8337095
Fix for plain CSS themes 2018-04-09 21:12:53 +01:00
Samuel Elliott 7adf63dfa8
Prevent escape closing Discord and BetterDiscord menus/modals at the same time 2018-04-08 19:54:48 +01:00
Samuel Elliott d2f7e6142f
Fix dropdowns not showing the selected option 2018-04-08 17:00:26 +01:00
Samuel Elliott b62727b046
Fix channel members not always being rerendered to show badges 2018-04-08 01:37:15 +01:00
Samuel Elliott f0a337e0ed
Fix custom CSS file not being used if the custom editor CSS is empty 2018-04-08 00:07:23 +01:00
Samuel Elliott 5c755bc121
Update pump
Fixes release dependencies not being copied properly
2018-04-07 16:42:16 +01:00
Samuel Elliott 4d0631ba38
Add wait util 2018-04-04 21:53:02 +01:00
Samuel Elliott d4962bb2ab
Fix settings being partially saved while loading 2018-04-04 21:39:55 +01:00
Samuel Elliott cf319a2604
Separate load 2018-04-04 21:38:56 +01:00
Samuel Elliott 256db71aa4
Hide emote autocomplete when emotes are disabled 2018-04-04 21:08:50 +01:00
Samuel Elliott de8601ded4
Show favourite emotes in autocomplete 2018-04-04 20:51:25 +01:00
Samuel Elliott a96f3b1eb7
Fix border radius of the message input field 2018-04-04 20:36:11 +01:00
Samuel Elliott a7aa1fa5ec
Fix up/down at the end of the list when the list has less than 10 emotes 2018-04-04 20:34:54 +01:00
Alexei Stukov bbd12a0381
Merge pull request #187 from samuelthomas2774/tweaks-and-emote-favourites
Tweaks and favourite emotes
2018-04-02 16:25:45 -02:00
Samuel Elliott 027ca8d639
Change plugin API WebpackModules
getModule[…] returns a module (first = true)
getModules[…] returns an array (first = false)
2018-04-01 23:17:33 +01:00
Samuel Elliott a0f60dddb2
Update plugin API (fix Utils not being passed arguments) 2018-04-01 23:12:23 +01:00
Samuel Elliott a3038c46fd
Undo 10fd25607d (diff-e0997702acb90b93fb46357f7576ab03L423) 2018-04-01 23:02:02 +01:00
Samuel Elliott d98f152009
Refactor UserProfileModals badges 2018-04-01 22:44:01 +01:00
Samuel Elliott 68beee12d3
Add the BD badge before the server owner icon 2018-04-01 17:39:46 +01:00
Samuel Elliott 4b59b9f65d
Prevent opening the popout when the badge is clicked 2018-04-01 17:35:09 +01:00
Samuel Elliott 85d390e18d
Rerender messages and channel members after patching 2018-04-01 15:24:28 +01:00
Samuel Elliott 3f89286946
Refactor message badges 2018-04-01 15:21:31 +01:00
Samuel Elliott 554b8d195b
Rename ReactComponentHelpers to ReactHelpers 2018-04-01 15:16:50 +01:00
Samuel Elliott 7f5fa44fd3
Refactor ChannelMember badges 2018-04-01 15:15:31 +01:00
Samuel Elliott c95d60ab0f
Don’t toggle favourite when the emote itself is clicked 2018-04-01 02:39:58 +01:00
Samuel Elliott 60a82a3ad9
Add package script and fix release script not working when the release directory doesn’t already exist 2018-04-01 00:18:05 +01:00
Samuel Elliott 2f9af2e2d0
Use correct Electron version 2018-03-31 23:06:24 +01:00
Samuel Elliott 858fdcec59
Clean up and comment 2018-03-31 22:49:40 +01:00
Samuel Elliott 3eb1782a64
Fix for Discord Canary 2018-03-31 22:44:24 +01:00
Samuel Elliott 0e14d167dc
Fix event callbacks not being passed any arguments 2018-03-31 17:38:11 +01:00
Samuel Elliott c701a2b5f9
Add emotes to the plugin API 2018-03-31 16:51:14 +01:00
Samuel Elliott b3442ee108
Store emote database in a map 2018-03-31 04:47:30 +01:00
Samuel Elliott 1bde3b4ec9
Add setting to enable/disable emotes 2018-03-31 03:26:42 +01:00
Samuel Elliott e83c6f92cb
Add emote favourite button 2018-03-31 03:22:44 +01:00
Samuel Elliott 06cca44376
Make plugin/theme descriptions preformatted 2018-03-31 01:19:05 +01:00
Samuel Elliott 3f3898c774
Add favourite emotes (no UI yet) 2018-03-31 01:17:42 +01:00
Samuel Elliott f8a380fd59
Add more advanced content authors (links to Discord profile, GitHub, Twitter, etc) 2018-03-31 01:10:33 +01:00
Samuel Elliott f28525129e
Add menu API 2018-03-31 01:03:13 +01:00
Samuel Elliott d2cbbd309b
Fix plugin/themes view not updating after reloading content 2018-03-31 00:50:03 +01:00
Samuel Elliott 74d78f4bca
Remove old monkey patch 2018-03-31 00:47:25 +01:00
Samuel Elliott 68af931128
Record plugin/theme load/start/stop timestamp 2018-03-31 00:46:05 +01:00
Samuel Elliott 5331afb763
Tweak card styles and use events 2018-03-31 00:45:14 +01:00
Samuel Elliott 069b1ff689
Extend AsyncEventEmitter and allow changing of some properties 2018-03-30 04:23:32 +01:00
Samuel Elliott 009d6be057
All clicking through the transparent area when the menu is open but nothing is selected 2018-03-30 01:38:36 +01:00
Samuel Elliott da4b592e54
Extend AsyncEventEmitter 2018-03-30 01:34:37 +01:00
Samuel Elliott 81f3519408
Use events in the settings menu 2018-03-30 01:17:02 +01:00
Samuel Elliott 8c09112cff
Use events 2018-03-30 01:07:56 +01:00
Samuel Elliott 8983256ade
Use Logger 2018-03-30 01:06:37 +01:00
Samuel Elliott d323292162
Add textarea for updating custom setting’s values in debug mode 2018-03-30 01:04:58 +01:00
Samuel Elliott 1714a0225e
Change autocomplete class names 2018-03-30 01:03:04 +01:00
Samuel Elliott fd3b0a92ce
Use events on modal close button click 2018-03-30 00:57:01 +01:00
Samuel Elliott 9b1dd771ad
Use v-model/events instead of a change function
Custom settings still work the same
2018-03-29 21:48:06 +01:00
Samuel Elliott 441e80e0e8
Tweak colour picker and add animation 2018-03-29 21:23:15 +01:00
Samuel Elliott 4634266e14
Make the button look more built in 2018-03-29 20:16:06 +01:00
Samuel Elliott 10fd25607d
Remove installer from release build script 2018-03-29 20:04:01 +01:00
Samuel Elliott 946f68e4ef
Fix theme edit button 2018-03-25 18:31:17 +01:00
Alexei Stukov a4ceb8bd2c
Merge pull request #184 from samuelthomas2774/refactor
Refactor and comment
2018-03-25 09:52:32 -02:00
Samuel Elliott 545b72cc3e
Refactor logger (use util.inspect) and fix CSS editor not awaiting settings saving 2018-03-25 02:18:40 +01:00
Samuel Elliott 9e229a1c0f
Cleanup profile badges 2018-03-24 16:13:24 +00:00
Samuel Elliott ddfd0653ac
Fix emote injection 2018-03-24 16:06:34 +00:00
Samuel Elliott 6bb8c18857
Update repository URL 2018-03-22 17:13:47 +00:00
Samuel Elliott 66eee86eb3
Fix cloning settings sets with schemes 2018-03-22 16:46:42 +00:00
Samuel Elliott eaeae7ad98
Use a warning when settings failed to load 2018-03-22 16:41:20 +00:00
Samuel Elliott a3eeee9b57
Store content config with it’s type 2018-03-22 16:38:09 +00:00
Samuel Elliott 6d46ac67de
Remove SimplerFlat 2018-03-22 16:27:53 +00:00
Samuel Elliott db6be20864
Use correct path for logs 2018-03-22 16:25:06 +00:00
Samuel Elliott 5e8e9fa19f
CSS editor fixes 2018-03-22 02:37:30 +00:00
Samuel Elliott ebff286c31
Add release build configuration 2018-03-22 02:19:25 +00:00
Samuel Elliott 0f805d57e3
More comments 2018-03-22 02:13:32 +00:00
Samuel Elliott 33adb92902
Add updater view 2018-03-21 22:24:23 +00:00
Samuel Elliott a85422f29e
Fix tooltips and add Vue to vendor 2018-03-21 21:07:57 +00:00
Samuel Elliott aa933d9a09
Refactor IPC 2018-03-21 20:52:42 +00:00
Samuel Elliott 8a9c8edf39
Add patcher to the plugin API and fix error when rendering system messages 2018-03-21 20:50:49 +00:00
Samuel Elliott 74e3605ec6
Get version from package.json 2018-03-21 20:48:01 +00:00
Samuel Elliott dc44af6968
Cleanup core 2018-03-21 17:41:27 +00:00
Samuel Elliott a4a130bfc6
Write logs to a file 2018-03-21 15:57:37 +00:00
Samuel Elliott 2fb5d8fe11
Pause all keybinds while recording and add debugger keybind 2018-03-21 00:27:25 +00:00
Samuel Elliott 1772edd37c
Cleanup project root and update package-lock.json 2018-03-20 23:29:00 +00:00
Samuel Elliott b4bd9e9c7b
Comments and fix tooltip arrow positioning 2018-03-20 23:24:38 +00:00
Samuel Elliott 994faf94d6
Refactor Vue injector and sparkplug and move contributors to data 2018-03-20 21:11:11 +00:00
Alexei Stukov 048abaeeed
Merge pull request #183 from JsSucks/utils-load-latest
Utils load latest
2018-03-20 07:51:52 -03:00
Jiiks f3fa3c2ae2 Tests should be true other than for building a release 2018-03-20 07:49:19 -03:00
Jiiks ee87cbc25c lint before building release 2018-03-20 07:48:03 -03:00
Jiiks 4ce32c415e copy prebuilt bindings 2018-03-20 07:47:03 -03:00
Jiiks c60411c901 Don't have to resolve it twice 2018-03-20 07:46:34 -03:00
Jiiks 9f24d0d1ce Fix package ver and make sure we always load the latest client script 2018-03-20 07:45:11 -03:00
Jiiks 684f85b45e Update release scripts and packages 2018-03-20 03:54:33 -03:00
Jiiks 83d9419131 css editor path fix 2018-03-19 20:02:40 -03:00
Alexei Stukov 1fe233bc91
Merge pull request #182 from JsSucks/release-script
Release script
2018-03-19 19:09:16 -03:00
Jiiks 70ae8365fe Remove merge-stream devdep 2018-03-19 19:03:48 -03:00
Jiiks 038d15ecf3 add release gulpfile and deps for it 2018-03-19 19:02:44 -03:00
Alexei Stukov 86fc492af4
Merge pull request #181 from JsSucks/css-editor-path
Dist path for css editor
2018-03-19 18:28:53 -03:00
Jiiks eed634217e Dist path for css editor 2018-03-19 18:26:13 -03:00
Alexei Stukov 122036fd14
Merge pull request #180 from JsSucks/configs
Configs
2018-03-19 14:20:28 -03:00
Jiiks a150c3cd4a Move stuff to their locations. Use tests as the proxy install dir when testing 2018-03-19 14:15:31 -03:00
Jiiks 01b7e81f44 add global getters 2018-03-19 13:45:20 -03:00
Alexei Stukov e1456f530c
Merge pull request #178 from JsSucks/installer
add initial installer base
2018-03-17 20:02:03 -03:00
Jiiks 5d86b6cf50 css editor build script and installer watch script 2018-03-17 19:59:48 -03:00
Jiiks 76a72c8341 add initial installer base 2018-03-17 19:57:43 -03:00
Alexei Stukov 7b52b22c5f
Merge pull request #177 from JsSucks/emote-styling
Wrapper should also be 32px
2018-03-17 19:25:45 -03:00
Jiiks c84a79d3f5 Wrapper should also be 32px 2018-03-17 19:23:19 -03:00
Alexei Stukov 0dd49b7c9b
Merge pull request #176 from JsSucks/data-attributes
Data attributes
2018-03-17 18:46:32 -03:00
Jiiks f8b9cdaead Missing Logger import 2018-03-17 18:42:16 -03:00
Jiiks b83e3c967d Emote styling 2018-03-17 18:40:47 -03:00
Jiiks 5ed34c149a Initial force update through reflection 2018-03-17 18:35:09 -03:00
Alexei Stukov cf2b3485ad
Merge pull request #175 from JsSucks/data-attributes
add guild, channel and user data attributes
2018-03-17 15:43:15 -03:00
Jiiks 8740c286a0 add guild, channel and user data attributes 2018-03-17 15:23:21 -03:00
Alexei Stukov ffea5bd3ae
Merge pull request #174 from JsSucks/patcher
Patcher changes and emote module fixes
2018-03-17 13:24:51 -03:00
Jiiks 0820735fa2 Unreachable code 2018-03-17 13:21:08 -03:00
Jiiks 549275e5dc Log emote loading error 2018-03-17 13:18:56 -03:00
Jiiks e268f769b7 Fix emote wrapper children 2018-03-17 13:17:50 -03:00
Jiiks 0af356823a Reinstate emote injection 2018-03-17 13:05:44 -03:00
Jiiks b5fc88bc8e Rewrite a bit and provide patch wrapper. add patcher test plugin as example 2018-03-17 12:48:08 -03:00
Jiiks 86528a3335 add overloads 2018-03-16 02:18:27 -03:00
Alexei Stukov f6d994e6a4
Merge pull request #173 from samuelthomas2774/add-guild-setting
Add guild setting
2018-03-16 03:56:40 +02:00
Samuel Elliott 533d4aead1 Make selected state more noticeable and sort the value array 2018-03-16 01:21:44 +00:00
Samuel Elliott 094ef7e173 Cleanup 2018-03-16 01:09:18 +00:00
Samuel Elliott 086b6253bc Add guild selection setting and developer mode option 2018-03-16 00:54:50 +00:00
Alexei Stukov d3a5be365e
Merge pull request #172 from JsSucks/react-components
Patch all React component  functions automatically
2018-03-15 16:22:09 +02:00
Jiiks 87cc894512 Path all React component functions automatically 2018-03-15 16:16:32 -03:00
Alexei Stukov c99eedd5c8
Merge pull request #171 from JsSucks/emote-module
Start filter and db getter
2018-03-15 15:16:07 +02:00
Jiiks 7643588b00 add search cache and push vendor to window dev object 2018-03-15 15:11:46 -03:00
Jiiks ce457e4ad4 Start filter and db getter 2018-03-15 14:44:41 -03:00
Alexei Stukov ae63213809
Merge pull request #170 from JsSucks/emote-changes-and-minor-stuff
Emote changes and minor stuff
2018-03-15 14:25:12 +02:00
Jiiks c44a35a6c4 Undef 2018-03-15 14:20:37 -03:00
Jiiks cc8f10f971 Traverse autocomplete with keydown 2018-03-15 14:14:42 -03:00
Jiiks 13f7ce0cad Make autocomplete function like Discord one except with ; 2018-03-15 14:11:48 -03:00
Jiiks e1f3bd2f41 Use ;; wrapper for emotes and change how they are injected 2018-03-15 14:07:16 -03:00
Jiiks 6bc2e0cca5 Export Filters from WebpackModules 2018-03-15 13:47:40 -03:00
Jiiks a4e51dd4a7 and unpatcher 2018-03-15 13:41:54 -03:00
Jiiks 0eaf63f5f7 Remove old render patcher 2018-03-15 13:41:43 -03:00
Jiiks bd5ded7333 Renaming 2018-03-15 13:39:09 -03:00
Jiiks 6d1dbfad1e add logging for patches 2018-03-15 13:20:13 -03:00
Alexei Stukov 96059d156c
Merge pull request #169 from JsSucks/plugin-apis
Give plugins everything and auto refactor
2018-03-14 14:23:43 +02:00
Jiiks 30c57cf998 Give plugins everything and auto refactor 2018-03-14 14:19:46 +02:00
Alexei Stukov d1dc8140e4
Merge pull request #168 from JsSucks/optimize
Optimize - Requires Core Rebuild(?)
2018-03-14 11:16:11 +02:00
Jiiks bf7919a877 add developer mode 2018-03-14 11:13:18 +02:00
Jiiks 25044beaef Don't 2018-03-14 11:11:08 +02:00
Jiiks 81941bb140 Lint 2018-03-14 11:06:54 +02:00
Jiiks d6794e6de8 Remove branch warning 2018-03-14 11:02:52 +02:00
Jiiks b3ed044408 add copyright headers 2018-03-14 11:01:10 +02:00
Jiiks 1e438764a0 Reset and remove old 2018-03-14 10:59:16 +02:00
Jiiks 9e875f4039 Fix autocomplete handlers and keys and trigger it with tab 2018-03-14 10:58:40 +02:00
Jiiks 5f7ddcb8ce add TODO notice 2018-03-14 09:43:03 +02:00
Jiiks e73ac58ff3 Go back to did-finish-load 2018-03-14 09:25:48 +02:00
Jiiks bcc856bc6b Don't need separate displayName 2018-03-14 09:17:58 +02:00
Jiiks 6473ddaf9f add important component scanner through reflection 2018-03-14 09:12:00 +02:00
Jiiks ce9a4c6b3d Fix channel member render 2018-03-14 02:36:34 +02:00
Jiiks 006a67ee01 DO NOT USE THIS BRANCH YOU WILL DIE IF YOU DO 2018-03-14 00:34:49 +02:00
Jiiks ae6b745e68 Partially fix autocomplete and use patches 2018-03-14 00:34:03 +02:00
Jiiks 7599271f31 add author id 2018-03-12 17:52:24 +02:00
Jiiks 2c2ef33565 Use DiscordApi to get current user 2018-03-12 17:50:43 +02:00
Jiiks d965e29867 Throw everything into _bd object 2018-03-12 17:50:09 +02:00
Jiiks 67dddf5391 Replay index 2018-03-12 17:48:29 +02:00
Jiiks 7116efe207 Replay exports 2018-03-12 17:46:55 +02:00
Jiiks 6a854ab070 Patcher 2018-03-12 17:46:20 +02:00
Jiiks 5083a80ba2 Remove observers 2018-03-12 17:46:20 +02:00
Alexei Stukov 37be465174
Merge pull request #167 from JsSucks/discord-api
Add DiscordAPI
2018-03-12 17:32:06 +02:00
Zack Rauen fd68da9566 update discord api 2018-03-11 22:42:06 -04:00
Zack Rauen 6917724700 update to master 2018-03-11 22:38:03 -04:00
Alexei Stukov 2c33d1f7f0
Merge pull request #166 from JsSucks/data-attributes
Data attributes
2018-03-11 16:35:22 +02:00
Jiiks f612fcbf00 Remove window var 2018-03-10 17:36:55 +02:00
Jiiks afc9f91dc3 Don't 2018-03-10 17:35:02 +02:00
Jiiks 2952331998 More attributes 2018-03-10 14:27:17 +02:00
Jiiks da6aecc3f2 add more attributes and file upload author 2018-03-10 13:53:27 +02:00
Alexei Stukov ad522dd745
Merge pull request #165 from JsSucks/emotes-and-databases
Emotes and databases
2018-03-10 10:26:49 +02:00
Jiiks b0fcedd3f3 Don't do anything if emotes don't exist 2018-03-10 10:21:35 +02:00
Jiiks fe319e58fe Remove data addition 2018-03-10 10:20:29 +02:00
Jiiks 45545d86b4 It's ugly for now. 2018-03-10 09:58:25 +02:00
Jiiks c59494f604 Emote autocomplete ui 2018-03-10 05:29:04 +02:00
Jiiks 523d226b91 Initial autocomplete and all emotes 2018-03-10 05:05:12 +02:00
Alexei Stukov 27aa21a47a
Merge pull request #164 from JsSucks/dom-attributes
UI Events, badges, data attributes, etc
2018-03-09 12:38:13 +02:00
Jiiks 4984ae996e Merge branch 'dom-attributes' of https://github.com/JsSucks/BetterDiscordApp into dom-attributes 2018-03-09 12:33:58 +02:00
Jiiks f494cbbb7a Bad filename 2018-03-09 12:33:38 +02:00
Alexei Stukov ef19f4723e
Merge branch 'master' into dom-attributes 2018-03-09 12:26:50 +02:00
Alexei Stukov 1adf372de9
Merge pull request #163 from samuelthomas2774/settings-menu-keybinds-and-fixes
Add keybind settings, add settings menu items to the plugin API and fix theme loading
2018-03-09 12:23:04 +02:00
Jiiks fe884ae436 filter check 2018-03-09 11:00:15 +02:00
Jiiks ae651e08e9 Reliable observers 2018-03-09 10:43:03 +02:00
Samuel Elliott b24e0ef178
Fix error on keypress
Uncaught TypeError: Cannot assign to read only property 'ignoreNextKeypress' of object '[object Object]'
    at ../node_modules/combokeys/Combokeys/index.js.module.exports.../node_modules/combokeys/Combokeys/prototype/handleKey.js.module.exports [as handleKey] (/Users/Samuel/Documents/BetterDiscord/2018-01-19/betterdiscordapp/client/dist/betterdiscord.client.…:4703)
    at ../node_modules/combokeys/Combokeys/index.js.module.exports.../node_modules/combokeys/Combokeys/prototype/handleKeyEvent.js.module.exports (/Users/Samuel/Documents/BetterDiscord/2018-01-19/betterdiscordapp/client/dist/betterdiscord.client.…:4752)
    at HTMLDocument.r (721226c….js:25)
2018-03-09 01:57:27 +00:00
Samuel Elliott 3578698a86
Fix deleting all injected styles 2018-03-09 01:26:45 +00:00
Samuel Elliott 1319793123
Unbind keybind event when plugin stopped 2018-03-09 00:46:56 +00:00
Samuel Elliott 47c786a98a
Can’t freeze internals as then Vue can’t make any plugin/theme’s info and enabled state reactive 2018-03-09 00:18:05 +00:00
Samuel Elliott bc1f93dd89
Store patched functions in a weakmap, move events wrapper and prevent plugins from modifying the plugin and content prototypes and their internals object 2018-03-08 23:43:26 +00:00
Jiiks 976ea796f8 Reliable switch events 2018-03-08 23:40:38 +02:00
Jiiks a746d6a03e Remove test badge 2018-03-08 23:15:57 +02:00
Jiiks 393362c8fb Userlist badges 2018-03-08 21:58:53 +02:00
Jiiks af8f7b0c9f Trigger on loaded more as well 2018-03-08 21:42:19 +02:00
Jiiks 1c63b8a05d Extend EventListener and add badges on other events 2018-03-08 21:40:43 +02:00
Jiiks dfa7987756 add badges to messages as well 2018-03-08 20:46:03 +02:00
Jiiks 7737dacd05 Use data- prefix for dataset access 2018-03-08 19:45:17 +02:00
Jiiks b75c7716c9 User reflection prop iterator 2018-03-08 19:37:50 +02:00
Jiiks 7e2be8bb19 add initial user-id manip 2018-03-08 19:35:05 +02:00
Jiiks 399f8a790d add deeper find 2018-03-08 19:30:21 +02:00
Jiiks fdfd0a6454 add loading more mutation callback 2018-03-08 17:37:38 +02:00
Jiiks 88b46bc359 only set currentuser attr if true 2018-03-08 16:46:50 +02:00
Jiiks fcebb43f35 Remove useless obeservers then 2018-03-08 16:44:51 +02:00
Samuel Elliott e7b0acb5a0
Fix plugin API basic modals 2018-03-08 13:59:19 +00:00
Jiiks e22e7f7af8 Hide mutable markup when editing 2018-03-08 14:47:15 +02:00
Jiiks 7a82d9e860 Edits and new messages functional 2018-03-08 14:45:31 +02:00
Jiiks 4804cd6ccb No class needed 2018-03-08 14:19:17 +02:00
Jiiks 44f0effba5 Renam event 2018-03-08 14:04:51 +02:00
Jiiks 5fd62c8050 Move markup cloning to automanipulator 2018-03-08 13:15:58 +02:00
Jiiks 8bda3e9b4d Don't need the classname 2018-03-08 11:18:21 +02:00
Jiiks 0154a7e97b add prop iterator 2018-03-08 11:17:33 +02:00
Jiiks fdfd961390 Change how reflection works 2018-03-08 10:59:51 +02:00
Jiiks 43359d771c add automa, new functions to ui and base reflection 2018-03-08 10:40:29 +02:00
Jiiks ff71042bb0 add ignoreExternal for faster testing other things 2018-03-08 08:25:51 +02:00
Samuel Elliott 68c0133381
Make menu keybind customisable 2018-03-08 02:42:06 +00:00
Samuel Elliott dfd0208394
Fix theme loading 2018-03-08 02:41:47 +00:00
Samuel Elliott 0229482be8
Add keybind setting 2018-03-08 02:41:38 +00:00
Samuel Elliott e78089a509
Add menu items to the plugin API 2018-03-07 20:32:04 +00:00
Samuel Elliott 5e259f50f8
Refactor settings menu
Adds support for dynamically adding items
2018-03-07 20:19:02 +00:00
Samuel Elliott 0bbd7b506a
Add option to ignore content manager errors 2018-03-07 19:57:00 +00:00
Alexei Stukov 1ddb93bd5d
Merge pull request #162 from JsSucks/socket-events
Simply emit everything we have instead of anything fancy
2018-03-07 12:42:02 +02:00
Jiiks 2e512e61b2 Push the data in generic events as well 2018-03-07 12:33:56 +02:00
Jiiks 37ecd7ec4e Simply emit everything we have instead of anything fancy 2018-03-07 12:32:58 +02:00
Alexei Stukov 67747f85eb
Merge pull request #161 from JsSucks/emote-module
Emote module
2018-03-07 11:43:20 +02:00
Alexei Stukov b5a5baa1bf
Merge pull request #159 from JsSucks/database
Database
2018-03-07 10:39:33 +02:00
Jiiks bca83da8c9 Correct error response for ipc 2018-03-07 10:36:18 +02:00
Jiiks ce0d9e826c Remove other db candidates 2018-03-07 10:35:49 +02:00
Jiiks 8d33d80e1c Convert content to use database instead of individual configs 2018-03-07 10:28:14 +02:00
Jiiks 30a886d84a Database wrappers 2018-03-07 10:12:44 +02:00
Jiiks bb2c3e54a5 add nedb 2018-03-07 07:06:38 +02:00
Jiiks aa3226ce43 New message event 2018-03-07 07:04:52 +02:00
Alexei Stukov f263cfac24
Merge pull request #158 from samuelthomas2774/array-merging-dynamic-settingssets-categories-fixes-and-comments
Better array merging, changeable settings sets and categories, fixes and comments
2018-03-07 06:42:33 +02:00
Samuel Elliott d122e27578
Add extmodules and webpack modules to plugin API 2018-03-07 02:07:17 +00:00
Samuel Elliott 7e82ae8a85
Add comments 2018-03-07 02:05:38 +00:00
Samuel Elliott a8d60582d0
Update plugin API modals 2018-03-07 01:10:06 +00:00
Jiiks 605e869413 add emote module and replaceroot to vue injector 2018-03-07 01:37:14 +02:00
Samuel Elliott a89d186730
Add comments 2018-03-06 21:58:09 +00:00
Samuel Elliott 6647595a3a
Move styles out of template 2018-03-06 21:55:50 +00:00
Samuel Elliott c9e681c242
Recalculate height on any update 2018-03-06 21:55:04 +00:00
Samuel Elliott c13884414d
Refactor event category/setting event binding 2018-03-06 08:26:48 +00:00
Samuel Elliott b7a769e883
Fixes 2018-03-06 01:59:53 +00:00
Samuel Elliott 93f08b715b
Add example custom settings set 2018-03-06 01:43:18 +00:00
Samuel Elliott 07dde5b1fa
Add live adding schemes and fix PluginApi.Settings 2018-03-06 01:15:11 +00:00
Samuel Elliott e67c08ff02
Allow setting a category’s name using name instead of category_name 2018-03-06 00:58:40 +00:00
Samuel Elliott 72dd93503a
Better merging of array setting items 2018-03-06 00:49:10 +00:00
Samuel Elliott da5e0ac99c
Add live updating settings sets and categories 2018-03-06 00:47:34 +00:00
Samuel Elliott 3ab4fd8a9a
Added base content class 2018-03-06 00:24:14 +00:00
Alexei Stukov 626b6cec64
Merge pull request #157 from samuelthomas2774/escape-windows-paths
Escape SCSS import path
2018-03-06 00:40:32 +02:00
Samuel Elliott e5078f4160
Fixed drawers 2018-03-05 21:46:28 +00:00
Samuel Elliott 5373512d9b
Added asynceventemitter.once and add comments 2018-03-05 19:55:53 +00:00
Samuel Elliott 26404843c2
Fix issues with multiline text settings 2018-03-05 19:48:39 +00:00
Samuel Elliott f236abdca9
Escape SCSS import path 2018-03-05 16:19:09 +00:00
Alexei Stukov 382ee68125
Merge pull request #156 from JsSucks/small-changes
Small changes
2018-03-05 06:45:40 +02:00
Jiiks 5908e39e52 Dropdown above colourpicker swatch 2018-03-05 06:42:53 +02:00
Jiiks 17672e674b Visible overflow when drawer open to fix dropdown/colour 2018-03-05 06:38:50 +02:00
Alexei Stukov 6841594a9a
Merge pull request #155 from JsSucks/small-changes
Small changes
2018-03-05 05:39:55 +02:00
Jiiks e7f5a2e118 add Beard's refresh button and change tab styling a bit 2018-03-05 05:37:33 +02:00
Jiiks 064065cfe1 add min-width to tabs 2018-03-05 05:02:49 +02:00
Jiiks da58d2e8b5 add placeholders for now 2018-03-05 05:01:29 +02:00
Jiiks 13364f1c9c Change tabs to say Installed/Browse instead 2018-03-05 04:54:40 +02:00
Alexei Stukov ccb5a1ce56
Merge pull request #154 from samuelthomas2774/settings
Fix settingsset.findSetting and arraysetting.items
2018-03-05 04:51:19 +02:00
Samuel Elliott e9f533d600
Add multi parameter for slider and number settings 2018-03-04 23:48:46 +00:00
Samuel Elliott 05b3abd290
Revert "Add multi parameter for slider and number settings"
This reverts part of commit 6cac091c27.
2018-03-04 23:20:39 +00:00
Samuel Elliott 6cac091c27
Add multi parameter for slider and number settings 2018-03-04 23:09:26 +00:00
Samuel Elliott 0332027963
Add comment 2018-03-04 22:55:58 +00:00
Samuel Elliott 9617890ab6
Handle changes better 2018-03-04 22:54:37 +00:00
Samuel Elliott 47637eca75
Fix settingsset.findSetting and arraysetting.items not being populated
- Changed plugin/theme event emitters to AsyncEventEmitter
2018-03-04 21:51:04 +00:00
Samuel Elliott d32959b8b9 Merge branch 'master' into settings 2018-03-04 21:45:40 +00:00
Alexei Stukov 050118f26c
Merge pull request #153 from JsSucks/setting-getters
Find first setting
2018-03-04 23:06:21 +02:00
Jiiks 43bc873bcb Find first setting 2018-03-04 23:03:38 +02:00
Alexei Stukov 1b6a846102
Merge pull request #152 from samuelthomas2774/settings
Refactor settings, add CSS/SCSS utilities to the plugin API and add automatic recompile of theme/custom SCSS
2018-03-04 22:29:45 +02:00
Samuel Elliott 88b063ca8e
Add monkeypatch utility function 2018-03-04 20:21:18 +00:00
Samuel Elliott 2bf1709dba
Fix “emit is not defined” 2018-03-04 01:35:32 +00:00
Samuel Elliott 1dffb1f40b
Add comments 2018-03-04 01:33:06 +00:00
Samuel Elliott 00d909f16c
Async setting and category events
- Async setting and category events
- Added deepfreeze utility
- Fix dropdown staying open after selecting an option
2018-03-04 00:22:05 +00:00
Samuel Elliott 91275f4332
CSS editor improvements 2018-03-03 23:36:17 +00:00
Samuel Elliott 976aecd8f2
Fix “css is not defined” 2018-03-03 01:47:50 +00:00
Samuel Elliott 9bc29cc66e
Add automatic recompile of SCSS in themes and the CSS editor when any file is changed 2018-03-03 01:44:39 +00:00
Samuel Elliott a6db490f49
Update package-lock.json 2018-03-03 00:20:41 +00:00
Samuel Elliott 2c6ae62c7e
Radio and dropdown fixes 2018-03-03 00:03:19 +00:00
Samuel Elliott 05c08ca51f
Update eslint-plugin-vue to version 4.3.0 2018-03-02 23:50:53 +00:00
Samuel Elliott dc1acf140f
Recompile themes when settings have changed 2018-03-02 22:28:17 +00:00
Samuel Elliott 90c256ed76
Fix relative file path resolution in file settings 2018-03-02 22:24:54 +00:00
Samuel Elliott 88e563501a
Fix inline settings arrays 2018-03-02 22:20:34 +00:00
Samuel Elliott bd72246715
Fix for eslint-plugin-vue and some things eslint detected 2018-03-02 21:24:55 +00:00
Samuel Elliott 2060a41f5d
Fix plugin API modal manager 2018-03-02 20:48:29 +00:00
Samuel Elliott fdc9330195
Add modal manager to plugin API 2018-03-02 20:19:59 +00:00
Samuel Elliott e94a7c50a4
Merge remote-tracking branch 'upstream/master' into settings
# Conflicts:
#	client/src/modules/thememanager.js
#	client/src/ui/components/BdSettings.vue
2018-03-02 19:47:29 +00:00
Samuel Elliott f9e278cc75
Updated plugin API
- Renamed Settings to InternalSettings
- Renamed getPlugins/getThemes to listPlugins/listThemes
- Add Utils to the plugin API
- Add CssUtils to the plugin API
- Add error handling on plugin start
- Changed ThemeManager.getConfigAsSCSS[Map] to accept a SettingsSet instead of an array of SettingsCategory objects
- Add examples to the example plugin
2018-03-02 19:42:17 +00:00
Samuel Elliott 3168012fde
Fix internal settings 2018-03-02 19:34:53 +00:00
Samuel Elliott 5e2b5975ed
Allow custom settings to extend the CustomSetting class 2018-03-01 21:10:30 +00:00
Alexei Stukov d6cb8f74fe
Merge pull request #151 from samuelthomas2774/add-menu-content-closing-animation
Add menu content closing animation and fix plugin/theme descriptions
2018-03-01 21:46:49 +02:00
Samuel Elliott 59bbc8d8ef
Add support for colour setting spelled as ‘color’ 2018-03-01 19:30:31 +00:00
Samuel Elliott 7954ebd764
Cleanup 2018-03-01 19:26:44 +00:00
Samuel Elliott 92612fc616
Fix modals closing with unsaved changes when clicking the close button, and added a shortcut to force close a modal by holding shift and clicking the close button 2018-03-01 19:01:45 +00:00
Samuel Elliott 3437c36b87
Use settings structs 2018-03-01 19:00:24 +00:00
Samuel Elliott 3574d6a5ba
Add settings structs 2018-03-01 18:50:49 +00:00
Samuel Elliott 9a72a7425e
Add async EventEmitter and deep clone 2018-03-01 18:42:53 +00:00
Samuel Elliott 5707da5f72
Fix plugin/theme descriptions 2018-03-01 01:52:08 +00:00
Samuel Elliott bff6057e0c
Add an animation when closing the settings menu content panel 2018-03-01 00:25:40 +00:00
Alexei Stukov ecf7f872cb
Merge pull request #150 from JsSucks/plugin-permissions
Initial plugin permissions
2018-02-28 21:39:23 +02:00
Alexei Stukov 22485bc26a
Merge pull request #149 from samuelthomas2774/add-relative-files
Add relative file path resolution for themes
2018-02-28 21:36:54 +02:00
Jiiks deaa680aae Initial plugin permissions 2018-02-28 21:34:12 +02:00
Samuel Elliott 1f5cf04eb6 Add scheme icon 2018-02-28 18:18:34 +00:00
Samuel Elliott cfdf3e0b4a Add relative file path resolution for themes 2018-02-28 18:14:35 +00:00
Alexei Stukov 4f451e3822
Merge pull request #148 from JsSucks/colour-picker-styling
Colour picker styling
2018-02-28 09:01:46 +02:00
Jiiks f4692c5e32 Move picker a bit more left 2018-02-28 08:59:34 +02:00
Jiiks 327fb09973 Remove pointer-events if no changes 2018-02-28 08:58:50 +02:00
Jiiks 7046316d60 add top offset 2018-02-28 08:55:30 +02:00
Jiiks 67142ca7db Picker z-index 2018-02-28 08:35:57 +02:00
Jiiks 1e977fb407 Return raw colour value for colour picker 2018-02-28 07:46:48 +02:00
Jiiks e418964819 Close colour picker when clicked outside 2018-02-28 07:41:57 +02:00
Alexei Stukov fab7371d66
Merge pull request #147 from JsSucks/settings-animation
Hide activepanel when settingsmenu closes
2018-02-28 07:04:09 +02:00
Jiiks e0de230ef2 Hide activepanel when settingsmenu closes 2018-02-28 06:23:21 +02:00
Alexei Stukov f255c010cd
Merge pull request #146 from JsSucks/colour-picker
Save and reset
2018-02-28 06:00:36 +02:00
Jiiks e7e79c9ac8 add colour picker save and reset 2018-02-28 05:58:13 +02:00
Alexei Stukov 963d9e61d8
Merge pull request #145 from JsSucks/colour-picker
Colour picker base
2018-02-28 04:31:32 +02:00
Jiiks 779a59c87e Make colour picker a popout and style it 2018-02-28 04:29:28 +02:00
Jiiks 160e6699e3 add missing .val ref #144 2018-02-28 00:10:37 +02:00
Jiiks 9b7b5d3b02 Colour picker base 2018-02-28 00:08:47 +02:00
Jiiks ca9264a672 add vue-color 2018-02-27 23:30:39 +02:00
Alexei Stukov 43e95bbba8
Merge pull request #142 from samuelthomas2774/add-full-width-settings
Add full width settings
2018-02-26 09:26:09 +02:00
Alexei Stukov 6380f9fc33
Merge pull request #143 from samuelthomas2774/add-custom-settings
Add custom settings and content reloading
2018-02-26 09:25:31 +02:00
Samuel Elliott df0f823f1d
Fixes 2018-02-22 16:19:35 +00:00
Samuel Elliott ff3ef34784
Show error modal when reloading content 2018-02-21 18:06:44 +00:00
Samuel Elliott 4cfa4ee466
Content reloading 2018-02-21 17:46:27 +00:00
Samuel Elliott b9145b5b85
Add custom settings 2018-02-21 16:00:49 +00:00
Samuel Elliott 5be5002ea1
Fix drawer open/close animation where height > width 2018-02-21 13:11:55 +00:00
Samuel Elliott d88caab321
Add full width settings 2018-02-21 10:46:13 +00:00
Alexei Stukov 99e9ce3852
Merge pull request #141 from samuelthomas2774/tabs-and-settings-arrays
Tabs and settings arrays
2018-02-21 07:52:39 +02:00
Samuel Elliott eae9d67649
Add support for file settings in themes
Files are added to the SCSS variables as a list of maps like (data: [base64 encoded file contents], type: [file MIME type], url: [data uri]), …
2018-02-21 01:16:41 +00:00
Samuel Elliott 2eaafdb1ac
Async SCSS configuration 2018-02-21 00:14:06 +00:00
Samuel Elliott 0be09f6cf8
Indent with spaces 2018-02-20 00:13:24 +00:00
Samuel Elliott afacd9cfbb
Add hover colour to settings schemes 2018-02-20 00:01:46 +00:00
Samuel Elliott 7123f5f100
Add support for array settings in themes 2018-02-20 00:01:23 +00:00
Samuel Elliott 522e798669
Remove scss_raw setting option 2018-02-19 23:54:37 +00:00
Samuel Elliott 201af9473e
Setting specific styles for inline arrays
Adds the ability for settings in an array to have no header text and appear full width
2018-02-19 22:19:50 +00:00
Samuel Elliott fae6fc8511
Add settings arrays 2018-02-19 18:20:44 +00:00
Samuel Elliott 847d88a628
Add confirm modal 2018-02-19 18:18:55 +00:00
Samuel Elliott 7cf1cf36fa
Add modal IDs 2018-02-19 18:17:49 +00:00
Samuel Elliott bd19a633b0
Move scroller outside settings, always show scrollbar in content 2018-02-19 18:17:06 +00:00
Samuel Elliott 8419bc51c1
Add transition between default/changed state on setting dividers 2018-02-19 18:13:02 +00:00
Samuel Elliott 9f6394eae3
Tabs SCSS 2018-02-19 18:12:17 +00:00
Samuel Elliott 6b94437b89
Fix modal backdrop still fading out when the first modal is closing even with additional modals on top 2018-02-19 18:11:47 +00:00
Samuel Elliott fca89aaaa6
Hide inactive tabs’ refresh button 2018-02-19 18:10:09 +00:00
Samuel Elliott 5931bffca3
Move plugins and themes view tab bars to the header 2018-02-17 02:17:55 +00:00
Samuel Elliott 5938e39d99
Update tab bar styles 2018-02-17 02:16:12 +00:00
Samuel Elliott 36a2fb1ec5
Tidy settings wrapper SCSS 2018-02-17 01:40:59 +00:00
Samuel Elliott c7db7fc2a7
Tidy tabs SCSS 2018-02-17 00:56:03 +00:00
Alexei Stukov d1d2610416
Merge pull request #139 from samuelthomas2774/add-object-logging
Add object logging handler
2018-02-15 23:02:02 +02:00
Alexei Stukov f528ef6bda
Merge pull request #140 from samuelthomas2774/fix-empty-css-editor
Fix CSS editor not updating when empty
2018-02-15 23:01:06 +02:00
Samuel Elliott fadd0574ac
Fixed clearing compiler error when empty 2018-02-15 19:27:44 +00:00
Samuel Elliott 01cacb3ef6
Ignore SCSS empty errors 2018-02-15 19:19:08 +00:00
Samuel Elliott c9a20b7fcf
Fix CSS editor not updating when empty 2018-02-15 19:14:08 +00:00
Samuel Elliott 48ee29b621
Indent with spaces 2018-02-15 17:09:06 +00:00
Samuel Elliott 78a61dc60f
Add object logging 2018-02-15 17:00:21 +00:00
Alexei Stukov fdb6ddd540
Merge pull request #138 from JsSucks/updater
Updater
2018-02-15 01:07:49 +02:00
Jiiks 3a09dfb066 Store interval 2018-02-15 01:05:12 +02:00
Jiiks 877b59d0d3 k 2018-02-15 01:04:25 +02:00
Jiiks 5df556f96e add updater events 2018-02-15 01:01:52 +02:00
Jiiks cd936201b5 add individual build scripts 2018-02-15 00:56:33 +02:00
Jiiks 807cb9241b Change version in dummy args 2018-02-15 00:54:20 +02:00
Alexei Stukov 5ba8c41850
Merge pull request #137 from JsSucks/updater
Updater
2018-02-14 22:30:49 +02:00
Jiiks 7ba43f8763 Emit update check end event 2018-02-14 22:28:55 +02:00
Jiiks 666960a9bd use rawgit foir now 2018-02-14 22:26:26 +02:00
Alexei Stukov 8c2f59ecf1
Update package.json 2018-02-14 22:26:01 +02:00
Alexei Stukov 1be6992da0
TEST 2018-02-14 22:25:28 +02:00
Alexei Stukov 050f8d40e0
TEST IGNORE 2018-02-14 22:19:35 +02:00
Alexei Stukov 77f4b7f0ec
TEST IGNORE 2018-02-14 22:16:56 +02:00
Jiiks eb9e3dd4c6 Updater runs every 30 minutes 2018-02-14 22:15:27 +02:00
Jiiks 2962d1fc9f Styles for update check 2018-02-14 22:02:12 +02:00
Alexei Stukov b51e675291
Merge pull request #134 from samuelthomas2774/add-settings-schemes
Add settings schemes
2018-02-14 21:41:24 +02:00
Samuel Elliott 0373d81199
Fixed showing content manager error modal with no errors 2018-02-14 18:51:51 +00:00
Samuel Elliott a9d488b748
Throw an error instead 2018-02-14 18:19:20 +00:00
Samuel Elliott c9d9feb63f
Prevent modal close when settings have changed 2018-02-14 18:14:46 +00:00
Samuel Elliott bea87f5be8
Add scheme hints 2018-02-14 18:03:10 +00:00
Samuel Elliott 9fb914fb70
Add settings schemes 2018-02-14 17:55:10 +00:00
Alexei Stukov a49551f7bb
Merge pull request #133 from samuelthomas2774/add-generic-settings-modal
Add generic settings modal
2018-02-14 19:13:57 +02:00
Samuel Elliott 0cfb6d36ca
Rename new Settings.saveSettings to Settings.mergeSettings 2018-02-14 16:32:12 +00:00
Samuel Elliott dcb2704a28
Merge Modals.pluginSettings and Modals.themeSettings to a single function for both 2018-02-14 16:22:48 +00:00
Samuel Elliott 8c5796e4f6
Remove old code 2018-02-14 16:14:59 +00:00
Samuel Elliott 41b7906612
Use Utils.compare for internal settings 2018-02-14 16:11:26 +00:00
Samuel Elliott 1dd01e186b
Use Plugin/Theme.config 2018-02-14 15:45:10 +00:00
Samuel Elliott 0af22b21d4
Merge remote-tracking branch 'upstream/master' into add-generic-settings-modal
# Conflicts:
#	client/src/modules/plugin.js
#	tests/plugins/Example/config.json
2018-02-14 15:40:22 +00:00
Jiiks 16763c4a3e Some apis 2018-02-14 17:26:48 +02:00
Alexei Stukov 12a5bd35d5
Merge pull request #132 from JsSucks/refactor-and-comments
Refactors and comments for now
2018-02-14 15:45:24 +02:00
Jiiks 57e73050cd User const 2018-02-14 15:36:18 +02:00
Jiiks df7d9fa0da User ContentConfig and bug fix 2018-02-14 15:35:35 +02:00
Jiiks b1f4fb637e add a base for content config object 2018-02-14 15:32:19 +02:00
Jiiks a37bccfbb2 Some commenting 2018-02-14 15:00:15 +02:00
Jiiks 287e2c9cd2 Some commenting 2018-02-14 14:55:06 +02:00
Alexei Stukov 401f67382d
Merge pull request #131 from JsSucks/plugin-depenencies
Plugin depenencies
2018-02-14 10:22:27 +02:00
Jiiks b23a5ba7ac Pass deps to plugins directly. Should be used when a plugin must have a module to function. 2018-02-14 10:05:34 +02:00
Jiiks 4fba4049e1 Check that plugin dependencies exist 2018-02-14 09:56:55 +02:00
Jiiks 4329517b0f add a depend error test plugin 2018-02-14 09:42:29 +02:00
Alexei Stukov dcd69d7b29
Merge pull request #130 from samuelthomas2774/add-setting-events
Add setting change events
2018-02-14 09:39:15 +02:00
Samuel Elliott cebaba2de3
Fix file setting 2018-02-14 01:52:45 +00:00
Samuel Elliott 8e71ee5a5c
Undo stuff from samuelthomas2774/add-setting-events 2018-02-14 01:49:23 +00:00
Samuel Elliott 145df5e7cc
Add Plugin.config 2018-02-14 01:45:41 +00:00
Samuel Elliott f13726d8e2
Remove old settings modals 2018-02-14 01:42:10 +00:00
Samuel Elliott 4b9084bee4
Add generic settings modal and recursive compare 2018-02-14 01:40:47 +00:00
Samuel Elliott 6b96bdbc3b
Add category names 2018-02-14 01:37:47 +00:00
Samuel Elliott 227b2cc0d8
Fix events for themes and extmodules 2018-02-13 23:36:40 +00:00
Samuel Elliott 08271deea1
Add plugin settings events
- Moved the Theme class to it’s own file
2018-02-13 23:26:39 +00:00
Samuel Elliott d3c3de5a79
Merge remote-tracking branch 'upstream/master' into add-setting-events
# Conflicts:
#	client/src/modules/pluginapi.js
2018-02-13 23:07:46 +00:00
Samuel Elliott 9b9162346b
Add internal settings access to the plugin API 2018-02-13 22:37:24 +00:00
Samuel Elliott 210d085caf
Fix “cannot read property ‘width’ of undefined” 2018-02-13 22:33:17 +00:00
Alexei Stukov 058fd2f7b5
Merge pull request #129 from JsSucks/modules
Modules
2018-02-14 00:32:56 +02:00
Samuel Elliott 8b85c829d6
Add setting updated event 2018-02-13 22:30:58 +00:00
Samuel Elliott 79af725f7f
Move error event struct 2018-02-13 22:28:58 +00:00
Jiiks 728aab8e95 Import modulemanager, add modules path to config, requires core rebuild 2018-02-14 00:24:04 +02:00
Samuel Elliott 1bded3121e Add event structs 2018-02-13 22:23:40 +00:00
Jiiks e01567bd6a Move example module 2018-02-14 00:17:24 +02:00
Jiiks 01b54a37bc load modules 2018-02-14 00:17:02 +02:00
Jiiks 44832fb11a Exports 2018-02-14 00:15:46 +02:00
Jiiks fca1d49506 add class name to Plugin 2018-02-14 00:14:50 +02:00
Jiiks 842f0d6229 Move module stuff to it's own module 2018-02-14 00:14:26 +02:00
Jiiks 0ac1cf240d Ext module base and ext module manager base 2018-02-14 00:10:22 +02:00
Alexei Stukov 13e9c53520
Merge pull request #128 from samuelthomas2774/css-editor
Add SCSS and saving support to the CSS editor
2018-02-14 00:06:00 +02:00
Alexei Stukov 91a658db44
Merge pull request #127 from samuelthomas2774/modals
Add modal manager
2018-02-14 00:03:27 +02:00
Samuel Elliott c581ba1b75
Add save/restore of CSS editor window bounds 2018-02-13 21:03:48 +00:00
Samuel Elliott a9a45e0f20
Fixed unnecessary escape characters 2018-02-13 20:11:34 +00:00
Samuel Elliott 6a11d3049a
Fix error when the CSS editor isn’t open 2018-02-13 20:09:39 +00:00
Samuel Elliott 729657f345
Add saving to the CSS editor 2018-02-13 20:06:04 +00:00
Samuel Elliott 5ca04f0652
Add SCSS support to the CSS editor 2018-02-13 19:56:01 +00:00
Samuel Elliott a965dc9515
Tidy modal SCSS files 2018-02-13 17:50:01 +00:00
Samuel Elliott 98261a864d Hide lower modals 2018-02-13 17:39:32 +00:00
Samuel Elliott 2ec2df6efd Tidy and tweak modal SCSS files 2018-02-13 17:39:32 +00:00
Samuel Elliott 21c70124e5 Bring back the logo animation on menu open/close 2018-02-13 17:39:31 +00:00
Samuel Elliott 10abf0353f Rename the tooltips container to bd-tooltips and move it above the settings and modals elements 2018-02-13 17:39:31 +00:00
Samuel Elliott 1f85d4d2f4 Added Plugin/Theme.showSettingsModal 2018-02-13 17:39:31 +00:00
Samuel Elliott 3b66d320e8 Move plugin/theme settings modals to the modal manager 2018-02-13 17:39:31 +00:00
Samuel Elliott 21a8554d6f Change lower modals’ opacity 2018-02-13 17:39:31 +00:00
Samuel Elliott 8706e9ef0f Merge plugin/theme manager errors 2018-02-13 17:39:31 +00:00
Samuel Elliott 64ac3677b1 Add modal manager 2018-02-13 17:39:31 +00:00
Alexei Stukov cbc727f951
Merge pull request #126 from JsSucks/refactor
Rename require to bridge
2018-02-13 18:47:34 +02:00
Jiiks 66721d80b5 Rename require to bridge 2018-02-13 18:43:44 +02:00
Alexei Stukov 0d660ac523
Merge pull request #125 from JsSucks/external-modules
External modules
2018-02-13 18:33:15 +02:00
Jiiks 8984be5c3e add a import test 2018-02-13 18:26:20 +02:00
Jiiks ebeae46991 Wait for all plugins to load before starting them 2018-02-13 18:22:48 +02:00
Jiiks 9a652e3748 add import to api 2018-02-13 18:18:01 +02:00
Jiiks 1f1d748687 Module loading 2018-02-13 18:06:36 +02:00
Jiiks d406384dd0 add types and module config 2018-02-13 17:54:53 +02:00
Alexei Stukov 0994c1f94f
Merge pull request #124 from samuelthomas2774/add-plugin-exports
Add plugin exports
2018-02-13 17:40:48 +02:00
Samuel Elliott 7664266dfe
Add plugin exports 2018-02-12 22:51:22 +00:00
Alexei Stukov 663af3ca83
Merge pull request #123 from samuelthomas2774/add-core-settings-storage
Fixed setting loading
2018-02-12 22:12:06 +02:00
Samuel Elliott e793a8d380
Change Settings.get to return undefined when a setting isn’t found 2018-02-12 19:48:36 +00:00
Samuel Elliott 61c913b55b
Renamed Settings.getSetting to Settings.get 2018-02-12 19:31:50 +00:00
Samuel Elliott cc1aee6842
Fixed setting loading 2018-02-12 19:23:35 +00:00
Alexei Stukov 80ce233e6d
Merge pull request #122 from samuelthomas2774/add-core-settings-storage
Add core settings storage
2018-02-12 21:22:10 +02:00
Alexei Stukov 9aeb5972cd
Merge pull request #121 from samuelthomas2774/fix-plugin-getsetting
Fix Plugin.getSetting
2018-02-12 21:20:02 +02:00
Samuel Elliott f085364760
Fix drawer header size 2018-02-12 19:05:28 +00:00
Samuel Elliott 1f4c2df3ae
Add functions to get a set, category and setting value 2018-02-12 19:01:07 +00:00
Samuel Elliott 32326471b1
Tidy switches Vue files 2018-02-12 19:00:42 +00:00
Samuel Elliott 8d7261a24a
Remove old components 2018-02-12 17:56:22 +00:00
Samuel Elliott 7e2fca9059
Add update hook 2018-02-12 17:54:40 +00:00
Samuel Elliott 26fbac6bbc
Add support for disabled settings 2018-02-12 17:54:16 +00:00
Samuel Elliott eaa8d3a03a
Fix CSS editor panel 2018-02-12 17:46:29 +00:00
Samuel Elliott 4fa91563a5
Tidy switches SCSS files 2018-02-12 17:46:02 +00:00
Samuel Elliott 09cff282cb
Update internal settings format and use a generic settings panel 2018-02-12 17:33:32 +00:00
Samuel Elliott 52f8c1cf31
Rename PluginSetting to Setting 2018-02-12 16:52:09 +00:00
Samuel Elliott 15f683d4c9
Fix Plugin.getSetting 2018-02-12 15:20:27 +00:00
Samuel Elliott 4dfe349802
Add core settings storage 2018-02-12 15:19:11 +00:00
Alexei Stukov 0eddaf86eb
Merge pull request #120 from JsSucks/settings
Change dropdown/radio structure
2018-02-12 04:58:51 +02:00
Jiiks cb2536437b Change test setting text 2018-02-12 04:56:42 +02:00
Jiiks 194c1c1ff8 Change dropdown/radio structure 2018-02-12 04:54:15 +02:00
Alexei Stukov aae9653a4a
Merge pull request #117 from JsSucks/theme-settings
Theme settings
2018-02-12 02:54:34 +02:00
Jiiks c52f1eb0b8 Number test setting 2018-02-12 02:51:10 +02:00
Jiiks f37058779a Radio functional 2018-02-12 02:48:44 +02:00
Jiiks 44b9450efa Dropdown functional 2018-02-12 02:44:12 +02:00
Alexei Stukov 06b3b70272
Merge pull request #116 from JsSucks/plugin-api
Plugin api
2018-02-12 01:10:34 +02:00
Jiiks 4e46675f94 add events for plugins 2018-02-12 01:04:07 +02:00
Jiiks 4a7a9ae1db add base plugin api and pass vendor to plugins 2018-02-12 00:07:23 +02:00
Alexei Stukov 35338dd104
Merge pull request #115 from samuelthomas2774/plugin-theme-configuration
Remove unnecessary information when saving plugin/theme configuration
2018-02-11 23:45:52 +02:00
Samuel Elliott 14822ab51a Don't save unnecessary information with plugin/theme configuration 2018-02-11 21:30:35 +00:00
Alexei Stukov 0043292b25
Merge pull request #114 from JsSucks/slider
Slider
2018-02-11 23:03:36 +02:00
Jiiks fad9a5336a add another test var 2018-02-11 22:41:38 +02:00
Jiiks 2453797400 add slider theme setting 2018-02-11 22:35:29 +02:00
Alexei Stukov 0b1dabd80b
Merge pull request #113 from JsSucks/themes
Ensure forward slashes
2018-02-11 22:28:18 +02:00
Jiiks da702bd40a Ensure forward slashes 2018-02-11 22:25:15 +02:00
Alexei Stukov 600991fd50
Merge pull request #112 from samuelthomas2774/theme-scss
Add theme reloading
2018-02-11 22:19:52 +02:00
Samuel Elliott 8d70e9cd54 Add theme reloading 2018-02-11 20:12:15 +00:00
Alexei Stukov c502ee8909
Merge pull request #111 from samuelthomas2774/theme-scss
Add theme configuration to SCSS variables and add compile caching
2018-02-11 21:57:31 +02:00
Samuel Elliott 9301ad627c Add SCSS theme configuration and compile caching 2018-02-11 19:31:24 +00:00
Alexei Stukov 702b770058
Merge pull request #110 from JsSucks/sass
Sass
2018-02-11 21:20:08 +02:00
Alexei Stukov 1db9ad3425
Merge pull request #109 from samuelthomas2774/add-unix-node-sass-build-scripts
Add node-sass build scripts for macOS and Linux
2018-02-11 18:30:01 +02:00
Jiiks 8bb388fb25 Dynamic vars support 2018-02-11 18:28:47 +02:00
Jiiks fa9c0d2f94 Compile theme scss 2018-02-11 17:42:24 +02:00
Samuel Elliott 997ae3369d
Add node-sass build scripts for macOS and Linux 2018-02-11 15:34:15 +00:00
Jiiks 31655e558c add sass compiler and reject to ipc 2018-02-11 16:59:55 +02:00
Alexei Stukov 49103b1c49
Merge pull request #108 from JsSucks/sass
Sass
2018-02-11 16:06:32 +02:00
Jiiks 45c372b71c unzip 2018-02-11 16:04:06 +02:00
Jiiks 00cc38ae33 add node-sass bindings for all platforms 2018-02-11 15:55:41 +02:00
Jiiks 34435465a3 add node-sass rebuild script 2018-02-11 15:54:45 +02:00
Jiiks e25c3fe846 Change electron version and add electron-rebuild 2018-02-11 15:54:22 +02:00
Alexei Stukov 224b51f1c3
Merge pull request #107 from samuelthomas2774/linux-fixes
Fix position of the settings menu button on Linux
2018-02-09 18:31:52 +02:00
Samuel Elliott 01655f0c04 Fix position of the settings menu button on Linux 2018-02-09 15:48:58 +00:00
Alexei Stukov aa7e6ab160
Merge pull request #106 from samuelthomas2774/macos-linux-fixes
macOS and Linux fixes
2018-02-09 17:16:29 +02:00
Alexei Stukov f05517a0a4
Merge pull request #105 from samuelthomas2774/add-theme-config
Save theme configuration when enabled/disabled
2018-02-09 17:16:12 +02:00
Samuel Elliott d4c71452bc
Enable theme on start if enabled 2018-02-08 23:53:39 +00:00
Samuel Elliott 08b791e547
Add theme configuration and saving 2018-02-08 20:19:26 +00:00
Samuel Elliott f3aef1d61d
macOS and Linux fixes 2018-02-08 20:15:18 +00:00
Alexei Stukov f71d79fd90
Merge pull request #104 from JsSucks/socketstrcuts
add socket event structs
2018-02-08 00:08:13 +02:00
Jiiks 0ec190612b add socket event structs 2018-02-08 00:03:39 +02:00
Alexei Stukov fc2a374344
Merge pull request #103 from JsSucks/error-handling
Error handling
2018-02-07 23:33:33 +02:00
Jiiks 39c83b7fa6 Select all for stacktrace 2018-02-07 18:07:17 +02:00
Jiiks 67f7111f66 Content manager error modal 2018-02-07 18:02:27 +02:00
Jiiks bf0c74b516 add error struct 2018-02-07 16:41:10 +02:00
Alexei Stukov bcdd694ec9
Merge pull request #102 from JsSucks/error-modals
Modals
2018-02-07 14:25:16 +02:00
Jiiks 208ca763ab add header 2018-02-07 14:21:51 +02:00
Jiiks 51f5a93da2 add modal footer, styling and error modal on plugin load fail 2018-02-07 14:15:46 +02:00
Jiiks f69ea55967 Make additional modal backdrops transparent 2018-02-07 13:56:10 +02:00
Jiiks b395ed767d add error mi, event based modals 2018-02-07 13:52:59 +02:00
Alexei Stukov 18c71fe7da
Merge pull request #100 from JsSucks/theme-manager
Theme manager
2018-02-05 19:02:31 +02:00
Jiiks 72b024c4f3 User a card base for both plugin and theme cards 2018-02-05 18:58:35 +02:00
Jiiks e7b488316b Initial themes view with enable/disable functional 2018-02-05 18:48:03 +02:00
Alexei Stukov 63b1e9d1e6
Merge pull request #99 from samuelthomas2774/save-plugin-enabled
Save plugin config when enabled/disabled
2018-02-05 17:31:25 +02:00
Samuel Elliott 6e4d6307e8
Save plugin config when enabled/disabled 2018-02-05 14:33:30 +00:00
Jiiks 2472743660 Theme manager base 2018-02-05 16:19:24 +02:00
Jiiks 83783a9ece add example theme 2018-02-05 16:06:53 +02:00
Alexei Stukov 9fb51c57b3
Merge pull request #98 from JsSucks/ui
Ui
2018-02-05 16:01:51 +02:00
Jiiks ca3ce86dc5 Correctly toggle changed state 2018-02-05 15:58:30 +02:00
Jiiks c5a011012f Functional bool setting 2018-02-05 15:57:41 +02:00
Alexei Stukov 6a96ce1237
Merge pull request #97 from samuelthomas2774/tweak-sliders
Add preset points along a slider
2018-02-05 15:54:01 +02:00
Samuel Elliott 5b87a928ba
Add preset points along a slider 2018-02-05 13:36:43 +00:00
Alexei Stukov e314faf157
Merge pull request #96 from JsSucks/ui
add value tooltip to slider
2018-02-05 12:52:21 +02:00
Jiiks 45448e23d3 add value tooltip to slider 2018-02-05 12:45:59 +02:00
Alexei Stukov fd8eaa363b
Merge pull request #95 from samuelthomas2774/add-multiline-text
Add multiline text
2018-02-05 10:54:36 +02:00
Alexei Stukov 93607fde0c
Merge branch 'master' into add-multiline-text 2018-02-05 10:54:29 +02:00
Alexei Stukov dc7805c835
Merge pull request #94 from samuelthomas2774/add-sliders
Add sliders
2018-02-05 10:52:11 +02:00
Samuel Elliott 30121ecc9c
Add multiline text 2018-02-05 01:14:19 +00:00
Samuel Elliott 64dd9cd6fb
Moved scrollbar styles to a mixin 2018-02-05 01:13:11 +00:00
Samuel Elliott 4c414e80d4
Removed 2s timeout before saving plugin config 2018-02-05 01:12:16 +00:00
Samuel Elliott 7250ab6cf9
Add sliders 2018-02-05 00:34:22 +00:00
Alexei Stukov 61cbcd8bb5
Merge pull request #93 from JsSucks/ui
Changed settings green divider colour
2018-02-05 01:17:35 +02:00
Jiiks 5165094a1b Set the divider colour for changed settings to green 2018-02-05 01:14:28 +02:00
Alexei Stukov 2da3fb95c2
Merge pull request #92 from samuelthomas2774/add-drawer-animation
Add drawer open/close animation
2018-02-05 00:51:10 +02:00
Samuel Elliott 9245e921ce
Add drawer open/close animation 2018-02-04 22:47:27 +00:00
Alexei Stukov 17f9487225
Merge pull request #91 from JsSucks/ui
Wheel number input
2018-02-05 00:44:59 +02:00
Jiiks 4ba99b654e Wheel to increment number 2018-02-05 00:40:01 +02:00
Alexei Stukov e09afda0f2
Merge pull request #90 from JsSucks/ui
Full width radio
2018-02-05 00:33:25 +02:00
Jiiks a783072cca Full width radio 2018-02-05 00:30:24 +02:00
Alexei Stukov 848af986e6
Merge pull request #89 from samuelthomas2774/tweak-form-elements
Dropdown and radio tweaks
2018-02-05 00:13:34 +02:00
Samuel Elliott 4ef24b8b85
Organised form SCSS files and updated styles for dropdowns and radios 2018-02-04 22:09:24 +00:00
Samuel Elliott ba4a02b501
Fix file setting open button 2018-02-04 22:07:03 +00:00
Jiiks 41ff8e6445 add user config files to ignore 2018-02-04 23:24:16 +02:00
Alexei Stukov 4caab690ac
Merge pull request #88 from JsSucks/plugins
Plugin icon
2018-02-04 23:22:02 +02:00
Jiiks c73346292e Give plugins an option to set an icon 2018-02-04 23:19:05 +02:00
Alexei Stukov 634180a6e5
Merge pull request #87 from samuelthomas2774/fix-config-loading
Fix merging user configuration into default configuration
2018-02-04 22:37:46 +02:00
Samuel Elliott 1a95a7db4b
Fixed merging user config into default config 2018-02-04 20:17:22 +00:00
Alexei Stukov a0fb11d591
Merge pull request #86 from JsSucks/plugins
Merge
2018-02-04 21:10:06 +02:00
Jiiks a706e6f2fc Plugin setting saving 2018-02-04 21:06:08 +02:00
Alexei Stukov 6e4f90cdfb
Merge pull request #85 from samfun123/master
Add Number, Radio and Dropdown setting types
2018-02-04 20:30:49 +02:00
samfun123 7cfd141260 Make the cursor be a pointer 2018-02-04 11:44:13 -05:00
samfun123 5bcd43bb48 Fixed two bugs in the Number type 2018-02-04 11:32:03 -05:00
samfun123 75410b4ce9 Add Number, Radio and Dropdown setting types 2018-02-04 11:12:38 -05:00
Alexei Stukov 4480458bd6
Merge pull request #84 from JsSucks/ui
Merge
2018-02-04 16:23:17 +02:00
Jiiks 932d91876b Drawer button animation 2018-02-04 16:20:57 +02:00
Alexei Stukov 71df600173
Merge pull request #83 from samuelthomas2774/fix-modal-backdrop-animation
Fix modal backdrop animation
2018-02-04 16:12:53 +02:00
Samuel Elliott ace7bab65e
Fix modal backdrop animation 2018-02-04 14:04:17 +00:00
Jiiks 3034ea4934 User chevron and make entire header clickable 2018-02-04 15:51:11 +02:00
Jiiks fc6bb75229 Add chevron-down material icon 2018-02-04 15:44:55 +02:00
Jiiks 3edceebd89 typo 2018-02-04 14:34:09 +02:00
Alexei Stukov e65e4d116e
Merge pull request #79 from samuelthomas2774/add-modal-animation
Add animation on modal open/close
2018-02-04 14:29:05 +02:00
Alexei Stukov 996ab6a73f
Merge branch 'master' into add-modal-animation 2018-02-04 14:28:56 +02:00
Alexei Stukov 2befa12cc4
Merge pull request #82 from JsSucks/fullscreen-modals
Merge
2018-02-04 14:22:06 +02:00
Jiiks 267a545ea5 Remove debug 2018-02-04 14:19:55 +02:00
Jiiks 18926dd58a add keyup to close modal 2018-02-04 14:19:12 +02:00
Alexei Stukov e2e2ab74ef
Merge pull request #81 from JsSucks/fullscreen-modals
Fullscreen modal z-index fix
2018-02-04 14:11:11 +02:00
Jiiks 230e9e6560 Fix footer save alert 2018-02-04 14:08:28 +02:00
Jiiks 8a799f29f7 Fullscreen modals
fixes #80
2018-02-04 14:00:08 +02:00
Jiiks bf648dce6c Remove transforms so fixed positioning actually works. Chrome: 20574 wontfix lel 2018-02-04 11:51:35 +02:00
Alexei Stukov aac97dd7c4
Merge pull request #78 from samuelthomas2774/add-drawers
Add drawers, add hairline when scrolling in a modal and organise form SCSS files
2018-02-04 11:11:21 +02:00
Samuel Elliott 21025e759e
Add animation on modal open/close 2018-02-03 21:52:56 +00:00
Samuel Elliott 915db146e8
Added plus icon 2018-02-03 15:00:36 +00:00
Samuel Elliott c5442f709d
Add drawers and hairline when scrolling in a modal and organise form SCSS files 2018-02-03 14:52:58 +00:00
Alexei Stukov a97682b2a4
Merge pull request #77 from JsSucks/plugins
New plugin config struct
2018-02-03 11:33:44 +02:00
Jiiks 39da2ffdb8 Change how plugin config works and set z index for modals 2018-02-03 11:25:34 +02:00
Alexei Stukov 7ce0ecbf62
Merge pull request #76 from JsSucks/styling
Merge
2018-02-03 07:48:56 +02:00
Jiiks e0ce4c00c1 coom != com 2018-02-03 07:46:18 +02:00
Jiiks 889e4916ef Sidebar should be col 2018-02-03 07:45:18 +02:00
Jiiks b1edcf5810 add twitter 2018-02-03 07:44:18 +02:00
Jiiks b8116ddc58 Remove grow from info and add padding 2018-02-03 07:39:56 +02:00
Jiiks 071b60b986 Move info to sidebar footer and set scroller padding 2018-02-03 07:38:28 +02:00
Alexei Stukov 2f680a9a4e
Merge pull request #75 from JsSucks/ui
added icons
2018-02-03 02:41:48 +02:00
Jiiks 801235e50b add minus and open-in-new 2018-02-03 02:36:05 +02:00
Alexei Stukov 4d716439b6
Merge pull request #74 from JsSucks/ui
Material icons
2018-02-03 02:29:49 +02:00
Alexei Stukov 7ab6daf626
Merge pull request #73 from samuelthomas2774/add-file-setting
Add file setting
2018-02-03 02:26:07 +02:00
Jiiks e05b5c3377 add and use material/close 2018-02-03 02:17:35 +02:00
Jiiks 2f463fad32 Like so instead 2018-02-03 02:00:18 +02:00
Jiiks f18c594744 Start baking material icons straight in 2018-02-03 01:45:00 +02:00
Samuel Elliott 2d0ba0cc0e
Add file setting 2018-02-02 23:42:12 +00:00
Alexei Stukov 64385a5631
Merge pull request #72 from JsSucks/ui
Plugin setting categories base
2018-02-02 22:51:23 +02:00
Jiiks 20c9dacf71 Category support for plugin settings 2018-02-02 22:47:50 +02:00
Alexei Stukov af9f0e21aa
Merge pull request #71 from JsSucks/ui
Merge
2018-02-02 21:48:46 +02:00
Jiiks 853e2a03aa Move backdrop to modal and add a warning when attempting to close with unsaved changes 2018-02-02 21:43:35 +02:00
Alexei Stukov 5fe333c3d3
Merge pull request #70 from samuelthomas2774/fix-close-plugin-settings-button
Made the close button in the plugin settings modal work
2018-02-02 21:17:00 +02:00
Samuel Elliott 67e6a22ca7
Made the close button in the plugin settings modal work 2018-02-02 18:07:05 +00:00
Alexei Stukov aefab7c677
Merge pull request #69 from JsSucks/plugins
Merge
2018-02-02 19:55:33 +02:00
Jiiks fe06db3d3c Functional plugin settings(almost) 2018-02-02 19:52:38 +02:00
Alexei Stukov b75c8892f7
Merge pull request #68 from samuelthomas2774/fix-tooltip-positioning
Fix tooltip positioning
2018-02-02 17:40:37 +02:00
Samuel Elliott 26de9a3197
Fix tooltip positioning
JsSucks/BetterDiscordApp#67
2018-02-02 15:14:12 +00:00
Jiiks eec595185c Unsaved changes alert footer 2018-02-02 16:40:17 +02:00
Jiiks 1647f8d8c2 Single bd-modal container 2018-02-02 16:10:53 +02:00
Jiiks a7a2e6b08b Correct settings body structure 2018-02-02 16:05:44 +02:00
Jiiks 27dac58dda add more test settings to test overflow 2018-02-02 16:02:13 +02:00
Alexei Stukov dbc40a9850
Merge pull request #66 from JsSucks/ui
Merge
2018-02-02 15:32:40 +02:00
Jiiks b6489cefaa add repo and site links #42 2018-02-02 15:23:02 +02:00
Alexei Stukov aec27f2493
Merge pull request #63 from JsSucks/eventhook
Merge
2018-02-02 15:00:50 +02:00
Jiiks c046f5f92f Extend below 2018-02-02 14:58:25 +02:00
Jiiks 48a086c29d Cleanup index 2018-02-02 14:56:23 +02:00
Jiiks cd87bd0e35 Revert for now 2018-02-02 14:55:57 +02:00
Jiiks 415d196954 Space 2018-02-02 14:49:05 +02:00
Jiiks fce24e6a6a Eventhook base, structures, add lodash 2018-02-02 14:45:06 +02:00
Alexei Stukov 1dae0a40b2
Merge pull request #62 from JsSucks/events
Merge
2018-02-01 05:06:51 +02:00
Jiiks 600eed9dbc Eventlistener module base 2018-02-01 05:00:28 +02:00
Jiiks c92a293d31 Module manager 2018-02-01 04:36:47 +02:00
Jiiks c078c7b686 https 2018-01-31 21:12:36 +02:00
Jiiks 2104770c9d Fix badge wrap 2018-01-31 21:10:33 +02:00
Jiiks c01f022ede Fix props passing for now 2018-01-31 18:25:41 +02:00
Alexei Stukov 0bb70aebde
Merge pull request #61 from JsSucks/ui
Merge
2018-01-31 17:51:43 +02:00
Jiiks a6bc800436 Change version number of full package to 2.0.0a 2018-01-31 17:48:41 +02:00
Jiiks eca427ce46 Cleanup 2018-01-31 17:47:47 +02:00
Jiiks 14de558305 Profilebadges. Implements #55 2018-01-31 17:45:25 +02:00
Jiiks 92634a2f98 BD Dev/Contributor badge 2018-01-31 16:10:35 +02:00
Alexei Stukov 60d9bf6ef6
Merge pull request #60 from JsSucks/dom
DOM Observer
2018-01-31 15:55:41 +02:00
Jiiks 6b800d94e3 For is faster 2018-01-31 15:46:57 +02:00
Jiiks 76730d38d4 add dom observer 2018-01-31 15:35:22 +02:00
Alexei Stukov 2c8508fe32
Merge pull request #59 from JsSucks/refactor
Missed refactor commits
2018-01-31 14:32:54 +02:00
Jiiks 7d09b38963 Logger imports 2018-01-31 14:17:40 +02:00
Alexei Stukov 363c7e9f7c
Merge pull request #58 from JsSucks/refactor
Client refactor
2018-01-31 13:52:56 +02:00
Jiiks 9f094a08cc Plugin settings modal 2018-01-31 13:35:38 +02:00
Jiiks 8621898558 Local refresh 2018-01-31 13:29:19 +02:00
Jiiks 235b373f1a Plugin Start/Stop switch 2018-01-31 10:32:20 +02:00
Jiiks e0df52b6ab Plugin reloading 2018-01-31 10:17:15 +02:00
Jiiks 1896a0d558 Content refresh 2018-01-31 00:21:06 +02:00
Jiiks a19570c205 PluginCard 2018-01-30 19:12:13 +02:00
Jiiks 5ad5eeff64 New util functions and pluginmanager 2018-01-30 17:59:27 +02:00
Jiiks 2a8c6189e4 WebpackModules 2018-01-30 15:48:25 +02:00
Jiiks 9d7bc8a058 Utils 2018-01-30 15:38:34 +02:00
Jiiks cb8b448da9 params 2018-01-30 15:27:39 +02:00
Jiiks ca8a421a9c Globals module 2018-01-30 15:25:35 +02:00
Jiiks 85db5af655 Module resolves and base pluginmanager 2018-01-30 15:20:24 +02:00
Jiiks 6385c15236 Css editor view 2018-01-30 13:20:42 +02:00
Jiiks 031e93185a Css editor and ipc module 2018-01-30 13:14:16 +02:00
Jiiks 9c14b44d22 add settings and consistency 2018-01-30 12:01:24 +02:00
Jiiks 30b4a8a55d Add components 2018-01-30 11:28:28 +02:00
Jiiks 5cdd9948e8 Consistency, add settings component, trigger ready 2018-01-29 20:15:58 +02:00
Jiiks ca5467addb add vue usings 2018-01-29 20:00:31 +02:00
Jiiks 5791368a75 add main ui module and id to dom 2018-01-29 19:56:48 +02:00
Jiiks 88ad25ecc7 add events module 2018-01-29 19:46:24 +02:00
Jiiks 4c5ff964e6 Refactor base, add DOM 2018-01-29 19:34:31 +02:00
Alexei Stukov 28c573e5c5
Merge pull request #52 from samuelthomas2774/check-plugin-directory
Make sure plugins are directories
2018-01-28 19:10:22 +02:00
Alexei Stukov c5083733be
Merge pull request #53 from samogot/lint
Add ESLint and some more stuff
2018-01-28 19:09:53 +02:00
Pierce 981de1b9e2
Merge pull request #54 from Pierce01/master
CSS Window opens when ready
2018-01-27 14:20:33 -05:00
Pierce bac4ce5323
CSS Window opens when ready 2018-01-27 13:57:44 -05:00
samogot 4ab90e780f Install eslint
Add basic eslint config, based on recommended options and disabling the most "shitty" warnings in current codebase
Dependencies list is sorted by npm
Npm asks me to commit new package-lock.json file
2018-01-27 17:03:15 +02:00
samogot e41b289eb5 Fix The "components" property should be above the "template" property [Error/vue/order-in-components] ESLint error
FYI: https://vuejs.org/v2/style-guide/#Component-instance-options-order-recommended
2018-01-27 16:58:48 +02:00
samogot 46d67ae88a Fix Unreachable code. [Error/no-unreachable] ESLint error 2018-01-27 16:58:48 +02:00
samogot 8e7c6b45b8 Fix 'reject' is not defined. [Error/no-undef] ESLint error
Fix Unnecessary semicolon. [Error/no-extra-semi] ESLint error
2018-01-27 16:58:37 +02:00
samogot 63c239f36f Extract global BetterDiscord.vendor into separate module, so it can be used through require 2018-01-27 16:40:35 +02:00
samogot d980a23dd3 Use --prefix instead of cd in npm scripts 2018-01-27 16:32:23 +02:00
Samuel Elliott a27d586d38
Check if plugin directory is a directory 2018-01-25 16:49:02 +00:00
Samuel Elliott d11cfbcdaa
Fix FileUtils promises 2018-01-25 16:47:13 +00:00
Alexei Stukov 65cf800283
Merge pull request #51 from JsSucks/ui
Merge
2018-01-25 15:29:34 +02:00
Jiiks 7bd1fc2eea add tooltips 2018-01-25 15:26:42 +02:00
Jiiks 366deb02fc Remove test timeout 2018-01-25 14:54:02 +02:00
Jiiks 271101ba0b Open plugin dir when edit is clicked 2018-01-25 14:53:37 +02:00
Jiiks e66c1ce447 Hide settings button if plugin doesn't have any settings 2018-01-25 14:50:07 +02:00
Jiiks 5faaaa0276 add todo 2018-01-25 14:47:26 +02:00
Jiiks a509495b9f Functional plugin reload 2018-01-25 14:46:53 +02:00
Alexei Stukov 4345abad15
Merge pull request #50 from JsSucks/ui
Merge
2018-01-25 13:46:55 +02:00
Jiiks 0a05c0d68a Styles 2018-01-25 13:11:36 +02:00
Jiiks 88a89bbe4f add a loading animation to button 2018-01-25 13:03:12 +02:00
Jiiks a3f9b50c8c Plugin settings modal 2018-01-25 12:48:41 +02:00
Alexei Stukov e548f75b68
Merge pull request #49 from JsSucks/ui
Merge
2018-01-25 11:26:08 +02:00
Jiiks 9a8f2eddef Textinput for plugin settings 2018-01-25 11:21:48 +02:00
Alexei Stukov 5157ad165d
Merge pull request #48 from JsSucks/ui
Merge
2018-01-25 11:09:43 +02:00
Jiiks 14a5331ecc Missing styles and base for text input 2018-01-25 11:01:20 +02:00
Alexei Stukov b7aab16185
Merge pull request #47 from JsSucks/ui
Merge
2018-01-25 09:56:47 +02:00
Alexei Stukov 25dac4d258
Merge branch 'master' into ui 2018-01-25 09:54:57 +02:00
Jiiks cb542acbd0 Remove any inline styles 2018-01-25 09:52:15 +02:00
Jiiks d934bc4aff Up to date with master 2018-01-25 09:50:28 +02:00
Alexei Stukov 7372cf778d
Merge pull request #45 from samuelthomas2774/tidy-scss
Tidied SCSS files
2018-01-25 08:31:40 +02:00
Jiiks 38783631c5 Modal plugin settings, use [] instead of {} for plugin configs 2018-01-25 07:13:40 +02:00
Samuel Elliott ecfc2ca7d6
Tidied SCSS files
Organised SCSS files for the client, moved all styles still in a Vue file to an SCSS file and moved styles for the CSS editor to their own files. JsSucks/BetterDiscordApp#41
2018-01-24 20:35:45 +00:00
Jiiks 17a8c2372b add some test settings for ui testing 2018-01-24 12:37:28 +02:00
Jiiks 87b07d0a0e Change how plugins are reloaded 2018-01-24 12:35:43 +02:00
Jiiks 1d9e6037d9 Hover styles for alt colours 2018-01-24 08:43:04 +02:00
Jiiks 71ac54911a Styling 2018-01-24 08:42:10 +02:00
Jiiks b3218d636a Styling, common components and add buttons to plugin card 2018-01-24 07:47:04 +02:00
Alexei Stukov 31041f75dd
Merge pull request #44 from JsSucks/casing
Corrected casing hopefully fixes #38 (Update: it does.)
2018-01-24 06:43:37 +02:00
Zack Rauen ff818d721d correct casing hopefully fixes #38 2018-01-23 19:05:03 -05:00
Jiiks 098ac8fb17 Make plugin switch actually do something 2018-01-23 18:19:45 +02:00
Jiiks 19b88b4be0 Fix plugin start/stop 2018-01-23 15:19:55 +02:00
Jiiks e9b15a33b1 add a version thing and fix css editor import 2018-01-23 13:58:04 +02:00
Jiiks a5cad6731c Restructure components 2018-01-23 13:34:15 +02:00
Jiiks 17d7e83590 Remove old componets 2018-01-23 13:30:43 +02:00
Jiiks 4fc630cf0a Static disabled bg 2018-01-23 09:25:21 +02:00
Jiiks c195786ffc add some generics and styling + new spinners 2018-01-23 09:23:15 +02:00
Alexei Stukov c44131e0dd
Merge pull request #37 from JsSucks/ui
Merge so far changes to master
2018-01-22 22:48:37 +02:00
Jiiks b908b2e42e backface-visibility bugs 2018-01-22 22:43:46 +02:00
Jiiks 7476d4d499 Make switches functional 2018-01-22 22:25:55 +02:00
Jiiks 23cde9cb9f Use setting.checked and setting.enabled 2018-01-22 22:11:43 +02:00
Jiiks 4ad2cc52dd Pass setting back to parent on click 2018-01-22 22:10:18 +02:00
Jiiks e11787c585 add some test settings 2018-01-22 22:08:08 +02:00
Jiiks 38776569ed Remove click listener if disabled 2018-01-22 22:07:19 +02:00
Jiiks b90fda127d Typo and disable disabled settings 2018-01-22 22:03:39 +02:00
Jiiks fc49277e1d Disabled class for switch 2018-01-22 22:01:58 +02:00
Jiiks db874b6218 add disabled styling for switch 2018-01-22 22:00:12 +02:00
Jiiks 90b9efe5ba Switch style fixes and settings render 2018-01-22 20:51:57 +02:00
Jiiks 13343283d5 add initial settings 2018-01-22 20:26:19 +02:00
Jiiks e8d4517606 add functional setting switch 2018-01-22 19:29:53 +02:00
Jiiks 79827b946d Styles 2018-01-22 19:08:38 +02:00
Jiiks 48fabda81f Styles 2018-01-22 19:06:33 +02:00
Jiiks 6cf4322127 Don't toggle dev tools 2018-01-22 19:01:19 +02:00
Jiiks 2cc0e6c1aa Css editor panel 2018-01-22 19:00:51 +02:00
Jiiks a666a52f72 add material icons. Maybe just use the font instead? Maybe 2018-01-22 15:07:30 +02:00
Jiiks 47371b3a19 ui up to date with master 2018-01-22 14:35:13 +02:00
Alexei Stukov 9cdf200ae7
Merge pull request #36 from JsSucks/css-editor
Merge new css editor package
2018-01-22 13:31:31 +02:00
Jiiks e714a9267f Fix import 2018-01-22 13:29:10 +02:00
Jiiks 8cf6d6f2e0 add csseditor build to root 2018-01-22 13:23:50 +02:00
Jiiks 2618876e62 css saving 2018-01-22 13:22:39 +02:00
Jiiks dd9ec12b36 Implement all functionality that master has 2018-01-22 13:10:09 +02:00
Jiiks 725c95d6d3 Start converting csseditor to another module 2018-01-22 12:16:23 +02:00
Alexei Stukov 43fb6eb2c9
Merge pull request #34 from samuelthomas2774/css-editor
CSS editor tweaks
Fixes #14
2018-01-22 08:43:36 +02:00
Samuel Elliott 10ea33f270 Fixed bug where CSS editor cannot be opened twice without restarting
Uncaught exception:
 Error: Object has been destroyed
    at CSSEditor.openEditor (/Users/Samuel/Documents/BetterDiscord/2018-01-19/betterdiscordapp/core/dist/modules/csseditor.js:21:40)
2018-01-22 00:20:15 +00:00
Samuel Elliott 731d18e4da CSS editor tweaks and fixes
- Load CodeMirror locally
- CSS tweaks - editor window look more native now
- Fixed bug where the live update checkbox can’t be unchecked
2018-01-22 00:02:19 +00:00
Jiiks 5d07d9b429 Set node ver 2018-01-21 15:50:00 +02:00
Jiiks 11e42a4ce9 Move deps to root 2018-01-21 15:41:56 +02:00
Jiiks 111bc2da2f This is a test 2018-01-21 15:30:01 +02:00
Jiiks d88556ccba Restructure 2018-01-21 15:26:57 +02:00
Jiiks 2abbe56498 Readme 2018-01-21 15:21:48 +02:00
Alexei Stukov 8a7320baab
Merge pull request #33 from JsSucks/webpack
Remove async from WebpackModules, update filters and known modules
2018-01-21 15:17:08 +02:00
Jiiks a323531dfc Travis 2018-01-21 15:12:48 +02:00
Zack Rauen 645bf81160 Hopefully fixes #11 with other changes 2018-01-21 07:52:02 -05:00
Zack Rauen 316f30196c Merge remote-tracking branch 'refs/remotes/origin/master' into webpack 2018-01-21 07:29:14 -05:00
Jiiks a288d2473f add temp spinner for online plugins 2018-01-21 12:24:43 +02:00
Jiiks 87fcff3ffb add spinners by Beard <3 https://codepen.io/Beard-Design/pen/zpeWjV 2018-01-21 12:19:25 +02:00
Jiiks 0fbe5f8ce7 PluginView and PluginCard styling 2018-01-21 12:15:19 +02:00
Alexei Stukov cb091b594d
Merge pull request #32 from JsSucks/css-editor
Merge
2018-01-21 11:28:27 +02:00
Jiiks 6f9f005ed9 added a missing return if editor is already open. 2018-01-21 11:27:44 +02:00
Alexei Stukov 7add5afc30
Merge pull request #31 from JsSucks/ui
Merge
2018-01-21 11:25:23 +02:00
Jiiks 3500b2890b CssEditor button functionality 2018-01-21 11:24:28 +02:00
Alexei Stukov d57b394768
Merge pull request #30 from JsSucks/csseditor
Merge current css editor
2018-01-21 11:18:29 +02:00
Jiiks e1e3e77e08 Resolve conflicts 2018-01-21 11:16:50 +02:00
Jiiks 6816a2938a Conflict resolve 2018-01-21 11:12:29 +02:00
Jiiks 0e70eea85c Merge master into csseditor 2018-01-21 11:11:46 +02:00
Jiiks 1f618684b8 Added gulp plumber, gulp watch, parent package with scripts and windows batch files for everything. 2018-01-21 10:38:49 +02:00
Alexei Stukov d1988f915f
Merge pull request #29 from samfun123/csseditor
Implement the main features of the CSS Editor
2018-01-21 10:14:46 +02:00
Alexei Stukov 623aaeb01a
Merge pull request #28 from JsSucks/webpack
WebpackModules rewrite + remove external moment.js dependency
2018-01-21 10:12:39 +02:00
samfun123 5251d42c2f Implement the main features of the CSS Editor 2018-01-20 22:48:48 -05:00
Zack Rauen 7b578dcc56 rewrite webpack with known modules 2018-01-20 20:10:24 -05:00
Zack Rauen 0cd70e5da3 Merge remote-tracking branch 'refs/remotes/origin/master' into webpack 2018-01-20 19:47:04 -05:00
Alexei Stukov 906bda3489
Merge pull request #27 from JsSucks/plugin-manager
Merge
2018-01-21 02:46:34 +02:00
Zack Rauen 10b843d53e Merge remote-tracking branch 'refs/remotes/BDBeta/master' into webpack 2018-01-20 19:34:37 -05:00
Jiiks 4362d39624 add some more trycatch for external code calls 2018-01-21 01:46:49 +02:00
Jiiks 6640fa1890 Cleanup manually deleted plugin 2018-01-21 01:43:17 +02:00
Jiiks fe29c78583 Refresh instead of reload and remove debug 2018-01-21 01:38:57 +02:00
Pierce de5fd43b84
Merge pull request #25 from samuelthomas2774/master
Fixed bug introduced in #24
2018-01-20 17:48:39 -05:00
Samuel Elliott 7d1416da67 Fixed bug with pressing B
JsSucks/BetterDiscordApp#22
2018-01-20 22:42:22 +00:00
Alexei Stukov 5aed82573f
Merge pull request #1 from JsSucks/master
Merge
2018-01-21 00:17:44 +02:00
Jiiks 8b9d923ae2 Temp refresh button 2018-01-20 21:07:04 +02:00
Jiiks 9f0eb844c2 Display local plugins in tab 2018-01-20 20:30:05 +02:00
Jiiks 1a9fbef1f5 Logger object handler and start using Logger in plugin manager 2018-01-20 20:16:01 +02:00
Jiiks 5c3e7e780e add log shortcuts and error object logger 2018-01-20 20:01:36 +02:00
Jiiks 497e989e76 add another dummy plugin for testing 2018-01-20 19:48:27 +02:00
Jiiks b3f5f46e74 add try catch to plugin loading 2018-01-20 19:47:00 +02:00
Jiiks 2bcde666d8 Preliminary method for loading all plugins in plugins directory 2018-01-20 19:46:04 +02:00
Jiiks 48e1fda6cf add readDir method for getting files in a directory 2018-01-20 19:41:20 +02:00
Alexei Stukov 1f46323dc9
Merge pull request #24 from samuelthomas2774/master
Add keyboard shortcut
2018-01-20 19:35:01 +02:00
Alexei Stukov abda678167
Update BdSettingsWrapper.vue
No need to check for platform and return instead of if else. We can also hide settings with Ctrl/Cmd+b
2018-01-20 19:33:53 +02:00
Samuel Elliott f21aec5226 Add keyboard shortcut
Also fixes bug where pressing escape with another dialog open closes both at once
2018-01-20 16:17:51 +00:00
Alexei Stukov f9cd4e1a8a
Merge pull request #23 from JsSucks/ui
Merge ui changes
2018-01-20 17:59:38 +02:00
Jiiks da20f417c3 More style fixes 2018-01-20 17:55:51 +02:00
Jiiks e19f2ad8d7 Style fixes and pluginview/plugincard bases 2018-01-20 17:31:17 +02:00
Jiiks 357706f4c5 Styling fixes 2018-01-20 17:05:09 +02:00
Jiiks 49bdd4b1fd Style changes and class prefix 2018-01-20 16:20:18 +02:00
Jiiks 461d3468a5 Reset state on close 2018-01-20 16:04:22 +02:00
Jiiks 4575c3428a Add missing styles and props 2018-01-20 16:02:12 +02:00
Jiiks 2d128eb0a4 Restructuring and added some components 2018-01-20 15:45:53 +02:00
Jiiks ac1b5ef38d Static dark scrollbars for SidebarView 2018-01-20 15:31:45 +02:00
Jiiks 5419484825 Close settings with escape key 2018-01-20 15:07:35 +02:00
Jiiks ff1510dbcc Style changes and scrollerwrap props 2018-01-20 14:51:30 +02:00
Jiiks 9492bb0bc2 Style restructuring 2018-01-20 14:19:54 +02:00
Jiiks b42f17437c Cleanup and template splitting 2018-01-20 12:52:00 +02:00
Alexei Stukov 992aa63cd8
Merge pull request #22 from samuelthomas2774/master
Add editor config and macOS tweaks
2018-01-20 03:00:12 +02:00
Samuel Elliott 4076da01c9 Add macOS tweaks 2018-01-20 00:35:27 +00:00
Samuel Elliott 708b4e5e63 Add editor config 2018-01-20 00:34:41 +00:00
Alexei Stukov 8b9ccf0e0d
Merge pull request #21 from JsSucks/ui
Merge
2018-01-20 01:08:27 +02:00
Alexei Stukov 146f64aa04
Merge branch 'master' into ui 2018-01-20 01:08:20 +02:00
Jiiks 389738c278 Unread messages override 2018-01-20 01:07:09 +02:00
Jiiks 5fe1bfed8f https://github.com/JsSucks/BetterDiscordApp/pull/20 2018-01-20 01:05:32 +02:00
Alexei Stukov f002440899
Merge pull request #20 from Pierce01/master
makes BD button look "naturally built in"
2018-01-20 00:53:36 +02:00
Pierce 722af5cec6
makes BD button look "naturally built in" 2018-01-19 17:42:17 -05:00
Jiiks a375f9ed6e Discord overrides 2018-01-19 11:28:30 +02:00
Jiiks ddaa663067 Updated styles and components 2018-01-19 11:26:36 +02:00
Alexei Stukov fb0326d371
Merge pull request #19 from JsSucks/ui
Loaders and components
2018-01-19 07:18:16 +02:00
Jiiks 4e1b5cfc89 Components and loaders. 2018-01-19 07:17:07 +02:00
Alexei Stukov e9c97b89ab
Merge pull request #18 from JsSucks/ui
Ui components
2018-01-19 05:37:51 +02:00
Jiiks a544a42436 Add settingspanel base and update button 2018-01-19 05:36:38 +02:00
Alexei Stukov eac7f62911
Merge pull request #17 from JsSucks/ui
Merge
2018-01-19 04:21:01 +02:00
Jiiks ec50f750aa Bye most of react 2018-01-19 04:19:09 +02:00
Jiiks 2f1a268cc5 Preliminary settings button to test vue render 2018-01-19 04:15:47 +02:00
Jiiks e826079fc1 Added vue and loaders 2018-01-19 04:10:10 +02:00
Jiiks 0f762c1e58 ignore everything in ui 2018-01-19 03:37:21 +02:00
Jiiks 6b0423ebb0 Close button handler 2018-01-17 16:39:39 +02:00
Jiiks b7e0de3e41 Rewriting css editor 2018-01-17 15:46:27 +02:00
Jiiks ef7009f5a1 Base for CSS Editor 2018-01-17 13:28:52 +02:00
Alexei Stukov 9fc2eb559a
Merge pull request #16 from JsSucks/plugin-manager
Merge
2018-01-17 12:55:01 +02:00
Jiiks 509f44bcb1 add some plugin getters 2018-01-17 10:17:01 +02:00
Jiiks 289533b755 Add dirName check and remove debug 2018-01-17 10:10:29 +02:00
Jiiks e3367768eb Plugin reloading 2018-01-17 10:06:40 +02:00
Jiiks 3ee59845de Plugin name as param for tests 2018-01-17 09:42:40 +02:00
Jiiks 7c12617448 Correct Object.assign 2018-01-17 09:41:31 +02:00
Alexei Stukov b4be857f70
Merge pull request #15 from JsSucks/utils
FileUtils writes
2018-01-17 09:36:33 +02:00
Jiiks 626a83c8a7 add writes 2018-01-17 09:35:36 +02:00
Jiiks 006b7bed7a Add watch script 2018-01-16 09:05:33 +02:00
Jiiks 20abc525d3 add watch scripts 2018-01-16 09:04:59 +02:00
Alexei Stukov 902119fbae
Merge pull request #8 from JsSucks/master
Match with master
2018-01-16 08:46:29 +02:00
Jiiks 2a8ebbe80c Correct dist ignore 2018-01-16 08:41:22 +02:00
Jiiks 0faad8d654 Ignore dist 2018-01-16 08:40:30 +02:00
Alexei Stukov 602258b6d8
Merge pull request #6 from JsSucks/plugin-manager
Plugin manager
2018-01-16 08:33:57 +02:00
Jiiks 9c488f996f Typo 2018-01-16 08:03:02 +02:00
Jiiks 48dbbb1ea3 Load configs into plugin instance 2018-01-16 08:01:22 +02:00
Jiiks a9b253ebad Push tests to window object 2018-01-16 07:18:43 +02:00
Jiiks 98d58b1303 Read paths from Global 2018-01-16 07:13:36 +02:00
Alexei Stukov 7fd368f936
Merge pull request #5 from JsSucks/master
Global changes to plugin-manager
2018-01-16 07:05:03 +02:00
Alexei Stukov 4d44ba673b
Merge branch 'plugin-manager' into master 2018-01-16 07:04:51 +02:00
Alexei Stukov 02df356931
Merge pull request #4 from JsSucks/global
Global
2018-01-16 07:02:01 +02:00
Jiiks 80170a5bbd Restructure args 2018-01-16 07:00:39 +02:00
Jiiks 2aa9b46c10 Load config into globals 2018-01-16 06:59:59 +02:00
Jiiks 39fbae166f Load plugins by directory name not full path 2018-01-16 06:38:28 +02:00
Jiiks a1261cab0a Use Utils 2018-01-16 03:55:14 +02:00
Alexei Stukov f160cb9c8b
Merge pull request #3 from JsSucks/master
Up to date Utils to plugin-manager
2018-01-16 03:53:49 +02:00
Jiiks 7aa7d9df10 Requires 2018-01-16 03:52:39 +02:00
Alexei Stukov 48d6098285
Merge pull request #2 from JsSucks/utils
FileUtils
2018-01-16 03:50:51 +02:00
Jiiks 2e26f472ea FileUtils 2018-01-16 03:49:26 +02:00
Jiiks 50f0d4f91f Plugin loading and tests 2018-01-16 03:45:23 +02:00
Jiiks bc05138037 Tests base 2018-01-15 14:17:13 +02:00
Jiiks e823b1c9d0 Test vs branch manager 2018-01-15 14:01:43 +02:00
Jiiks cc55db87b7 Final nobranch 2018-01-15 13:59:45 +02:00
Jiiks 1040650ae4 addEventListener instead 2018-01-15 08:01:34 +02:00
Jiiks 8c2692caba Socket proxy base 2018-01-15 07:09:28 +02:00
Jiiks 403ffc839d Utils overload 2018-01-15 06:53:08 +02:00
Jiiks c801b09e9c erlpack require 2018-01-15 06:43:28 +02:00
Jiiks 861d95bd06 Socket base, event bindings, initial socket emit 2018-01-15 06:40:24 +02:00
Jiiks 6b96b191aa Emit socket-created event 2018-01-15 06:30:15 +02:00
Jiiks c851d2e92c Eventemitter 2018-01-15 06:29:06 +02:00
Jiiks 9ecb14ab23 Use base state 2018-01-15 05:29:11 +02:00
Jiiks 8e5f007f5b Remove test 2018-01-14 08:00:58 +02:00
Jiiks ba4ba87eec Send navigate events to client module 2018-01-14 08:00:21 +02:00
Jiiks e1932b7f74 Global is a module 2018-01-12 21:46:55 +02:00
Jiiks 7be0ab71fc wat 2018-01-12 08:41:47 +02:00
Jiiks b57255487a Sparkplug fixes 2018-01-12 08:31:02 +02:00
Jiiks 8e308f2a65 Igniter 2018-01-12 03:06:43 +02:00
Jiiks 662329c5e9 Webpackmodules 2018-01-11 17:22:49 +02:00
Jiiks 03505fcdb6 Client ipc 2018-01-11 16:12:24 +02:00
Jiiks 8863c20661 Forward slashes 2018-01-11 14:49:19 +02:00
Jiiks b75177dadd Resolve client script path instead of hardcoding 2018-01-11 14:40:31 +02:00
Jiiks 71f785cdd1 Remove debugs 2018-01-11 14:38:25 +02:00
Jiiks 38c61484c1 Paths for plugins and themes 2018-01-11 14:37:52 +02:00
Jiiks 5ec53510be Pluginmanager stuff 2018-01-11 08:24:29 +02:00
Jiiks 881b33f4b6 Exports 2018-01-11 08:03:06 +02:00
Jiiks 4cd0f4fb9b Typo 2018-01-11 08:02:11 +02:00
Jiiks 32e563effc Bases 2018-01-11 03:03:32 +02:00
Jiiks 69e10f69cd add vendor scripts 2018-01-11 01:46:05 +02:00
Jiiks f6047265e3 Logger styling 2018-01-11 01:13:45 +02:00
Jiiks c8ebe4bfad Inject failsafe 2018-01-11 01:07:35 +02:00
Jiiks e72fb0d525 Handle reloading through simple inject 2018-01-11 00:41:57 +02:00
Jiiks 149a4e0dec WindowUtils and script inject 2018-01-11 00:15:31 +02:00
Jiiks 3ab286f81e Move tests 2018-01-10 22:52:49 +02:00
Jiiks 78952f190c Client base and restrucutre 2018-01-10 22:48:10 +02:00
Jiiks 273a4ae50b Test 2018-01-10 22:27:47 +02:00
Jiiks ba0ba4b2ce Base module 2018-01-10 22:25:27 +02:00
Jiiks a6d2e200f6 LICENSE 2018-01-10 21:23:01 +02:00
Jiiks 660729eaf7 Licenses 2018-01-10 21:19:34 +02:00
Jiiks 8d9ba8fed9 Base 2018-01-10 18:02:29 +02:00
Jiiks ea8ac32a1c Fresh 2018-01-10 17:58:57 +02:00
Jiiks e9e3627339 Delete obj 2018-01-10 17:54:00 +02:00
Jiiks 8688a9ea7d Don't crash if stable doesn't exist 2018-01-10 17:50:26 +02:00
Jiiks 2a29984950 Ignore .suo 2018-01-10 17:32:48 +02:00
Jiiks cf1a9ecb91 Restructure 2018-01-10 17:29:29 +02:00
Jiiks 4114a6ee26 New installer 2018-01-10 17:17:15 +02:00
Alexei Stukov 55a6fb8697
remin 2018-01-10 16:50:32 +02:00
Alexei Stukov 5344fd2b1e
Merge pull request #664 from rauenzi/patch1
patch react, react-dom and layer changes
2018-01-10 16:49:18 +02:00
Zack Rauen 7322ea8ba9 patch react, react-dom and layer changes 2018-01-09 21:13:44 -05:00
pohky 4a377d9648
Update emotefilter.json 2017-11-01 09:33:14 +01:00
Jiiks 1a6648ebf0 Emote parser bug fix 2017-10-16 21:38:44 +03:00
Jiiks 9ab77a8217 Support for twitchemotes v3 api 2017-09-30 05:07:53 +03:00
pohky 1d07436569 Merge pull request #536 from SomeGuyNamedDavid/patch-1
Update emotefilter.json
2017-07-26 03:23:42 +02:00
pohky f91dff5c1b Update emotefilter.json 2017-07-26 03:22:06 +02:00
David a160359413 Update emotefilter.json 2017-07-25 02:04:53 -04:00
pohky ebe69a5369 Merge pull request #537 from DeathStrikeV/master
Updated FFZ emotes =)
2017-07-24 05:28:08 +02:00
DeathStrikeV 0831320b61 Updated FFZ emotes =3 2017-07-24 03:56:39 +01:00
David 4df677c28d Update emotefilter.json 2017-07-22 22:17:33 -04:00
David aee8aa7483 Update emotefilter.json 2017-07-22 21:09:25 -04:00
Alexei Stukov 1cc631b29d 626d414 2017-07-22 13:31:47 +03:00
Alexei Stukov 626d41480c Hide changelog for now, fix things that use ta 2017-07-22 13:28:23 +03:00
pohky caaa0aba8b Merge pull request #484 from SomeGuyNamedDavid/master
Alphabetize EmoteFilter (and add a whole lot of items)
2017-07-21 10:13:34 +02:00
pohky daec28f2b0 Update emotefilter.json
added missing commas
2017-07-21 10:12:40 +02:00
pohky 6d1baa0639 Merge pull request #531 from DeathStrikeV/master
Updated FFZ emotes =)
2017-07-21 09:55:09 +02:00
DeathStrikeV 31e94d72f7 Updated FFZ emotes =3 2017-07-21 03:59:40 +01:00
David 055b3b9a25 Update emotefilter.json 2017-07-19 01:35:49 -04:00
DeathStrikeV c0fd7e41cc Updated FFZ emotes =3 2017-07-17 03:55:29 +01:00
David 187b39dac1 Update emotefilter.json 2017-07-16 12:09:58 -04:00
DeathStrikeV 10f686a71f Updated FFZ emotes =3 2017-07-15 08:55:27 +01:00
DeathStrikeV eabad3bced Updated FFZ emotes =3 2017-07-14 03:55:54 +01:00
David 6daeeaf866 Update emotefilter.json 2017-07-13 15:23:05 -04:00
David 255caea48e Update emotefilter.json 2017-07-13 14:50:13 -04:00
pohky a46fb246ed Merge pull request #518 from DeathStrikeV/master
Updated FFZ emotes =)
2017-07-13 16:44:41 +02:00
David 054efe9e75 Update emotefilter.json 2017-07-12 19:39:43 -04:00
DeathStrikeV 07f5c3b6d5 Updated FFZ emotes =3 2017-07-10 03:54:32 +01:00
David 895f987ca9 Update emotefilter.json 2017-07-08 23:06:53 -04:00
David cefa91aa13 Update emotefilter.json 2017-07-07 01:15:19 -04:00
DeathStrikeV 0271df21c9 Updated FFZ emotes =3 2017-07-07 03:55:56 +01:00
David a6b89cf205 Update emotefilter.json 2017-07-06 22:24:47 -04:00
David a74e425a8e Update emotefilter.json 2017-07-05 17:56:26 -04:00
David 191bfaca02 Update emotefilter.json 2017-07-05 17:55:34 -04:00
David de1a63f7bd Update emotefilter.json 2017-07-04 12:22:57 -04:00
David 39e7982c64 Update emotefilter.json 2017-07-03 19:05:18 -04:00
David ccbebd6855 Update emotefilter.json 2017-07-03 17:02:39 -04:00
David 192184e4d1 Update emotefilter.json 2017-07-03 14:49:48 -04:00
DeathStrikeV 94622aa854 Updated FFZ emotes =3 2017-07-03 03:53:23 +01:00
David 051edcf619 Update emotefilter.json 2017-07-02 13:40:39 -04:00
David 3c1c8f27a4 Update emotefilter.json 2017-07-01 23:54:11 -04:00
David 11ca29c2fb Update emotefilter.json 2017-07-01 22:16:43 -04:00
David 4eb5c183a5 Update emotefilter.json 2017-07-01 19:25:43 -04:00
David bf041b54ef Update emotefilter.json 2017-06-30 14:38:04 -04:00
DeathStrikeV 3c53865150 Updated FFZ emotes =3 2017-06-30 03:55:54 +01:00
David db66110556 Update emotefilter.json 2017-06-29 20:51:31 -04:00
DeathStrikeV d1371a5383 Updated FFZ emotes =3 2017-06-28 00:17:57 +01:00
David c5e0886690 Update emotefilter.json 2017-06-26 02:04:28 -04:00
DeathStrikeV 6d77162321 Updated FFZ emotes =3 2017-06-26 03:53:18 +01:00
David 5ebeb06520 Update emotefilter.json 2017-06-25 13:04:29 -04:00
David 35dadec203 Update emotefilter.json 2017-06-24 21:36:22 -04:00
Alexei Stukov 9f1314e75c Merge pull request #509 from DeathStrikeV/master
Updated FFZ emotes =)
2017-06-24 01:55:14 +03:00
David a21cb93d3b Update emotefilter.json 2017-06-23 16:21:41 -04:00
DeathStrikeV 6cf7f8583d Updated FFZ emotes =3 2017-06-23 03:53:03 +01:00
DeathStrikeV 3787744a71 Updated FFZ emotes =3 2017-06-22 03:56:17 +01:00
David 358c8e288d Update emotefilter.json 2017-06-21 18:40:33 -04:00
DeathStrikeV e5a8224c49 Updated FFZ emotes =3 2017-06-21 03:54:25 +01:00
DeathStrikeV d34db2cbc2 Updated FFZ emotes =3 2017-06-20 04:20:36 +01:00
David c5abd4703a Update emotefilter.json 2017-06-19 01:05:51 -04:00
David b63b4a31f3 Update emotefilter.json 2017-06-19 01:01:34 -04:00
DeathStrikeV 8f0c9b5158 Updated FFZ emotes =3 2017-06-19 03:54:52 +01:00
DeathStrikeV 715480c429 Updated FFZ emotes =3 2017-06-18 21:02:09 +01:00
BlazingSky 12444400a0 Merge pull request #16 from Jiiks/master
Update to latest
2017-06-18 18:42:31 +01:00
BlazingSky 9d7e1bae32 Update to latest (#15)
* Settings panel injection fix

* css fixes

* 1.792

* 1.792

* Fix scrolling and tools

* Fix scrolling and tools
2017-06-18 18:39:57 +01:00
DeathStrikeV 3fb10a820a Updated FFZ emotes =3 2017-06-18 13:31:59 +01:00
Alexei Stukov 565ff12946 Fix scrolling and tools 2017-06-18 08:04:03 +03:00
Alexei Stukov da082999cb Fix scrolling and tools 2017-06-18 08:03:34 +03:00
Alexei Stukov 4fc5abe092 1.792 2017-06-18 03:38:14 +03:00
Alexei Stukov ecc8b3baa1 1.792 2017-06-18 03:38:12 +03:00
Alexei Stukov 319fd6b12b css fixes 2017-06-18 03:36:24 +03:00
David cf6a9ca3b7 Update emotefilter.json 2017-06-17 20:02:50 -04:00
Alexei Stukov df8b319275 Settings panel injection fix 2017-06-17 20:08:43 +03:00
David 19b37a9feb Update emotefilter.json 2017-06-16 20:57:54 -04:00
David 633e2fb986 Update emotefilter.json 2017-06-15 20:53:03 -04:00
David b24b1b7cda Create emotefilter.json 2017-06-15 20:03:16 -04:00
David ab58d87acd Create emotefilter.json 2017-06-15 16:52:37 -04:00
Alexei Stukov db7f9911c9 Merge pull request #487 from DeathStrikeV/master
Updated FFZ emotes =)
2017-06-14 15:51:56 +03:00
DeathStrikeV 21cc2c8beb Updated FFZ emotes =3 2017-06-14 01:17:37 +01:00
DeathStrikeV b805ec8b2c Updated FFZ emotes =3 2017-06-10 00:34:34 +01:00
DeathStrikeV c8f21ae02e Updated FFZ emotes =3 2017-06-07 02:37:30 +01:00
David 154d916a9e Update emotefilter.json 2017-06-06 01:54:30 -04:00
DeathStrikeV e4681e2a23 Updated FFZ emotes =3 2017-06-05 07:49:35 +01:00
David e5aeea60e9 Update emotefilter.json 2017-06-04 01:37:21 -04:00
David 37c3f12178 Update emotefilter.json 2017-06-02 01:17:57 -04:00
David 72e9d2f455 Update emotefilter.json 2017-06-01 13:41:08 -04:00
David e3c8befb25 Update emotefilter.json 2017-05-29 23:08:46 -04:00
DeathStrikeV 8e9b59521a Updated FFZ emotes =3 2017-05-29 10:57:40 +01:00
DeathStrikeV 1c882bc52d Updated FFZ emotes =3 2017-05-29 10:43:11 +01:00
David a33a2b205d Update emotefilter.json 2017-05-29 03:07:20 -04:00
David 0c014877ea Update emotefilter.json 2017-05-24 23:03:32 -04:00
pohky d5522e547c Merge pull request #486 from DeathStrikeV/master
Updated FFZ emotes =3
2017-05-23 09:46:19 +02:00
DeathStrikeV 1e997efa28 Updated FFZ emotes =3 2017-05-23 08:30:45 +01:00
David 01eb06ab23 Update emotefilter.json 2017-05-22 18:29:21 -04:00
David 42ee775176 Update emotefilter.json 2017-05-21 15:00:56 -04:00
David 187966d4b0 Update emotefilter.json 2017-05-20 17:34:24 -04:00
DeathStrikeV 50edc74c55 Updated FFZ emotes =3 2017-05-20 10:51:09 +01:00
BlazingSky 29d8bba9a9 Merge pull request #14 from Jiiks/master
Pull latest changes in
2017-05-20 08:11:33 +01:00
David 2382b1e130 Update emotefilter.json 2017-05-18 20:15:50 -04:00
David e67e4ee7b9 Update emotefilter.json 2017-05-16 21:06:52 -04:00
David 1bf65e5706 Update emotefilter.json 2017-05-16 21:01:26 -04:00
Alexei Stukov 4dfc413227 Fix open folder button position 2017-05-13 13:26:23 +03:00
Alexei Stukov 7a9ac5b035 Fix open folder button position 2017-05-13 13:26:20 +03:00
pohky 678a756dd6 Merge pull request #479 from Zerthox/patch-2
Add "You!" to emotefilter
2017-05-13 06:37:24 +02:00
Alexei Stukov 1e8f45e825 Restore open folder buttons 2017-05-12 22:45:29 +03:00
Alexei Stukov 85f79d5259 Restore open folder buttons 2017-05-12 22:45:25 +03:00
Alexei Stukov 5f83b20f6b Restore open folder buttons 2017-05-12 22:45:22 +03:00
Alexei Stukov c9b6a11941 Restore open folder buttons 2017-05-12 22:45:19 +03:00
Zerthox 4a33c39e8b Add "You!" 2017-05-12 21:16:36 +02:00
Alexei Stukov 05d379ba79 Merge pull request #477 from DeathStrikeV/master
Updated FFZ emotes + Added some new words to emotefilter.json
2017-05-12 18:33:30 +03:00
DeathStrikeV 8aa4a7c700 Updated FFZ emotes =3 2017-05-11 01:18:15 +01:00
BlazingSky 04c0df30e7 Merge pull request #13 from Jiiks/master
Merging changes from master
2017-05-11 00:08:30 +01:00
Alexei Stukov 0ea7990226 added Hai! 2017-05-08 16:02:04 +03:00
Alexei Stukov a96a0384b2 https://github.com/Jiiks/BetterDiscordApp/pull/441/files 2017-05-08 07:37:44 +03:00
Alexei Stukov bf6f826c9d https://github.com/Jiiks/BetterDiscordApp/pull/441 2017-05-08 07:36:59 +03:00
Alexei Stukov 81bd8938fe Merge pull request #439 from noodlebox/osx-electron-fix
Fix Electron installer for OSX
2017-05-08 07:34:24 +03:00
Alexei Stukov 0255164f42 Merge pull request #430 from AlcaDesign/patch-1
Reduce cases in Node installer
2017-05-08 07:34:07 +03:00
Alexei Stukov 4a7422039e Merge pull request #385 from noodlebox/rewrite-autogif
Fix AutoPlayGifs plugin
2017-05-08 07:32:03 +03:00
Alexei Stukov 8dfd0f2a73 Merge pull request #361 from yozora-mikazuki/master
Version-agnostic uninstaller for Windows
2017-05-08 07:30:40 +03:00
Alexei Stukov 5abe7c4a9e Merge pull request #464 from SomeGuyNamedDavid/patch-1
Update emotefilter.json
2017-05-08 07:26:25 +03:00
Alexei Stukov 1c75af3513 Merge branch 'master' into patch-1 2017-05-08 07:26:00 +03:00
Alexei Stukov 214c77be13 Merge pull request #456 from Violetnred2/patch-2
Update emotefilter.json
2017-05-08 07:23:59 +03:00
Alexei Stukov 7c62116554 License 2017-05-07 19:44:59 +03:00
Alexei Stukov 4cb39d90c0 close issues
Closes #111 Closes #153 Closes #215 Closes #238 Closes #275 Closes #280 Closes #281 Closes #286 Closes #289 Closes #291 Closes #294 Closes #302 Closes #304  Closes #308  Closes #315  Closes #317  Closes #320  Closes #321 Closes #322 Closes #323 Closes #324  Closes #325  Closes #327  Closes #331  Closes #332  Closes #333  Closes #334  Closes #337  Closes #337 Closes #340 Closes #341 Closes #345 Closes #346 Closes #347 Closes #348 Closes #351 Closes #354 Closes #359 Closes #360 Closes #364 Closes #367 Closes #368 Closes #370 Closes #371 Closes #372 Closes #373 Closes #374 Closes #375 Closes #376 Closes #377 Closes #378 Closes #379 Closes #380 Closes #382 Closes #383 Closes #386 Closes #387 Closes #388 Closes #390 Closes #393 Closes #394 Closes #395 Closes #396 Closes #397 Closes #398 Closes #402
2017-05-05 09:02:04 +03:00
Alexei Stukov db34f5c6b0 Test
Closes #469 Closes #468
2017-05-05 08:56:35 +03:00
Alexei Stukov 8bfd9cdaa5 Fixed name overflow and plugin settings close button. 2017-05-05 04:24:22 +03:00
Alexei Stukov e7aeb7d1af Fixed name overflow and plugin settings close button. 2017-05-05 04:24:20 +03:00
Alexei Stukov 327c08fd93 Localization fix and layer identifiers 2017-05-04 18:47:16 +03:00
Alexei Stukov b933703f4f Localization fix and layer identifiers 2017-05-04 18:47:15 +03:00
pohky a5089721db Merge pull request #467 from DeathStrikeV/master
Updated FFZ emotes =3
2017-05-03 13:30:06 +02:00
DeathStrikeV 5a51afd01e Updated FFZ emotes =3 2017-05-02 20:15:17 +01:00
Alexei Stukov fc7a85a79c minify 2017-05-02 18:15:35 +03:00
Alexei Stukov 707afde649 Fix setting saving 2017-05-02 18:15:02 +03:00
Alexei Stukov a85d8e19d9 Fix setting saving 2017-05-02 18:14:59 +03:00
David 1a367d83ba Update emotefilter.json 2017-05-01 23:57:45 -04:00
Alexei Stukov 05d55ea6fa Fixed settings sidebar injection 2017-05-01 12:36:49 +03:00
Alexei Stukov 9859064dc6 Fixed settings sidebar injection 2017-05-01 12:36:48 +03:00
Alexei Stukov 2d4416466c Fixed theme and plugin state not saving 2017-04-30 14:21:23 +03:00
Alexei Stukov 6372743f9f Fixed theme and plugin state not saving 2017-04-30 14:21:19 +03:00
Alexei Stukov 060c2ab0ec Fix for pluginpanel crashing 2017-04-30 14:16:29 +03:00
Alexei Stukov 91dd2e6ee7 Fix for pluginpanel crashing 2017-04-30 14:16:27 +03:00
Alexei Stukov eff75f27dc Allow dom nodes for plugin settings. 2017-04-30 14:02:42 +03:00
Alexei Stukov 8650b376ef Allow dom nodes for plugin settings. 2017-04-30 14:02:23 +03:00
Alexei Stukov f58ccdad4a Fix license link 2017-04-30 06:27:03 +03:00
Alexei Stukov 6e020a0298 Update credits and license 2017-04-30 06:26:35 +03:00
Alexei Stukov bdb22e9fb6 v1.78 2017-04-30 06:24:11 +03:00
Alexei Stukov f6cae7c238 v1.78 2017-04-30 06:11:58 +03:00
Alexei Stukov ad86bbb8c8 v1.78 2017-04-30 06:11:32 +03:00
Alexei Stukov 5bf01fa3c8 Fix missing keys 2017-04-30 06:07:07 +03:00
Alexei Stukov 2fbf1e9985 Show BD server regardless 2017-04-30 05:44:50 +03:00
Alexei Stukov 2fbe862933 Invite code joining 2017-04-30 05:34:52 +03:00
Alexei Stukov 2d554d0086 BD Blue add friend button bg 2017-04-30 05:25:59 +03:00
Alexei Stukov 3262eb58a9 Editor detached bdblue
Fixed editor attach button bdblue styling
2017-04-30 05:22:26 +03:00
Alexei Stukov b15f56212d Editor attach
Fixed css editor updating when attaching if open.
2017-04-30 05:21:08 +03:00
Alexei Stukov 6d23660361 Pinned server css 2017-04-30 04:49:40 +03:00
Alexei Stukov fbb0283148 xhr creds 2017-04-30 04:36:23 +03:00
Alexei Stukov 93ecab675d Changelog 2017-04-30 04:20:55 +03:00
Alexei Stukov 8820d0e674 v1.78 public test 2017-04-30 04:11:51 +03:00
Alexei Stukov df7f12d5bd v1.78 public test 2017-04-30 04:11:22 +03:00
DeathStrikeV f01ea2473c Updated FFZ emotes =3 2017-04-27 00:56:32 +01:00
pohky 32b6e6dc48 Merge pull request #466 from DeathStrikeV/master
Updated FFZ emotes =3
2017-04-26 10:24:52 +02:00
DeathStrikeV d71acb07fd Updated emotes 2017-04-24 18:36:19 +01:00
pohky b92989ac14 Merge pull request #465 from DeathStrikeV/master
More FFZ emotes =)
2017-04-21 14:56:07 +02:00
DeathStrikeV d517bae2d3 Updated emotes 2017-04-17 03:28:15 +01:00
pohky 889a415314 Merge pull request #463 from DeathStrikeV/master
More FFZ emotes =)
2017-04-16 02:09:00 +02:00
David 77d72d6284 Update emotefilter.json 2017-04-14 18:32:14 -04:00
DeathStrikeV 206685c29d Updated emotes 2017-04-09 13:34:39 +01:00
DeathStrikeV 3b1c5ee3a8 Updated emotes 2017-04-03 00:38:45 +01:00
pohky a17497d9a4 Merge pull request #460 from DeathStrikeV/master
More FFZ Emotes =)
2017-04-02 12:19:52 +02:00
DeathStrikeV cc64dfa958 Updated emotes 2017-04-02 10:02:31 +01:00
DeathStrikeV f7ab2a5b59 Updated emotes 2017-03-30 01:04:54 +01:00
pohky 8230b05046 Merge pull request #459 from DeathStrikeV/master
More FFZ emotes =)
2017-03-26 23:34:03 +02:00
DeathStrikeV 29c91bdfdf Updated emotes 2017-03-26 20:16:52 +01:00
pohky bd34bd6157 Merge pull request #455 from DeathStrikeV/master
More FFZ Emotes =D
2017-03-24 22:33:22 +01:00
Violetnred2 70ef5cd327 Update emotefilter.json
filtering out few extra single word emotes that does not represent their word well
2017-03-23 13:28:24 +02:00
DeathStrikeV c3450d50c4 Updated emotes 2017-03-21 21:12:00 +00:00
DeathStrikeV e4796621b7 Updated emotes 2017-03-17 00:11:29 +00:00
pohky aefd07995d Merge pull request #454 from DeathStrikeV/master
More ffz emotes
2017-03-12 16:07:18 +01:00
DeathStrikeV b7f46fd7f4 Updated emotes 2017-03-12 03:00:25 +00:00
DeathStrikeV 36d68836d4 Updated emotes 2017-03-10 18:35:03 +00:00
Alexei Stukov 897be73f09 Merge pull request #453 from DeathStrikeV/master
More FFZ emotes
2017-03-06 23:11:40 +02:00
DeathStrikeV 3e89697b4f Updated emotes 2017-03-06 20:42:16 +00:00
DeathStrikeV b78666140a Updated emotes 2017-03-04 00:45:09 +00:00
DeathStrikeV 52e8bc512d Merge pull request #12 from Jiiks/master
Merge updates
2017-03-03 18:56:09 +00:00
DeathStrikeV bb50c6f48e Updated emotes 2017-03-03 18:54:54 +00:00
Alexei Stukov b02340a130 Merge pull request #452 from Violetnred2/patch-1
Update emotefilter.json
2017-03-03 15:44:13 +02:00
Alexei Stukov 319e6db4fc Remove excess comma 2017-03-03 15:43:44 +02:00
Violetnred2 5c52b3b987 Update emotefilter.json
blacklist some LoL champion names plus assorted words
2017-03-03 13:58:09 +02:00
Alexei Stukov 72c2585e6a Merge pull request #450 from SomeGuyNamedDavid/patch-2
Blacklist emotes
2017-02-28 10:42:05 +02:00
Alexei Stukov a64dfa8bf0 missing comma 2017-02-28 10:41:33 +02:00
Alexei Stukov f35e867358 Merge branch 'master' into patch-2 2017-02-28 10:40:59 +02:00
David b200229b26 Update emotefilter.json 2017-02-27 16:55:51 -05:00
Alexei Stukov 770eae466e Merge pull request #449 from Zerthox/patch-1
Add "Technical" to emotefilter
2017-02-27 13:01:31 +02:00
David 6a86149b63 Blacklist emotes 2017-02-26 22:09:22 -05:00
DeathStrikeV b6833d2962 Merge branch 'master' of github.com:DeathStrikeV/BetterDiscordApp 2017-02-26 22:37:30 +00:00
DeathStrikeV a976753b93 Updated emotes 2017-02-26 22:36:45 +00:00
Zerthox e0885c6d6a Add Technical 2017-02-24 13:47:14 +01:00
DeathStrikeV 717586cee1 Merge pull request #11 from Jiiks/master
Update
2017-02-23 22:38:48 +00:00
Jiiks 23724784e2 Merge pull request #447 from DeathStrikeV/master
More updated emotes =D
2017-02-23 19:41:53 +02:00
DeathStrikeV e26b1db0c4 Updated emotes 2017-02-22 00:41:28 +00:00
DeathStrikeV c687da23fe Updated emotes 2017-02-18 00:15:26 +00:00
DeathStrikeV e509f16648 Updated emotes 2017-02-17 00:32:43 +00:00
DeathStrikeV 1919061656 Updated emotes 2017-02-15 18:47:13 +00:00
Jiiks 90fd6199a1 Merge pull request #446 from jjtcm/master
Add "Profi" to emotefilter
2017-02-14 00:55:39 +02:00
jjtcm d6aabd89ae Add "Profi" to emotefilter 2017-02-13 18:45:55 +01:00
DeathStrikeV 406ced863f Updated emotes 2017-02-12 22:51:38 +00:00
DeathStrikeV 1d9e4753be Merge branch 'master' of github.com:DeathStrikeV/BetterDiscordApp 2017-02-12 21:20:19 +00:00
DeathStrikeV aad61c5281 Updated emotes 2017-02-12 21:05:22 +00:00
DeathStrikeV 3543b57f53 Updated emotes 2017-02-12 15:29:04 +00:00
Jiiks fb927b093a Merge pull request #445 from DeathStrikeV/master
Added "Seriously" to emotesfilter
2017-02-12 16:10:38 +02:00
Jiiks 01cfee0ebd Fixed indent 2017-02-12 16:10:12 +02:00
DeathStrikeV c811e2a064 Added "Seriously" to emotesfilter 2017-02-12 09:25:43 +00:00
DeathStrikeV 92e992abd2 Merge pull request #10 from Jiiks/master
Pull latest changes
2017-02-12 09:04:55 +00:00
Jiiks d8feba59ea deprecate branch 2017-02-12 00:37:49 +02:00
Jiiks 11190a8a4c Merge pull request #288 from sarnex/master
Update Linux support to 0.0.13
2017-02-10 16:00:38 +02:00
Jiiks 143602a729 More case sentivity fixes 2017-02-10 15:58:37 +02:00
Jiiks 713e9e93d3 Fixed case sensitivity for storage file 2017-02-10 15:55:13 +02:00
Jiiks beb013122f Merge pull request #436 from mkody/fix-version-config
Update version of BD in config.json
2017-02-10 15:54:00 +02:00
Jiiks f7fa19dcf8 Conflict merge
https://github.com/Jiiks/BetterDiscordApp/pull/424
2017-02-10 15:52:14 +02:00
Jiiks 44073ed15d Conflict merge
https://github.com/Jiiks/BetterDiscordApp/pull/433
2017-02-10 15:50:16 +02:00
Jiiks 031c64271a Conflict merge
https://github.com/Jiiks/BetterDiscordApp/pull/420
2017-02-10 15:48:56 +02:00
Jiiks 79d9c6f00c Conflict merge
https://github.com/Jiiks/BetterDiscordApp/pull/432
2017-02-10 15:46:12 +02:00
Jiiks 391b6a2085 Merge pull request #426 from Zerthox/patch-5
Add Spooky, Spaghetti, Rucksack, Rein, Moin to emotefilter
2017-02-10 15:42:18 +02:00
Jiiks 0c22d475c3 Merge pull request #438 from SapiensAnatis/patch-1
add 'the'
2017-02-10 15:37:51 +02:00
Jiiks e8e52cf7c6 Merge pull request #442 from brodycas3/master
Add Minecraft to emote filter
2017-02-10 14:52:12 +02:00
Jiiks b6e2ca2670 Merge pull request #443 from NooB-AssassinZ3/patch-1
Fixing error in Linux
2017-02-05 16:38:18 +02:00
NooB-AssassinZ3 e06509ca0a Fixed with install path 2017-02-05 07:12:16 -06:00
NooB-AssassinZ3 cc4df4ada4 FIXING YOUR BLUNDER
SERIOUSLY GUYS. CONSISTENCY
2017-02-05 07:01:54 -06:00
Jiiks de617fed27 Merge pull request #434 from DeathStrikeV/master
Updated emotes
2017-01-31 21:38:50 +02:00
DeathStrikeV 59c931191b Updated emotes 2017-01-31 19:16:17 +00:00
Zerthox ca3859d343 Add Moin 2017-01-31 12:04:23 +01:00
brodycas3 30df5f6158 Update emotefilter.json 2017-01-29 21:23:46 -05:00
DeathStrikeV f15b0dee3d Updated emotes 2017-01-29 22:52:57 +00:00
Nick Sarnie ddda646afc Merge pull request #1 from mkody/fix-mainjs-linux
Change linux path to use the $HOME/.config folder
2017-01-29 12:28:42 -05:00
Nick Sarnie be22c14356
Update Linux support to 0.0.14
Signed-off-by: Nick Sarnie <commendsarnex@gmail.com>
2017-01-29 12:27:32 -05:00
MKody f08539d5f9
Fix path to the bdStorage.json for case-sensitive partitions 2017-01-29 12:27:32 -05:00
MKody ef10e075f6
Update version of BD in config.json 2017-01-29 12:27:32 -05:00
MKody c6f85e545f Change linux path to use the $HOME/.config folder 2017-01-29 15:37:51 +01:00
MKody 0f2812bc10 Update version of BD in config.json 2017-01-29 15:37:17 +01:00
Jiiks 513fb57621 Removed garbage 2017-01-28 03:48:36 +02:00
Jiiks 0878f4ab00 Merge pull request #440 from EhsanKia/bttv-update-jan18
Fully update BTTV db, removing ~6k deleted emotes and adding ~14k new ones
2017-01-28 02:42:06 +02:00
DeathStrikeV dc18638567 Updated emotes 2017-01-28 00:05:11 +00:00
noodlebox e793920ed9 Use path for stable release as Linux default 2017-01-26 18:03:52 -06:00
noodlebox b6bdaedb6d Add sane default paths for Linux 2017-01-26 00:24:52 -06:00
noodlebox 3431d30ac2 Add default install path for OSX 2017-01-25 23:04:28 -06:00
DeathStrikeV c74e9c1030 Updated emotes 2017-01-23 00:58:07 +00:00
Jiiks 5daf0bbdc5 Added z-index to minimal mode restore button 2017-01-23 01:43:18 +02:00
Jiiks 604ec38101 Fix localStorage path
Removed extra `/`
2017-01-22 20:01:17 +02:00
Jiiks fcfd75346b Change localStorage path 2017-01-22 20:00:24 +02:00
DeathStrikeV 6768b064f7 Updated emotes 2017-01-19 19:23:26 +00:00
Ehsan Kia 71124e0129 Fully update BTTV emotes, removing 6000 404'd emotes and adding around 14k new ones. 2017-01-18 21:18:31 -08:00
noodlebox 43aae6ac72 Fix default Discord path for OSX 2017-01-18 04:12:35 -06:00
noodlebox 5a4e121e2b Fix missing value for OSX 2017-01-18 03:40:01 -06:00
SapiensAnatis 810b0fcee2 add 'the'
yeah
2017-01-16 19:13:18 +00:00
DeathStrikeV 5120488766 Updated emotes 2017-01-13 21:37:19 +00:00
DeathStrikeV 8e9ebaa853 Updated emotes 2017-01-13 02:04:51 +00:00
Jiiks d862285c63 make proxystorage return null instead of undefined 2017-01-11 20:59:24 +02:00
Jiiks 52c4114148 1.77
Fixed empty data loading and added localstorage proxy
2017-01-11 12:55:08 +02:00
Jiiks 19feb05e9b Really fixed customcss and favourite emotes loading 2017-01-11 12:51:37 +02:00
Jiiks 47a36a2e56 Fixed customcss and fav emotes load handling 2017-01-11 12:46:18 +02:00
Jiiks e1fd1f0df7 Custom localStorage for old plugin compatibility 2017-01-11 12:43:46 +02:00
Jiiks 46fe0f7c37 Actually write on setItem 2017-01-11 11:40:17 +02:00
Jiiks 00dfb68677 Actually supply a filename and run the function 2017-01-11 11:25:20 +02:00
Jiiks 0a55c0edae Logging 2017-01-11 11:23:15 +02:00
Jiiks 33162a1798 Localstorage fix so old plugins can work 2017-01-11 11:21:17 +02:00
DeathStrikeV a6f53183c1 Updated emotes 2017-01-09 21:49:20 +00:00
Jiiks b0b24974e6 alt storage release 2017-01-09 10:38:52 +02:00
Jiiks 7ff3971168 Use individual storages per plugin 2017-01-09 08:32:58 +02:00
Jiiks ba56f3bf6e Updated to comply with the new storage spec 2017-01-09 08:29:18 +02:00
Jiiks b7851955b2 Updated to use individual storage files for plugins 2017-01-09 08:15:00 +02:00
Jiiks 5784e45e87 Updated emote blacklist to use the new storage 2017-01-09 07:46:58 +02:00
Jiiks 186d6c9bc5 Alternate storage lib fix 2017-01-09 07:42:14 +02:00
Jiiks 6e1816d973 Alternate storage fix 2017-01-09 07:41:36 +02:00
DeathStrikeV 5e23ad66af Updated emotes 2017-01-06 17:28:44 +00:00
DeathStrikeV 788d20e452 Updated emotes 2017-01-06 12:42:32 +00:00
DeathStrikeV 032b69d564 Updated emotes 2017-01-05 13:20:22 +00:00
DeathStrikeV 01a55116b0 Updated emotes 2017-01-05 13:17:20 +00:00
DeathStrikeV 31603634ce Updated emotes 2017-01-05 03:37:23 +00:00
Jiiks 9c99e8a27d Merge pull request #428 from DeathStrikeV/master
Updated emotes
2017-01-05 04:23:21 +02:00
DeathStrikeV f2d4680698 Updated emotes 2017-01-02 22:12:25 +00:00
Jacob Foster 028b96589e Reduce cases in Node installer 2017-01-02 03:46:50 -06:00
Zerthox b4bc6ff109 Add Dirk 2016-12-31 20:24:44 +01:00
DeathStrikeV e21c1dc28a Updated emotes 2016-12-31 10:54:51 +00:00
DeathStrikeV bebf352bd0 Updated emotes 2016-12-29 23:29:16 +00:00
Jiiks 8369decbfc Merge pull request #425 from DeathStrikeV/master
More emote updates
2016-12-24 14:17:18 +02:00
DeathStrikeV 1111b98767 Updated emotes 2016-12-24 11:09:20 +00:00
DeathStrikeV ffb456c466 Updated emotes 2016-12-22 23:21:20 +00:00
DeathStrikeV 68247caf66 Updated emotes 2016-12-20 07:38:43 +00:00
Zerthox c65b760ca1 Add Spooky, Spaghetti, Rucksack, Rein 2016-12-19 19:18:31 +01:00
DeathStrikeV 8e4b5f6ee0 Updated emotes 2016-12-17 22:10:30 +00:00
DeathStrikeV 6e08a4b1ed Updated emotes 2016-12-17 12:26:26 +00:00
DeathStrikeV 0b26620901 Updated emotes 2016-12-17 08:23:40 +00:00
DeathStrikeV d4c8f04331 Merge pull request #9 from Jiiks/master
Update to latest
2016-12-17 07:23:23 +00:00
DeathStrikeV 67f0257cb4 Updated emotes 2016-12-17 07:20:25 +00:00
pohky a2de68ec1f Update emotefilter.json
Added Bella
2016-12-16 23:22:19 +01:00
DeathStrikeV 93115073e9 Updated emotes 2016-12-13 23:11:30 +00:00
DeathStrikeV 19f5f9f7a5 Updated emotes 2016-12-13 08:27:48 +00:00
Jiiks 131eab393d Merge pull request #418 from Zerthox/patch-3
Added Meow, Hartz, Brille, Affe, Baby, YOUTUBE to emote filter
2016-12-12 22:44:18 +02:00
Jiiks 8f7cc5e06f Merge pull request #419 from elnormous/installer_fix
Fix Node installer
2016-12-12 22:43:37 +02:00
Jiiks b46e797728 Merge pull request #417 from DeathStrikeV/master
More FFZ emotes, duplicates/filtered emotes can be accessed with ~# modifier (e.g. FeelsBadMan~1)
2016-12-12 22:43:22 +02:00
DeathStrikeV 42898de340 Updated emotes 2016-12-12 20:33:40 +00:00
Zerthox 65fda6f4e7 Added YOUTUBE 2016-12-12 20:01:55 +01:00
Zerthox e15af62927 Added Baby 2016-12-12 19:58:18 +01:00
DeathStrikeV d2a7c6734a Updated emotes 2016-12-10 07:39:51 +00:00
Zerthox 1b9eb941d2 Added Affe 2016-12-09 20:59:12 +01:00
Zerthox 59263be1b5 Added Brille 2016-12-09 20:35:32 +01:00
DeathStrikeV df2b647750 Updated emotes 2016-12-08 05:01:16 +00:00
DeathStrikeV 4e0a23ec03 Updated emotes 2016-12-07 01:39:00 +00:00
DeathStrikeV beae2087a8 Updated emotes 2016-12-06 19:49:43 +00:00
Jiiks 2039252e69 Fixed bd server join button 2016-12-05 22:05:48 +02:00
Elviss Strazdins 1219eb76bc Fix Node installer 2016-12-05 15:05:25 +02:00
DeathStrikeV 31a1fcfc46 Updated emotes 2016-12-05 11:13:33 +00:00
DeathStrikeV 37731b9fa7 Merge branch 'master' of github.com:DeathStrikeV/BetterDiscordApp 2016-12-02 21:38:41 +00:00
DeathStrikeV 2d8120fc1e Updated emotes 2016-12-02 21:38:09 +00:00
DeathStrikeV bd0e1b135e Merge pull request #8 from Jiiks/master
Update to latest
2016-12-02 10:23:05 +00:00
Jiiks 9a2b4fb8b2 Hide serverlist on join 2016-12-02 12:03:09 +02:00
Jiiks e7b9be97b0 Unliteral 2016-12-02 11:59:40 +02:00
Jiiks 5cea881ed9 Open invite codes in browser 2016-12-02 11:58:11 +02:00
DeathStrikeV e40b9fe82c Updated emotes 2016-12-02 09:54:24 +00:00
Jiiks c14c4255eb Fix icode regex 2016-12-02 11:42:54 +02:00
Jiiks fec2679fc8 icxss 2016-12-02 11:28:41 +02:00
Jiiks 520ca3faea icxss 2016-12-02 11:27:48 +02:00
Jiiks c8e906b00d Fix tags and minify 2016-12-02 09:24:44 +02:00
Jiiks 9bddcaa181 Undefined check for unsafes 2016-12-02 09:20:53 +02:00
Jiiks aa4877d851 live debug 2016-12-02 09:19:37 +02:00
Jiiks a9a2d09ae0 return not continue 2016-12-02 09:18:51 +02:00
Jiiks 422c18917c Ignore servers with undefined invite codes 2016-12-02 09:16:58 +02:00
Jiiks ccdc5f1a9f Fixed publicservers categories 2016-12-02 09:14:00 +02:00
Jiiks 080141e7d0 Fixed publicservers identifier filter 2016-12-02 09:10:51 +02:00
Jiiks b55bd54b29 Fixed publicserver search 2016-12-02 09:03:40 +02:00
Jiiks 8c0951a0ea Updated public servers endpoint 2016-12-02 07:36:41 +02:00
DeathStrikeV bb5744dfe9 Updated emotes 2016-11-29 21:36:09 +00:00
DeathStrikeV 5bf2597030 Updated emotes 2016-11-28 23:38:15 +00:00
DeathStrikeV ade5cbc446 Updated emotes 2016-11-28 13:45:55 +00:00
DeathStrikeV 35ca5f6339 Updated emotes 2016-11-28 07:03:14 +00:00
DeathStrikeV 97c259f1c4 Updated emotes 2016-11-27 20:48:51 +00:00
DeathStrikeV 8eedc29d71 Updated emotes 2016-11-27 12:33:46 +00:00
DeathStrikeV 3975eabca0 Updated emotes 2016-11-27 11:10:46 +00:00
DeathStrikeV 1b99b6289a Updated emotes 2016-11-25 07:36:15 +00:00
DeathStrikeV 0b9fb52800 Updated emotes 2016-11-25 06:34:40 +00:00
DeathStrikeV f1a0f11257 Updated emotes 2016-11-24 09:55:07 +00:00
DeathStrikeV dea323a0b8 Updated emotes 2016-11-23 07:30:50 +00:00
Zerthox c0bd71fe7d Added Meow & Hartz 2016-11-21 19:57:26 +01:00
DeathStrikeV 85093234fa Updated emotes 2016-11-20 09:44:32 +00:00
DeathStrikeV 13e21fb052 Updated emotes 2016-11-19 19:56:18 +00:00
DeathStrikeV e592126078 Updated emotes 2016-11-19 14:40:30 +00:00
DeathStrikeV 35de874ced Updated emotes 2016-11-18 02:00:28 +00:00
DeathStrikeV cdc95aef68 Updated emotes 2016-11-16 23:17:58 +00:00
DeathStrikeV 08cc4c5bc3 Updated emotes 2016-11-16 01:35:32 +00:00
DeathStrikeV 5c514efa96 Updated emotes 2016-11-16 01:31:48 +00:00
DeathStrikeV a9bc977764 Updated emotes 2016-11-16 00:12:44 +00:00
DeathStrikeV 2fa3e7a4b5 Updated emotes 2016-11-15 21:06:06 +00:00
DeathStrikeV 9b4f5f4366 Updated emotes 2016-11-15 07:57:48 +00:00
DeathStrikeV 2b55554af1 Updated emotes 2016-11-14 22:33:50 +00:00
DeathStrikeV 5aff38bf39 Updated emotes 2016-11-13 22:36:49 +00:00
Jiiks 53d4989a79 Merge pull request #415 from DeathStrikeV/master
More FFZ Emotes
2016-11-13 06:35:58 +02:00
Jiiks d23d331463 Merge pull request #414 from Zerthox/patch-2
Added "Snorlax" (Broken)
2016-11-13 06:35:47 +02:00
DeathStrikeV 020b1b8d4e Updated emotes 2016-11-12 18:07:45 +00:00
DeathStrikeV e251a03914 Merge pull request #7 from Jiiks/master
Pull latest updates
2016-11-11 19:14:50 +00:00
DeathStrikeV 1faac18e8d Updated emotes 2016-11-11 19:14:13 +00:00
DeathStrikeV a23878fd0b Updated emotes 2016-11-11 07:29:05 +00:00
Zerthox 56773ae55f Added "Snorlax" (Broken) 2016-11-10 19:22:07 +01:00
Jiiks dd28c89236 Merge pull request #413 from TakosThings/patch-1
Add "Bomb" to filter
2016-11-10 15:48:17 +02:00
DeathStrikeV 14331ddee5 Merge branch 'master' of github.com:DeathStrikeV/BetterDiscordApp 2016-11-10 07:29:45 +00:00
DeathStrikeV b1a06a519f Updated emotes 2016-11-10 07:28:27 +00:00
TakosThings cc1938b14b Add "Bomb" to filter 2016-11-10 04:35:26 +10:30
Jiiks c4e0cc15c9 Merge pull request #406 from Leeo97one/patch-1
Electron installer fix
2016-11-09 10:41:31 +02:00
Jiiks 6651b5ac3f Merge pull request #410 from DeathStrikeV/master
More FFZ Emotes
2016-11-09 05:30:45 +02:00
DeathStrikeV faa7b30df5 Merge pull request #6 from Jiiks/master
Update to latest changes
2016-11-08 19:53:25 +00:00
DeathStrikeV 9a638e7eb3 Updated emotes 2016-11-08 19:38:07 +00:00
DeathStrikeV 06770ca1af Merge branch 'master' of github.com:DeathStrikeV/BetterDiscordApp 2016-11-08 07:31:08 +00:00
DeathStrikeV 337a79efbb Updated emotes 2016-11-08 07:29:51 +00:00
Jiiks fd3dab39de Merge pull request #409 from Zerthox/patch-1
Added "Nein" and "Pokeball" to emote filter
2016-11-07 22:32:01 +02:00
Zerthox 84092e1c6f Add "Nein" and "Pokeball" 2016-11-07 21:17:28 +01:00
Jiiks 77addb5b03 Merge pull request #408 from DeathStrikeV/master
More emotes - Pull at your own leisure
2016-11-07 22:09:54 +02:00
DeathStrikeV 68e56d9ea8 Merge pull request #5 from Jiiks/master
Pull latest changes
2016-11-07 19:24:08 +00:00
Jiiks 71b0077fc0 Formatting 2016-11-07 20:46:14 +02:00
DeathStrikeV 2e64e4c47b Updated emotes 2016-11-06 23:46:21 +00:00
Léo c4f4ac41e8 Electron installer fix
Fix the index.js file path in the Electron installer.
2016-11-06 12:03:29 +01:00
Jiiks 07f38008d8 Merge pull request #405 from EhsanKia/bttv-update-nov5
Bttv update nov5
2016-11-06 09:54:24 +02:00
Ehsan Kia 5c70075ca0 Merge branch 'master' of github.com:Jiiks/BetterDiscordApp into bttv-update-nov5
# Conflicts:
#	data/emotedata_ffz.json
2016-11-06 00:48:42 -07:00
Jiiks e09fb169ae Merge pull request #404 from DeathStrikeV/master
More emote updates GG
2016-11-06 08:32:50 +02:00
Ehsan Kia dc48d88d59 Update BTTV emote db 2016-11-05 16:27:00 -07:00
Ehsan Kia 227547d7e7 Remove ImTriggered from FFZ 2016-11-05 16:24:35 -07:00
DeathStrikeV 00da2ef58c Updated emotes 2016-11-05 22:35:26 +00:00
DeathStrikeV 195e8a9b77 Updated emotes 2016-11-05 12:11:29 +00:00
DeathStrikeV 7cb778f884 Updated emotes 2016-11-05 01:56:58 +00:00
DeathStrikeV 289abee257 Updated emotes 2016-11-05 00:07:28 +00:00
DeathStrikeV 2c49e52f90 Merge branch 'master' of github.com:DeathStrikeV/BetterDiscordApp 2016-11-04 22:43:53 +00:00
DeathStrikeV 07968430e3 Updated emotes 2016-11-04 22:43:27 +00:00
Alex e10b78dc9b Merge pull request #4 from Jiiks/master
Updates
2016-11-04 22:42:10 +00:00
Jiiks a1f9f29198 Changed info arrow colour 2016-11-04 07:11:52 +02:00
Jiiks 0b614022ad Final logger format maybe 2016-11-04 07:11:22 +02:00
Jiiks 821a9f8749 Reformatted logger again 2016-11-04 07:03:39 +02:00
Jiiks 1bb83de279 Reformatted logs 2016-11-04 06:51:56 +02:00
Jiiks 48e55c9417 Timestamps and init log 2016-11-04 06:49:51 +02:00
Jiiks 5dc6327fda Loggers 2016-11-04 06:46:02 +02:00
DeathStrikeV e1470dab3e Updated emotes 2016-11-04 00:06:53 +00:00
DeathStrikeV ab0e948fe4 Updated emotes 2016-11-03 20:43:07 +00:00
Jiiks d5f16c0b2d Merge pull request #403 from DeathStrikeV/master
Updated FFZ emotes
2016-11-03 01:06:20 +02:00
Alex 66c24f246a Merge pull request #3 from Jiiks/master
Updating to latest
2016-11-02 21:28:33 +00:00
DeathStrikeV 27b1978515 Updated emotes 2016-11-02 21:22:04 +00:00
Jiiks 8df7431743 Skeletons 2016-11-02 07:38:32 +02:00
Jiiks c3443b5725 added Okie 2016-11-02 07:38:03 +02:00
DeathStrikeV 5e466e79fd Updated emotes 2016-11-01 08:07:46 +00:00
Jiiks 4f549676bc Merge pull request #392 from DeathStrikeV/master
FFZ Emote Update
2016-11-01 05:50:31 +02:00
Jiiks cfd651eaab Updated plugin base 2016-11-01 05:44:51 +02:00
Jiiks 6d58d8f2f8 event and plugin bases 2016-11-01 05:42:15 +02:00
Jiiks 1a7d84a14c Added resource injection, fixed timestamps, ignores 2016-10-31 20:33:04 +02:00
Jiiks 376471cb2d added noclean grunt tasks 2016-10-31 19:24:51 +02:00
Jiiks 3eea2eacc3 Client side skeleton and grunt config for js 2016-10-31 19:20:34 +02:00
Jiiks 9416be4105 Added resources downloader and hash getter 2016-10-31 18:47:59 +02:00
Jiiks e7b56fe792 Reformatted logger, added eventhook and tests
Standalone test file skeleton
2016-10-31 18:40:55 +02:00
Jiiks 7f5986aa01 {} convention, logs, exit and hook skeleton 2016-10-31 18:05:51 +02:00
Jiiks fc53df5e4b Default configs 2016-10-31 17:57:12 +02:00
Jiiks c5454a8f57 v2 initial slow track 2016-10-31 17:36:03 +02:00
DeathStrikeV 3d381b7ca1 Updated emotes 2016-10-30 21:56:27 +00:00
DeathStrikeV 469cb2a2da Updated emotes 2016-10-29 21:09:50 +01:00
DeathStrikeV 8b57885002 Updated emotes 2016-10-29 00:36:56 +01:00
DeathStrikeV 3429d6c8ca Updated emotes 2016-10-28 07:58:50 +01:00
Jiiks 28ad0c0acc Merge pull request #401 from EhsanKia/fix-lul
Change BTTV emote length to 3 (allowing LUL)
2016-10-25 20:17:29 +03:00
Jiiks 70c6eaca03 Merge pull request #400 from EhsanKia/bttv-update-oct16
Updated BTTV emote database
2016-10-25 20:17:23 +03:00
DeathStrikeV a80d16fbd8 Updated emotes 2016-10-20 08:07:38 +01:00
Ehsan Kia 4fa0825bc7 Change BTTV emote length to 3 (allowing LUL) 2016-10-17 00:19:29 -07:00
Ehsan Kia 2db776f93a Updated BTTV emote database 2016-10-16 19:01:11 -07:00
DeathStrikeV e330ff197d Updated emotes 2016-10-16 19:52:23 +01:00
DeathStrikeV b002ae6130 Updated emotes 2016-10-11 09:41:09 +01:00
DeathStrikeV 5c27d91fde Updated emotes 2016-10-09 22:02:09 +01:00
DeathStrikeV 5f94a8b155 Updated emotes 2016-10-08 17:13:27 +01:00
DeathStrikeV f18f353501 Updated emotes 2016-10-08 16:33:12 +01:00
DeathStrikeV 0e2bf5b1c4 Updated emotes 2016-10-07 20:05:05 +01:00
DeathStrikeV ea34f260df Updated emotes 2016-10-07 20:02:43 +01:00
DeathStrikeV 56f590dbf4 Updated emotes 2016-10-07 19:37:07 +01:00
DeathStrikeV 54709b608a Updated emotes 2016-10-07 10:58:51 +01:00
DeathStrikeV aaea907eac Updated emotes 2016-10-06 23:01:55 +01:00
DeathStrikeV ebb99040e4 Updated emotes 2016-10-06 22:43:01 +01:00
DeathStrikeV d874f6becc Updated emotes 2016-10-06 20:09:35 +01:00
DeathStrikeV f3d8865df5 Updated emotes 2016-10-06 00:36:17 +01:00
DeathStrikeV 9098bca396 Updated emotes 2016-10-05 19:42:21 +01:00
DeathStrikeV e7bda2e6c1 Updated ffz emotes 2016-10-02 21:16:52 +01:00
Alex a8534308b7 Merge pull request #2 from Jiiks/master
Update
2016-10-02 21:15:18 +01:00
Jiiks 24eb3f3d9d Merge pull request #389 from EhsanKia/bttv-update-sep21
Add new bttv emotes
2016-09-21 13:19:32 +03:00
Ehsan Kia ad2f98107a Add new bttv emotes 2016-09-21 00:47:21 -07:00
noodlebox b9b28c0bd9 Fix AutoPlayGifs plugin 2016-09-10 05:06:17 -05:00
pohky 2b361cbcc3 Merge pull request #381 from EhsanKia/bttv-update-sep5
Added new bttv emotes
2016-09-07 19:05:14 +02:00
Ehsan Kia 39505125fd Added new bttv emotes 2016-09-05 15:44:04 -07:00
Jiiks 48d4a58102 ayy and indent 2016-08-16 12:24:55 +03:00
pohky c51bb8cc43 Merge pull request #366 from EhsanKia/bttv-update-aug15
Adding new BTTV emotes
2016-08-16 05:21:16 +02:00
Ehsan Kia 51ae2698c4 Adding new BTTV emotes 2016-08-15 21:55:01 -04:00
pohky 501f38357f FFZ Emote Update 2016-08-16 02:32:19 +02:00
Jiiks 2fc35436a4 Fixed replace 2016-08-15 02:03:18 +03:00
Jiiks b87e0781f6 User input escapes 2016-08-15 02:00:09 +03:00
Jiiks fe1a30027a Merge pull request #362 from Cyken-Zeraux/patch-2
Canary 0.0.138 Support
2016-08-12 21:14:01 +03:00
pohky eb58553ade Update emotefilter.json 2016-08-12 04:54:22 +02:00
Jiiks b28ef7abc5 Publicservers user data escape 2016-08-11 17:53:25 +03:00
Jiiks 8625b1bdbf Added uri encoding 2016-08-11 17:30:37 +03:00
Yozora 9ae3b5ba69 Remove unnecessary line of code
I forgot to delete this line before committing the file
2016-08-06 23:48:46 +02:00
pohky 42971a5714 Update emotefilter.json 2016-08-06 23:47:03 +02:00
pohky 7bd1a219cd Update emotefilter.json 2016-08-06 23:46:34 +02:00
CZauX 336152802a Canary 0.0.138 Support
app.asar extracts to resources/app, not resources/app/app. Fixed pathing for index.js to check both locations and display error if not found rather than crashing.

Also added splice file detection, errors out instead of crashes.
2016-08-06 10:06:35 -05:00
Yozora d067bc2cfc Added version-agnostic uninstaller for Windows
This uninstaller.bat removes BetterDiscord from all app-* folders in %localappdata%\Discord\ and restarts Discord afterwards.
2016-08-06 12:50:27 +02:00
pohky f751f540ec Update emotefilter.json 2016-08-04 22:13:27 +02:00
pohky bd576ef69c Update emotefilter.json 2016-08-04 16:14:20 +02:00
pohky d186bc9218 Update emotefilter.json 2016-08-03 22:22:48 +02:00
pohky ef8ca8fd15 Update emotefilter.json 2016-08-03 06:26:02 +02:00
Jiiks 9e4f6ccf25 Added some emotes 2016-08-02 19:50:14 +03:00
pohky d377cef33c FFZ Emotes Update 2016-08-02 14:44:31 +02:00
pohky 99afa4ccc7 Merge pull request #358 from EhsanKia/bttv-update-aug1
Fix stupid javascript issue
2016-08-01 21:37:46 +02:00
Ehsan Kia 320a68f8cb Fix stupid javascript issue 2016-08-01 15:34:01 -04:00
pohky b09590e8e7 Merge pull request #357 from EhsanKia/bttv-update-aug1
BTTV database update
2016-08-01 21:20:45 +02:00
Ehsan Kia 4b63daaf48 BTTV database update 2016-08-01 15:16:30 -04:00
Jiiks d26247bbd6 v1.74 minor fixes
Fixed bd invite link and dev mode breaking
2016-07-31 01:47:35 +03:00
pohky 0ab1fe3f19 Update emotefilter.json 2016-07-25 10:31:12 +02:00
pohky 00ff05bfe0 Update emotefilter.json 2016-07-25 07:05:18 +02:00
pohky 2bd94b9ae4 Merge pull request #355 from EhsanKia/bttv-update-july24
BTTV database update july 24
2016-07-24 22:15:14 +02:00
Ehsan Kia 6d1b7667b8 BTTV database update july 24 2016-07-24 16:13:23 -04:00
Jiiks 51cf6e531c Pre-release, windows and linux support
Missing error handling, uninstall and advanced options
2016-07-22 11:56:15 +03:00
Jiiks e5d91a8564 Rebase 2016-07-22 11:52:05 +03:00
pohky 91fcf59656 Update emotefilter.json 2016-07-22 10:22:36 +02:00
pohky 20337f3f36 Update emotefilter.json 2016-07-22 06:37:19 +02:00
pohky 7eac80b59f Update emotefilter.json 2016-07-21 00:38:22 +02:00
pohky 8c2e38662c Update emotefilter.json 2016-07-20 21:14:37 +02:00
pohky 31617f79b3 FFZ Emotes Update 2016-07-20 15:22:20 +02:00
pohky 08ec6a4ddb Merge pull request #352 from EhsanKia/bttv-update-july18
updated bttv db emote
2016-07-20 00:15:27 +02:00
Ehsan Kia 1a394c75c9 updated bttv db emote 2016-07-18 20:09:22 -04:00
pohky b604daf201 Update emotefilter.json 2016-07-16 10:54:10 +02:00
pohky 2eb0f8d9c7 Update emotefilter.json 2016-07-13 07:37:37 +02:00
pohky 839c06d968 Update emotefilter.json 2016-07-12 12:26:09 +02:00
Jiiks 2b32ffac01 Create node_modules folder if it doesn't exist 2016-07-12 06:13:11 +03:00
pohky 456852070e Merge pull request #344 from EhsanKia/fix-bttv-db
Fix missing BTTV emotes
2016-07-11 18:18:24 +02:00
Ehsan Kia f2d76b2e99 Fix missing emotes 2016-07-11 10:43:42 -04:00
pohky 4d63434d51 Update emotefilter.json 2016-07-10 03:02:48 +02:00
pohky d2a6b384d3 Merge pull request #342 from EhsanKia/bttv-update-july9
New BTTV emote db update
2016-07-09 16:44:29 +02:00
Ehsan Kia ba4402a4d4 New BTTV emote db update 2016-07-09 09:50:50 -04:00
pohky d36caf0599 Update emotefilter.json 2016-07-08 11:03:03 +02:00
pohky 40dbd67e80 Update emotefilter.json 2016-07-07 23:12:33 +02:00
pohky 19393f4480 Update emotefilter.json 2016-07-06 18:48:15 +02:00
pohky 9bf4b9dcb6 Update emotefilter.json 2016-07-05 23:05:49 +02:00
pohky c07f7ac73f Update FFZ emotes 2016-07-05 23:03:16 +02:00
pohky 3ba91bfbf3 Update emotefilter.json 2016-07-02 18:11:12 +02:00
pohky 1a48e6045f Update emotefilter.json 2016-06-30 04:04:35 +02:00
Jiiks 3c62a57b96 Merge branch 'master' of https://github.com/Jiiks/BetterDiscordApp 2016-06-29 12:30:31 +03:00
Jiiks 1a560a1656 added "Freddie" 2016-06-29 12:30:27 +03:00
Jiiks d2c5a95f13 Merge pull request #339 from EhsanKia/bttv-update-june26
Update BTTV db
2016-06-27 23:50:46 +03:00
Jiiks d81b806d6b Merge branch 'master' of https://github.com/Jiiks/BetterDiscordApp 2016-06-27 20:09:52 +03:00
Jiiks 9a97a5cc2e added 12h option 2016-06-27 20:09:48 +03:00
pohky 6998c5c131 Update emotefilter.json 2016-06-27 11:41:37 +02:00
pohky 01070c916c Update emotefilter.json 2016-06-27 01:46:01 +02:00
Ehsan Kia 136266be85 Update BTTV db 2016-06-26 16:45:59 -04:00
Jiiks 284838bb5c Versioning 2016-06-24 02:13:18 +03:00
Jiiks 4fa8d75653 Merge branch 'master' of https://github.com/Jiiks/BetterDiscordApp 2016-06-24 02:12:47 +03:00
Jiiks ef3d2ad9b1 Updated for latest Discord version 2016-06-24 02:12:41 +03:00
pohky 995868b5b9 FFZ Emotes update 2016-06-21 04:01:47 +02:00
pohky d8457795e4 Update emotefilter.json 2016-06-20 11:44:24 +02:00
pohky 8de42e7931 Merge pull request #335 from EhsanKia/bttv-update-june19
Updated BTTV emote database
2016-06-20 03:05:05 +02:00
Ehsan Kia d8db32f389 Updated BTTV emote database 2016-06-19 17:33:25 -04:00
pohky 22513f3d27 Update FFZ emotes 2016-06-13 04:02:36 +02:00
pohky 3470dc2594 Merge pull request #330 from EhsanKia/bttv-update-june12
Updated BTTV emote database
2016-06-12 19:12:41 +02:00
Ehsan Kia f978d4b2d9 Updated BTTV emote database 2016-06-12 00:26:27 -04:00
pohky 1a40b63d04 Merge pull request #326 from EhsanKia/bttv-update-june6
Update BTTV emote database
2016-06-06 22:22:19 +02:00
Ehsan Kia 4e20898cae Update BTTV emote database 2016-06-06 09:13:44 -04:00
Jiiks 849c139124 Remove unused 2016-06-05 12:24:32 +03:00
Jiiks c1af5fd726 Merge branch 'master' of https://github.com/Jiiks/BetterDiscordApp 2016-06-05 12:23:44 +03:00
Jiiks 1e79726b73 Electron installer update 2016-06-05 12:23:40 +03:00
pohky 1dfd428995 FFZ Emotes Update 2016-06-05 10:27:27 +02:00
Jiiks cfe00cd50d Merge branch 'master' of https://github.com/Jiiks/BetterDiscordApp 2016-06-04 07:41:29 +03:00
Jiiks 36d832d3e2 Installer version info 2016-06-04 07:41:25 +03:00
pohky 46f983f132 Update emotefilter.json 2016-06-03 04:35:16 +02:00
pohky f535aa5761 Update emotefilter.json 2016-06-02 19:46:09 +02:00
pohky ab07e14d7f Update emotefilter.json 2016-06-01 03:13:11 +02:00
pohky bdbc2c0110 Update emotefilter.json 2016-05-31 04:55:45 +02:00
pohky 00e64da94a Update emotefilter.json 2016-05-31 01:00:21 +02:00
pohky 0370e80071 Update FFZ Emotes 2016-05-30 21:35:51 +02:00
pohky b25201b576 Merge pull request #318 from EhsanKia/bttv-update-may26
Update BTTV emote DB
2016-05-26 07:14:00 +02:00
Ehsan Kia e6955f919d Update BTTV emote DB 2016-05-26 01:12:24 -04:00
Jiiks 8205109f29 Updater vi 2016-05-25 22:50:26 +03:00
Jiiks b277ab2c7f Versioning for updater 2016-05-25 22:21:45 +03:00
Jiiks b68a850750 Added loading/update splash base and quit modal 2016-05-25 22:14:08 +03:00
pohky b55607f1b2 Update emotefilter.json 2016-05-25 08:25:14 +02:00
pohky 3451215be9 Update emotefilter.json 2016-05-25 00:17:27 +02:00
Jiiks f649c729b2 1.73 disabled native sub emotes and added initial dev mode 2016-05-24 23:33:24 +03:00
pohky 8a786de8cc Update emotefilter.json 2016-05-24 17:07:28 +02:00
pohky e8e82cb02b Bugfix blacklisted emotes
fixed a bug where blacklisted emotes cut the text off
2016-05-24 14:29:30 +02:00
Jiiks 329d8bc55e Updated separated files 2016-05-22 19:40:14 +03:00
pohky 1137428be4 Update emotefilter.json 2016-05-22 16:55:03 +02:00
pohky d09d870d9e FFZ Emotes update 2016-05-22 07:17:14 +02:00
Jiiks ab7ccf061d Fixed server invite code 2016-05-21 22:00:32 +03:00
pohky b343b5d7c9 quick fix
open themes/plugins folder
2016-05-21 19:09:22 +02:00
Jiiks 13c1ab4be0 v1.72
Fixed emotes
Fixed public server button not showing
Changed public server api endpoint
Added public server description, tags and category search
Added mutation listener for settings panel instead of relying on defers
Fixed many small bugs
2016-05-21 12:19:29 +03:00
Jiiks 512ccd1904 Fixed typo 2016-05-20 08:14:02 +03:00
Jiiks c4a1b2bc20 Merge branch 'master' of https://github.com/Jiiks/BetterDiscordApp 2016-05-20 08:12:53 +03:00
Jiiks 457f314ac3 But notice 2016-05-20 08:12:49 +03:00
pohky dde563e0eb Minimal Mode fix
hotfix
2016-05-20 06:42:49 +02:00
Jiiks b742f86ee0 v1.71
Fixed emotes, emote edits, new changelog and versioning
2016-05-20 05:30:54 +03:00
Jiiks 596b0e8490 Fixed emotes 2016-05-20 05:12:32 +03:00
pohky e9461a9830 Update emotefilter.json 2016-05-19 15:44:48 +02:00
Jiiks 178f2b464c Added Choco 2016-05-18 03:43:21 +03:00
pohky 220e75e29b Merge pull request #310 from EhsanKia/bttv-update-may15
Updated BTTV emote database
2016-05-15 14:16:33 +02:00
Ehsan Kia c7fa09505d Updated BTTV emote database 2016-05-15 00:45:28 -04:00
pohky d6c55d7e1b Update emotefilter.json 2016-05-15 01:58:02 +02:00
pohky 276b39e169 Update emotedata_ffz.json, emotefilter.json
weekly update
2016-05-15 01:19:22 +02:00
pohky 9c6b3629d3 Update emotefilter.json 2016-05-13 09:14:22 +02:00
pohky 5a636f6e9a Update emotefilter.json 2016-05-12 23:39:55 +02:00
Jiiks db31c2662a Installer base 2016-05-12 17:17:05 +03:00
pohky 66d7636228 Update emotefilter.json 2016-05-12 14:56:03 +02:00
Jiiks ae9dcd6220 Moved installers 2016-05-12 05:14:52 +03:00
Jiiks f4461ed97f Added WindowInstaller/bin/ to ignore 2016-05-12 05:09:47 +03:00
pohky 201d1fb22b Update emotefilter.json 2016-05-11 22:59:18 +02:00
pohky cb7176be5d Update emotefilter.json 2016-05-11 02:20:00 +02:00
pohky c3dff1ca6e Update emotefilter.json 2016-05-11 00:54:06 +02:00
pohky 6be4da2197 Update emotedata_ffz.json, emotefilter.json 2016-05-09 11:30:45 +02:00
pohky 5add6c9a21 Update emotefilter.json 2016-05-08 02:55:15 +02:00
pohky 2f4716714d Merge pull request #296 from EhsanKia/bttv-update-may7
Updated BTTV emote database
2016-05-07 20:21:51 +02:00
Ehsan Kia 5c3f653718 Updated BTTV emote database 2016-05-07 13:45:20 -04:00
pohky 6b8f324199 Update emotefilter.json 2016-05-07 19:21:16 +02:00
Jiiks 199aa4fa45 Updated styling 2016-05-07 18:53:52 +03:00
Jiiks 2845884954 Updated css 2016-05-07 18:51:40 +03:00
Jiiks 25e2d278a8 Updated preview image 2016-05-07 01:26:59 +03:00
pohky c86be946ee Update emotefilter.json 2016-05-07 00:17:08 +02:00
Jiiks bdf889e14f Fixed a eol bug 2016-05-07 00:44:48 +03:00
Jiiks c61af06452 Removed some unintended css 2016-05-07 00:07:46 +03:00
Jiiks 6d16dea9ac For 0.2.8 and fixed settings import 2016-05-06 23:57:38 +03:00
pohky 9b4f2bac09 Update emotefilter.json 2016-05-06 21:52:53 +02:00
Jiiks 71131ef335 Refactoring and 0.2.8 support 2016-05-06 22:03:17 +03:00
Jiiks 2689708b49 0.2.8
Mostly error catching, require *.plugin.js *.theme.css, better hooking
2016-05-06 21:34:40 +03:00
Jiiks 640f1a5930 1.70
New plugin/theme listtings, 24hr timestamps, coloured text, new alert
window, public server list infinite scroll, 0.2.8 support and more
2016-05-06 21:31:28 +03:00
pohky 888bebbfb0 Update emotefilter.json 2016-05-06 12:59:12 +02:00
pohky be5f2cf70d Update emotedata_ffz 2016-05-06 11:28:35 +02:00
pohky 7087d174fa Update emotefilter.json 2016-05-06 11:27:34 +02:00
Jiiks b79775f82c Added try repeater and opendir 2016-05-05 13:04:21 +03:00
pohky 62684b80e7 Update emotefilter.json 2016-05-04 03:47:03 +02:00
pohky 725b0ce80e Update emotefilter.json 2016-05-03 18:38:20 +02:00
pohky b7a2cd30f9 Update emotefilter.json 2016-05-02 14:17:16 +02:00
pohky 30e2700fa6 Update emotefilter.json 2016-05-02 05:19:03 +02:00
pohky fb500bcfb5 Update emotefilter.json 2016-05-02 00:27:39 +02:00
pohky 18c11def46 Update emotefilter.json 2016-05-01 16:49:56 +02:00
pohky cb63744be6 Update emotefilter.json 2016-05-01 15:22:39 +02:00
pohky f0b3fb07b0 Update emotefilter.json 2016-05-01 15:18:20 +02:00
Jiiks 0fd8d3856f Public server list infinite scroll and changelog 2016-05-01 12:56:12 +03:00
pohky 2306ce740f Update emotefilter.json 2016-05-01 08:06:41 +02:00
pohky a723e0871d Merge pull request #292 from EhsanKia/bttv-update-april30
updated bttv database
2016-05-01 01:36:52 +02:00
Ehsan Kia a084e422d0 updated bttv database 2016-04-30 19:30:49 -04:00
pohky c7f19ddf06 Update emotefilter.json 2016-05-01 00:21:46 +02:00
Jiiks 9a087db3a8 0.2.8 config 2016-05-01 01:00:00 +03:00
Jiiks ab72fe0a0b 0.2.8 base 2016-05-01 00:57:21 +03:00
Jiiks a74827d515 Removed public server owner name 2016-05-01 00:26:59 +03:00
Jiiks 29303ea92a New alert modal and support for 0.2.8 vars 2016-05-01 00:25:14 +03:00
Jiiks 11f67dd4b7 Merge branch 'master' of https://github.com/Jiiks/BetterDiscordApp 2016-05-01 00:24:19 +03:00
Jiiks c8381267ed Updated alert id 2016-05-01 00:24:15 +03:00
pohky a4d83d07b1 Update emotefilter.json 2016-04-30 23:08:57 +02:00
Jiiks d85fd95050 Updated utils and 0.2.8 dev 2016-04-30 12:19:49 +03:00
Jiiks b556f0a7de Unusued 2016-04-30 10:53:20 +03:00
pohky 9e38ff567a Update emotefilter.json 2016-04-30 09:00:25 +02:00
Jiiks e35c003de8 Added "Okie" 2016-04-30 06:27:47 +03:00
pohky fc711076cd Update emotefilter.json 2016-04-30 01:34:15 +02:00
pohky 6c2d7ab661 Update emotefilter.json 2016-04-29 20:54:14 +02:00
pohky 06f4c5d138 Update emotefilter.json 2016-04-29 10:35:06 +02:00
pohky aec51443eb Update emotedata_ffz.json and emotefilter.json 2016-04-29 00:24:25 +02:00
pohky 1b616b165a Add emote mod :bttv
emote mod to force use the BTTV emote version if one exists
2016-04-28 23:36:01 +02:00
pohky 9b6a982084 Update emotefilter.json 2016-04-28 02:04:51 +02:00
pohky c2adc2ebe2 Update emotefilter.json 2016-04-27 23:50:39 +02:00
pohky d34f72b4e2 Update emotefilter.json 2016-04-27 23:45:38 +02:00
pohky e93f084a6c Changed emote priority 2016-04-27 16:30:06 +02:00
pohky c83021cc05 Update emotefilter.json 2016-04-27 12:43:41 +02:00
pohky d105bfd289 Update emotefilter.json 2016-04-27 10:04:24 +02:00
pohky abc0f0b469 Update emotefilter.json 2016-04-26 06:29:27 +02:00
pohky 7476810154 Update emotefilter.json 2016-04-25 17:43:07 +02:00
pohky c07d7fd638 Update emotefilter.json 2016-04-25 05:56:58 +02:00
pohky 5de975f188 Update emotefilter.json 2016-04-25 01:01:56 +02:00
pohky 98da9248c4 Update emotefilter.json 2016-04-24 19:44:30 +02:00
pohky 842aff647b Update emotefilter.json 2016-04-24 11:27:02 +02:00
pohky cb5898ae0c Update emotefilter.json 2016-04-24 08:41:20 +02:00
pohky 10d47be03c Update emotefilter.json 2016-04-24 08:41:05 +02:00
pohky ed558448d3 Update emotefilter.json 2016-04-23 16:00:39 +02:00
Jiiks 8a11655dcf Mhm 2016-04-23 12:10:12 +03:00
pohky fe3352dd5f Update emotefilter.json 2016-04-23 05:33:35 +02:00
pohky 0590a25562 Update emotedata_ffz.json
db update
2016-04-23 00:27:40 +02:00
pohky 799ca59b0c Update emotedata_ffz
db update
2016-04-21 07:22:11 +02:00
pohky 1f674d3968 Update emotefilter.json 2016-04-21 05:39:06 +02:00
pohky 213083ef1e Update emotedata_ffz.json
db update
2016-04-21 05:37:57 +02:00
pohky e9c2d6a19a Merge pull request #287 from EhsanKia/bttv-update-420
new bttv db update
2016-04-21 05:36:43 +02:00
Ehsan Kia fe7fe345d7 new bttv db update 2016-04-20 23:15:51 -04:00
pohky a54777afcf Update emotefilter.json 2016-04-21 02:06:36 +02:00
Jiiks 639655412d devp 2016-04-20 22:54:25 +03:00
Jiiks c517ef6c3b Removed old debugs 2016-04-20 22:52:26 +03:00
pohky 3f98486e92 Update emotefilter.json 2016-04-20 20:26:11 +02:00
Jiiks 51ac3ab4ad Addded support link 2016-04-20 18:03:16 +03:00
Jiiks ce83b1ce25 Error modal 2016-04-20 17:57:13 +03:00
Jiiks 2fd5667b3d Changed logger format 2016-04-20 14:10:37 +03:00
pohky 23ec794f07 Update emotefilter.json 2016-04-20 02:42:01 +02:00
pohky ea8bf70e53 Update emotefilter.json 2016-04-20 02:37:43 +02:00
pohky 8b421a04f0 Update emotefilter.json 2016-04-19 22:28:29 +02:00
pohky 7e9024d658 Update emotefilter.json 2016-04-19 04:23:55 +02:00
pohky 4b21053bb2 Update emotefilter.json 2016-04-19 03:18:57 +02:00
Jiiks 7be821f9a5 Revert changes for now 2016-04-18 14:00:33 +03:00
Jiiks 9d50d8c1c8 Added my dev folders to ignore 2016-04-18 13:56:31 +03:00
pohky 80049a375e Update emotefilter.json 2016-04-18 09:07:45 +02:00
pohky 015e22e0ce Update emotefilter.json 2016-04-18 09:01:15 +02:00
pohky fa205cf7c6 Update emotefilter.json 2016-04-18 09:00:33 +02:00
pohky d7b3e10658 Update emotefilter.json 2016-04-18 03:03:16 +02:00
pohky 8a7b7e50f1 Update emotefilter.json 2016-04-17 20:16:10 +02:00
pohky aabd6ef947 Update emotefilter.json 2016-04-17 20:15:19 +02:00
pohky 87e978e13b Update emotefilter.json 2016-04-17 15:14:17 +02:00
pohky f10b01e14c Update emotedata_ffz.json
db update
2016-04-17 10:41:11 +02:00
pohky 8fb9175654 Merge pull request #285 from EhsanKia/bttv-update-april17
bttv db update
2016-04-17 10:09:36 +02:00
Ehsan Kia 428f6e0510 bttv db update 2016-04-17 03:13:34 -04:00
pohky abb257cf8f Update emotefilter.json 2016-04-17 01:29:01 +02:00
pohky be1ae216d3 Update emotefilter.json 2016-04-16 19:40:30 +02:00
pohky f65d224cec Update emotefilter.json 2016-04-16 02:34:26 +02:00
Jiiks 4faea66bff 24 hour timestamps 2016-04-15 21:30:34 +03:00
pohky 2c1dc27265 Update emotedata_ffz.json 2016-04-14 23:48:48 +02:00
pohky 6b8fe6b5dc Update emotedata_ffz.json 2016-04-14 22:44:54 +02:00
pohky 7a8db351a1 Update emotefilter.json 2016-04-14 18:49:48 +02:00
pohky d3302e5286 Update emotefilter.json 2016-04-14 04:24:19 +02:00
pohky 1b3f159119 Update emotefilter.json
filtered out not needed blacklisted words
2016-04-14 04:21:31 +02:00
pohky 8bbc236302 Update emotedata_ffz.json
update
2016-04-14 04:09:40 +02:00
pohky 3f6296e867 Update emotefilter.json 2016-04-14 03:16:35 +02:00
pohky 27fece2e1e Update emotefilter.json 2016-04-14 02:40:30 +02:00
pohky 44aa9b6268 Update emotefilter.json 2016-04-14 02:30:36 +02:00
pohky cab9a609bf Update emotefilter.json 2016-04-13 08:47:53 +02:00
pohky e76468c2fb Update emotefilter.json 2016-04-13 00:33:38 +02:00
pohky e9023272a8 Update emotefilter.json 2016-04-12 23:53:51 +02:00
pohky aba679eb58 Update emotefilter.json
added BOOP
2016-04-12 19:50:21 +02:00
Jiiks 1ceef37b7b Added Grrr 2016-04-12 18:00:46 +03:00
pohky 5beab21b7c Update emotedata_ffz.json
removed KKona
2016-04-12 07:43:38 +02:00
pohky 3322a5ada9 Update emotefilter.json 2016-04-12 03:13:13 +02:00
pohky 037333e8de Update emotefilter.json 2016-04-12 01:02:34 +02:00
pohky b09a10e07d Update emotefilter.json 2016-04-11 23:16:31 +02:00
pohky 90edc67d8e Update emotefilter.json 2016-04-11 23:06:36 +02:00
pohky f6312eee85 Update emotefilter.json 2016-04-11 19:07:22 +02:00
pohky d5aebb5a72 Update emotefilter.json 2016-04-11 17:52:09 +02:00
Jiiks ea9808f12d Initialize favoriteEmotes 2016-04-11 12:57:04 +03:00
Jiiks 325584372f Rewrites 2016-04-11 11:17:56 +03:00
Jiiks 3a365f30ed Core rewrite 2016-04-11 11:10:25 +03:00
Jiiks 8a15d57e39 Renaming and updated gruntfile 2016-04-11 10:41:17 +03:00
Jiiks 12122cc2cd Merge branch 'master' of https://github.com/Jiiks/BetterDiscordApp 2016-04-11 10:34:36 +03:00
Jiiks 6c3955c9d8 Settings 2016-04-11 10:34:32 +03:00
pohky 1e081df2b1 Update emotedata_ffz.json
big update, should fix most issues
2016-04-11 06:40:02 +02:00
Jiiks ae10fa9542 Rename to retain order 2016-04-10 16:31:20 +03:00
Jiiks c9afc3d0d4 Remove unused devmain.js 2016-04-10 16:25:34 +03:00
Jiiks 46de429953 Moved everything under dev 2016-04-10 16:24:00 +03:00
Jiiks 3b657daffa Dev dependancies and Gruntfile 2016-04-10 16:22:47 +03:00
Jiiks 31607f11e8 Updated gitignore 2016-04-10 16:21:42 +03:00
Jiiks 3821077eaf Updated separated files 2016-04-10 15:43:27 +03:00
Jiiks 659dc085fd Separate core settings from emote settings 2016-04-09 22:56:29 +03:00
Jiiks 97bbc0f3d2 Updated readme 2016-04-09 21:33:48 +03:00
Jiiks 8e4d0b68f9 Merge branch 'master' of https://github.com/Jiiks/BetterDiscordApp 2016-04-09 21:32:49 +03:00
Jiiks 151428d0e2 Updated readme info for 0.2.8 2016-04-09 21:32:43 +03:00
pohky fd556b0ecb Update emotedata_ffz.json 2016-04-09 20:14:46 +02:00
pohky 79c3ff7579 Update emotedata_ffz.json 2016-04-09 20:11:11 +02:00
pohky c6d6c97ef6 Updated emotedata_ffz.json
big emote fix
2016-04-09 20:04:30 +02:00
pohky c139628a69 Update emotefilter.json
added NOICE
2016-04-09 18:09:38 +02:00
Jiiks 1d41646acc Merge pull request #279 from DeathStrikeV/master
Added "Derp" to emotefilter.json
2016-04-09 16:14:24 +03:00
Jiiks e7b74ccd15 Dark mode update 2016-04-09 15:59:31 +03:00
Jiiks 52489b6e0a v1.63 dark mode 2016-04-09 15:52:07 +03:00
DeathStrikeV 2f0dab4dca Added Derp to emotefilter.json 2016-04-09 10:51:47 +01:00
Alex 4d6467b1e0 Merge pull request #1 from Jiiks/master
Rebase branch
2016-04-09 10:46:58 +01:00
pohky 74db61eed3 Update emotedata_ffz.json
id fix
2016-04-09 09:40:56 +02:00
Jiiks 5cd211333d Typo in changelogs 2016-04-09 09:22:16 +03:00
Jiiks 3b58822088 Added missing changelog description 2016-04-09 09:06:15 +03:00
Jiiks 7cbfc6f19a v1.62 Css fixes and new emote menu 2016-04-09 09:04:39 +03:00
pohky 4ad2fa5c38 Update emotedata_ffz.json
remove FeelsGoodMan
2016-04-09 07:14:43 +02:00
pohky cb8f98e9a6 Update emotedata_ffz.json 2016-04-09 07:02:22 +02:00
Jiiks 8ceea67da1 Added min-width 2016-04-08 20:52:57 +03:00
Jiiks 6397c1e527 Added clock plugin 2016-04-08 20:50:44 +03:00
pohky c537e541e6 Update emotefilter.json 2016-04-08 09:52:11 +02:00
pohky 95fd50d141 Merge pull request #277 from EhsanKia/bttv-update-april7
Big BTTV database update
2016-04-08 07:50:31 +02:00
Ehsan Kia f001b44146 big bttv database update 2016-04-07 20:42:19 -04:00
Jiiks a478c362fa JSv1.61
New CSS editor and auto voice disconnect on exit by Pohky
2016-04-08 01:21:30 +03:00
Jiiks 797c37b623 Remove and archive serverlist 2016-04-07 17:01:24 +03:00
Jiiks 753f2240dc Updated readme
Fixed a typo and added EhsanKia to credits
2016-04-07 16:39:25 +03:00
Jiiks 47bf32fb8b Fixed a scope issue 2016-04-07 15:24:02 +03:00
Jiiks 2a8175e119 Fixed an issue with public server button not appearing at all 2016-04-07 15:22:33 +03:00
Jiiks 480254aedc JS v1.6 and updated readme 2016-04-07 15:08:25 +03:00
pohky 14eedbb26c Update emotefilter.json 2016-04-07 03:15:23 +02:00
pohky e6ddddd7c5 Update emotedata_ffz.json 2016-04-07 01:14:50 +02:00
pohky e24c78304f Update emotefilter.json 2016-04-06 23:58:31 +02:00
pohky 6b9fc31d80 Updated emotedata_ffz.json
removed emotes requested by EhsanKia
2016-04-06 22:04:30 +02:00
pohky e29e1935a6 Update emotefilter.json 2016-04-06 16:32:06 +02:00
pohky 956b434a20 Update emotefilter.json 2016-04-06 15:01:11 +02:00
Jiiks 9eba040264 Remove debug 2016-04-06 05:09:33 +03:00
Jiiks d214a5909c Emote blacklist plugin 2016-04-06 05:07:44 +03:00
Jiiks 19150649d6 Double click edit plugin 2016-04-06 02:46:26 +03:00
pohky 1b91804142 Merge pull request #268 from Raygius/patch-8
Update emotefilter.json
2016-04-06 00:53:50 +02:00
Jiiks 4fc642cae1 Removed a console.log 2016-04-06 00:44:32 +03:00
Raygius 581452098a Update emotefilter.json
Pokeball and Pokeball are annoying
and we have enough of these balls already. (pokeBall , PokeBallz , PokeBALL , PokeballGo)
2016-04-05 18:47:34 +02:00
pohky be32d5c1ff Update emotedata_ffz.json
removed bttv duplicates
2016-04-05 16:51:56 +02:00
pohky 422e5e786f Update emotefilter.json 2016-04-05 14:38:44 +02:00
pohky 14925e3a60 Update emotefilter.json
added Asuna
2016-04-05 13:54:34 +02:00
pohky cceaec68fa Update serverlist.json 2016-04-05 13:29:21 +02:00
pohky d73145409a Update emotedata_ffz.json
ID fixes
2016-04-05 07:46:51 +02:00
pohky 7dab7741fa Update emotedata_ffz.json
Added RoryCoy request
2016-04-04 23:00:57 +02:00
pohky c46515954f Update emotedata_ffz.json
Updated IDs
2016-04-04 22:11:59 +02:00
Jiiks 6c496b1898 JS 1.59
Plugin MutationObserver callback, new emote mods, minimal mode css, sub
emote mods https://github.com/Jiiks/BetterDiscordApp/pull/260
2016-04-04 17:22:53 +03:00
Jiiks 028d279cae Added Herro 2016-04-04 16:08:42 +03:00
Jiiks 870778b21d Merge pull request #266 from SkyWielder/patch-3
Update serverlist.json
2016-04-04 16:08:24 +03:00
SkyWielder a84b23c9e4 Update serverlist.json 2016-04-04 08:54:31 -04:00
Jiiks efc22eef6d Added Dante and Moin https://github.com/Jiiks/BetterDiscordApp/pull/262 2016-04-04 15:48:59 +03:00
Jiiks 7533169b35 Added https://github.com/Jiiks/BetterDiscordApp/pull/263 2016-04-04 15:47:07 +03:00
Jiiks 4e521f09fc Merge pull request #264 from Galios/patch-1
Update serverlist.json
2016-04-04 15:45:03 +03:00
Jiiks b08a8f44a4 Merge pull request #253 from ILM126/patch-1
Added "Space Enthusiasts" and "Unreal Gaming"
2016-04-04 15:42:58 +03:00
pohky 6d9299d247 Update emotefilter.json 2016-04-04 01:25:28 +02:00
Galios 052027a87f Update serverlist.json 2016-04-03 15:24:24 -04:00
pohky a24492ccf7 Update emotefilter.json 2016-04-03 11:23:00 +02:00
pohky 48b6fdba91 Update emotefilter.json 2016-04-03 11:15:30 +02:00
pohky 3b8e41d914 Update emotefilter.json 2016-04-03 05:49:31 +02:00
pohky 5519e89df6 Update emotefilter.json 2016-04-03 05:37:47 +02:00
pohky c7be04cfc2 Update emotefilter.json 2016-04-03 05:26:02 +02:00
pohky 3ffa686b47 Update emotefilter.json 2016-04-03 04:53:56 +02:00
pohky de2acfd6d9 Update emotedata_ffz.json 2016-04-03 04:40:58 +02:00
pohky 342c3e07ca Update emotefilter.json 2016-04-03 04:31:39 +02:00
pohky 025b634bf2 Update emotedata_ffz.json 2016-04-03 04:07:33 +02:00
pohky 1d1c816696 Update emotedata_ffz.json
rename POI to POIPOI
2016-04-03 03:29:59 +02:00
Jiiks 0eb921b303 Fixed emote blacklist and added new emote modifiers 2016-04-03 02:47:11 +03:00
pohky 8d083ccc5c Update emotefilter.json 2016-04-02 22:51:13 +02:00
pohky 90165f020b Merge pull request #258 from Raygius/patch-7
Update emotefilter.json
2016-04-02 21:19:32 +02:00
Raygius 6ba126de6e Update emotefilter.json 2016-04-02 20:41:41 +02:00
Raygius f479f636b5 Update emotefilter.json 2016-04-02 19:56:19 +02:00
pohky a88d6c9ee8 Update emotefilter.json 2016-04-02 19:21:03 +02:00
pohky d7f936321e Update emotedata_ffz.json
changed OhMy
2016-04-02 18:58:43 +02:00
pohky a1283bf4f6 Update emotefilter.json 2016-04-02 18:50:02 +02:00
pohky 730d9e04e9 Update emotefilter.json 2016-04-02 18:46:22 +02:00
pohky ba0d089c13 Update emotefilter.json 2016-04-02 18:39:09 +02:00
pohky 20a50d39a8 Updated emotedata_ffz.json 2016-04-02 18:24:27 +02:00
pohky be39955f2d Update emotefilter.json 2016-04-02 17:17:11 +02:00
pohky 31b0a7c783 Update emotedata_ffz.json
removed FeelsWeirdMan
2016-04-02 16:50:51 +02:00
Jiiks c6990352db Added Bella and Jaxx 2016-04-02 14:51:02 +03:00
pohky af8519f7fe Update emotedata_ffz.json
id corrections
2016-04-02 11:08:12 +02:00
pohky a31a329f10 Update emotedata_ffz.json 2016-04-02 10:39:12 +02:00
Jiiks 6e350f440b Added option to disable emote mods 2016-04-02 10:56:19 +03:00
Jiiks 8047b953d1 Version info 1.58 2016-04-02 10:14:20 +03:00
Jiiks 78c7860c6c Added new modifiers 2016-04-02 08:53:39 +03:00
Jiiks f5953cf72e Fixed modified emote titles 2016-04-02 08:35:14 +03:00
Jiiks 536cfab145 Remove april fools and add emote suffixes 2016-04-02 08:23:35 +03:00
pohky 8f73d0ad10 Update emotefilter.json 2016-04-02 06:36:22 +02:00
pohky 90767d8fb5 Update emotefilter.json 2016-04-02 06:04:39 +02:00
Treble Sketch 51b0e0e5a3 Corrected the missing commas
Whoops, sorry about that ^^"
2016-04-02 14:26:35 +10:30
pohky b9e1b71c0f Update emotefilter.json 2016-04-02 03:14:36 +02:00
pohky dfa344756a Update emotedata_ffz.json
removed Yappa and KKona
2016-04-02 03:06:01 +02:00
pohky f576d5b816 Update emotefilter.json 2016-04-02 03:01:23 +02:00
pohky ae10fffecd Update emotefilter.json 2016-04-02 03:00:50 +02:00
pohky ec9804a9a9 Merge pull request #257 from EhsanKia/bttv-update-april1
bttv database update
2016-04-02 02:59:36 +02:00
Ehsan Kia cbc93dd6ae bttv database update 2016-04-01 20:57:01 -04:00
pohky df7e780ca1 Update emotefilter.json 2016-04-01 22:48:23 +02:00
pohky 9f3ad4b976 Update emotefilter.json 2016-04-01 18:40:36 +02:00
Jiiks 24d0fe5c56 Merge pull request #254 from ILM126/patch-2
Updated "Team Fortress 2" Server Code
2016-04-01 19:20:55 +03:00
pohky bd3979b7d3 Update ffz emotedata
remove FeelsGoodMan
2016-04-01 17:50:09 +02:00
Treble Sketch b8ab889d97 Updated "Team Fortress 2" Server Code
I guessed that the link submitted was a temp one XD
I think this is the permanent one for the server, I found it on a /r/TF2 [url=https://www.reddit.com/r/tf2/comments/4b51e5/introducing_the_official_rtf2_discord_server_and/]thread[/url]. So I'm sure that it is authentic.
2016-04-02 01:25:16 +10:30
Treble Sketch 67ffca5e5b Added "Space Enthusiasts" and "Unreal Gaming"
Both code are for infinite invites, but a few code I found in the list are not infinite and already expired.
I own "Space Enthusiasts", but a friend of mine owns "Unreal Gaming".
2016-04-02 01:17:14 +10:30
pohky e37f909fc2 Update emotedata_ffz.json
added uppercase emotes back
2016-04-01 01:33:33 +02:00
pohky 893440ae0a Update emotedata_ffz.json 2016-03-31 18:27:44 +02:00
pohky 35f0efa0e0 Update emotedata_ffz.json 2016-03-31 18:21:00 +02:00
pohky 6cb89d93d6 Updated emotedata_ffz.json 2016-03-31 18:02:08 +02:00
Jiiks 18dad0e83a Readme 2016-03-31 18:49:20 +03:00
pohky 4af669789c Update emotedata_ffz.json 2016-03-31 17:39:42 +02:00
pohky e8e30469e7 Merge pull request #249 from Eonfow/patch-2
update emotedata_ffz.json
2016-03-31 17:29:02 +02:00
Jiiks d17b1fe18f Merge pull request #250 from AraHaan/patch
Added Division and fixed the spacing/tabbing on some other servers.
2016-03-31 13:26:38 +03:00
AraHaan 3e78699c4f Added Division and fixed the spacing/tabbing on some other servers. 2016-03-31 05:08:54 -05:00
Jiiks f789547e5a Rename to plugin.js 2016-03-31 10:32:45 +03:00
Jiiks 688998114e Use Discord as the imagehost 2016-03-31 10:31:17 +03:00
Jiiks 3bf30d0790 http => https 2016-03-31 10:18:40 +03:00
Jiiks 76d0b7d9fc Working autogif plugin 2016-03-31 10:16:25 +03:00
Bruno de Moura Ribeiro 3d24701139 update emotedata_ffz.json
New emotes
2016-03-31 03:22:15 -03:00
pohky 66e30fd54e Update emotedata_ffz.json
added Bwendin's emotes
2016-03-31 03:34:41 +02:00
Jiiks 4ec4daedbc Merge pull request #247 from xiaolii/patch-1
adding leagueconnect to public server list
2016-03-30 19:48:52 +03:00
Jiiks 3f5f9fb0ad Merge pull request #246 from FierceFrankie/patch-1
Update serverlist.json
2016-03-30 19:48:40 +03:00
Jiiks aeae9529aa Merge pull request #245 from MissKiri/patch-2
Update serverlist.json
2016-03-30 19:48:27 +03:00
Jiiks 286db2d316 Minor fixed 2016-03-30 17:56:08 +03:00
pohky fc52d3dd6c Update emotedata_ffz,json
added grayyl's emotes
2016-03-30 14:24:22 +02:00
xiaolii f55d1a27ef adding leagueconnect to public server list 2016-03-30 05:48:29 +02:00
Jiiks c68a84ed03 Info 2016-03-30 04:47:40 +03:00
Jiiks b767f9b4f7 Correct name 2016-03-30 04:44:38 +03:00
Jiiks fd07b37bc7 Video support plugin with support for mp3 and wav 2016-03-30 04:43:55 +03:00
Jiiks 51b1913ab1 0.2.7 2016-03-30 04:37:03 +03:00
Jiiks 2e914032ed 0.2.7 updater 2016-03-30 04:09:10 +03:00
Jiiks 3f61dc0928 Twitch emotedata 2016-03-30 04:08:18 +03:00
Jiiks 3f6c51b046 Use .message instead of .message-group 2016-03-29 02:54:46 +03:00
Jiiks e2112c73c2 Add a timeout 2016-03-29 02:44:55 +03:00
Jiiks 3dcacb5199 Use a simple video tag 2016-03-29 02:42:35 +03:00
Jiiks e2c4546ca8 Don't replace http in https with https 2016-03-29 02:40:51 +03:00
Jiiks 066a8789e9 http => https check 2016-03-29 02:39:27 +03:00
Jiiks bd1274cf92 Add .ogg check 2016-03-29 02:35:51 +03:00
Jiiks 31fc14aa5c HTML5 Video Plugin
Adds support for embedding video
2016-03-29 02:34:46 +03:00
FierceFrankie 88729d94ce Update serverlist.json
Added my server.
2016-03-28 11:43:05 -06:00
MissKiri 504224f4fa Update serverlist.json 2016-03-28 10:30:47 -07:00
Jiiks 35ff38638c Fixed missing " and } 2016-03-28 12:21:57 +03:00
Jiiks 0d9728b26f Added server 2016-03-28 12:19:54 +03:00
Jiiks a8fb3b73d2 Merge pull request #241 from GarettM/patch-3
Update serverlist.json
2016-03-28 12:15:57 +03:00
Jiiks 5a7ec4f0f8 Merge pull request #234 from Forcellrus/patch-1
Added World of Tanks server
2016-03-28 12:12:53 +03:00
Jiiks a1c868fe6c Merge pull request #237 from MissKiri/patch-1
Added Kiri's Bubble
2016-03-28 12:12:32 +03:00
pohky 9d27626ad1 Merge pull request #243 from EhsanKia/bttv-update-march27
BTTV emote db update
2016-03-27 18:48:03 +02:00
Ehsan Kia a8f8106d41 BTTV emote db update 2016-03-27 10:25:24 -04:00
Garett c479e59966 Update serverlist.json
previous owned server marimonda no longer exists, added new server
2016-03-25 13:32:18 -04:00
MissKiri fa37d4515a Update serverlist.json 2016-03-24 07:19:25 -07:00
MissKiri 821c5444c0 Update serverlist.json 2016-03-24 07:18:37 -07:00
MissKiri feaef6224d Update serverlist.json 2016-03-23 14:45:10 -07:00
Forcellrus 633135aee7 Update serverlist.json 2016-03-21 19:24:30 +01:00
Forcellrus 21058ab993 Added World of Tanks server 2016-03-21 19:17:53 +01:00
pohky 3770edc13a Merge pull request #230 from keyphact/patch-1
Updated serverlist.json
2016-03-20 16:53:53 +01:00
pohky b62eaab1d9 Merge pull request #232 from EhsanKia/bttv-update-march20
Update bttv emote database
2016-03-20 16:53:11 +01:00
Ehsan Kia d2fd44a406 Update bttv emote database 2016-03-20 10:23:02 -04:00
KeyPhact Moon cdf7b262ed Updated serverlist.json
Added in server for PSO2.
2016-03-20 00:58:01 +00:00
pohky caf0ae0f35 Update emotedata_ffz.json 2016-03-15 11:05:26 +01:00
pohky 76c9b62ba9 Update serverlist.json
requests from
-HK-LooKAqui
GarettM
sadozin
2016-03-14 03:33:48 +01:00
pohky 463f843789 Merge pull request #224 from unforgivingmorsecode/patch-5
Update serverlist.json
2016-03-13 07:37:20 +01:00
pohky 61824516a9 Merge pull request #223 from EhsanKia/bttv-update-march12
update bttv emotes
2016-03-13 07:36:36 +01:00
unforgivingmorsecode 8a1e77755e Update serverlist.json 2016-03-12 20:57:35 -06:00
Ehsan Kia 4443d909a9 update bttv emotes 2016-03-12 21:55:28 -05:00
pohky b4114b3115 Update emotefilter.json 2016-03-12 07:32:26 +01:00
pohky 97cb511480 Merge pull request #222 from GarettM/patch-1
Update serverlist.json
2016-03-12 07:30:40 +01:00
GarettM 8b86322434 Update serverlist.json
added

    "Marimonda Gaming": {
      "code": "0b0XbRZUIQGnkit6",
      "description": "Marimonda Gaming Community",
      "icon": null,
      "language": "EN",
      "title": "Marimonda Gaming"
2016-03-11 19:12:14 -05:00
Jiiks 256c2fdad7 Indent 2016-03-11 17:38:55 +02:00
Jiiks a5c27caacf Indent? 2016-03-11 17:38:06 +02:00
Jiiks 4111949cbc Merge branch 'master' of https://github.com/Jiiks/BetterDiscordApp 2016-03-11 17:36:12 +02:00
Jiiks b9c7787465 Disabled customgame and added custom role colour plugin 2016-03-11 17:36:04 +02:00
pohky 9b5f7d7f6b Update emotedata_ffz.json 2016-03-11 10:15:23 +01:00
pohky b654bc2003 Update emotefilter.json 2016-03-10 15:45:54 +01:00
pohky 51076d872e Update serverlist.json
added "Dirty Bomb" server
2016-03-09 21:08:39 +01:00
pohky 8626654559 Update emotedata_ffz.json
added Faux emotes
2016-03-08 22:41:02 +01:00
pohky db548c1a26 Update emotedata_ffz.json 2016-03-08 22:22:31 +01:00
pohky b641c17932 Update emotedata_ffz.json
krait emotes
2016-03-08 22:21:17 +01:00
pohky 321d482b9f Update serverlist.json
removed server "FRENCH" - invalid invite code
2016-03-08 09:08:37 +01:00
pohky a6a2f84a65 Merge pull request #216 from EhsanKia/bttv-update-march7
Weekly bttv db update
2016-03-08 09:05:13 +01:00
Ehsan Kia 91194c204f Weekly bttv db update 2016-03-07 15:20:33 -05:00
pohky 00b72c6436 Update emotedata_ffz.json
fixed KrunsHello
2016-03-07 18:40:07 +01:00
pohky 9b193ef14b Update serverlist.json 2016-03-07 17:45:35 +01:00
pohky 32a1f4a298 Update emotedata_ffz.json
KongouWot new id
2016-03-06 00:48:15 +01:00
pohky d0f8bec1d4 Update serverlist.json
added some requests manually
2016-03-05 06:48:36 +01:00
pohky 8acab48afd Update emote injection
changed the order of the injection to prio sub emotes over bttv and ffz
emotes
2016-03-05 06:19:10 +01:00
pohky 83ad1a6dc9 Update emotedata_ffz.json
Gumi -> kGumi
2016-03-05 05:20:12 +01:00
pohky cdef86f518 Merge pull request #213 from isackender/patch-1
Add server
2016-03-04 15:42:39 +01:00
Isackender ecb1794afe Update serverlist.json 2016-03-04 14:39:59 +01:00
pohky c4f7539a79 Merge pull request #212 from Kwoth/patch-1
Update serverlist.json
2016-03-04 14:18:54 +01:00
Master Kwoth af08e9969b Update serverlist.json 2016-03-04 14:16:26 +01:00
pohky d807811c9d Update serverlist.json 2016-03-04 13:43:09 +01:00
pohky d8776e50be Merge pull request #210 from CactusNugget/patch-2
Update serverlist.json
2016-03-04 13:36:57 +01:00
CactusNugget 267970883c Update serverlist.json 2016-03-04 21:22:05 +11:00
pohky 885920788b Update serverlist.json 2016-03-04 10:41:30 +01:00
pohky 9f4c9a8f42 Update README.md 2016-03-04 06:35:23 +01:00
pohky 87511e089f Updated emotedata_ffz.json 2016-03-03 04:10:11 +01:00
pohky dfc93d7ad5 Updated emotes
removed BabyMage from bttv for usage of the ffz version
added ALittleHead to ffz
2016-03-03 04:06:47 +01:00
pohky 7318f9a208 Update serverlist.json 2016-03-03 01:52:41 +01:00
pohky 25e413ac7d Merge pull request #207 from Nisserino/patch-1
Update serverlist.json
2016-03-03 01:49:08 +01:00
Nisserino c20fd9fc77 Update serverlist.json 2016-03-02 17:44:08 +01:00
pohky 15f9a17d5d Update emotedata_ffz.json
removed WanWan
2016-03-02 05:10:14 +01:00
pohky 302934698b Merge pull request #205 from EhsanKia/bttv-update-feb29
Weekly update of BTTV emote database
2016-02-29 19:39:06 +01:00
Ehsan Kia 83b8b26d36 Weekly update of BTTV emote database 2016-02-29 13:18:15 -05:00
pohky d3bd15c1fe Update emotefilter.json 2016-02-27 05:28:46 +01:00
pohky b7f79b2cd8 Update emotedata_ffz.json 2016-02-26 15:06:11 +01:00
pohky d15fcd1ca9 Update emotedata_ffz.json 2016-02-26 15:03:48 +01:00
pohky 346c68ac61 Update emotedata_ffz.json 2016-02-26 15:01:23 +01:00
pohky cae03de77d Merge pull request #201 from Raygius/patch-5
Update emotedata_ffz.json
2016-02-26 14:58:53 +01:00
Raygius a32e4cfb1f Update emotedata_ffz.json
Updated ID
2016-02-26 05:23:40 +01:00
Jiiks a441072751 Readd emotes 2016-02-25 21:53:43 +02:00
Jiiks 496d984c2a Reload 2016-02-25 21:52:03 +02:00
Jiiks c441936005 Reload 2016-02-25 21:51:48 +02:00
Jiiks 362a5e3d40 Revert 2016-02-25 21:48:08 +02:00
Jiiks 486f98d1e9 Remove newline 2016-02-25 21:47:00 +02:00
Jiiks 712c1655d9 Revert "Remove newline"
This reverts commit 9336247180.
2016-02-25 21:45:34 +02:00
Jiiks 9336247180 Remove newline 2016-02-25 21:13:51 +02:00
pohky e9f79c382f Merge pull request #199 from TopBunk/patch-2
Added some FFZ emotes
2016-02-25 15:46:24 +01:00
TopBunk 943986954e Added some FFZ emotes
Emotes: AkaneHappy, AkaneKappa, AkaneMmm, AkaneOh, AkanePuppy, AkaneShy, AyakaLewd, KayoJi
2016-02-25 03:18:20 -06:00
Jiiks b0cfc3bb00 Update typingsound.plugin.js 2016-02-23 08:49:09 +02:00
Jiiks 1ea96f9da8 Typing sounds 2016-02-23 08:45:50 +02:00
pohky 3c276a84e0 Merge pull request #194 from EhsanKia/bttv-emote-feb20
Updated BTTV emote database
2016-02-21 02:05:36 +01:00
Ehsan Kia 1795c5e6cb Updated BTTV emote database 2016-02-20 17:52:10 -05:00
Jiiks ef265b8962 Fix id 2016-02-18 08:32:54 +02:00
pohky 44b2f66695 Merge pull request #190 from EhsanKia/bttv-update-feb14
Added 657 new shared emotes
2016-02-14 19:12:58 +01:00
Ehsan Kia e17709dcb8 Added 657 new shared emotes 2016-02-14 00:39:59 -05:00
Jiiks 9dcf8ff17e Merge pull request #189 from jzanutto/master
Fixed OSX installer issues
2016-02-14 03:26:30 +02:00
jzanutto 6f3026fff5 Fixed installer issues
- Moved app.asar extraction before BetterDiscord directory mv
- Fixed issue with errors being thrown by installer when emote files did
  not exist in library preferences directory
2016-02-13 20:03:20 -05:00
pohky 4cab5e6067 Update emotedata_ffz.json 2016-02-13 05:45:43 +01:00
pohky 3106504ef4 Update emotefilter.json 2016-02-13 05:37:36 +01:00
Jiiks f62b53866d Merge pull request #184 from iVEnoVaLue/master
Fixed installer for Discord, PTB, Canary
2016-02-13 04:15:13 +02:00
Jiiks 53d9a81849 Disable ws pending for fix 2016-02-12 21:35:12 +02:00
Jiiks 7d4244e1cb Node installer for 0.2.6 | Discord 0.0.284 2016-02-12 19:04:35 +02:00
ivenovalue bf8ab019c6 Changed the sequence of actions. 2016-02-11 20:00:33 +01:00
ivenovalue 95871691a0 Check for app.asar file 2016-02-11 19:47:34 +01:00
ivenovalue 069fb6b05b Fixed installer for Discord, PTB, Canary 2016-02-11 17:09:56 +01:00
Jiiks bcf4867474 Merge pull request #175 from SydneyAoi/patch-1
Update serverlist.json
2016-02-10 07:02:18 +02:00
Jiiks 5b5cacc0f3 Merge pull request #174 from lecomonad/patch-3
Add Kancolle server to serverlist.json
2016-02-10 07:01:58 +02:00
Jiiks 3c843ada58 Merge pull request #171 from cosmicsalad/patch-1
Updated serverlist.json
2016-02-10 07:01:45 +02:00
Jiiks d439923678 Update updater latest version 2016-02-10 04:35:05 +02:00
Jiiks 532776a696 Latest asar.net, added emotecache deletion 2016-02-10 04:27:04 +02:00
Jiiks dc708de857 Latest asar.net 2016-02-10 04:12:46 +02:00
Jiiks 8b30e1df10 Version 0.2.6 2016-02-10 04:11:54 +02:00
Jiiks ed6993cc08 Remove https from twitchemotes domain 2016-02-10 04:09:44 +02:00
Jiiks b18a22e83d Use https for twitchemotes.com api 2016-02-10 04:04:44 +02:00
Jiiks 14061f2c1e Update splices and add offset 2016-02-10 04:03:52 +02:00
Jiiks 9090a41341 Autogif 2016-02-09 19:17:47 +02:00
Jiiks 24f556d31b Gif autoplayer 2016-02-09 19:08:20 +02:00
pohky c926443540 Merge pull request #177 from EhsanKia/bttv-update-feb7
Updated BTTV emote database
2016-02-08 07:42:13 +01:00
Jiiks dd1075879f Temp fix 2016-02-08 00:46:09 +02:00
Jiiks 9694e11137 Add twitch sub data 2016-02-08 00:43:30 +02:00
Jiiks e9f1af2530 Add twitch emotes to github 2016-02-08 00:39:03 +02:00
Ehsan Kia 1a4e5398d6 Updated BTTV emote database 2016-02-07 06:35:40 -05:00
SydneyAoi 90fbaa4885 Update serverlist.json 2016-02-05 14:05:04 -07:00
lecomonad 8bcbb5ec8f Add Kancolle server to serverlist.json 2016-02-05 10:25:33 -05:00
pohky 670ccf603c Updated emotedata_ffz.json
added Breefree
2016-02-05 03:23:45 +01:00
Jiiks 8d2af8186b Merge pull request #172 from AraHaan/Installer-Updates
Updated Installer See Commits for Details.
2016-02-03 02:38:14 +02:00
AraHaan 1cb8b8ab3a Added some more files to be able to Build. 2016-02-02 18:26:50 -06:00
AraHaan 07d1ce7c17 Removed Dupe Icon file. 2016-02-02 18:22:27 -06:00
AraHaan 40262cd068 Updated Installer with 2 New options and fixed PTB Installing for latest Build 2016-02-02 18:21:52 -06:00
Andrew Filip 86b1059406 Updated serverlist.json - Fifa desc 2016-02-02 15:59:23 -08:00
Andrew Filip d6b0a5994b Updated serverlist.json 2016-02-02 14:59:41 -08:00
Jiiks df542fe3c9 Merge pull request #166 from EhsanKia/bttv-update-jan30
weekly BTTV database update (January 30)
2016-02-02 02:14:27 +02:00
Jiiks e70ab32780 Add missing } 2016-02-02 02:10:06 +02:00
Jiiks 7a693d33b6 Merge pull request #167 from RinkuTalks/patch-2
Update serverlist.json
2016-02-02 02:08:46 +02:00
Jiiks 10c97ad59e Merge pull request #165 from unforgivingmorsecode/patch-4
Update serverlist.json
2016-02-02 02:08:38 +02:00
Jiiks c82d38fd97 Merge pull request #164 from FlashDeviant/patch-1
Update serverlist.json
2016-02-02 02:08:32 +02:00
Jiiks 4b885483d3 Merge pull request #163 from thefiz/patch-1
Update serverlist.json
2016-02-02 02:08:24 +02:00
Jiiks 88a75f5c2b Merge pull request #160 from wedidntnamethisatall/patch-1
Update serverlist.json
2016-02-02 02:08:15 +02:00
Jiiks 09b75c984c Merge pull request #159 from unforgivingmorsecode/patch-3
Update serverlist.json
2016-02-02 02:08:00 +02:00
Jiiks 288b401b26 Merge pull request #162 from AraHaan/patch-1
Updated the Installer
2016-02-02 01:10:27 +02:00
Ehsan Kia 37e4c725b5 Another quick update 2016-02-01 07:09:56 -05:00
AraHaan 9d1a2f1302 Got PTB installing finally working yay. 2016-01-31 21:23:10 -06:00
RinkuTalks efeb191da2 Update serverlist.json 2016-01-31 09:37:48 -08:00
Ehsan Kia 5a4f6b447c weekly BTTV database update (January 30) 2016-01-30 00:58:40 -05:00
unforgivingmorsecode 6086040aa8 Update serverlist.json 2016-01-29 13:23:51 -06:00
Flash Deviant e74cd1da3e Update serverlist.json
Added The Deviant Network server to the list
2016-01-28 22:54:24 +00:00
AraHaan 3c0f1e8b3d Forgot to remove the Break
Forgot to remove the Break in the DiscordPTB part of the Task Terminator so that it would terminate all 3 instances of DiscordPTB.exe and yes it is normal for this.
2016-01-28 16:39:37 -06:00
thefiz 6a8dace6f6 Update serverlist.json
Added Server
2016-01-28 03:17:28 -05:00
AraHaan 1bf8127ebe Update README.md 2016-01-28 01:32:45 -06:00
AraHaan e913998453 Update App.manifest 2016-01-28 01:30:25 -06:00
AraHaan c4b855d7c5 Updated Installer stuff. 2016-01-28 01:26:47 -06:00
AraHaan 6a0df69964 Updated the Installer and some other files. 2016-01-28 01:26:43 -06:00
AraHaan c9711b6763 Update README.md 2016-01-28 01:14:25 -06:00
Jiiks b1478b2dc1 Url fi 2016-01-27 09:31:56 +02:00
Jiiks aeabee9c25 Remove autojoin and add disclaimer 2016-01-27 09:30:57 +02:00
wedidntnamethisatall d79b85f66d Update serverlist.json 2016-01-26 18:47:58 -08:00
unforgivingmorsecode 58b7a1e9c0 Update serverlist.json 2016-01-26 20:37:01 -06:00
pohky f5b5d2a7cc Merge pull request #158 from SomecallmeSarge/patch-1
Update serverlist.json
2016-01-27 00:21:01 +01:00
SomecallmeSarge 74ec2be036 Update serverlist.json 2016-01-26 14:08:47 -05:00
pohky 5623a604d5 Merge pull request #156 from OitoYuuki/patch-1
Add my Undertale RP server please
2016-01-26 03:31:04 +01:00
OitoYuuki 2ea87a7f40 Add my Undertale RP server
IDK if that's fine. Also, I have no idea if what I edited is good or not, haven't gotten into JavaScript yet and had to copy-paste some of that.
2016-01-25 17:08:31 -05:00
pohky 69e6abdccf Merge pull request #155 from unforgivingmorsecode/patch-2
Update serverlist.json
2016-01-25 08:47:16 +01:00
unforgivingmorsecode 7d347488f7 Update serverlist.json 2016-01-24 23:44:59 -06:00
Jiiks 40345b7cdd Remove autojoin due to limits 2016-01-24 17:59:06 +02:00
pohky 5e2ef11cc9 Merge pull request #151 from Sosolol261/master
Added "Anime Discord" to the server list
2016-01-24 04:44:50 +01:00
pohky 562ffc9db5 Update emotefilter.json 2016-01-24 04:33:23 +01:00
Sosolol261 9e51a142ff Added "Anime Discord" to list 2016-01-24 12:31:50 +09:00
Sosolol261 70b9af44a3 Added "Anime Discord" to list 2016-01-24 12:29:18 +09:00
pohky b7e68d1f6b Fix for latest Discord Update 2016-01-24 04:16:40 +01:00
pohky 90f1c5dbac Merge pull request #150 from 3Dymensional/patch-2
Update serverlist.json
2016-01-23 23:29:29 +01:00
3Dymensional b380552e76 Update serverlist.json 2016-01-23 12:29:25 -06:00
pohky 1c14050ecf Merge pull request #147 from 3Dymensional/patch-1
Update serverlist.json
2016-01-22 07:42:54 +01:00
pohky aa68763979 Merge pull request #148 from EhsanKia/bttv-update-jan22
Updated BTTV db (360 new emotes)
2016-01-22 07:41:22 +01:00
Ehsan Kia 79803ac4cf Updated BTTV db (360 new emotes) 2016-01-22 00:34:55 -05:00
3Dymensional a1a80033da Update serverlist.json 2016-01-21 22:06:57 -06:00
pohky b18d0a413d Merge pull request #146 from cyan28/master
added NerdChat to serverlist
2016-01-20 01:02:25 +01:00
Cy Timothy Johnson 14a3824792 added NerdChat to serverlist 2016-01-19 12:52:20 -06:00
pohky f240c1f59e Merge pull request #135 from EhsanKia/bttv-db-update
Remade BTTV emote database with all shared emotes
2016-01-18 22:10:09 +01:00
Ehsan Kia 259a21975d Moved updated BTTV db to the data folder 2016-01-18 15:14:42 -05:00
Ehsan Kia cd3004d669 Merge remote-tracking branch 'upstream/master' into bttv-db-update
# Conflicts:
#	emotedata_bttv.json
2016-01-18 15:13:45 -05:00
pohky fc1a4fbfb7 Merge pull request #145 from Hostail/update-serverlist.json
Update serverlist.json
2016-01-18 20:29:59 +01:00
Hostail b1516f301a Update serverlist.json 2016-01-18 16:38:51 +01:00
pohky acb722c934 Merge pull request #144 from Blitzcronk/patch-1
Update serverlist.json
2016-01-18 11:33:38 +01:00
Blitzcronk a96bbb64f6 Update serverlist.json 2016-01-18 03:01:06 +00:00
pohky dc9fba64ec Merge pull request #143 from Kaeloron/patch-2
Update serverlist.json
2016-01-17 15:34:32 +01:00
Kaeloron 791f2b4dda Update serverlist.json 2016-01-17 14:24:05 +01:00
pohky 92339a2e22 Update README.md 2016-01-17 13:03:53 +01:00
Jiiks e80c617bc2 Move stuff to misc, remove unsused files add .dev. to ignore 2016-01-17 01:16:11 +02:00
Jiiks 4702ce7f38 Update serverlist link 2016-01-17 01:09:40 +02:00
Jiiks 5e40663761 0.2.3 and 0.2.4 EOL 2016-01-17 01:08:52 +02:00
Jiiks fe66b1ba65 Merge branch 'master' of https://github.com/Jiiks/BetterDiscordApp 2016-01-17 01:05:35 +02:00
Jiiks f8007f77fd 0.2.3 and 0.2.4 EOL 2016-01-17 01:05:29 +02:00
pohky b6f655ceeb Emote request Raygius 2016-01-17 00:05:06 +01:00
pohky cc5f1e6e36 Emote request Raygius 2016-01-17 00:00:37 +01:00
pohky 7028868c57 Merge pull request #137 from pohky/master
update emotes
2016-01-16 21:52:10 +01:00
Jiiks ee671c5540 Fixed missing , 2016-01-15 01:51:02 +02:00
Ehsan Kia 98c3620388 Updated database (400 new emotes since 5 days ago) 2016-01-14 00:01:00 -05:00
Jiiks 5d63b812b3 a5923eb8ab 2016-01-14 00:53:18 +02:00
Jiiks b5ef38a5cb Merge pull request #139 from Kaeloron/patch-1
Update to serverlist.json
2016-01-14 00:50:11 +02:00
Jiiks a5923eb8ab Merge pull request #138 from megamit/master
Fix for random doubling of public server button
2016-01-14 00:50:01 +02:00
Jiiks 81e03e5a79 Merge pull request #136 from eBunny/patch-2
Blade Symphony link update
2016-01-14 00:49:21 +02:00
Jiiks 3d4a5a8beb Merge pull request #134 from zetterburn/patch-1
Update serverlist.json
2016-01-14 00:49:10 +02:00
Kaeloron c09a06dbde Update to serverlist.json
Added our Rainbow 6: Siege Community discord server to the list.
2016-01-13 15:18:28 +01:00
Jiiks ebb9c7e0e6 Fix match issue some people are having 2016-01-13 10:59:56 +02:00
Mitchell 2e9e46ae90 Fix for random doubling of public server button 2016-01-12 11:43:35 +00:00
Jiiks a9c73c721a Dafuq and sync 2016-01-12 03:54:37 +02:00
pohky a2fce66f54 update 2016-01-11 07:09:38 +01:00
Ehsan Kia c3b74660c9 Another pass with a bigger dictionary and list of common names 2016-01-10 23:26:51 -05:00
pohky 666c317ffa update emote_data 2016-01-11 04:27:39 +01:00
eBunny bb78fc192a Blade Symphony link update
Updated the invite code for Blade Symphony, since the old one seemed to have some problems.
2016-01-10 23:30:15 +01:00
Jiiks 26ae69ed77 Bot icon bug fix 2016-01-10 11:38:27 +02:00
Jiiks a1cc5218ed Bug fix 2016-01-10 11:36:16 +02:00
Ehsan Kia b33dc0c536 Removed all words below 7 characters that looked common 2016-01-09 23:16:31 -05:00
Ehsan Kia ca4bacd805 Removed even more common words 2016-01-09 22:57:07 -05:00
Ehsan Kia 9cc0aab965 Remade BTTV emote database with all shared emotes 2016-01-09 22:35:50 -05:00
zetterburn 773da182a1 Update serverlist.json
Add server for Rivals of Aether (At bottom of list)
2016-01-08 19:27:20 -05:00
Jiiks a892cb5784 Dafuq and sync 2016-01-09 02:15:02 +02:00
Jiiks 3dc9cd04ea Merge pull request #132 from pohky/master
compact mode fix
2016-01-09 02:12:31 +02:00
Jiiks fd4c4af3a2 Merge pull request #131 from ayydriel/patch-2
Ayydriel server
2016-01-09 02:12:23 +02:00
Jiiks 645ae53b04 Merge pull request #128 from ianiD/patch-1
Add the Gamedev group
2016-01-09 02:12:14 +02:00
Jiiks 2ec87e29db Merge pull request #129 from alexismartin/patch-1
Update emotefilter.json
2016-01-09 02:11:20 +02:00
pohky 45d3ec2cc0 compact mode fix 2016-01-08 16:33:43 +01:00
ayydriel 7d516b74f0 Ayydriel's d&c
:D
2016-01-07 17:37:35 -05:00
Jiiks ffd67dce4f Bugifx 2016-01-07 17:48:59 +02:00
Jiiks 87c49a61bd Bot icons 2016-01-07 11:19:46 +02:00
Jiiks 1b06641a24 Bot icon 2016-01-07 10:47:03 +02:00
Jiiks 40239dfc40 Emotemenu random icon 2016-01-07 10:01:20 +02:00
Jiiks 08d5eb0740 Emotemenu button icons 2016-01-07 09:53:07 +02:00
Jiiks a79cf31f35 Custom game plugin
allows user to set custom game as status
2016-01-07 09:39:01 +02:00
Jiiks dcff0a3a51 Clear interval 2016-01-07 08:53:03 +02:00
Jiiks c2b491c0f4 Remove logging 2016-01-07 08:45:51 +02:00
Jiiks b51f1caf36 Plugin socket events, textarea margin 2016-01-07 08:44:14 +02:00
Jiiks 98bb5a3c79 Socket active, added api functions for setting game and status 2016-01-07 08:35:40 +02:00
Alexis Martin 0ded805494 Update emotefilter.json
Adding Paul
2016-01-04 22:34:59 +01:00
Dragomir Ioan e82666dd55 Add the Gamedev group 2016-01-04 22:21:23 +02:00
Jiiks 1b23fd15f8 Mario 2016-01-04 06:52:36 +02:00
Jiiks 00e1dede75 Merge pull request #124 from pohky/master
new word
2016-01-04 06:51:50 +02:00
pohky ef9c969d47 new word
added Mario
2016-01-03 19:43:04 +01:00
Jiiks c856a344cc Sync 2016-01-03 04:46:40 +02:00
Jiiks eaa5212f7e Merge pull request #123 from pohky/master
emoterequests
2016-01-03 04:45:54 +02:00
Jiiks d92c331986 Merge pull request #121 from pohky/patch-1
Add Sonic
2016-01-03 04:45:41 +02:00
pohky 06a8a85a4c emoterequests 2016-01-03 02:25:29 +01:00
Jiiks 43837e3c2f Remove fireworks 2016-01-02 09:06:25 +02:00
pohky 852ac71c3f Add Sonic 2016-01-01 05:49:48 +01:00
Jiiks 355d264311 https://github.com/Jiiks/BetterDiscordApp/pull/120 2016-01-01 03:27:28 +02:00
Jiiks 28ceac99e1 Merge pull request #120 from eBunny/patch-1
Blade Symphony server
2016-01-01 03:27:52 +02:00
eBunny 066bbdcef5 Blade Symphony server
Added server for the game Blade Symphony
2016-01-01 02:23:42 +01:00
Jiiks e5393d8a93 Fix , : 2016-01-01 01:02:15 +02:00
Jiiks 8ad112b77d Fixed emote ids 2016-01-01 00:59:09 +02:00
Jiiks be84041d57 Firework credits 2015-12-31 19:36:34 +02:00
Jiiks c04efb568a Merge branch 'master' of https://github.com/Jiiks/BetterDiscordApp 2015-12-31 19:27:48 +02:00
Jiiks 36e6b4a229 Fireworks 2015-12-31 19:27:43 +02:00
Jiiks ca5965b178 Merge pull request #118 from Bluscream/patch-4
Added 2 servers + sorted alphabetically.
2015-12-30 00:18:13 +02:00
Jiiks 65b651c9ec Added Fighting 2015-12-30 00:15:23 +02:00
Bluscream d07b907c73 Added 2 servers + sorted alphabetically. 2015-12-29 19:49:31 +01:00
Jiiks 54043d0926 Added Dream 2015-12-29 20:32:02 +02:00
Jiiks 4d14cbaccd v1.57 2015-12-27 17:39:10 +02:00
Jiiks ba50e4c433 Added Demo 2015-12-25 13:48:48 +02:00
Jiiks cc8c43170b Merge branch 'master' of https://github.com/Jiiks/BetterDiscordApp 2015-12-24 11:51:22 +02:00
Jiiks 60bd3ee16c https://github.com/Jiiks/BetterDiscordApp/pull/114 2015-12-24 11:51:15 +02:00
Jiiks f2c45c550e Merge pull request #112 from williamnguyen13/patch-1
Update serverlist.json
2015-12-24 11:45:48 +02:00
Jiiks 3b5f5ce27a Merge pull request #110 from pohky/master
emote request
2015-12-24 11:43:05 +02:00
williamnguyen13 21e66aac91 Update serverlist.json 2015-12-24 10:44:17 +07:00
Jiiks 91984955e9 Remove debugs and danSgame 2015-12-24 00:22:28 +02:00
Jiiks cbcec9c289 ClauZ 2015-12-24 00:14:35 +02:00
Jiiks 4fb9cc809b addhat 2015-12-24 00:01:03 +02:00
Jiiks 8ccf3f78ff Fix default settings 2015-12-23 23:48:59 +02:00
Jiiks 0d23d72198 Up to date files 2015-12-23 22:02:55 +02:00
pohky 0f190d965d emote request 2015-12-23 20:26:45 +01:00
Jiiks eb03f5a85a Hide context menu on click 2015-12-23 11:49:38 +02:00
Jiiks b0c5fe130d 0.2.5 updater 2015-12-23 11:42:49 +02:00
Jiiks 08e1f1e9ea Readme link 2015-12-23 11:33:14 +02:00
Jiiks 6d3bed07e4 1.56 minified 2015-12-23 11:28:14 +02:00
Jiiks 31f40f33ab Ide comments 2015-12-23 11:20:18 +02:00
Jiiks a9c8428442 JSV1.56 2015-12-23 11:12:39 +02:00
Jiiks 8f3b498922 Alerts close button 2015-12-23 10:58:49 +02:00
Jiiks 806979ee41 Alerts 2015-12-23 10:56:16 +02:00
Jiiks b9e32b80e0 Close emotemenu when clicked outside of it 2015-12-23 10:22:19 +02:00
Jiiks c0f8c43f1b Fix favorite emote removing 2015-12-23 10:16:30 +02:00
Jiiks ddbaf290b3 Use nullorempty 2015-12-23 09:45:12 +02:00
Jiiks 9369be568b Merge branch 'master' of https://github.com/Jiiks/BetterDiscordApp 2015-12-23 09:43:44 +02:00
Jiiks ffa570b08c xpi and jquery ignore 2015-12-23 09:43:38 +02:00
Jiiks beb542aab6 Merge pull request #104 from KaizoGT/patch-5
Updating Link
2015-12-23 02:39:20 +02:00
KaizoGT d5e72f744b Updating Link
One of the public discord chats has updated link.
2015-12-22 19:35:28 -05:00
Jiiks ad578fdc47 Add dancepls 2015-12-22 11:11:44 +02:00
Jiiks a7220fd2fc Addded ability to close modal 2015-12-22 11:09:20 +02:00
Jiiks 082aaae415 Merge branch 'master' of https://github.com/Jiiks/BetterDiscordApp 2015-12-22 10:44:19 +02:00
Jiiks 15276acda5 Plugin settings modal 2015-12-22 10:44:14 +02:00
Jiiks 59036404fe Merge pull request #103 from MyMeatStick/patch-2
Update serverlist.json
2015-12-22 10:21:27 +02:00
MyMeatStick bb029c49fe Update serverlist.json 2015-12-22 08:17:47 +00:00
Jiiks 9bfafc7866 Settingspanel inject method 2015-12-21 15:51:15 +02:00
Jiiks cdffc9917b fff 2015-12-21 14:21:01 +02:00
Jiiks 9afe4888e0 Firefox emote injects 2015-12-21 13:26:33 +02:00
Jiiks 12f1b0934e Firefox extension initial 2015-12-21 09:41:28 +02:00
Jiiks 514bec9dcd Train and Shame 2015-12-20 20:21:22 +02:00
Jiiks 9f07aa3670 Parse theme names 2015-12-20 06:20:16 +02:00
Jiiks 670dc81562 Emotemenu icon 2015-12-20 05:28:06 +02:00
Jiiks 3f62190c5b Encoded santa 2015-12-20 05:15:35 +02:00
Jiiks bf53a3dfa1 Merge branch 'master' of https://github.com/Jiiks/BetterDiscordApp 2015-12-20 05:07:41 +02:00
Jiiks af711f0921 Santa OpieOP 2015-12-20 05:07:35 +02:00
Jiiks 3fe477d643 Merge pull request #101 from KaizoGT/patch-2
Update serverlist.json
2015-12-19 23:47:20 +02:00
KaizoGT 62e9cd846b Update serverlist.json 2015-12-19 16:42:36 -05:00
Jiiks 9d340b41d1 Fix light theme comment border color 2015-12-18 18:34:47 +02:00
Jiiks 2eeadd4c3c Fix compact mode emotes 2015-12-18 18:28:22 +02:00
Jiiks bfb855081c Added a restart Discord checkbox 2015-12-18 18:00:52 +02:00
Jiiks 86749ad34a Config and package version 2015-12-18 17:48:09 +02:00
Jiiks 54bc94bb07 Latest version 2015-12-18 17:46:22 +02:00
Jiiks cfd600e5f4 Updater datapath 2015-12-18 17:46:03 +02:00
Jiiks 5f8eeedd1b 0.2.5 use datapaths 2015-12-18 17:43:44 +02:00
Jiiks fcb189b9c1 Organize repo for 0.2.5
All data files should be under data folder
2015-12-18 17:40:26 +02:00
Jiiks d2c117f346 Correct backup ignore 2015-12-18 17:37:24 +02:00
Jiiks 880e1bfa7b Add backup files to ignore 2015-12-18 17:36:25 +02:00
Jiiks 9c9737fee7 Updated readme with emotes link 2015-12-18 17:33:00 +02:00
Jiiks c53474f77b Updated readme 2015-12-18 17:32:08 +02:00
Jiiks 293725202b Splices moved to module, keep it instead of compiling a new installer jic 2015-12-18 17:26:49 +02:00
Jiiks 0fdfcaa3e8 Move loaders to same dom event and added a failsafe dom hook 2015-12-18 17:23:16 +02:00
Jiiks 105a04a000 Merge pull request #98 from pohky/master
invalid emotes updated
2015-12-18 15:08:49 +02:00
pohky 9c21586661 invalid emotes updated 2015-12-18 14:02:23 +01:00
Jiiks d4f18fbfaf rage 2015-12-18 12:46:52 +02:00
Jiiks b2a8034645 Merge pull request #96 from Bluscream/patch-1
Update emotefilter.json
2015-12-18 12:46:07 +02:00
Jiiks 60d6ed4197 Guilds Scrollbar Plugin
Adds scrollbar to guilds
2015-12-18 12:39:44 +02:00
Bluscream 70d316997f Update emotefilter.json 2015-12-18 09:59:53 +01:00
Jiiks f934e4f833 Merge pull request #95 from pohky/master
newline fix
2015-12-17 17:43:10 +02:00
pohky 5890805644 newline fix 2015-12-17 16:35:32 +01:00
Jiiks 20e7a12345 Merge pull request #92 from Legsbiter/patch-3
Update emotedata_bttv.json
2015-12-17 17:14:07 +02:00
Jiiks 68f4082b73 Merge pull request #91 from Legsbiter/patch-2
Update emotedata_ffz.json
2015-12-17 17:13:23 +02:00
Jiiks 4295ed9da3 Merge pull request #94 from mrdiablo/master
Updated Ragnarok Online url
2015-12-17 13:27:06 +02:00
Jiiks 14ed68fe8f Merge pull request #93 from YourSelfAvent/patch-2
adding Cell Geek House
2015-12-17 05:59:09 +02:00
Jiiks a699450133 Restore version info 2015-12-17 05:52:14 +02:00
Martin Panin 4a6bf85aff adding Cell Geek House 2015-12-17 00:16:20 +02:00
Florian Weber 5ccfb9fa68 Updated Ragnarok Online url 2015-12-16 22:30:50 +01:00
Legsbiter 55b4d612e9 Update emotedata_bttv.json
new emote Kappa b
2015-12-16 10:21:56 -05:00
Legsbiter c01ba1e5bc Update emotedata_ffz.json 2015-12-16 10:20:28 -05:00
Jiiks 9c20612ac9 Update seperated files 2015-12-16 13:21:46 +02:00
Jiiks 2efcdedf83 Ugh 2015-12-16 05:02:21 +02:00
Jiiks 10adc3cd4a Merge pull request #86 from pohky/master
updated emotes
2015-12-15 19:55:29 +02:00
pohky 83bdf85eba updated emotes 2015-12-15 18:47:16 +01:00
Jiiks ac774930e5 Move loaders to bd module for 0.2.4 2015-12-15 16:03:39 +02:00
Jiiks d24a6222dd New themesupport var 2015-12-15 11:13:40 +02:00
Jiiks cf7c68cef0 Fix 2015-12-15 11:11:49 +02:00
Jiiks 9d306ed4e1 Fix for theme trimming 2015-12-15 11:11:31 +02:00
Jiiks a1f55a7be1 Theme support minified 2015-12-15 09:38:21 +02:00
Jiiks 261659d387 Support for themes 2015-12-15 09:37:15 +02:00
Jiiks 5330884a7b Add name to themeobject 2015-12-15 08:43:56 +02:00
Jiiks a88fd77fd6 Add theme support variabl 2015-12-15 08:37:10 +02:00
Jiiks 8dafff1b34 Themeloader indendation 2015-12-15 08:33:23 +02:00
Jiiks 3459d52dbd Merge branch 'master' of https://github.com/Jiiks/BetterDiscordApp 2015-12-15 08:32:17 +02:00
Jiiks c369887d2b Themeloader 2015-12-15 08:32:12 +02:00
Jiiks 29f69ffd8a Merge pull request #85 from Brightqwerty12/patch-1
Binding of Isaac: Afterbirth
2015-12-15 06:14:09 +02:00
Brightqwerty12 83b8f916fb Binding of Isaac: Afterbirth
Hello,
I currently admin along with 4 other people and group of 143 people and rising. We are always looking for more ways to increase in size and this looks like an amazing opportunity. Here is a link to the server in case you want to check it out. https://discord.gg/0gonaBVBNISU8zhS
Thanks,
Luke "Brightqwerty" Jacob
2015-12-14 23:07:26 -05:00
Jiiks 02379bd5d2 manual 4 space 2015-12-15 05:39:39 +02:00
Jiiks 855211ef5a Merge pull request #84 from pohky/master
remove emote
2015-12-15 05:38:16 +02:00
pohky 9b8be4da48 remove emote
removed Hate
2015-12-15 04:35:04 +01:00
Jiiks aa68bbeaeb Added Hate 2015-12-15 05:34:18 +02:00
Jiiks 4c8c5c4115 Merge pull request #83 from pohky/master
added emote requested
2015-12-15 05:21:49 +02:00
pohky d439b0eef1 added emote requested 2015-12-15 04:16:03 +01:00
Jiiks 2733ade804 Merge pull request #82 from Sinyxs/patch-1
Update serverlist.json
2015-12-15 02:12:28 +02:00
Sinyxs c8a3c13cee Update serverlist.json 2015-12-14 11:01:04 +01:00
Jiiks 4eb04c1a09 FFZ Global emotes 2015-12-14 09:00:07 +02:00
Jiiks a1de5d7490 Missing styling 2015-12-14 08:26:12 +02:00
Jiiks 8c044f2488 v1.54 - Favorite emotes 2015-12-14 08:12:07 +02:00
Jiiks 09fa5b5a34 Remove debugs 2015-12-14 07:24:49 +02:00
Jiiks e93b5fdc73 Merge branch 'master' of https://github.com/Jiiks/BetterDiscordApp 2015-12-14 07:22:57 +02:00
Jiiks b1c0ada422 Favorite emotes 2015-12-14 07:22:52 +02:00
Jiiks 36155be600 Merge pull request #79 from SteelSliver/patch-1
Update serverlist.json
2015-12-14 02:04:16 +02:00
Cassius Qweuro a9e7c0541e Update serverlist.json
adds ElDewrito server
2015-12-13 16:02:21 -08:00
Jiiks 45cba396d1 Fix minimal mode channel speaker icon 2015-12-13 22:06:36 +02:00
Jiiks 8c4d689d44 remove LMAO 2015-12-13 17:31:40 +02:00
Jiiks 9d6427e4c0 0.2.3 updater 2015-12-13 17:21:38 +02:00
Jiiks bdab795306 Fix body background for light theme 2015-12-13 15:49:26 +02:00
Jiiks 5c3c06a143 Updated windows installer link 2015-12-13 15:29:11 +02:00
Jiiks ebd6e90c5f Fixed missing line addition 2015-12-13 15:28:33 +02:00
Jiiks 30eabbca68 Fix typo 2015-12-13 15:05:21 +02:00
Jiiks 2af8ac283a v1.53 minified 2015-12-13 14:57:09 +02:00
Jiiks 2f229356ef Use splice file 2015-12-13 14:44:21 +02:00
Jiiks 0f641a5f1d 0.2.3 Prep 2015-12-13 14:40:58 +02:00
Jiiks 08579a2035 Thread start 2015-12-13 14:36:44 +02:00
Jiiks ee6dfa5e61 Assembly version 2015-12-13 14:31:23 +02:00
Jiiks c6e92cda41 Use splice file 2015-12-13 14:27:22 +02:00
Jiiks 1580f0b790 Splices with plugin/theme loader 2015-12-13 14:25:23 +02:00
Jiiks 191ef2b43d Emote request 2015-12-12 22:54:46 +02:00
Jiiks e62aa36b51 !"#¤%&/()=@££$£€[}]\€^*;:_½§ 2015-12-12 20:28:21 +02:00
Jiiks aec8f9b93f Change api methods to return and for loop instead 2015-12-12 18:54:44 +02:00
Jiiks 41752faf1d Remove rels 2015-12-12 18:30:31 +02:00
Jiiks 85d947c122 Plugin and Theme loader splices. 2015-12-12 18:29:06 +02:00
Jiiks 4262dcf111 Docs 2015-12-12 14:54:21 +02:00
Jiiks 8520f1512d Api methods 2015-12-12 14:53:07 +02:00
Jiiks 2d95d001b6 New minimal mode changes 2015-12-12 12:05:24 +02:00
Jiiks ff1d5e6888 More 1.53 changelog 2015-12-12 11:24:23 +02:00
Jiiks e789abaf3f Improved minimal mode 2015-12-12 11:21:08 +02:00
Jiiks d8ec3ad1dc Remove api window return 2015-12-12 10:50:53 +02:00
Jiiks b66146d881 Plugin API 2015-12-12 10:50:25 +02:00
Jiiks 0caedb5a51 1.53 changelog 2015-12-12 10:36:26 +02:00
Jiiks 4086e399c1 1.53 changelog 2015-12-12 10:35:14 +02:00
Jiiks 203f1238e6 Fix log typo 2015-12-12 10:34:08 +02:00
Jiiks e7cf6e2667 Oops 2015-12-12 09:01:06 +02:00
Jiiks 63037bac1d Merge branch 'master' of https://github.com/Jiiks/BetterDiscordApp 2015-12-12 08:59:49 +02:00
Jiiks f885108947 Add missing commas 2015-12-12 08:59:44 +02:00
Jiiks 8662b35dc9 Merge pull request #75 from Bluscream/patch-1
Update serverlist.json
2015-12-12 08:57:24 +02:00
Jiiks b58b52f902 CustomCSS Editor functional 2015-12-12 08:52:54 +02:00
Jiiks d66b61ae40 Plugin data storage 2015-12-12 08:07:56 +02:00
Jiiks b379e570cd Move codemirror css to main.css and remove load from cdnjs 2015-12-12 04:55:02 +02:00
Jiiks de24f954f2 New tabbed settingspanel base
Missing plugins and themes still.
2015-12-12 04:28:42 +02:00
Bluscream 62edd607f5 Update serverlist.json
I hope there is no escaping in JSON. Else just correct it or tell me to ^^
2015-12-11 18:34:56 +01:00
Jiiks 7bb2f3b6f9 EOL Attribute 2015-12-11 11:58:06 +02:00
Jiiks dfa6fbe87f Remove ignores 2015-12-11 11:55:06 +02:00
Jiiks 7d606f44f9 Winrepair gitignore 2015-12-11 11:52:04 +02:00
Jiiks 2574de3a69 Versioning, changelog 2015-12-11 11:21:16 +02:00
Jiiks 63a8d60ee1 Fixed edit emotes 2015-12-11 11:13:38 +02:00
Jiiks 97daae9090 Microoptimization
Move word length check before banned emotes check
2015-12-11 08:46:37 +02:00
Jiiks 6e621098e3 Autocap use emotesTwitch, pluginmodule init 2015-12-11 08:43:36 +02:00
Jiiks a32769ce43 Right 2015-12-11 06:53:23 +02:00
Jiiks 7e92798513 Initial api 2015-12-11 06:49:40 +02:00
Jiiks b3d9e1fe40 Restore public servers 2015-12-11 05:24:28 +02:00
Jiiks 1fec4fbaa8 Fixed reload crashing and serverlist inject
Not ready for release yet.
2015-12-11 04:46:03 +02:00
Jiiks 493944e991 public server dialog testing 2015-12-11 02:46:49 +02:00
Jiiks 2fe458f8bd New public servers test 2015-12-11 02:39:07 +02:00
Jiiks 2b673e2e96 HTML Loader 2015-12-11 02:09:59 +02:00
Jiiks d03420f053 Merge branch 'master' of https://github.com/Jiiks/BetterDiscordApp 2015-12-11 01:57:57 +02:00
Jiiks 7ff31931c0 Html loader test 2015-12-11 01:57:52 +02:00
Jiiks 31d0ca3e34 Merge pull request #74 from pohky/master
emote requests added
2015-12-11 01:45:43 +02:00
pohky aa03678107 emote request
SilenceGum
2015-12-11 00:41:17 +01:00
Jiiks e17ed347e4 v0.2.2 updater 2015-12-10 09:20:39 +02:00
Jiiks f606d62543 Merge pull request #72 from pohky/master
removed Love
2015-12-10 09:19:27 +02:00
pohky 1fc56e29ea removed Love 2015-12-10 07:59:38 +01:00
Jiiks 2ac9acc1ff v0.2.2 package 2015-12-10 05:07:26 +02:00
Jiiks f28fb85a20 Remove debugs 2015-12-10 05:06:30 +02:00
Jiiks 13f4ca29e1 BetterTTV Emote Support 2015-12-10 05:01:24 +02:00
Jiiks 986f392846 Merge branch 'master' of https://github.com/Jiiks/BetterDiscordApp 2015-12-10 04:58:07 +02:00
Jiiks 8e22483d06 hasher 2015-12-10 04:58:03 +02:00
Jiiks a78f6ef9c2 Merge pull request #71 from pohky/master
emote updates
2015-12-10 04:53:17 +02:00
pohky 16b29fd8aa emote updates 2015-12-10 03:52:31 +01:00
Jiiks e3f9055fea bttv emotedata 2015-12-10 04:52:20 +02:00
Jiiks 1eac4bfe3e Merge pull request #70 from The-Ringing-Bell/patch-2
Update serverlist.json
2015-12-09 23:00:53 +02:00
The-Ringing-Bell c9c8c9bb8f Update serverlist.json 2015-12-09 08:45:10 -06:00
Jiiks 2f925f9695 Merge pull request #69 from zSoulweaver/master
Emote titles overflow fix
2015-12-09 03:46:27 +02:00
zSoulweaver 47c6d92b32 Emote titles overflow fix
Blame twitch
2015-12-09 11:44:23 +10:00
Jiiks 9bd56951ca Merge pull request #67 from pohky/master
ID Fix
2015-12-09 03:28:27 +02:00
pohky 100695e367 ID Fix 2015-12-08 01:34:37 +01:00
Jiiks e3b1821fcf - 2015-12-08 01:23:31 +02:00
Jiiks 4cdf621fa9 Ajoin disclaimer 2015-12-07 01:02:49 +02:00
Jiiks 5bf9b23770 Merge pull request #66 from Candunc/master
Fixed an odd issue where installer prompted to install node
2015-12-06 21:46:41 +02:00
Duncan Bristow fce376923a Fixed an odd issue where installer prompted to install node, even though it is installed. 2015-12-06 12:32:19 -07:00
Jiiks b8c0eb4be8 Fixed nodecor maybe3 2015-12-06 20:59:40 +02:00
Jiiks 0d4fce33a9 ffz emotes link 2015-12-06 20:39:37 +02:00
Jiiks 14f3cf6442 Merge pull request #65 from pohky/master
ID fix and removed&added emotes
2015-12-06 20:38:47 +02:00
pohky 7fd5728af3 ID fix and removed&added emotes 2015-12-06 19:35:11 +01:00
Jiiks bc67c99983 Fixed recursion 2015-12-06 20:25:49 +02:00
Jiiks 35894f2cec Merge pull request #64 from xwmario/patch-1
Added anime discuss to serverlist.json
2015-12-06 19:08:40 +02:00
xwmario be52c7c259 Added anime discuss to serverlist.json 2015-12-06 21:51:00 +05:30
Jiiks 9c69d8cac6 WI Does not use json.net 2015-12-06 16:45:20 +02:00
Jiiks 8eb8695465 Windows repair utility 2015-12-06 16:19:40 +02:00
Jiiks c82ecaedd8 Merge pull request #62 from pohky/master
more fix and add
2015-12-05 17:54:49 +02:00
pohky b379975180 more fix and add 2015-12-05 16:49:00 +01:00
pohky 387e58d7cf id fixes 2015-12-05 16:41:35 +01:00
pohky 7f3e124958 id fix 2015-12-05 16:08:06 +01:00
Jiiks edd66f9930 Updated img 2015-12-05 15:49:53 +02:00
Jiiks 24d94b6945 Things.. OpieOP 2015-12-05 15:29:57 +02:00
Jiiks 7ac09d18f6 Merge pull request #59 from pohky/master
emote update
2015-12-05 10:13:02 +02:00
pohky 6802496f69 emote update 2015-12-05 08:17:21 +01:00
Jiiks 4062d4d88a Merge pull request #58 from pohky/master
emote update
2015-12-05 09:03:50 +02:00
pohky 2fc7a1c91e emote update 2015-12-05 07:57:39 +01:00
Jiiks 3f4d922016 asar.net link 2015-12-05 04:17:15 +02:00
Jiiks e062f9317f Disable public servers for now 2015-12-05 03:41:27 +02:00
Jiiks c89e3d4609 Windowsinstaller info 2015-12-05 03:29:32 +02:00
Jiiks 8b8a4de8fe Windows Installer initial version 2015-12-05 03:15:11 +02:00
Jiiks 074288fc8d Merge pull request #57 from pohky/master
fixes and updates
2015-12-04 23:52:34 +02:00
pohky 6b06438daa fixes and updates 2015-12-04 20:33:59 +01:00
pohky 6e4f3c5e75 updated and fixed private emotes 2015-12-04 20:21:56 +01:00
Jiiks 9e0993ae81 Merge pull request #55 from pohky/master
updated and filtered
2015-12-04 20:12:58 +02:00
pohky 9e1234cc40 updated and filtered 2015-12-04 18:08:31 +01:00
Jiiks 3509c67faa Merge pull request #54 from pohky/master
updated with 24790 FFZ emotes
2015-12-04 03:33:57 +02:00
Jiiks 88cbac4c1f Merge pull request #53 from zSoulweaver/master
Better Looking Titles
2015-12-04 03:33:48 +02:00
Jiiks 8cfcc92162 WI Doesn't require wrench 2015-12-04 03:26:29 +02:00
Jiiks b0269f10bf Proper config 2015-12-04 03:22:21 +02:00
Jiiks 6f66ad26d5 WindowsInstaller skeleton 2015-12-04 03:17:37 +02:00
Jiiks 19637bb5c6 Installer config "final" 2015-12-04 02:42:05 +02:00
Jiiks ec6f54b4a8 Remove empty resource 2015-12-04 02:16:44 +02:00
Jiiks 6321e64e52 Installer config 2015-12-04 02:16:04 +02:00
pohky 5c79f9c432 updated with 24790 FFZ emotes 2015-12-04 00:32:15 +01:00
zSoulweaver 91b90f956d Minify CSS
Minify for Twitch titles
2015-12-04 09:07:01 +10:00
zSoulweaver e010b9fab8 CSS for emote titles 2015-12-04 09:05:52 +10:00
zSoulweaver b3556b947e Blug- Minify stuff 2015-12-04 09:03:29 +10:00
zSoulweaver cf2456ae63 Add Twitch styled emote titles
Also makes you able to copy emotes when 'Show Titles' is turned off, due to the alt attribute.
2015-12-04 09:02:32 +10:00
Jiiks f9d0e6916f Merge pull request #50 from pendo324/emotefix
This should fix the emote edge cases for emotes of any length
2015-12-03 19:06:48 +02:00
pendo324 9df32d3b5e This should fix the emote edge cases for emotes of any length 2015-12-03 12:04:28 -05:00
Jiiks 10aa237f29 k 2015-12-03 05:53:11 +02:00
Jiiks c589efbb45 Merge pull request #49 from pohky/master
fixed the fix
2015-12-03 05:35:13 +02:00
pohky 87fa7d3d52 fixed the fix
removed too short emotes and fixed some IDs
2015-12-03 04:31:18 +01:00
Jiiks 0f65d7d21d Correct utils hash 2015-12-03 05:05:49 +02:00
Jiiks 0a4c73a56e Correct checksums 2015-12-03 05:01:48 +02:00
Jiiks 8a2274819d Correct index hash 2015-12-03 04:58:59 +02:00
Jiiks 729a6dd922 Installation validator 2015-12-03 04:52:03 +02:00
pohky 123e0a5a04 fix for the fix 2015-12-03 03:41:04 +01:00
Jiiks 5e58fc6271 Harsh dbg draft 2015-12-03 04:16:17 +02:00
Jiiks d70a7ec87b Option for snow everywhere 2015-12-03 03:42:08 +02:00
Jiiks eb33713290 Fixed snow stacking 2015-12-03 00:41:21 +02:00
Jiiks 09894971e9 ee 2015-12-03 00:14:30 +02:00
Jiiks 3d29d6267c Merge pull request #46 from pohky/master
fixed some IDs to the more used emote
2015-12-02 22:02:23 +02:00
Jiiks aad1229a20 Sneaky 2015-12-02 22:00:45 +02:00
pohky c39d099e03 fixed some IDs to the more used emote
some IDs got overwritten by less used emotes with the same name, like
FeelsBadMan
2015-12-02 20:33:39 +01:00
pohky 0ee68260ea fixed some IDs to the more used emote
some IDs got overwritten by less used emotes with the same name, like
FeelsBadMan
2015-12-02 20:26:58 +01:00
Jiiks bb709a5352 Fix OSX Path 2015-12-02 15:59:33 +02:00
Jiiks 3eb646a5c0 Merge pull request #45 from pohky/master
added 4000+ ffz emotes
2015-12-02 15:03:58 +02:00
pohky e8614b9b78 added 4000+ ffz emotes
first 100 pages sorted by usage + the ones that already were in
2015-12-02 02:31:45 +01:00
sakuzyo 792e62fbc0 Merge remote-tracking branch 'refs/remotes/Jiiks/master' 2015-12-02 01:30:14 +01:00
Jiiks 33cfd24a8e Local paths 2015-12-02 01:55:31 +02:00
Jiiks a3093940d4 fix 2015-12-01 17:36:57 +02:00
Jiiks 66bfbabb8d Merge pull request #44 from pohky/master
fix changed emote IDs
2015-12-01 17:34:21 +02:00
Pohky 29e54c1219 fix changed emote IDs 2015-12-01 16:25:10 +01:00
Jiiks 81bf11c464 jsv1.52 compact mode emotes fixed 2015-12-01 15:55:27 +02:00
Jiiks 0ba19bf6b6 Merge branch 'master' of https://github.com/Jiiks/BetterDiscordApp 2015-12-01 15:53:19 +02:00
Jiiks bd16913387 jsv1.51 compact mode emotes fixed 2015-12-01 15:53:15 +02:00
Jiiks 50f7b60097 Merge pull request #43 from zSoulweaver/patch-2
Close discord when installing
2015-12-01 03:56:51 +02:00
zSoulweaver be92b02ce8 Close discord when installing
Simple edit to the bat to close Discord before installing so the errors won't pop up.
2015-12-01 11:52:34 +10:00
Jiiks 154bf90d58 Updater 0.2.1 2015-12-01 01:00:31 +02:00
Jiiks 4d16b9fd89 Critical malformed url bug fix 2015-12-01 00:57:59 +02:00
Jiiks 4c622234ee Mikustare id 2015-12-01 00:50:25 +02:00
Jiiks a738ad01d2 Updater latest version = 0.2.0 2015-11-30 22:34:39 +02:00
Jiiks eb5abc67d7 Package version and comment out ide stuff 2015-11-30 21:57:09 +02:00
Jiiks d919a539b0 v0.2.0 - Improved resource loading and stability/bug fixes.
Tons of refactoring
2015-11-30 21:46:20 +02:00
Jiiks 00b9433717 Fir for nonchat text getting replaced by emotes 2015-11-29 23:28:21 +02:00
Jiiks 674460f32b New version dialog
Display a changelog on start.
2015-11-29 19:21:58 +02:00
Jiiks 79bb8a19c6 aded Happy and Cheese 2015-11-28 22:05:12 +02:00
Jiiks c0b0a82f5f Credits 2015-11-28 16:41:43 +02:00
Jiiks 13bd03d3e6 Installer config init 2015-11-28 14:37:05 +02:00
Jiiks cf5c4ffa9b Custom CSS 2015-11-28 05:17:39 +02:00
Jiiks 7f15dc8d57 Word replace fix 2015-11-28 02:17:48 +02:00
Jiiks 6e37027f97 Features 2015-11-28 02:13:40 +02:00
Jiiks 7868680389 Switch spoiler tag to [!s] 2015-11-28 02:13:19 +02:00
Jiiks 6b33fcea42 Features 2015-11-28 01:58:12 +02:00
Jiiks ca64ece346 Hide spoilers only when clicked 2015-11-28 01:44:56 +02:00
Jiiks 02db4d1822 Dont respoiler 2015-11-28 01:41:48 +02:00
Jiiks 3c149ce3fe Spoiler support(use [s]) for spoilers Quickemotemenu button overlap with textarea fixed. 2015-11-28 01:29:53 +02:00
Jiiks 1b3c551515 Emotemenu button background color 2015-11-28 00:46:05 +02:00
Jiiks 62b79e8150 Emotemenu button styling again 2015-11-28 00:44:37 +02:00
Jiiks 26f88a3c5c Emotemenu fix 2015-11-27 19:47:48 +02:00
Jiiks ec6bea553b Show button for restoring channels when hidden, autojoin bd server once 2015-11-27 12:07:59 +02:00
Jiiks 450c8970d1 Formatting 2015-11-27 03:52:01 +02:00
Jiiks af3a0204f0 formatting 2015-11-27 03:51:14 +02:00
Jiiks cef0317b78 New screenshot 2015-11-27 03:50:09 +02:00
Jiiks de97c3bcba New settings location 2015-11-27 03:47:17 +02:00
Jiiks a89d722edb JS v1.4
New settings menu
2015-11-27 02:14:33 +02:00
Jiiks ff9533f226 Emotemenu button styling 2015-11-27 02:06:35 +02:00
Jiiks 4effe41b6b Removed dead invite(speedrunning) 2015-11-19 17:22:42 +02:00
Jiiks 9f93c813d5 Merge pull request #37 from pendo324/master
Added a feature and menu option for it
2015-11-19 13:43:14 +02:00
Jiiks bf0657a3df Fix settings menu 2015-11-19 13:42:08 +02:00
pendo324 c1d38d1edd Fix a stupid error due to a hasty commit
Forgot to change the respective links in each different type of emote's
case
2015-11-18 23:00:52 -05:00
pendo324 ba091dac54 Added a menu option and a feature
Show Names menu option: Shows names of emotes when they are hovered over

CSS for the menu page needs to be updated. The new option is being
covered by the footer.
2015-11-18 18:35:39 -05:00
Jiiks 38bf6af2e0 v0.0.283 windows splices 2015-11-18 05:29:45 +02:00
Jiiks 2357470398 Fixed node download url
https://nodejs.org/download/ > https://nodejs.org/en/download/
2015-11-13 20:34:37 +02:00
Jiiks 6a09a7d6ca Regex split 2015-11-12 14:31:58 +02:00
Jiiks 62e3eb1adb Merge pull request #31 from zSoulweaver/patch-1
Update emotefilter.json
2015-11-06 14:19:33 +02:00
zSoulweaver fdbffbca1c Update emotefilter.json 2015-11-06 21:26:09 +10:00
Jiiks a47dc0bde3 Merge pull request #30 from alexismartin/patch-1
Update emotefilter.json
2015-11-05 19:37:02 +02:00
Alexis Martin a3ab204503 Update emotefilter.json
Add emotes from fahr3nh3it_ftw
2015-11-05 18:31:49 +01:00
Jiiks ed8cbfb535 Add hash for js instead of loading it again later. 2015-11-04 20:05:19 +02:00
Jiiks a6e0dd4ab8 Local match 2015-11-03 18:36:53 +02:00
481 changed files with 77926 additions and 4688 deletions

15
.editorconfig Normal file
View File

@ -0,0 +1,15 @@
root = true
[*]
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
indent_style = space
indent_size = 4
[*.md]
trim_trailing_whitespace = false
[package.json]
indent_size = 2

42
.eslintrc Normal file
View File

@ -0,0 +1,42 @@
{
"parserOptions": {
"ecmaVersion": 8,
"sourceType": "module"
},
"env": {
"browser": true,
"node": true
},
"plugins": [
"vue"
],
"extends": [
"eslint:recommended",
"plugin:vue/recommended"
],
"rules": {
"no-unused-vars": "off",
"no-console": "off",
"no-empty": "off",
"quotes": [
"error",
"single",
{ "allowTemplateLiterals": true }
],
"prefer-template": "warn",
"no-return-await": "error",
"indent": [ "warn", 4 ],
"no-lonely-if": "error",
"no-multiple-empty-lines": [
"warn",
{ "max": 1 }
],
"no-tabs": "warn",
"no-trailing-spaces": "warn",
"no-unneeded-ternary": "warn",
"no-useless-constructor": "warn",
"no-var": "error",
"prefer-const": "error",
"no-else-return": "error"
}
}

1
.gitattributes vendored Normal file
View File

@ -0,0 +1 @@
*.sh text=auto

33
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@ -0,0 +1,33 @@
---
name: Bug report
about: Create a report to help us improve
title: "[Bug]"
labels: bug
assignees: ''
---
- [ ] Used appropriate template for the issue type
- [ ] Searched both open and closed issues for duplicates of this issue
- [ ] Title adequately and _concisely_ reflects the feature or the bug
**Describe the bug**
<!-- A clear and concise description of what the bug is. -->
**To Reproduce**
<!-- Steps to reproduce the behavior -->
**Expected behavior**
<!-- A clear and concise description of what you expected to happen. -->
**Screenshots**
<!-- If applicable, add screenshots to help explain your problem. -->
**System information**
<!-- os, discord branch etc -->
**Additional context**
<!-- Add any other context about the problem here. -->
**Are you willing and able to fix this?**
<!-- "Yes" or, if "no", what can current contributors do to help you create a PR? -->

12
.github/ISSUE_TEMPLATE/custom.md vendored Normal file
View File

@ -0,0 +1,12 @@
---
name: Custom issue template
about: Describe this issue template's purpose here.
title: ''
labels: ''
assignees: ''
---
- [ ] Used appropriate template for the issue type
- [ ] Searched both open and closed issues for duplicates of this issue
- [ ] Title adequately and _concisely_ reflects the feature or the bug

View File

@ -0,0 +1,27 @@
---
name: Feature request
about: Suggest an idea for this project
title: "[Feature]"
labels: feature
assignees: ''
---
- [ ] Used appropriate template for the issue type
- [ ] Searched both open and closed issues for duplicates of this issue
- [ ] Title adequately and _concisely_ reflects the feature or the bug
**Is your feature request related to a problem? Please describe.**
<!-- A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] -->
**Describe the solution you'd like**
<!-- A clear and concise description of what you want to happen. -->
**Describe alternatives you've considered**
<!-- A clear and concise description of any alternative solutions or features you've considered. -->
**Additional context**
<!-- Add any other context or screenshots about the feature request here. -->
**Are you willing and able to implement this?**
<!-- "Yes" or, if "no", what can current contributors do to help you create a PR? -->

20
.gitignore vendored
View File

@ -1,4 +1,16 @@
.idea/*
*.name
*.xml
devjs/.idea/devjs.iml
# Generated files
node_modules
dist
etc
release
tests/tmp
tests/log.txt
# User data
tests/data
user.config.json
/.vs
/npm-debug.log
/tests/ext/extensions
/tests/userdata

29
.sasslintrc Normal file
View File

@ -0,0 +1,29 @@
{
"rules": {
"no-transition-all": [ 0 ],
"nesting-depth": [
1,
{ "max-depth": 5 }
],
"no-vendor-prefixes": [ 0 ],
"property-sort-order": [ 0 ],
"indentation": [
1,
{ "size": 4 }
],
"no-color-literals": [ 0 ],
"class-name-format": [
1,
{
"convention": "^bd-[a-z]"
}
],
"variable-name-format": [
2,
{
"convention": "camelcase"
}
],
"url-quotes": [ 0 ]
}
}

13
.travis.yml Normal file
View File

@ -0,0 +1,13 @@
language: node_js
node_js:
- stable
branches:
only:
- master
addons:
apt:
packages:
- libsecret-1-dev

9
LICENSE Normal file
View File

@ -0,0 +1,9 @@
The MIT License (MIT)
Copyright (c) 2015-present JsSucks - https://github.com/JsSucks
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -1,168 +0,0 @@
/*
* BetterDiscordApp Installer v0.3.2
*/
var dver = "0.0.280";
var asar = require('asar');
var wrench = require('wrench');
var fs = require('fs');
var readline = require('readline');
var util = require('util');
var _packageSplice;
var _importSplice;
var _functionSplice;
var _functionCallSplice;
var _discordPath;
var _appFolder = "/app";
var _appArchive = "/app.asar";
var _packageJson = _appFolder + "/package.json";
var _index = _appFolder + "/app/index.js";
var _force = false;
// Get Arguments
process.argv.forEach(function (val, index, array) {
if (val == "--force") {
_force = true;
}
if (val == "-d" || val == "--directory") {
_discordPath = array[(index+1)]
}
});
function install() {
if (typeof _discordPath == 'undefined') {
var _os = process.platform;
if (_os == "win32") {
_packageSplice = 10;
_importSplice = 83;
_functionCallSplice = 497;
_functionSplice = 597;
_discordPath = process.env.LOCALAPPDATA + "/Discord/app-"+dver+"/resources";
} else if (_os == "darwin") {
_packageSplice = 10;
_importSplice = 83;
_functionCallSplice = 500;
_functionSplice = 602;
_discordPath = "/Applications/Discord.app/Contents/Resources" // Defaults to Applications directory
}
}
console.log("Looking for discord resources at: " + _discordPath);
fs.exists(_discordPath, function(exists) {
if(exists) {
console.log("Discord resources found at: " + _discordPath + "\nLooking for app folder");
if(fs.existsSync(_discordPath + _appFolder)) {
console.log("Deleting " + _discordPath + _appFolder + " folder.");
wrench.rmdirSyncRecursive(_discordPath + _appFolder);
console.log("Deleted " + _discordPath + _appFolder + " folder.");
}
if(fs.existsSync(_discordPath + "/node_modules/BetterDiscord")) {
console.log("Deleting " + _discordPath + "/node_modules/BetterDiscord" + " folder.");
wrench.rmdirSyncRecursive(_discordPath + "/node_modules/BetterDiscord");
console.log("Deleted " + _discordPath + "/node_modules/BetterDiscord" + " folder.");
}
console.log("Copying BetterDiscord");
fs.mkdirSync(_discordPath + "/node_modules/BetterDiscord");
wrench.copyDirSyncRecursive(__dirname + "/BetterDiscord/", _discordPath + "/node_modules/BetterDiscord/", {forceDelete: true});
console.log("Looking for app archive");
if(fs.existsSync(_discordPath + _appArchive)) {
console.log("App archive found at: " + _discordPath + _appArchive);
} else {
console.log("Failed to locate app archive at: " + _discordPath + _appArchive);
process.exit();
}
console.log("Extracting app archive");
asar.extractAll(_discordPath + _appArchive, _discordPath + _appFolder);
fs.exists(_discordPath + _appFolder, function(exists) {
if(exists) {
console.log("Extracted to: " + _discordPath + _appFolder);
console.log("Injecting index.js");
var data = fs.readFileSync(_discordPath + _index).toString().split("\n");
data.splice(_importSplice, 0, 'var _betterDiscord = require(\'betterdiscord\');\n');
data.splice(_functionCallSplice, 0, 'betterDiscord(mainWindow);');
data.splice(_functionSplice, 0, 'function betterDiscord(mw) { _betterDiscord = new _betterDiscord.BetterDiscord(mw); _betterDiscord.init(); }');
fs.writeFile(_discordPath + _index, data.join("\n"), function(err) {
if(err) return console.log(err);
console.log("Injected index.js");
console.log("Injecting package.json");
var data = fs.readFileSync(_discordPath + _packageJson).toString().split("\n");
data.splice(_packageSplice, 0, '"betterdiscord":"^0.1.2",');
fs.writeFile(_discordPath + _packageJson, data.join("\n"), function(err) {
if(err) return console.log(err);
console.log("Injected package.json");
console.log("Looks like were done here :)");
process.exit();
});
});
} else {
console.log("Something went wrong, rerun.");
process.exit();
}
});
} else {
console.log("Discord resources not found at: " + _discordPath);
process.exit();
}
});
}
function init() {
console.log("BetterDiscord Simple Installer v0.3 for Discord "+dver+" by Jiiks.");
console.log("If Discord has updated then download the latest installer.");
var rl = readline.createInterface({ input: process.stdin, output: process.stdout });
if (_force == false) {
rl.question("The following directories will be deleted if they exists: discorpath/app, discordpath/node_modules/BetterDiscord, is this ok? Y/N", function(answer) {
var alc = answer.toLowerCase();
switch(alc) {
case "y":
install();
break;
case "yes":
install();
break;
case "n":
process.exit();
break;
case "no":
process.exit();
break;
}
});
} else {
install();
}
}
init();

View File

@ -1,10 +0,0 @@
@echo off
where node.exe >nul 2>nul
if %errorlevel%==1 (
echo "Node.exe not found, opening your browser..."
start "" "https://nodejs.org/dist/latest/win-x86/node.exe"
pause
) else (
cmd /k node.exe index.js
)
exit

View File

@ -1,7 +0,0 @@
#!/bin/bash
# As there is no Linux support, this script assumes OS X as the host system.
command -v node > /dev/null || echo 'Node not found, please download it!' && open 'https://nodejs.org/en/' && sleep 5 && exit
node index.js
exit

View File

@ -1,82 +1,12 @@
# BetterDiscordApp
Better Discord App enhances Discord desktop app with new features.
# BetterDiscordApp [![Travis][build-badge]][build] [![Snyk][snyk-badge]][snyk-url] [![deps][deps-badge]][deps-url] [![devdeps][devdeps-badge]][devdeps-url]
![ss](http://puu.sh/jTEBB.png)
[build-badge]: https://img.shields.io/travis/JsSucks/BetterDiscordApp/master.svg
[build]: https://travis-ci.org/JsSucks/BetterDiscordApp
[snyk-badge]: https://snyk.io/test/github/JsSucks/BetterDiscordApp/badge.svg
[snyk-url]: https://snyk.io/test/github/JsSucks/BetterDiscordApp
## If Discord has updated and the installer hasn't, try replacing the installer index.js with the latest one here: [index.js](https://github.com/Jiiks/BetterDiscordApp/blob/master/NodeInstaller/index.js)
## Auto Installation
* Download the latest package from [releases](https://github.com/Jiiks/BetterDiscordApp/releases)
* Run the installer
* Hopefully it works.
* Installer requires [node](https://nodejs.org/download/) download the binaries and place in the same folder as the installer if you don't have node installed.
* Installer uses [asar](https://github.com/atom/asar) which is bundled with the installer.
* Installer uses [wrench](https://github.com/ryanmcgrath/wrench-js) which is bundled with the installer.
## Manual Installation
* Extract app.asar
* Add BetterDiscord as a dependency
* Add init to Discord load event
* Move BetterDiscord to node_modules
## Features
**Emotes:**
BetterDiscord adds all [Twitch.tv](http://twitch.tv), some [FrankerFaceZ](http://frankerfacez.com)(~240 suggested emotes) and [BetterTTV](http://betterttv.net) emotes to Discord.
**Quick Emote Menu:**
Quick Emote Menu adds a menu for quickly adding twitch emotes.
**Emote Autocapitalize:**
Automatically capitalize [Twitch.tv](http://twitch.tv) global emotes.
**Emote Autocomplete:**
Automatically completes/suggests emotes.(soon)
**Minimal Mode:**
Minimal mode makes elements smaller and hides certain elements.
**Voice Chat Mode:**
Only display voice channels
**Public Servers:**
A menu for displaying public servers.(soon) [Serverlist](https://github.com/Jiiks/BetterDiscordApp/blob/master/serverlist.json)
**Save Logs Locally:**
Save chatlogs locally.(soon)
## Adding you server to public servers
Edit the [Serverlist](https://github.com/Jiiks/BetterDiscordApp/blob/master/serverlist.json) and submit a pull request.
## BetterDiscord Uses the following API's
* https://twitchemotes.com/apidocs for Twitch emotes
* https://api.betterttv.net/emotes for [BetterTTV](https://nightdev.com/betterttv/) emotes
## Credits
* MacOS Installer by [Candunc](https://github.com/Candunc)
## License
The MIT License (MIT)
Copyright (c) <year> <copyright holders>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
[deps-badge]: https://david-dm.org/JsSucks/BetterDiscordApp.svg
[deps-url]: https://david-dm.org/JsSucks/BetterDiscordApp
[devdeps-badge]: https://david-dm.org/JsSucks/BetterDiscordApp/dev-status.svg
[devdeps-url]: https://david-dm.org/JsSucks/BetterDiscordApp?type=dev

View File

@ -1,63 +0,0 @@
###############################################################################
# Set default behavior to automatically normalize line endings.
###############################################################################
* text=auto
###############################################################################
# Set default behavior for command prompt diff.
#
# This is need for earlier builds of msysgit that does not have it on by
# default for csharp files.
# Note: This is only used by command line
###############################################################################
#*.cs diff=csharp
###############################################################################
# Set the merge driver for project and solution files
#
# Merging from the command prompt will add diff markers to the files if there
# are conflicts (Merging from VS is not affected by the settings below, in VS
# the diff markers are never inserted). Diff markers may cause the following
# file extensions to fail to load in VS. An alternative would be to treat
# these files as binary and thus will always conflict and require user
# intervention with every merge. To do so, just uncomment the entries below
###############################################################################
#*.sln merge=binary
#*.csproj merge=binary
#*.vbproj merge=binary
#*.vcxproj merge=binary
#*.vcproj merge=binary
#*.dbproj merge=binary
#*.fsproj merge=binary
#*.lsproj merge=binary
#*.wixproj merge=binary
#*.modelproj merge=binary
#*.sqlproj merge=binary
#*.wwaproj merge=binary
###############################################################################
# behavior for image files
#
# image files are treated as binary by default.
###############################################################################
#*.jpg binary
#*.png binary
#*.gif binary
###############################################################################
# diff behavior for common document formats
#
# Convert binary document formats to text before diffing them. This feature
# is only available from the command line. Turn it on by uncommenting the
# entries below.
###############################################################################
#*.doc diff=astextplain
#*.DOC diff=astextplain
#*.docx diff=astextplain
#*.DOCX diff=astextplain
#*.dot diff=astextplain
#*.DOT diff=astextplain
#*.pdf diff=astextplain
#*.PDF diff=astextplain
#*.rtf diff=astextplain
#*.RTF diff=astextplain

View File

@ -1,156 +0,0 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# User-specific files
*.suo
*.user
*.sln.docstates
# Build results
[Dd]ebug/
[Rr]elease/
x64/
build/
[Bb]in/
[Oo]bj/
# Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets
!packages/*/build/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
*_i.c
*_p.c
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.log
*.scc
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opensdf
*.sdf
*.cachefile
# Visual Studio profiler
*.psess
*.vsp
*.vspx
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# NCrunch
*.ncrunch*
.*crunch*.local.xml
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.Publish.xml
# NuGet Packages Directory
## TODO: If you have NuGet Package Restore enabled, uncomment the next line
#packages/
# Windows Azure Build Output
csx
*.build.csdef
# Windows Store app package directory
AppPackages/
# Others
sql/
*.Cache
ClientBin/
[Ss]tyle[Cc]op.*
~$*
*~
*.dbmdl
*.[Pp]ublish.xml
*.pfx
*.publishsettings
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file to a newer
# Visual Studio version. Backup files are not needed, because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
App_Data/*.mdf
App_Data/*.ldf
#LightSwitch generated files
GeneratedArtifacts/
_Pvt_Extensions/
ModelManifest.xml
# =========================
# Windows detritus
# =========================
# Windows image file caches
Thumbs.db
ehthumbs.db
# Folder config file
Desktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Mac desktop service store files
.DS_Store

View File

@ -1,22 +0,0 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0.21005.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BetterDiscordWI", "BetterDiscordWI\BetterDiscordWI.csproj", "{469F7547-7664-4DE8-A568-E89525981539}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{469F7547-7664-4DE8-A568-E89525981539}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{469F7547-7664-4DE8-A568-E89525981539}.Debug|Any CPU.Build.0 = Debug|Any CPU
{469F7547-7664-4DE8-A568-E89525981539}.Release|Any CPU.ActiveCfg = Release|Any CPU
{469F7547-7664-4DE8-A568-E89525981539}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
</configuration>

View File

@ -1,88 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{469F7547-7664-4DE8-A568-E89525981539}</ProjectGuid>
<OutputType>WinExe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>BetterDiscordWI</RootNamespace>
<AssemblyName>BetterDiscordWI</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Deployment" />
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="FormMain.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="FormMain.Designer.cs">
<DependentUpon>FormMain.cs</DependentUpon>
</Compile>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<EmbeddedResource Include="FormMain.resx">
<DependentUpon>FormMain.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
<SubType>Designer</SubType>
</EmbeddedResource>
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@ -1,47 +0,0 @@
namespace BetterDiscordWI
{
partial class FormMain
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.SuspendLayout();
//
// FormMain
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(284, 261);
this.Name = "FormMain";
this.Text = "BetterDiscord Installer";
this.ResumeLayout(false);
}
#endregion
}
}

View File

@ -1,20 +0,0 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace BetterDiscordWI
{
public partial class FormMain : Form
{
public FormMain()
{
InitializeComponent();
}
}
}

View File

@ -1,120 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -1,22 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace BetterDiscordWI
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new FormMain());
}
}
}

View File

@ -1,36 +0,0 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("BetterDiscordWI")]
[assembly: AssemblyDescription("Better Discord Windows Installer")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Jiiks")]
[assembly: AssemblyProduct("BetterDiscordWI")]
[assembly: AssemblyCopyright("Copyright © 2015")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("17adafc9-c3e6-49c2-b2c9-d6866e7f4f23")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("0.1.0.0")]
[assembly: AssemblyFileVersion("0.1.0.0")]

View File

@ -1,71 +0,0 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace BetterDiscordWI.Properties
{
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources
{
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources()
{
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager
{
get
{
if ((resourceMan == null))
{
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("BetterDiscordWI.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture
{
get
{
return resourceCulture;
}
set
{
resourceCulture = value;
}
}
}
}

View File

@ -1,117 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -1,30 +0,0 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace BetterDiscordWI.Properties
{
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
{
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default
{
get
{
return defaultInstance;
}
}
}
}

View File

@ -1,7 +0,0 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
<Profiles>
<Profile Name="(Default)" />
</Profiles>
<Settings />
</SettingsFile>

View File

@ -1,12 +0,0 @@
/*Note this is partial changes*/
var _betterDiscord = require('betterdiscord');
function launchMainAppWindow(isVisible) {
_betterDiscord = new _betterDiscord.BetterDiscord(mainWindow);
_betterDiscord.init();
}

View File

@ -1,12 +0,0 @@
{
"name": "discord",
"description": "Discord Client for Desktop",
"version": "0.0.277",
"releaseChannel": "stable",
"main": "app/index.js",
"private": true,
"dependencies": {
"react": "^0.13.0",
"betterdiscord": "^0.1.2"
}
}

17
babel.config.js Normal file
View File

@ -0,0 +1,17 @@
module.exports = function(api) {
api.cache(true);
const presets = [['@babel/env', {
targets: {
'node': '8.6.0'
}
}]];
const plugins = [];
return {
presets,
plugins
}
}

View File

@ -1 +0,0 @@
module.exports = require('./lib/BetterDiscord');

18
client/babel.config.js Normal file
View File

@ -0,0 +1,18 @@
module.exports = function(api) {
api.cache(true);
const presets = [['@babel/env', {
targets: {
'node': '8.6.0',
'chrome': '60'
}
}], '@babel/react'];
const plugins = [];
return {
presets,
plugins
}
}

16
client/jsconfig.json Normal file
View File

@ -0,0 +1,16 @@
{
"compilerOptions": {
"target": "es2017",
"allowSyntheticDefaultImports": false,
"baseUrl": "./",
"paths": {
"modules": ["./src/modules/modules.js"],
"structs": ["./src/structs/structs.js"],
"common": ["../common/modules/common.js"],
"ui": ["./src/ui/ui.js"],
"builtin": ["./src/builtin/builtin.js"],
"vue$": ["../node_modules/vue/dist/vue.esm.js"]
}
},
"exclude": ["node_modules", "dist"]
}

23
client/package.json Normal file
View File

@ -0,0 +1,23 @@
{
"name": "bdclient",
"description": "BetterDiscord client package",
"author": "Jiiks",
"version": "2.0.0-beta.6",
"homepage": "https://betterdiscord.net",
"license": "MIT",
"main": "dist/betterdiscord.client.js",
"contributors": [
"Jiiks",
"Pohky"
],
"repository": {
"type": "git",
"url": "https://github.com/JsSucks/BetterDiscordApp.git"
},
"private": false,
"scripts": {
"build": "webpack --progress --colors",
"watch": "webpack --progress --colors --watch",
"release": "webpack --progress --colors --config=webpack.production.config.js"
}
}

View File

@ -0,0 +1,40 @@
/**
* BetterDiscord 24 Hour Timestamps Module
* Copyright (c) 2015-present Jiiks/JsSucks - https://github.com/Jiiks / https://github.com/JsSucks
* All rights reserved.
* https://betterdiscord.net
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import BuiltinModule from './BuiltinModule';
import { Reflection } from 'modules';
const twelveHour = new RegExp(`([0-9]{1,2}):([0-9]{1,2})\\s(AM|PM)`);
export default new class TwentyFourHour extends BuiltinModule {
/* Getters */
get moduleName() { return 'TwentyFourHour' }
get settingPath() { return ['ui', 'default', '24-hour'] }
/* Patches */
applyPatches() {
if (this.patches.length) return;
const { TimeFormatter } = Reflection.modules;
this.patch(TimeFormatter, 'calendarFormat', this.convertTimeStamps);
}
/**
* Convert 12 hours timestamps to 24 hour timestamps
*/
convertTimeStamps(that, args, returnValue) {
const matched = returnValue.match(twelveHour);
if (!matched || matched.length !== 4) return;
if (matched[3] === 'AM') return returnValue.replace(matched[0], `${matched[1] === '12' ? '00' : matched[1].padStart(2, '0')}:${matched[2]}`)
return returnValue.replace(matched[0], `${parseInt(matched[1]) + 12}:${matched[2]}`)
}
}

View File

@ -0,0 +1,56 @@
/**
* BetterDiscord Blocked Messages Module
* Copyright (c) 2015-present Jiiks/JsSucks - https://github.com/Jiiks / https://github.com/JsSucks
* All rights reserved.
* https://betterdiscord.net
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import BuiltinModule from './BuiltinModule';
import { Reflection } from 'modules';
export default new class BlockedMessages extends BuiltinModule {
/* Getters */
get moduleName() { return 'BlockedMessages' }
get settingPath() { return ['ui', 'default', 'blocked-messages'] }
async enabled(e) {
const MessageListComponents = Reflection.module.byProps('BlockedMessageGroup');
MessageListComponents.OriginalBlockedMessageGroup = MessageListComponents.BlockedMessageGroup;
MessageListComponents.BlockedMessageGroup = () => null;
this.cancelBlockedMessages = () => {
MessageListComponents.BlockedMessageGroup = MessageListComponents.OriginalBlockedMessageGroup;
delete MessageListComponents.OriginalBlockedMessageGroup;
}
}
disabled(e) {
if (this.cancelBlockedMessages) this.cancelBlockedMessages();
}
/* Methods */
static isBlocked(id) {
const { RelationshipStore } = Reflection.modules;
return RelationshipStore.isBlocked(id);
}
/* Patches */
applyPatches() {
if (this.patches.length) return;
const { MessageActions } = Reflection.modules;
this.patch(MessageActions, 'receiveMessage', this.processMessage, 'instead');
}
/**
* Ignore blocked messages completely
*/
processMessage(that, args, originalFunction) {
if (args[1] && args[1].author && args[1].author.id && BlockedMessages.isBlocked(args[1].author.id)) return;
return originalFunction(...args);
}
}

View File

@ -0,0 +1,106 @@
/**
* BetterDiscord Builtin Module Base
* Copyright (c) 2015-present Jiiks/JsSucks - https://github.com/Jiiks / https://github.com/JsSucks
* All rights reserved.
* https://betterdiscord.net
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import { Settings } from 'modules';
import { Patcher, MonkeyPatch as Patch, Cache } from 'modules';
import { ClientLogger as Logger } from 'common';
export default class BuiltinModule {
constructor() {
this._settingUpdated = this._settingUpdated.bind(this);
if (this.enabled) this.enabled = this.enabled.bind(this);
if (this.disabled) this.disabled = this.disabled.bind(this);
if (this.applyPatches) this.applyPatches = this.applyPatches.bind(this);
this.patch = this.patch.bind(this);
}
async init() {
this.setting.on('setting-updated', this._settingUpdated);
if (this.setting.value) {
if (this.enabled) await this.enabled();
if (this.applyPatches) this.applyPatches();
}
}
get setting() {
return Settings.getSetting(...this.settingPath);
}
get patches() {
return Patcher.getPatchesByCaller(`BD:${this.moduleName}`);
}
async _settingUpdated(e) {
if (e.value) {
if (this.enabled) await this.enabled(e);
if (this.applyPatches) await this.applyPatches();
if (this.rerenderPatchedComponents) this.rerenderPatchedComponents();
} else {
if (this.disabled) await this.disabled(e);
this.unpatch();
if (this.rerenderPatchedComponents) this.rerenderPatchedComponents();
}
}
get cache() {
return {
push: data => Cache.push(this.moduleName, data),
find: filter => Cache.find(this.moduleName, filter)
}
}
/**
* By default unpatch everything.
* Override to do something else.
*/
unpatch() {
Patcher.unpatchAll(`BD:${this.moduleName}`);
}
/**
* Patch a function in a module
* @param {any} module Module to patch
* @param {String} fnName Name of the function to patch
* @param {Function} cb Callback
* @param {String} [when=after] before|after|instead
*/
patch(module, fnName, cb, when = 'after') {
if (!['before', 'after', 'instead'].includes(when)) when = 'after';
return Patch(`BD:${this.moduleName}`, module)[when](fnName, cb.bind(this));
}
childPatch(module, fnName, child, cb, when = 'after') {
const last = child.pop();
this.patch(module, fnName, (component, args, retVal) => {
const unpatch = this.patch(child.reduce((obj, key) => obj[key], retVal), last, function(...args) {unpatch(); return cb.call(this, component, ...args);}, when);
});
}
/**
* Logger wraps
*/
log(message) {
Logger.log(this.moduleName, message);
}
warn(message) {
Logger.warn(this.moduleName, message);
}
info(message) {
Logger.warn(this.moduleName, message);
}
debug(message) {
Logger.dbg(this.moduleName, message);
}
}

View File

@ -0,0 +1,73 @@
/**
* BetterDiscord Colored Text Module
* Copyright (c) 2015-present Jiiks/JsSucks - https://github.com/Jiiks / https://github.com/JsSucks
* All rights reserved.
* https://betterdiscord.net
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import BuiltinModule from './BuiltinModule';
import { Utils } from 'common';
import { Settings, Reflection, ReactComponents, DiscordApi } from 'modules';
export default new class ColoredText extends BuiltinModule {
/* Getters */
get moduleName() { return 'ColoredText' }
get settingPath() { return ['ui', 'default', 'colored-text'] }
get intensityPath() { return ['ui', 'advanced', 'colored-text-intensity'] }
get intensitySetting() { return Settings.getSetting(...this.intensityPath) }
get intensity() { return 100 - this.intensitySetting.value }
get defaultColor() { return DiscordApi.UserSettings.theme == 'light' ? '#747f8d' : '#dcddde' }
constructor() {
super();
this._intensityUpdated = this._intensityUpdated.bind(this);
}
async enabled(e) {
this.intensitySetting.off('setting-updated', this._intensityUpdated);
this.intensitySetting.on('setting-updated', this._intensityUpdated);
}
disabled(e) {
this.intensitySetting.off('setting-updated', this._intensityUpdated);
}
rerenderPatchedComponents() {
if (this.MessageContent) this.MessageContent.forceUpdateAll();
}
/* Methods */
_intensityUpdated() {
this.MessageContent.forceUpdateAll();
}
/* Patches */
async applyPatches() {
if (this.patches.length) return;
this.MessageContent = await ReactComponents.getComponent('MessageContent');
this.patch(this.MessageContent.component.prototype, 'render', this.injectColoredText);
}
/**
* Set markup text colour to match role colour
*/
injectColoredText(thisObject, args, originalReturn) {
const unpatch = this.patch(originalReturn.props, 'children', (obj, args, returnValue) => {
unpatch();
const { TinyColor } = Reflection.modules;
const markup = Utils.findInReactTree(returnValue, m => m && m.props && m.props.className && m.props.className.includes('da-markup'));
const roleColor = thisObject.props.message.colorString;
if (markup && roleColor) markup.props.style = {color: TinyColor.mix(roleColor, this.defaultColor, this.intensity)};
});
}
}

View File

@ -0,0 +1,396 @@
/**
* BetterDiscord E2EE Module
* Copyright (c) 2015-present Jiiks/JsSucks - https://github.com/Jiiks / https://github.com/JsSucks
* All rights reserved.
* https://betterdiscord.net
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import { Settings, Cache, Events } from 'modules';
import BuiltinModule from '../BuiltinModule';
import { Reflection, ReactComponents, DiscordApi, Security } from 'modules';
import { VueInjector, Modals, Toasts } from 'ui';
import { ClientLogger as Logger, ClientIPC } from 'common';
import { request } from 'vendor';
import { Utils } from 'common';
import E2EEComponent from './E2EEComponent.vue';
import E2EEMessageButton from './E2EEMessageButton.vue';
import nodecrypto from 'node-crypto';
const userMentionPattern = new RegExp(`<@!?([0-9]{10,})>`, 'g');
const roleMentionPattern = new RegExp(`<@&([0-9]{10,})>`, 'g');
const everyoneMentionPattern = new RegExp(`(?:\\s+|^)@everyone(?:\\s+|$)`);
const START_DATE = new Date();
const TEMP_KEY = 'temporarymasterkey';
const ECDH_STORAGE = {};
let seed;
export default new class E2EE extends BuiltinModule {
/* Getters */
get moduleName() { return 'E2EE' }
get settingPath() { return ['security', 'default', 'e2ee'] }
get database() { return Settings.getSetting('security', 'e2eedb', 'e2ekvps').value }
constructor() {
super();
this.encryptNewMessages = true;
this.ecdhDate = START_DATE;
this.handlePublicKey = this.handlePublicKey.bind(this);
this.fetchMasterKey = this.fetchMasterKey.bind(this);
}
async enabled(e) {
await this.fetchMasterKey();
Events.on('discord:MESSAGE_CREATE', this.handlePublicKey);
Settings.getSetting('security', 'default', 'use-keytar').on('setting-updated', this.fetchMasterKey);
}
async disabled(e) {
Settings.getSetting('security', 'default', 'use-keytar').off('setting-updated', this.fetchMasterKey);
Events.off('discord:MESSAGE_CREATE', this.handlePublicKey);
const ctaComponent = await ReactComponents.getComponent('ChannelTextArea');
ctaComponent.forceUpdateAll();
}
/* Methods */
async fetchMasterKey() {
try {
if (Settings.get('security', 'default', 'use-keytar')) {
const master = await ClientIPC.getPassword('betterdiscord', 'master');
if (master) return this.setMaster(master);
if (Settings.getSetting('security', 'e2eedb', 'e2ekvps').items.length) {
// Ask the user for their current password to save to the system keychain
const currentMaster = await Modals.input('Save to System Keychain', 'Master Password', true).promise;
await ClientIPC.setPassword('betterdiscord', 'master', currentMaster);
return this.setMaster(currentMaster);
}
// Generate a new master password and save it to the system keychain
const newMaster = Security.randomBytes();
await ClientIPC.setPassword('betterdiscord', 'master', newMaster);
return this.setMaster(newMaster);
}
const newMaster = await Modals.input('Open Database', 'Master Password', true).promise;
return this.setMaster(newMaster);
} catch (err) {
Settings.getSetting(...this.settingPath).value = false;
Toasts.error('Invalid master password! E2EE Disabled');
Logger.err('E2EE', ['Error fetching master password', err]);
}
}
setMaster(key) {
seed = Security.randomBytes();
const newMaster = Security.encrypt(seed, key);
// TODO re-encrypt everything with new master
return (this.master = newMaster);
}
encrypt(key, content, prefix = '') {
if (!key) {
// Encrypt something with master
return Security.encrypt(Security.decrypt(seed, this.master), content);
}
if (!content) {
// Get key for current channel and encrypt
const haveKey = this.getKey(DiscordApi.currentChannel.id);
if (!haveKey) return 'nokey';
return Security.encrypt(Security.decrypt(seed, [this.master, haveKey]), key);
}
return prefix + Security.encrypt(key, content);
}
decrypt(key, content, prefix = '') {
return Security.decrypt(key, content, prefix);
}
async createHmac(data) {
const haveKey = this.getKey(DiscordApi.currentChannel.id);
if (!haveKey) return null;
return Security.createHmac(Security.decrypt(seed, [this.master, haveKey]), data);
}
getKey(channelId) {
const haveKey = this.database.find(kvp => kvp.value.key === channelId);
if (!haveKey) return null;
return haveKey.value.value;
}
setKey(channelId, key) {
const items = Settings.getSetting('security', 'e2eedb', 'e2ekvps').items;
const index = items.findIndex(kvp => kvp.value.key === channelId);
if (index > -1) {
items[index].value = { key: channelId, value: key };
return;
}
Settings.getSetting('security', 'e2eedb', 'e2ekvps').addItem({ value: { key: channelId, value: key } });
}
createKeyExchange(dmChannelID) {
if (ECDH_STORAGE.hasOwnProperty(dmChannelID)) return null;
ECDH_STORAGE[dmChannelID] = Security.createECDH();
setTimeout(() => {
if (ECDH_STORAGE.hasOwnProperty(dmChannelID)) {
delete ECDH_STORAGE[dmChannelID];
Toasts.error('Key exchange expired!');
if (this.preExchangeState) this.encryptNewMessages = this.preExchangeState;
this.preExchangeState = null;
}
}, 30000);
return Security.generateECDHKeys(ECDH_STORAGE[dmChannelID]);
}
publicKeyFor(dmChannelID) {
return Security.getECDHPublicKey(ECDH_STORAGE[dmChannelID]);
}
computeSecret(dmChannelID, otherKey) {
try {
const secret = Security.computeECDHSecret(ECDH_STORAGE[dmChannelID], otherKey);
delete ECDH_STORAGE[dmChannelID];
return Security.hash('sha384', secret, 'hex');
} catch (e) {
throw e;
}
}
/* Patches */
async applyPatches() {
if (this.patches.length) return;
const { Dispatcher } = Reflection.modules;
this.patch(Dispatcher, 'dispatch', this.dispatcherPatch, 'before');
this.patchMessageContent();
const ChannelTextArea = await ReactComponents.getComponent('ChannelTextArea');
this.patchChannelTextArea(ChannelTextArea);
this.patchChannelTextAreaSubmit(ChannelTextArea);
ChannelTextArea.forceUpdateAll();
}
dispatcherPatch(_, [event]) {
if (!event || event.type !== 'MESSAGE_CREATE') return;
const key = this.getKey(event.message.channel_id);
if (!key) return; // We don't have a key for this channel
if (typeof event.message.content !== 'string') return; // Ignore any non string content
if (!event.message.content.startsWith('$:')) return; // Not an encrypted string
let decrypt;
try {
decrypt = this.decrypt(this.decrypt(this.decrypt(seed, this.master), key), event.message.content);
} catch (err) { return } // Ignore errors such as non empty
const { MessageParser, Permissions, DiscordConstants } = Reflection.modules;
const currentChannel = DiscordApi.Channel.fromId(event.message.channel_id).discordObject;
// Create a generic message object to parse mentions with
const parsed = MessageParser.parse(currentChannel, decrypt).content;
if (userMentionPattern.test(parsed))
event.message.mentions = parsed.match(userMentionPattern).map(m => { return { id: m.replace(/[^0-9]/g, '') } });
if (roleMentionPattern.test(parsed))
event.message.mention_roles = parsed.match(roleMentionPattern).map(m => m.replace(/[^0-9]/g, ''));
if (everyoneMentionPattern.test(parsed))
event.message.mention_everyone = Permissions.can(DiscordConstants.Permissions.MENTION_EVERYONE, currentChannel);
}
// TODO Received exchange should also expire if not accepted in time
async handlePublicKey(e) {
if (!DiscordApi.currentChannel) return;
if (DiscordApi.currentChannel.type !== 'DM') return;
const { id, content, author, channelId } = e.args;
if (author.id === DiscordApi.currentUser.id || channelId !== DiscordApi.currentChannel.id) return;
const [tagstart, begin, key, end, tagend] = content.split('\n');
if (begin !== '-----BEGIN PUBLIC KEY-----' || end !== '-----END PUBLIC KEY-----') return;
try {
await Modals.confirm('Key Exchange', `Key exchange request from: ${author.username}#${author.discriminator}`, 'Accept', 'Reject').promise;
// We already sent our key
if (!ECDH_STORAGE.hasOwnProperty(channelId)) {
const publicKeyMessage = `\`\`\`\n-----BEGIN PUBLIC KEY-----\n${this.createKeyExchange(channelId)}\n-----END PUBLIC KEY-----\n\`\`\``;
if (this.encryptNewMessages) this.encryptNewMessages = false;
Reflection.modules.DraftActions.saveDraft(channelId, publicKeyMessage);
}
const secret = this.computeSecret(channelId, key);
this.setKey(channelId, secret);
Toasts.success('Key exchange complete!');
if (this.preExchangeState) this.encryptNewMessages = this.preExchangeState;
this.preExchangeState = null;
} catch (err) {
console.log(err);
return;
}
}
async patchMessageContent() {
const MessageContent = await ReactComponents.getComponent('MessageContent');
this.patch(MessageContent.component.prototype, 'render', this.beforeRenderMessageContent, 'before');
this.childPatch(MessageContent.component.prototype, 'render', ['props', 'children'], this.afterRenderMessageContent);
MessageContent.forceUpdateAll();
const ImageWrapper = await ReactComponents.getComponent('ImageWrapper');
this.patch(ImageWrapper.component.prototype, 'render', this.beforeRenderImageWrapper, 'before');
ImageWrapper.forceUpdateAll();
}
beforeRenderMessageContent(component) {
if (!component.props || !component.props.message) return;
const key = this.getKey(component.props.message.channel_id);
if (!key) return; // We don't have a key for this channel
const Message = Reflection.module.byPrototypes('isMentioned');
const { MessageParser, Permissions, DiscordConstants } = Reflection.modules;
const currentChannel = DiscordApi.Channel.fromId(component.props.message.channel_id).discordObject;
if (typeof component.props.message.content !== 'string') return; // Ignore any non string content
if (!component.props.message.content.startsWith('$:')) return; // Not an encrypted string
let decrypt;
try {
decrypt = Security.decrypt(seed, [this.master, key, component.props.message.content]);
} catch (err) { return } // Ignore errors such as non empty
component.props.message.bd_encrypted = true; // signal as encrypted
// Create a generic message object to parse mentions with
const message = MessageParser.createMessage(currentChannel.id, MessageParser.parse(currentChannel, decrypt).content);
if (userMentionPattern.test(message.content))
message.mentions = message.content.match(userMentionPattern).map(m => { return { id: m.replace(/[^0-9]/g, '') } });
if (roleMentionPattern.test(message.content))
message.mention_roles = message.content.match(roleMentionPattern).map(m => m.replace(/[^0-9]/g, ''));
if (everyoneMentionPattern.test(message.content))
message.mention_everyone = Permissions.can(DiscordConstants.Permissions.MENTION_EVERYONE, currentChannel);
// Create a new message to parse it properly
const create = Message.create(message);
if (!create.content || !create.contentParsed) return;
component.props.message.mentions = create.mentions;
component.props.message.mentionRoles = create.mentionRoles;
component.props.message.mentionEveryone = create.mentionEveryone;
component.props.message.mentioned = create.mentioned;
component.props.message.content = create.content;
component.props.message.contentParsed = create.contentParsed;
}
afterRenderMessageContent(component, _childrenObject, args, retVal) {
if (!component.props.message.bd_encrypted) return;
const { className } = Reflection.resolve('buttonContainer', 'avatar', 'username');
const buttonContainer = Utils.findInReactTree(retVal, m => m && m.className && m.className.indexOf(className) !== -1);
if (!buttonContainer) return;
const buttons = buttonContainer.children.props.children;
if (!buttons) return;
try {
buttons.unshift(VueInjector.createReactElement(E2EEMessageButton));
} catch (err) {
Logger.err('E2EE', err.message);
}
}
beforeRenderImageWrapper(component, args, retVal) {
if (!component.props || !component.props.src) return;
if (component.props.decrypting) return;
component.props.decrypting = true;
const src = component.props.original || component.props.src.split('?')[0];
if (!src.includes('bde2ee')) return;
component.props.className = 'bd-encryptedImage';
const haveKey = this.getKey(DiscordApi.currentChannel.id);
if (!haveKey) return;
const cached = Cache.find('e2ee:images', item => item.src === src);
if (cached) {
if (cached.invalidKey) { // TODO If key has changed we should recheck all with invalid key
component.props.className = 'bd-encryptedImage bd-encryptedImageBadKey';
component.props.readyState = 'READY';
return;
}
Logger.info('E2EE', 'Returning encrypted image from cache');
try {
const decrypt = Security.decrypt(seed, [this.master, haveKey, cached.image]);
component.props.className = 'bd-decryptedImage';
component.props.src = component.props.original = `data:;base64,${decrypt}`;
} catch (err) { return } finally { component.props.readyState = 'READY' }
return;
}
component.props.readyState = 'LOADING';
Logger.info('E2EE', `Decrypting image: ${src}`);
(async () => {
try {
const res = await request.get(src, { encoding: 'binary' });
const arr = new Uint8Array(new ArrayBuffer(res.length));
for (let i = 0; i < res.length; i++) arr[i] = res.charCodeAt(i);
const aobindex = Utils.aobscan(arr, [73, 69, 78, 68]) + 8;
const sliced = arr.slice(aobindex);
const image = new TextDecoder().decode(sliced);
const hmac = image.slice(-64);
const data = image.slice(0, -64);
const validateHmac = await this.createHmac(data);
if (hmac !== validateHmac) {
Cache.push('e2ee:images', { src, invalidKey: true });
if (component && component.props) {
component.props.decrypting = false;
component.forceUpdate();
}
return;
}
Cache.push('e2ee:images', { src, image: data });
if (!component || !component.props) {
Logger.warn('E2EE', 'Component seems to be gone');
return;
}
component.props.decrypting = false;
component.forceUpdate();
} catch (err) {
console.log('request error', err);
}
})();
}
patchChannelTextArea(cta) {
this.patch(cta.component.prototype, 'render', this.renderChannelTextArea);
}
renderChannelTextArea(component, args, retVal) {
if (!(retVal.props.children instanceof Array)) retVal.props.children = [retVal.props.children];
const inner = retVal.props.children.find(child => child.props.className && child.props.className.includes('inner'));
inner.props.children.splice(0, 0, VueInjector.createReactElement(E2EEComponent));
}
patchChannelTextAreaSubmit(cta) {
this.patch(cta.component.prototype, 'handleSubmit', this.handleChannelTextAreaSubmit, 'before');
}
handleChannelTextAreaSubmit(component, args, retVal) {
const key = this.getKey(DiscordApi.currentChannel.id);
if (!this.encryptNewMessages || !key) return;
component.props.value = Security.encrypt(Security.decrypt(seed, [this.master, key]), component.props.value, '$:');
}
}

View File

@ -0,0 +1,120 @@
/**
* BetterDiscord E2EE Component
* Copyright (c) 2015-present Jiiks/JsSucks - https://github.com/Jiiks / https://github.com/JsSucks
* All rights reserved.
* https://betterdiscord.net
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
<template>
<div class="bd-e2eeTaContainer">
<v-popover :popoverClass="['bd-popover', 'bd-e2eePopover', {'bd-e2eePopoverOver': popoutPositionSetting.value === 'over'}]"
:trigger="popoutPositionSetting.value === 'over' && popoutTriggerSetting.value === 'hover' ? 'hover' : 'click'"
:placement="popoutPositionSetting.value === 'over' ? 'top-start' : 'top'"
:disabled="error && DiscordApi.currentChannel.type !== 'DM'">
<div v-if="error" class="bd-e2eeTaBtn bd-e2eeLock bd-error">
<MiLock v-tooltip="error" />
</div>
<div v-else-if="state === 'loading'" class="bd-e2eeTaBtn bd-e2eeLock bd-loading bd-warn">
<MiLock v-tooltip="'Loading'" />
</div>
<div v-else-if="!E2EE.encryptNewMessages" class="bd-e2eeTaBtn bd-e2eeLock bd-warn">
<MiLock v-tooltip="'New messages will not be encrypted.'" />
</div>
<div v-else class="bd-e2eeTaBtn bd-e2eeLock bd-ok">
<MiLock v-tooltip="'Ready!'" />
</div>
<template slot="popover">
<div @click="toggleEncrypt" :class="{'bd-warn': !E2EE.encryptNewMessages, 'bd-ok': E2EE.encryptNewMessages}"><MiLock v-tooltip="'Toggle Encryption'" /></div>
<div v-close-popover @click="showUploadDialog" v-if="!error"><MiImagePlus v-tooltip="'Upload Encrypted Image'" /></div>
<div v-close-popover @click="generatePublicKey" v-if="DiscordApi.currentChannel.type === 'DM'"><MiIcVpnKey v-tooltip="'Begin Key Exchange'" /></div>
</template>
</v-popover>
<div class="bd-taDivider"></div>
</div>
</template>
<script>
import { Utils, FileUtils, ClientIPC } from 'common';
import { E2EE } from 'builtin';
import { Settings, DiscordApi, Reflection } from 'modules';
import { Toasts } from 'ui';
import { MiLock, MiImagePlus, MiIcVpnKey } from 'commoncomponents';
export default {
components: {
MiLock, MiImagePlus, MiIcVpnKey
},
data() {
return {
E2EE,
DiscordApi,
state: 'loading',
error: null,
popoutPositionSetting: Settings.getSetting('security', 'e2ee-popout', 'position'),
popoutTriggerSetting: Settings.getSetting('security', 'e2ee-popout', 'trigger')
};
},
methods: {
async showUploadDialog() {
const dialogResult = await ClientIPC.send('bd-native-open', {properties: ['openFile']});
if (!dialogResult || !dialogResult.length) return;
const readFile = await FileUtils.readFileBuffer(dialogResult[0]);
const FileActions = Reflection.module.byProps('makeFile');
const Uploader = Reflection.module.byProps('instantBatchUpload');
const img = await Utils.getImageFromBuffer(readFile);
const canvas = document.createElement('canvas');
canvas.height = img.height;
canvas.width = img.width;
const arrBuffer = await Utils.canvasToArrayBuffer(canvas);
const encrypted = E2EE.encrypt(img.src.replace('data:;base64,', ''));
const hmac = await E2EE.createHmac(encrypted);
const encodedBytes = new TextEncoder().encode(encrypted + hmac);
Uploader.upload(DiscordApi.currentChannel.id, FileActions.makeFile(new Uint8Array([...new Uint8Array(arrBuffer), ...encodedBytes]), 'bde2ee.png'));
},
toggleEncrypt() {
const newState = !E2EE.encryptNewMessages;
E2EE.encryptNewMessages = newState;
if (!newState) {
Toasts.warning('New messages will not be encrypted');
return;
}
Toasts.success('New messages will be encrypted');
},
generatePublicKey() {
const keyExchange = E2EE.createKeyExchange(DiscordApi.currentChannel.id);
if (keyExchange === null) {
Toasts.warning('Key exchange for channel already in progress!');
return;
}
E2EE.preExchangeState = E2EE.encryptNewMessages;
E2EE.encryptNewMessages = false; // Disable encrypting new messages so we won't encrypt public keys
const publicKeyMessage = `\`\`\`\n-----BEGIN PUBLIC KEY-----\n${keyExchange}\n-----END PUBLIC KEY-----\n\`\`\``;
Reflection.modules.DraftActions.saveDraft(DiscordApi.currentChannel.id, publicKeyMessage);
Toasts.info('Key exchange started. Expires in 30 seconds');
}
},
mounted() {
if (!E2EE.master) {
this.error = 'No master key set!';
return;
}
const haveKey = E2EE.getKey(DiscordApi.currentChannel.id);
if (!haveKey) {
this.error = 'No key for channel!';
return;
}
this.state = 'OK';
this.error = null;
}
}
</script>

View File

@ -0,0 +1,28 @@
/**
* BetterDiscord E2EE Component
* Copyright (c) 2015-present Jiiks/JsSucks - https://github.com/Jiiks / https://github.com/JsSucks
* All rights reserved.
* https://betterdiscord.net
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
<template>
<div class="bd-e2eeMessageButtonWrap">
<div class="bd-e2eeMessageButton">
<MiLock v-tooltip="'Encrypted'" :size="16" />
</div>
</div>
</template>
<script>
import { MiLock } from 'commoncomponents';
export default {
components: {
MiLock
},
props: ['message']
}
</script>

View File

@ -0,0 +1,3 @@
export { default as default } from './E2EE';
export { default as E2EEComponent } from './E2EEComponent.vue';
export { default as E2EEMessageButton } from './E2EEMessageButton.vue';

View File

@ -0,0 +1,104 @@
/**
* BetterDiscord Emote Autocomplete Module
* Copyright (c) 2015-present Jiiks/JsSucks - https://github.com/Jiiks / https://github.com/JsSucks
* All rights reserved.
* https://betterdiscord.net
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import { Settings } from 'modules';
import BuiltinModule from '../BuiltinModule';
import EmoteModule, { EMOTE_SOURCES } from './EmoteModule';
import GlobalAc from 'autocomplete';
import { BdContextMenu } from 'ui';
export default new class EmoteAc extends BuiltinModule {
/* Getters */
get moduleName() { return 'EmoteAC' }
get settingPath() { return ['emotes', 'default', 'emoteac'] }
async enabled(e) {
GlobalAc.add(';', this);
window.removeEventListener('contextmenu', this.acCm);
window.addEventListener('contextmenu', this.acCm);
}
disabled(e) {
GlobalAc.remove(';');
window.removeEventListener('contextmenu', this.acCm);
}
/* Methods */
acCm(e) {
const row = e.target.closest('.bd-emotAc');
if (!row) return;
const img = row.querySelector('img');
if (!img || !img.alt) return;
BdContextMenu.show(e, [
{
text: 'Test',
items: [
{
text: 'Favourite',
type: 'toggle',
checked: EmoteModule.isFavourite(img.alt.replace(/;/g, '')),
onChange: checked => {
if (!img || !img.alt) return;
const emote = img.alt.replace(/;/g, '');
if (!checked) return EmoteModule.removeFavourite(emote), false;
return EmoteModule.addFavourite(emote), true;
}
}
]
}
]);
}
/**
* Search for autocomplete
* @param {any} regex
*/
acsearch(regex) {
const acType = Settings.getSetting('emotes', 'default', 'emoteactype').value;
if (regex.length <= 0) {
return {
type: 'imagetext',
title: [`Your ${acType ? 'most used' : 'favourite'} emotes`, '', `${acType ? 'Favourites' : 'Most Used'}`],
items: EmoteModule[acType ? 'mostUsed' : 'favourites'].sort((a, b) => b.useCount - a.useCount).map(mu => {
return {
key: acType ? mu.key : mu.name,
value: {
src: EMOTE_SOURCES[mu.type].replace(':id', mu.id),
replaceWith: `;${acType ? mu.key : mu.name};`,
hint: mu.useCount ? `Used ${mu.useCount} times` : null
}
}
}),
extraClasses: ['bd-emotAc']
}
}
const results = EmoteModule.search(regex);
return {
type: 'imagetext',
title: ['Matching', regex.length],
items: results.map(result => {
result.value.src = EMOTE_SOURCES[result.value.type].replace(':id', result.value.id);
result.value.replaceWith = `;${result.key};`;
return result;
}),
extraClasses: ['bd-emotAc']
}
}
toggle(sterm) {
if (sterm.length > 1) return false;
Settings.getSetting('emotes', 'default', 'emoteactype').value = !Settings.getSetting('emotes', 'default', 'emoteactype').value;
return true;
}
}

View File

@ -0,0 +1,41 @@
/**
* BetterDiscord Emote Component
* Copyright (c) 2015-present Jiiks/JsSucks - https://github.com/Jiiks / https://github.com/JsSucks
* All rights reserved.
* https://betterdiscord.net
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import VrWrapper from '../../ui/vrwrapper';
import { EMOTE_SOURCES } from '.';
import EmoteComponent from './EmoteComponent.vue';
export default class Emote extends VrWrapper {
constructor(type, id, name) {
super();
this.jumboable = false;
this.type = type;
this.id = id;
this.name = name;
}
get component() { return EmoteComponent }
get props() {
return {
src: this.parseSrc(),
name: this.name,
jumboable: this.jumboable
}
}
parseSrc() {
const { type, id } = this;
if (type > 2 || type < 0) return '';
return EMOTE_SOURCES[type].replace(':id', id);
}
}

View File

@ -0,0 +1,32 @@
<template>
<img class="bd-emote emoji" :class="{jumboable}" :src="src" :alt="`;${name};`" v-tooltip="{ content: `;${name};`, delay: { show: 750, hide: 0 } }" />
</template>
<script>
import { ClientLogger as Logger } from 'common';
import EmoteModule from './EmoteModule';
import { MiStar } from 'commoncomponents';
export default {
components: {
MiStar
},
props: ['src', 'name', 'hasWrapper', 'jumboable'],
data() {
return {
EmoteModule
};
},
computed: {
favourite() {
return false;
}
},
methods: {
async toggleFavourite() {
await EmoteModule.setFavourite(this.name, !this.favourite);
Logger.log('EmoteComponent', `Set emote ${this.name} as ${this.favourite ? '' : 'un'}favourite`);
}
}
}
</script>

View File

@ -0,0 +1,406 @@
/**
* BetterDiscord Emote Module
* Copyright (c) 2015-present Jiiks/JsSucks - https://github.com/Jiiks / https://github.com/JsSucks
* All rights reserved.
* https://betterdiscord.net
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import BuiltinModule from '../BuiltinModule';
import path from 'path';
import { request } from 'vendor';
import { Utils, FileUtils, ClientLogger as Logger } from 'common';
import { DiscordApi, Settings, Globals, Reflection, ReactComponents, Database } from 'modules';
import { DiscordContextMenu } from 'ui';
import Emote from './EmoteComponent.js';
export const EMOTE_SOURCES = [
'https://static-cdn.jtvnw.net/emoticons/v1/:id/1.0',
'https://cdn.frankerfacez.com/emoticon/:id/1',
'https://cdn.betterttv.net/emote/:id/1x'
];
export default new class EmoteModule extends BuiltinModule {
/* Getters */
get moduleName() { return 'EmoteModule' }
/**
* @returns {String} Path to local emote database
*/
get dbpath() { return path.join(Globals.getPath('data'), 'emotes.json') }
/**
* @returns {Map} Cached raw emote database
*/
get database() { return this._db || (this._db = new Map()) }
/**
* @returns {Array} Favourite emotes
*/
get favourites() { return this._favourites || (this._favourites = []) }
/**
* @returns {Array} Most used emotes
*/
get mostUsed() { return this._mostUsed || (this._mostUsed = []) }
get settingPath() { return ['emotes', 'default', 'enable'] }
async enabled() {
// Add favourite button to context menu
this.favCm = DiscordContextMenu.add(target => [
{
text: 'Favourite',
type: 'toggle',
checked: target && target.alt && this.isFavourite(target.alt.replace(/;/g, '')),
onChange: (checked, target) => {
const { alt } = target;
if (!alt) return false;
const emote = alt.replace(/;/g, '');
if (!checked) return this.removeFavourite(emote), false;
return this.addFavourite(emote), true;
}
}
], target => target.closest('.bd-emote'));
if (!this.database.size) {
await this.loadLocalDb();
}
// Read favourites and most used from database
await this.loadUserData();
}
async disabled() {
DiscordContextMenu.remove(this.favCm);
}
/* Methods */
/**
* Adds an emote to favourites.
* @param {Object|String} emote
* @return {Promise}
*/
addFavourite(emote) {
if (this.isFavourite(emote)) return;
if (typeof emote === 'string') emote = this.findByName(emote, true);
this.favourites.push(emote);
return this.saveUserData();
}
/**
* Removes an emote from favourites.
* @param {Object|String} emote
* @return {Promise}
*/
removeFavourite(emote) {
if (!this.isFavourite(emote)) return;
Utils.removeFromArray(this.favourites, e => e.name === emote || e.name === emote.name, true);
return this.saveUserData();
}
/**
* Checks if an emote is in favourites.
* @param {Object|String} emote
* @return {Boolean}
*/
isFavourite(emote) {
return !!this.favourites.find(e => e.name === emote || e.name === emote.name);
}
/**
* Load emotes from local database
*/
async loadLocalDb() {
const emotes = await FileUtils.readJsonFromFile(this.dbpath);
for (const [index, emote] of emotes.entries()) {
const { type, id, src, value } = emote;
if (index % 10000 === 0) await Utils.wait();
this.database.set(id, { id: emote.value.id || value, type });
}
Logger.log('EmoteModule', ['Loaded emote database']);
}
async loadUserData() {
const userData = await Database.findOne({ type: 'builtin', id: 'EmoteModule' });
if (!userData) return;
if (userData.hasOwnProperty('favourites')) this._favourites = userData.favourites;
if (userData.hasOwnProperty('mostused')) this._mostUsed = userData.mostused;
}
async saveUserData() {
await Database.insertOrUpdate({ type: 'builtin', id: 'EmoteModule' }, {
type: 'builtin',
id: 'EmoteModule',
favourites: this.favourites,
mostused: this.mostUsed
});
}
/**
* Add/update emote to most used
* @param {Object} emote emote to add/update
* @return {Promise}
*/
addToMostUsed(emote) {
const isMostUsed = this.mostUsed.find(mu => mu.key === emote.name);
if (isMostUsed) {
isMostUsed.useCount += 1;
} else {
this.mostUsed.push({
key: emote.name,
id: emote.id,
type: emote.type,
useCount: 1
});
}
// Save most used to database
// TODO only save first n
return this.saveUserData();
}
/**
* Find an emote by name
* @param {String} name Emote name
* @param {Boolean} simple Simple object or Emote instance
* @returns {Object|Emote}
*/
findByName(name, simple = false) {
const emote = this.database.get(name);
if (!emote) return null;
return this.parseEmote(name, emote, simple);
}
/**
* Parse emote object
* @param {String} name Emote name
* @param {Object} emote Emote object
* @param {Boolean} simple Simple object or Emote instance
* @returns {Object|Emote}
*/
parseEmote(name, emote, simple = false) {
const { type, id } = emote;
if (type < 0 || type > 2) return null;
return simple ? { type, id, name } : new Emote(type, id, name);
}
/**
* Search for anything else
* @param {any} regex
* @param {any} limit
*/
search(regex, limit = 10) {
if (typeof regex === 'string') regex = new RegExp(regex, 'i');
const matching = [];
for (const [key, value] of this.database.entries()) {
if (matching.length >= limit) break;
if (regex.test(key)) matching.push({ key, value })
}
return matching;
}
/* Patches */
async applyPatches() {
this.patchMessageContent();
this.patchSendAndEdit();
this.patchSpoiler();
const MessageAccessories = await ReactComponents.getComponent('MessageAccessories');
this.patch(MessageAccessories.component.prototype, 'render', this.afterRenderMessageAccessories, 'after');
MessageAccessories.forceUpdateAll();
}
/**
* Patches MessageContent render method
*/
async patchMessageContent() {
const MessageContent = await ReactComponents.getComponent('MessageContent');
this.childPatch(MessageContent.component.prototype, 'render', ['props', 'children'], this.afterRenderMessageContent);
MessageContent.forceUpdateAll();
}
/**
* Patches MessageActions send and edit
*/
patchSendAndEdit() {
const { MessageActions } = Reflection.modules;
this.patch(MessageActions, 'sendMessage', this.handleSendMessage, 'instead');
this.patch(MessageActions, 'editMessage', this.handleEditMessage, 'instead');
}
async patchSpoiler() {
const Spoiler = await ReactComponents.getComponent('Spoiler');
this.childPatch(Spoiler.component.prototype, 'render', ['props', 'children', 'props', 'children'], this.afterRenderSpoiler);
Spoiler.forceUpdateAll();
}
afterRenderSpoiler(component, _childrenObject, args, retVal) {
const markup = Utils.findInReactTree(retVal, filter =>
filter &&
filter.className &&
filter.className.includes('inlineContent'));
if (!markup) return;
markup.children = this.processMarkup(markup.children);
}
/**
* Handle message render
*/
afterRenderMessageContent(component, _childrenObject, args, retVal) {
const markup = Utils.findInReactTree(retVal, filter =>
filter &&
filter.className &&
filter.className.includes('markup') &&
filter.children.length >= 2);
if (!markup) return;
markup.children[1] = this.processMarkup(markup.children[1]);
}
/**
* Handle send message
*/
async handleSendMessage(MessageActions, args, orig) {
if (!args.length) return orig(...args);
const { content } = args[1];
if (!content) return orig(...args);
Logger.log('EmoteModule', ['Sending message', MessageActions, args, orig]);
const emoteAsImage = Settings.getSetting('emotes', 'default', 'emoteasimage').value &&
(DiscordApi.currentChannel.type === 'DM' || DiscordApi.currentChannel.type === 'GROUP_DM' || DiscordApi.currentChannel.checkPermissions(DiscordApi.modules.DiscordPermissions.ATTACH_FILES));
if (!emoteAsImage || content.split(' ').length > 1) {
args[1].content = args[1].content.split(' ').map(word => {
const isEmote = /;(.*?);/g.exec(word);
if (isEmote) {
const emote = this.findByName(isEmote[1], true);
if (!emote) return word;
this.addToMostUsed(emote);
return emote ? `;${isEmote[1]};` : word;
}
return word;
}).join(' ');
return orig(...args);
}
const isEmote = /;(.*?);/g.exec(content);
if (!isEmote) return orig(...args);
const emote = this.findByName(isEmote[1]);
if (!emote) return orig(...args);
this.addToMostUsed(emote);
const FileActions = Reflection.module.byProps('makeFile');
const Uploader = Reflection.module.byProps('instantBatchUpload');
request.get(emote.props.src, { encoding: 'binary' }).then(res => {
const arr = new Uint8Array(new ArrayBuffer(res.length));
for (let i = 0; i < res.length; i++) arr[i] = res.charCodeAt(i);
const suffix = arr[0] === 71 && arr[1] === 73 && arr[2] === 70 ? '.gif' : '.png';
Uploader.upload(args[0], FileActions.makeFile(arr, `${emote.name}.bdemote${suffix}`));
});
}
/**
* Handle edit message
*/
handleEditMessage(component, args, orig) {
if (!args.length) return orig(...args);
const { content } = args[2];
if (!content) return orig(...args);
args[2].content = args[2].content.split(' ').map(word => {
const isEmote = /;(.*?);/g.exec(word);
return isEmote ? `;${isEmote[1]};` : word;
}).join(' ');
return orig(...args);
}
/**
* Handle MessageAccessories render
*/
afterRenderMessageAccessories(component, args, retVal) {
if (!component.props || !component.props.message) return;
if (!component.props.message.attachments || component.props.message.attachments.length !== 1) return;
const filename = component.props.message.attachments[0].filename;
const match = filename.match(/([^/]*)\.bdemote\.(gif|png)$/i);
if (!match) return;
const emote = this.findByName(match[1]);
if (!emote) return;
emote.jumboable = true;
retVal.props.children[2] = emote.render();
}
/**
* Inject emotes into markup
*/
processMarkup(markup) {
const newMarkup = [];
if (!(markup instanceof Array)) return markup;
const jumboable = !markup.some(child => {
if (typeof child !== 'string') return false;
return / \w+/g.test(child);
});
for (const child of markup) {
if (typeof child !== 'string') {
if (typeof child === 'object') {
const isEmoji = Utils.findInReactTree(child, filter => filter && filter.emojiName);
if (isEmoji) isEmoji.jumboable = jumboable;
}
newMarkup.push(child);
continue;
}
if (!/;(\w+);/g.test(child)) {
newMarkup.push(child);
continue;
}
const words = child.split(/([^\s]+)([\s]|$)/g).filter(f => f !== '');
let s = '';
for (const word of words) {
const isemote = /;(.*?);/g.exec(word);
if (!isemote) {
s += word;
continue;
}
const emote = this.findByName(isemote[1]);
if (!emote) {
s += word;
continue;
}
newMarkup.push(s);
s = '';
emote.jumboable = jumboable;
newMarkup.push(emote.render());
}
if (s !== '') newMarkup.push(s);
}
if (newMarkup.length === 1) return newMarkup[0];
return newMarkup;
}
}

View File

@ -0,0 +1,4 @@
export { default as EmoteModule, EMOTE_SOURCES } from './EmoteModule';
export { default as Emote } from './EmoteComponent';
export { default as EmoteComponent } from './EmoteComponent.vue';
export { default as EmoteAc } from './EmoteAc';

View File

@ -0,0 +1,28 @@
/**
* BetterDiscord Kill Clyde Module
* Copyright (c) 2015-present Jiiks/JsSucks - https://github.com/Jiiks / https://github.com/JsSucks
* All rights reserved.
* https://betterdiscord.net
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import BuiltinModule from './BuiltinModule';
import { Reflection } from 'modules';
export default new class KillClyde extends BuiltinModule {
/* Getters */
get moduleName() { return 'KillClyde' }
get settingPath() { return ['ui', 'default', 'kill-clyde'] }
/* Patches */
applyPatches() {
if (this.patches.length) return;
const { MessageActions } = Reflection.modules;
this.patch(MessageActions, 'sendBotMessage', () => void 0, 'instead');
}
}

View File

@ -0,0 +1,30 @@
import { EmoteModule, EmoteAc } from './Emotes';
import ReactDevtoolsModule from './ReactDevtoolsModule';
import VueDevtoolsModule from './VueDevToolsModule';
import TrackingProtection from './TrackingProtection';
import E2EE from './E2EE';
import ColoredText from './ColoredText';
import TwentyFourHour from './24Hour';
import KillClyde from './KillClyde';
import BlockedMessages from './BlockedMessages';
import VoiceDisconnect from './VoiceDisconnect';
export default class {
static get modules() {
return require('./builtin');
}
static initAll() {
EmoteModule.init();
ReactDevtoolsModule.init();
VueDevtoolsModule.init();
TrackingProtection.init();
E2EE.init();
ColoredText.init();
TwentyFourHour.init();
KillClyde.init();
BlockedMessages.init();
VoiceDisconnect.init();
EmoteAc.init();
}
}

View File

@ -0,0 +1,55 @@
/**
* BetterDiscord React Devtools Module
* Copyright (c) 2015-present Jiiks/JsSucks - https://github.com/Jiiks / https://github.com/JsSucks
* All rights reserved.
* https://betterdiscord.net
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import electron from 'electron';
import path from 'path';
import BuiltinModule from './BuiltinModule';
import { Globals } from 'modules';
import { Toasts } from 'ui';
export default new class ReactDevtoolsModule extends BuiltinModule {
/* Getters */
get moduleName() { return 'ReactDevTools' }
get settingPath() { return ['core', 'advanced', 'react-devtools'] }
constructor() {
super();
this.devToolsOpened = this.devToolsOpened.bind(this);
}
enabled(e) {
electron.remote.getCurrentWindow().webContents.on('devtools-opened', this.devToolsOpened);
if (electron.remote.getCurrentWindow().isDevToolsOpened) this.devToolsOpened();
}
disabled(e) {
electron.remote.BrowserWindow.removeDevToolsExtension('React Developer Tools');
electron.remote.getCurrentWindow().webContents.removeListener('devtools-opened', this.devToolsOpened);
}
devToolsOpened() {
electron.remote.BrowserWindow.removeDevToolsExtension('React Developer Tools');
try {
const res = electron.remote.BrowserWindow.addDevToolsExtension(path.join(Globals.getPath('ext'), 'extensions', 'rdt'));
if (res !== undefined) {
Toasts.success(`${res} Installed`);
return;
}
Toasts.error('React Developer Tools install failed');
} catch (err) {
Toasts.error('React Developer Tools install failed');
}
}
}

View File

@ -0,0 +1,36 @@
/**
* BetterDiscord Tracking Protection Module
* Copyright (c) 2015-present Jiiks/JsSucks - https://github.com/Jiiks / https://github.com/JsSucks
* All rights reserved.
* https://betterdiscord.net
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import BuiltinModule from './BuiltinModule';
import { Reflection } from 'modules';
export default new class TrackingProtection extends BuiltinModule {
/* Getters */
get moduleName() { return 'TrackingProtection' }
get settingPath() { return ['security', 'default', 'tracking-protection'] }
/* Patches */
applyPatches() {
if (this.patches.length) return;
const TrackingModule = Reflection.module.byProps('track');
if (!TrackingModule) {
this.warn('Tracking module not found!');
return;
}
this.patch(TrackingModule, 'track', this.track, 'instead');
}
track(e) {
this.debug('Tracking blocked');
}
}

View File

@ -0,0 +1,35 @@
/**
* BetterDiscord Voice Disconnect Timestamps Module
* Copyright (c) 2015-present Jiiks/JsSucks - https://github.com/Jiiks / https://github.com/JsSucks
* All rights reserved.
* https://betterdiscord.net
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import BuiltinModule from './BuiltinModule';
import { Reflection } from 'modules';
export default new class VoiceDisconnect extends BuiltinModule {
/* Getters */
get moduleName() { return 'VoiceDisconnect' }
get settingPath() { return ['core', 'default', 'voice-disconnect'] }
async enabled(e) {
window.addEventListener('beforeunload', this.listener);
}
disabled(e) {
window.removeEventListener('beforeunload', this.listener);
}
/* Methods */
listener() {
const { VoiceChannelActions } = Reflection.modules;
VoiceChannelActions.selectVoiceChannel(null, null);
}
}

View File

@ -0,0 +1,55 @@
/**
* BetterDiscord Vue Devtools Module
* Copyright (c) 2015-present Jiiks/JsSucks - https://github.com/Jiiks / https://github.com/JsSucks
* All rights reserved.
* https://betterdiscord.net
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import electron from 'electron';
import path from 'path';
import BuiltinModule from './BuiltinModule';
import { Globals } from 'modules';
import { Toasts } from 'ui';
export default new class VueDevtoolsModule extends BuiltinModule {
/* Getters */
get moduleName() { return 'VueDevTools' }
get settingPath() { return ['core', 'advanced', 'vue-devtools'] }
constructor() {
super();
this.devToolsOpened = this.devToolsOpened.bind(this);
}
enabled(e) {
electron.remote.getCurrentWindow().webContents.on('devtools-opened', this.devToolsOpened);
if (electron.remote.getCurrentWindow().isDevToolsOpened) this.devToolsOpened();
}
disabled(e) {
electron.remote.BrowserWindow.removeDevToolsExtension('Vue.js devtools');
electron.remote.getCurrentWindow().webContents.removeListener('devtools-opened', this.devToolsOpened);
}
devToolsOpened() {
electron.remote.BrowserWindow.removeDevToolsExtension('Vue.js devtools');
try {
const res = electron.remote.BrowserWindow.addDevToolsExtension(path.join(Globals.getPath('ext'), 'extensions', 'vdt'));
if (res !== undefined) {
Toasts.success(`${res} Installed`);
return;
}
Toasts.error('Vue.js devtools install failed');
} catch (err) {
Toasts.error('Vue.js devtools install failed');
}
}
}

View File

@ -0,0 +1,11 @@
export { EmoteModule, EmoteAc } from './Emotes';
export { default as ReactDevtoolsModule } from './ReactDevtoolsModule';
export { default as VueDevtoolsModule } from './VueDevToolsModule';
export { default as TrackingProtection } from './TrackingProtection';
export { default as BuiltinManager } from './Manager';
export { default as E2EE } from './E2EE';
export { default as ColoredText } from './ColoredText';
export { default as TwentyFourHour } from './24Hour';
export { default as KillClyde } from './KillClyde';
export { default as BlockedMessages } from './BlockedMessages';
export { default as VoiceDisconnect } from './VoiceDisconnect';

View File

@ -0,0 +1,79 @@
[
{
"__user": "Jiiks#5000",
"id": "81388395867156480",
"developer": true,
"webdev": true,
"contributor": true
},
{
"__user": "Pohky#0156",
"id": "98003542823944192",
"developer": true,
"webdev": false,
"contributor": true
},
{
"__user": "Hammock#3110",
"id": "138850472541814784",
"developer": false,
"webdev": true,
"contributor": true
},
{
"__user": "Zerebos#7790",
"id": "249746236008169473",
"developer": true,
"webdev": false,
"contributor": true
},
{
"__user": "Pierce#1337",
"id": "125367412370440192",
"developer": true,
"webdev": false,
"contributor": true
},
{
"__user": "Samuel Elliott#2764",
"id": "284056145272766465",
"developer": true,
"webdev": false,
"contributor": true
},
{
"__user": "Lilian Tedone#6223",
"id": "184021060562321419",
"developer": false,
"webdev": false,
"contributor": true
},
{
"__user": "samfun123#8972",
"id": "76052829285916672",
"developer": false,
"webdev": false,
"contributor": true
},
{
"__user": "samogot#4379",
"id": "171005991272316937",
"developer": false,
"webdev": false,
"contributor": true
},
{
"__user": "Lucario 🌌 V5.0.0#7902",
"id": "438469378418409483",
"developer": false,
"webdev": false,
"contributor": true
},
{
"__user": "Maks#3712",
"id": "340975736037048332",
"developer": false,
"webdev": false,
"contributor": true
}
]

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,311 @@
[
{
"id": "core",
"text": "Core",
"headertext": "Core Settings",
"settings": [
{
"id": "default",
"settings": [
{
"id": "voice-disconnect",
"type": "bool",
"text": "Voice Disconnect",
"hint": "Disconnect from voice server when Discord closes",
"value": false
},
{
"id": "menu-keybind",
"type": "keybind",
"text": "Menu keybind",
"value": "mod+b"
}
]
},
{
"id": "advanced",
"name": "Advanced",
"type": "drawer",
"settings": [
{
"id": "developer-mode",
"type": "bool",
"text": "Developer mode",
"hint": "Adds some of BetterDiscord's internal modules to `global._bd`.",
"value": false
},
{
"id": "debugger-keybind",
"type": "keybind",
"text": "Debugger keybind",
"hint": "Open developer tools and pause"
},
{
"id": "ignore-content-manager-errors",
"type": "bool",
"text": "Ignore content manager errors",
"hint": "Only when starting Discord. It gets annoying when you're reloading Discord often and have plugins that are meant to fail.",
"value": false
},
{
"id": "react-devtools",
"type": "bool",
"text": "React Developer Tools",
"hint": "Place extension in ext/extensions/rdt",
"value": false
},
{
"id": "vue-devtools",
"type": "bool",
"text": "Vue Developer Tools",
"hint": "Place extension in ext/extensions/vdt",
"value": false
}
]
},
{
"id": "window-preferences",
"name": "Window Preferences",
"type": "drawer",
"settings": [
{
"id": "window-preferences",
"type": "custom",
"component": "WindowPreferences"
}
]
}
]
},
{
"id": "ui",
"text": "UI",
"headertext": "UI Settings",
"settings": [
{
"id": "default",
"settings": [
{
"id": "hide-button",
"type": "bool",
"text": "Hide the BetterDiscord button",
"hint": "When this is enabled you can use Ctrl/Cmd + B to open the BetterDiscord settings menu.",
"value": false,
"disabled": false
},
{
"id": "enable-toasts",
"type": "bool",
"text": "Enable Toasts",
"hint": "Allows plugins to show toasts.",
"value": true
},
{
"id": "colored-text",
"type": "bool",
"text": "Colored Text",
"hint": "Colors messages to match the user's role color.",
"value": false
},
{
"id": "24-hour",
"type": "bool",
"text": "24 Hour Timestamps",
"hint": "Replaces 12 hour timestamps with proper ones.",
"value": false
},
{
"id": "kill-clyde",
"type": "bool",
"text": "Kill Clyde",
"hint": "Prevents Clyde from sending you error messages.",
"value": false
},
{
"id": "blocked-messages",
"type": "bool",
"text": "Prevent Blocked Messages",
"hint": "Hides blocked messages in chat and even hides the new message notification.",
"value": false
}
]
},
{
"id": "advanced",
"name": "Advanced",
"type": "drawer",
"settings": [
{
"id": "colored-text-intensity",
"type": "slider",
"text": "Colored Text Intensity",
"hint": "Intensity of the colored text setting.",
"value": 100,
"min": 0,
"max": 100,
"step": 1,
"unit": "%"
}
]
}
]
},
{
"id": "emotes",
"text": "Emotes",
"headertext": "Emote Settings",
"settings": [
{
"id": "default",
"settings": [
{
"id": "enable",
"type": "bool",
"text": "Enable emotes",
"value": true
},
{
"id": "emoteasimage",
"type": "bool",
"text": "Image Emote",
"hint": "Send single emotes as images if you have the permission",
"value": true
},
{
"id": "emoteac",
"type": "bool",
"text": "Emote Autocomplete",
"hint": "Autocomplete emotes when typing with ; prefix",
"value": true
},
{
"id": "emoteactype",
"type": "bool",
"text": "Show most used instead of favourites",
"hint": "Toggle with arrow keys in autocomplete menu",
"value": true
}
]
}
]
},
{
"id": "css",
"text": "CSS Editor",
"settings": [
{
"id": "default",
"settings": [
{
"id": "live-update",
"type": "bool",
"text": "Live update",
"hint": "Automatically recompile custom CSS when typing in the custom CSS editor.",
"value": true
},
{
"id": "watch-files",
"type": "bool",
"text": "Watch included files",
"hint": "Automatically recompile theme and custom CSS when a file it imports is changed.",
"value": true
}
]
}
]
},
{
"id": "security",
"text": "Security and Privacy",
"headertext": "Security and Privacy Settings",
"settings": [
{
"id": "default",
"settings": [
{
"id": "unsafe-content",
"type": "bool",
"text": "Allow unverified content",
"hint": "Allow loading unverified plugins/themes",
"value": "false"
},
{
"id": "tracking-protection",
"type": "bool",
"text": "Tracking Protection",
"hint": "Disable any Discord tracking",
"value": false
},
{
"id": "e2ee",
"type": "bool",
"text": "E2EE",
"hint": "End-to-end encryption",
"value": false
},
{
"id": "use-keytar",
"type": "bool",
"text": "Use system keychain",
"hint": "Store the master password in the system keychain",
"value": true
}
]
},
{
"id": "e2eedb",
"name": "E2EE Database",
"type": "drawer",
"settings": [
{
"id": "e2ekvps",
"type": ["securekvp"],
"value": []
}
]
},
{
"id": "e2ee-popout",
"name": "E2EE Popout",
"type": "drawer",
"settings": [
{
"id": "position",
"type": "radio",
"text": "Position",
"value": "above",
"fullwidth": true,
"options": [
{
"text": "Above the lock icon",
"value": "above"
},
{
"text": "Over the lock icon",
"value": "over"
}
]
},
{
"id": "trigger",
"type": "radio",
"text": "Trigger",
"hint": "Only applies when the popout is over the lock icon",
"value": "click",
"fullwidth": true,
"options": [
{
"text": "After clicking the lock icon",
"value": "click"
},
{
"text": "When hovering over the lock icon",
"value": "hover"
}
]
}
]
}
]
}
]

232
client/src/dev/serveremu.js Normal file
View File

@ -0,0 +1,232 @@
const dummyTags = ['dark', 'light', 'simple', 'minimal', 'extra', 'something', 'tag', 'whatever', 'another', 'transparent'];
export default class ServerEmu {
static async themes(args) {
if (!this._themes) this._themes = this.generateThemes();
await new Promise(r => setTimeout(r, Math.random() * 3000));
let docs = [];
if (args && args.sterm) {
const { sterm } = args;
const reg = new RegExp(sterm, 'gi');
docs = this._themes.filter(doc => doc.tags.includes(sterm) || reg.exec(doc.name) || reg.exec(doc.description));
} else {
docs = this._themes;
}
if (args.sort) {
switch (args.sort) {
case 'updated':
if (args.ascending) docs = docs.sort((docA, docB) => new Date(docA.updated).getTime() - new Date(docB.updated).getTime());
else docs = docs.sort((docA, docB) => new Date(docB.updated).getTime() - new Date(docA.updated).getTime());
break;
case 'installs':
if (args.ascending) docs = docs.sort((docA, docB) => docA.installs - docB.installs);
else docs = docs.sort((docA, docB) => docB.installs - docA.installs);
break;
case 'users':
if (args.ascending) docs = docs.sort((docA, docB) => docA.activeUsers - docB.activeUsers);
else docs = docs.sort((docA, docB) => docB.activeUsers - docA.activeUsers);
break;
case 'rating':
if (args.ascending) docs = docs.sort((docA, docB) => docA.rating - docB.rating);
else docs = docs.sort((docA, docB) => docB.rating - docA.rating);
break;
}
}
const total = docs.length;
const pages = Math.ceil(total / 9);
let page = 1;
if (args && args.page) {
page = args.page;
docs = docs.slice((page - 1) * 9, page * 9);
} else {
docs = docs.slice(0, 9);
}
return {
docs,
filters: {
sterm: args.sterm || '',
ascending: args.ascending || false,
sort: args.sort || 'name'
},
pagination: {
total,
pages,
limit: 9,
page
}
}
}
static async plugins(args) {
if (!this._plugins) this._plugins = this.generatePlugins();
await new Promise(r => setTimeout(r, Math.random() * 3000));
let docs = [];
if (args && args.sterm) {
const { sterm } = args;
const reg = new RegExp(sterm, 'gi');
docs = this._plugins.filter(doc => doc.tags.includes(sterm) || reg.exec(doc.name) || reg.exec(doc.description));
} else {
docs = this._plugins;
}
if (args.sort) {
switch (args.sort) {
case 'updated':
if (args.ascending) docs = docs.sort((docA, docB) => new Date(docA.updated).getTime() - new Date(docB.updated).getTime());
else docs = docs.sort((docA, docB) => new Date(docB.updated).getTime() - new Date(docA.updated).getTime());
break;
case 'installs':
if (args.ascending) docs = docs.sort((docA, docB) => docA.installs - docB.installs);
else docs = docs.sort((docA, docB) => docB.installs - docA.installs);
break;
case 'users':
if (args.ascending) docs = docs.sort((docA, docB) => docA.activeUsers - docB.activeUsers);
else docs = docs.sort((docA, docB) => docB.activeUsers - docA.activeUsers);
break;
case 'rating':
if (args.ascending) docs = docs.sort((docA, docB) => docA.rating - docB.rating);
else docs = docs.sort((docA, docB) => docB.rating - docA.rating);
break;
}
}
const total = docs.length;
const pages = Math.ceil(total / 9);
let page = 1;
if (args && args.page) {
page = args.page;
docs = docs.slice((page - 1) * 9, page * 9);
} else {
docs = docs.slice(0, 9);
}
return {
docs,
filters: {
sterm: args.sterm || '',
ascending: args.ascending || false,
sort: args.sort || 'name'
},
pagination: {
total,
pages,
limit: 9,
page
}
}
}
static generateThemes() {
const docs = [];
const count = Math.floor(Math.random() * 50 + 30);
for (let i = 0; i < count; i++) {
const id = `theme${i}-${this.randomId()}`;
const name = `Dummy Theme ${i}`;
const tags = dummyTags.sort(() => .5 - Math.random()).slice(0, 3);
docs.push({
id,
name,
tags,
installs: Math.floor(Math.random() * 5000) + 5000,
updated: this.randomTimestamp(),
rating: Math.floor(Math.random() * 500) + 500,
activeUsers: Math.floor(Math.random() * 1000) + 1000,
rated: Math.random() > .5,
version: this.randomVersion(),
repository: this.dummyThemeRepo,
files: this.dummyFiles,
author: this.dummyAuthor,
description: ''
});
}
return docs;
}
static generatePlugins() {
const docs = [];
const count = Math.floor(Math.random() * 50 + 30);
for (let i = 0; i < count; i++) {
const id = `plugin${i}-${this.randomId()}`;
const name = `Dummy Plugin ${i}`;
const tags = dummyTags.sort(() => .5 - Math.random()).slice(0, 3);
docs.push({
id,
name,
tags,
installs: Math.floor(Math.random() * 5000) + 5000,
updated: this.randomTimestamp(),
rating: Math.floor(Math.random() * 500) + 500,
activeUsers: Math.floor(Math.random() * 1000) + 1000,
rated: Math.random() > .5,
version: this.randomVersion(),
repository: this.dummyPluginRepo,
files: this.dummyFiles,
author: this.dummyAuthor,
description: ''
});
}
return docs;
}
static get dummyThemeRepo() {
return {
name: 'ExampleRepository',
baseUri: 'https://github.com/Jiiks/ExampleRepository',
rawUri: 'https://github.com/Jiiks/ExampleRepository/raw/master',
assetUri: 'https://api.github.com/repos/Jiiks/ExampleRepository/releases/assets/10023264'
}
}
static get dummyPluginRepo() {
return {
name: 'ExampleRepository',
baseUri: 'https://github.com/Jiiks/ExampleRepository',
rawUri: 'https://github.com/Jiiks/ExampleRepository/raw/master',
assetUri: 'https://api.github.com/repos/Jiiks/ExampleRepository/releases/assets/10023265'
}
}
static get dummyFiles() {
return {
readme: 'Example/readme.md',
previews: [{
large: 'Example/preview1-big.png',
thumb: 'Example/preview1-small.png'
}]
}
}
static get dummyAuthor() {
return 'Someone';
}
static randomId() {
return btoa(Math.random()).substring(3, 9);
}
static randomTimestamp() {
return `2018-${Math.floor((Math.random() * 12) + 1).toString().padStart(2, '0')}-${Math.floor((Math.random() * 30) + 1).toString().padStart(2, '0')}T14:51:32.057Z`;
}
static randomVersion() {
return `${Math.round(Math.random() * 3)}.${Math.round(Math.random() * 10)}.${Math.round(Math.random() * 10)}`;
}
}

141
client/src/index.js Normal file
View File

@ -0,0 +1,141 @@
/**
* BetterDiscord Client Core
* Copyright (c) 2015-present Jiiks/JsSucks - https://github.com/Jiiks / https://github.com/JsSucks
* All rights reserved.
* https://betterdiscord.net
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import { DOM, BdUI, BdMenu, Modals, Toasts, Notifications, BdContextMenu, DiscordContextMenu, Autocomplete } from 'ui';
import BdCss from './styles/index.scss';
import { Events, Globals, Settings, Database, Updater, ModuleManager, PluginManager, ThemeManager, ExtModuleManager, Vendor, Patcher, MonkeyPatch, ReactComponents, ReactHelpers, ReactAutoPatcher, DiscordApi, BdWebApi, Connectivity, Cache, Reflection, PackageInstaller } from 'modules';
import { ClientLogger as Logger, ClientIPC, Utils, Axi } from 'common';
import { BuiltinManager, EmoteModule, ReactDevtoolsModule, VueDevtoolsModule, TrackingProtection, E2EE } from 'builtin';
import electron from 'electron';
import path from 'path';
const tests = typeof PRODUCTION === 'undefined';
const ignoreExternal = tests && true;
class BetterDiscord {
constructor() {
Logger.file = tests ? path.resolve(__dirname, '..', '..', 'tests', 'log.txt') : path.join(__dirname, 'log.txt');
Logger.trimLogFile();
Logger.log('main', 'BetterDiscord starting');
this._bd = {
DOM, BdUI, BdMenu, Modals, Reflection, Toasts, Notifications, BdContextMenu, DiscordContextMenu, Autocomplete,
Events, Globals, Settings, Database, Updater,
ModuleManager, PluginManager, ThemeManager, ExtModuleManager, PackageInstaller,
Vendor,
Patcher, MonkeyPatch, ReactComponents, ReactHelpers, ReactAutoPatcher, DiscordApi,
BuiltinManager, EmoteModule,
BdWebApi,
Connectivity,
Cache,
Logger, ClientIPC, Utils, Axi,
plugins: PluginManager.localContent,
themes: ThemeManager.localContent,
extmodules: ExtModuleManager.localContent,
__filename, __dirname,
module: Globals.require.cache[__filename],
require: Globals.require,
webpack_require: __webpack_require__, // eslint-disable-line no-undef
get discord_require() { return Reflection.require }
};
const developermode = Settings.getSetting('core', 'advanced', 'developer-mode');
if (developermode.value) window._bd = this._bd;
developermode.on('setting-updated', event => {
if (event.value) window._bd = this._bd;
else if (window._bd) delete window._bd;
});
const debuggerkeybind = Settings.getSetting('core', 'advanced', 'debugger-keybind');
debuggerkeybind.on('keybind-activated', () => {
const currentWindow = electron.remote.getCurrentWindow();
if (currentWindow.isDevToolsOpened()) return eval('debugger;');
currentWindow.openDevTools();
setTimeout(() => eval('debugger;'), 1000);
});
DOM.injectStyle(BdCss, 'bdmain');
this.globalReady = this.globalReady.bind(this);
Events.on('global-ready', this.globalReady);
Globals.initg();
}
globalReady() {
BdUI.initUiEvents();
this.vueInstance = BdUI.injectUi();
this.init();
}
async init() {
try {
await Database.init();
await Settings.loadSettings();
await ModuleManager.initModules();
BuiltinManager.initAll();
if (tests) this.initTests();
if (!ignoreExternal) {
await ExtModuleManager.loadAllModules(true);
await PluginManager.loadAllPlugins(true);
await ThemeManager.loadAllThemes(true);
}
Events.emit('ready');
Events.emit('discord-ready');
if (!Settings.get('core', 'advanced', 'ignore-content-manager-errors'))
Modals.showContentManagerErrors();
} catch (err) {
Logger.err('main', ['FAILED TO LOAD!', err]);
}
}
initTests() {
let notifications = 0;
function showDummyNotif() { // eslint-disable-line no-inner-declarations
Notifications.add(notifications++ ? `Notification ${notifications}` : undefined, 'Dummy Notification', [
{
text: 'Show Again', onClick: function () {
setTimeout(showDummyNotif, 5000);
return true;
}
},
{
text: 'Ignore', onClick: function () {
return true;
}
}
]);
}
showDummyNotif();
DiscordContextMenu.add([
{
text: 'Hello',
onClick: () => { Toasts.info('Hello!'); }
}
]);
}
}
if (window.BetterDiscord) {
Logger.log('main', 'Attempting to inject again?');
} else {
let instance;
Events.on('autopatcher', () => instance = new BetterDiscord());
ReactAutoPatcher.autoPatch().then(() => Events.emit('autopatcher'));
}

View File

@ -0,0 +1,82 @@
/**
* BetterDiscord Web Apis
* Copyright (c) 2015-present Jiiks/JsSucks - https://github.com/Jiiks / https://github.com/JsSucks
* All rights reserved.
* https://betterdiscord.net
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import ServerEmu from '../dev/serveremu';
import { request } from 'vendor';
const APIBASE = 'ifyouareinwebtestthenyouknowwhatthisshouldbe'; // Do not push
const ENDPOINTS = {
'themes': `${APIBASE}/themes`,
'theme': id => `${APIBASE}/theme/${id}`,
'users': `${APIBASE}/users`,
'user': id => `${APIBASE}/user/${id}`,
'statistics': `${APIBASE}/statistics`
};
export default class BdWebApi {
static get themes() {
return {
get: this.getThemes
};
}
static get plugins() {
return {
get: this.getPlugins
};
}
static get users() {
return {
get: this.getUsers
};
}
static get statistics() {
return {
get: this.getStatistics,
patch: this.patchStatistics
};
}
static getThemes(args) {
return ServerEmu.themes(args);
// return dummyThemes();
/*
if (!args) return request.get(ENDPOINTS.themes);
const { id } = args;
if (id) return request.get(ENDPOINTS.theme(id));
return request.get(ENDPOINTS.themes);
*/
}
static getPlugins(args) {
return ServerEmu.plugins(args);
}
static getUsers(args) {
if (!args) return request.get(ENDPOINTS.users);
const { id } = args;
if (id) return request.get(ENDPOINTS.user(id));
return request.get(ENDPOINTS.users);
}
static getStatistics() {
return request.get(ENDPOINTS.statistics);
}
static patchStatistics(json) {
return request({ method: 'PATCH', url: ENDPOINTS.statistics, json });
}
}

View File

@ -0,0 +1,38 @@
/**
* BetterDiscord Cache Module
* Copyright (c) 2015-present Jiiks/JsSucks - https://github.com/Jiiks / https://github.com/JsSucks
* All rights reserved.
* https://betterdiscord.net
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
const CACHE = [];
export default class Cache {
static get cache() {
return CACHE;
}
/**
* Push something to cache
* @param {String} where Cache identifier
* @param {any} data Data to push
*/
static push(where, data) {
if (!this.cache[where]) this.cache[where] = [];
this.cache[where].push(data);
}
/**
* Find something in cache
* @param {String} where Cache identifier
* @param {Function} what Find callback
*/
static find(where, what) {
if (!this.cache[where]) this.cache[where] = [];
return this.cache[where].find(what);
}
}

View File

@ -0,0 +1,25 @@
/**
* BetterDiscord Connectivity Module
* Copyright (c) 2015-present Jiiks/JsSucks - https://github.com/Jiiks / https://github.com/JsSucks
* All rights reserved.
* https://betterdiscord.net
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import BdWebApi from './bdwebapi';
import { ClientLogger as Logger } from 'common';
export default class Connectivity {
static start() {
Logger.info('Connectivity', `Patching anonymous statistics`);
BdWebApi.statistics.patch({ themes: [], plugins: [] });
setInterval(() => {
Logger.info('Connectivity', `Patching anonymous statistics`);
BdWebApi.statistics.patch({ themes: [], plugins: [] });
}, 15*60*1000);
}
}

View File

@ -0,0 +1,149 @@
/**
* BetterDiscord Content Base
* Copyright (c) 2015-present Jiiks/JsSucks - https://github.com/Jiiks / https://github.com/JsSucks
* All rights reserved.
* https://betterdiscord.net
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import { Utils, ClientLogger as Logger, AsyncEventEmitter } from 'common';
import { Modals } from 'ui';
import Database from './database';
export default class Content extends AsyncEventEmitter {
constructor(internals) {
super();
internals.loaded = Date.now();
internals.started = undefined;
internals.stopped = undefined;
Utils.deepfreeze(internals.info);
Object.freeze(internals.paths);
this.__internals = internals;
this.settings.on('setting-updated', event => this.emit('setting-updated', event));
this.settings.on('settings-updated', event => this.emit('settings-updated', event));
this.settings.on('settings-updated', event => this.__settingsUpdated(event));
// Add hooks
if (this.onstart) this.on('start', event => this.onstart(event));
if (this.onStart) this.on('start', event => this.onStart(event));
if (this.onstop) this.on('stop', event => this.onstop(event));
if (this.onStop) this.on('stop', event => this.onStop(event));
if (this.onunload) this.on('unload', event => this.onunload(event));
if (this.onUnload) this.on('unload', event => this.onUnload(event));
if (this.settingUpdated) this.on('setting-updated', event => this.settingUpdated(event));
if (this.settingsUpdated) this.on('settings-updated', event => this.settingsUpdated(event));
}
get type() { return undefined }
get configs() { return this.__internals.configs }
get info() { return this.__internals.info }
get paths() { return this.__internals.paths }
get main() { return this.__internals.main }
get defaultConfig() { return this.configs.defaultConfig }
get userConfig() { return this.configs.userConfig }
get configSchemes() { return this.configs.schemes }
get id() { return this.info.id || this.name.toLowerCase().replace(/[^a-zA-Z0-9-]/g, '-').replace(/--/g, '-') }
get name() { return this.info.name }
get icon() { return this.info.icon }
get description() { return this.info.description }
get authors() { return this.info.authors }
get version() { return this.info.version }
get loadedTimestamp() { return this.__internals.loaded }
get startedTimestamp() { return this.__internals.started }
get stoppedTimestamp() { return this.__internals.stopped }
get contentPath() { return this.paths.contentPath }
get dirName() { return this.paths.dirName }
get enabled() { return this.userConfig.enabled }
get settings() { return this.userConfig.config }
get config() { return this.settings.categories }
get data() { return this.userConfig.data || (this.userConfig.data = {}) }
get packed() { return this.dirName.packed }
get packagePath() { return this.dirName.packagePath }
get packageName() { return this.dirName.pkg }
/**
* Opens a settings modal for this content.
* @return {Modal}
*/
showSettingsModal() {
return Modals.contentSettings(this);
}
/**
* Whether this content has any settings.
*/
get hasSettings() {
return !!this.settings.findSetting(() => true);
}
/**
* Saves the content's current configuration.
* @return {Promise}
*/
async saveConfiguration() {
try {
Database.insertOrUpdate({ type: `${this.type}-config`, id: this.id }, {
type: `${this.type}-config`,
id: this.id,
enabled: this.enabled,
config: this.settings.strip().settings,
data: this.data
});
this.settings.setSaved();
} catch (err) {
Logger.err(this.name, ['Failed to save configuration', err]);
throw err;
}
}
/**
* Called when settings are updated.
* This can be overridden by other content types.
*/
__settingsUpdated(event) {
return this.saveConfiguration();
}
/**
* Enables the content.
* @param {Boolean} save Whether to save the new enabled state
* @return {Promise}
*/
async enable(save = true) {
if (this.enabled) return;
await this.emit('enable');
await this.emit('start');
this.__internals.started = Date.now();
this.__internals.stopped = undefined;
this.userConfig.enabled = true;
if (save) await this.saveConfiguration();
}
/**
* Disables the content.
* @param {Boolean} save Whether to save the new enabled state
* @return {Promise}
*/
async disable(save = true) {
if (!this.enabled) return;
await this.emit('stop');
await this.emit('disable');
this.__internals.started = undefined;
this.__internals.stopped = Date.now();
this.userConfig.enabled = false;
if (save) await this.saveConfiguration();
}
}
Object.freeze(Content.prototype);

View File

@ -0,0 +1,449 @@
/**
* BetterDiscord Content Manager Module
* Copyright (c) 2015-present Jiiks/JsSucks - https://github.com/Jiiks / https://github.com/JsSucks
* All rights reserved.
* https://betterdiscord.net
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import asar from 'asar';
import path, { dirname } from 'path';
import rimraf from 'rimraf';
import { remote } from 'electron';
import Content from './content';
import Globals from './globals';
import Database from './database';
import { Utils, FileUtils, ClientLogger as Logger } from 'common';
import { SettingsSet, ErrorEvent } from 'structs';
import { Modals } from 'ui';
import Combokeys from 'combokeys';
import Settings from './settings';
/**
* Base class for managing external content
*/
export default class {
/**
* Any errors that happened.
* @return {Array}
*/
static get errors() {
return this._errors || (this._errors = []);
}
/**
* Locally stored content.
* @return {Array}
*/
static get localContent() {
return this._localContent ? this._localContent : (this._localContent = []);
}
/**
* The type of content this content manager manages.
*/
static get contentType() {
return undefined;
}
/**
* The name of this content manager.
*/
static get moduleName() {
return undefined;
}
/**
* The path used to store this content manager's content.
*/
static get pathId() {
return undefined;
}
/**
* Local path for content.
* @return {String}
*/
static get contentPath() {
return Globals.getPath(this.pathId);
}
static async packContent(path, contentPath) {
return new Promise((resolve, reject) => {
remote.dialog.showSaveDialog({
title: 'Save Package',
defaultPath: path,
filters: [
{
name: 'BetterDiscord Package',
extensions: ['bd']
}
]
}, filepath => {
if (!filepath) return;
asar.uncache(filepath);
asar.createPackage(contentPath, filepath, () => {
resolve(filepath);
});
});
});
}
/**
* Load all locally stored content.
* @param {bool} suppressErrors Suppress any errors that occur during loading of content
*/
static async loadAllContent(suppressErrors = false) {
try {
await FileUtils.ensureDirectory(this.contentPath);
const directories = await FileUtils.listDirectory(this.contentPath);
for (const dir of directories) {
const packed = dir.endsWith('.bd');
if (!packed) {
try {
await FileUtils.directoryExists(path.join(this.contentPath, dir));
} catch (err) { continue; }
}
try {
if (packed) {
await this.preloadPackedContent(dir);
} else {
await this.preloadContent(dir);
}
} catch (err) {
this.errors.push(new ErrorEvent({
module: this.moduleName,
message: `Failed to load ${dir}`,
err
}));
Logger.err(this.moduleName, err);
}
}
if (this.errors.length && !suppressErrors) {
Modals.error({
header: `${this.moduleName} - ${this.errors.length} ${this.contentType}${this.errors.length !== 1 ? 's' : ''} failed to load`,
module: this.moduleName,
type: 'err',
content: this.errors
});
this._errors = [];
}
} catch (err) {
throw err;
}
}
/**
* Refresh locally stored content
* @param {bool} suppressErrors Suppress any errors that occur during loading of content
*/
static async refreshContent(suppressErrors = false) {
if (!this.localContent.length) return this.loadAllContent();
try {
await FileUtils.ensureDirectory(this.contentPath);
const directories = await FileUtils.listDirectory(this.contentPath);
for (const dir of directories) {
const packed = dir.endsWith('.bd');
// If content is already loaded this should resolve
if (this.getContentByDirName(dir)) continue;
try {
await FileUtils.directoryExists(path.join(this.contentPath, dir));
} catch (err) { continue; }
try {
// Load if not
await this.preloadContent(dir);
} catch (err) {
// We don't want every plugin/theme to fail loading when one does
this.errors.push(new ErrorEvent({
module: this.moduleName,
message: `Failed to load ${dir}`,
err
}));
Logger.err(this.moduleName, err);
}
}
for (const content of this.localContent) {
if (directories.includes(content.dirName)) continue;
try {
// Plugin/theme was deleted manually, stop it and remove any reference
await this.unloadContent(content);
} catch (err) {
this.errors.push(new ErrorEvent({
module: this.moduleName,
message: `Failed to unload ${content.dirName}`,
err
}));
Logger.err(this.moduleName, err);
}
}
if (this.errors.length && !suppressErrors) {
Modals.error({
header: `${this.moduleName} - ${this.errors.length} ${this.contentType}${this.errors.length !== 1 ? 's' : ''} failed to load`,
module: this.moduleName,
type: 'err',
content: this.errors
});
this._errors = [];
}
} catch (err) {
throw err;
}
}
static async preloadPackedContent(pkg, reload = false, index) {
try {
const packagePath = path.join(this.contentPath, pkg);
const packageName = pkg.replace('.bd', '');
await FileUtils.fileExists(packagePath);
const config = JSON.parse(asar.extractFile(packagePath, 'config.json').toString());
const unpackedPath = path.join(Globals.getPath('tmp'), packageName);
asar.extractAll(packagePath, unpackedPath);
return this.preloadContent({
config,
contentPath: unpackedPath,
packagePath: packagePath,
pkg,
packageName,
packed: true
}, reload, index);
} catch (err) {
Logger.log('ContentManager', ['Error extracting packed content', err]);
throw err;
}
}
/**
* Common loading procedure for loading content before passing it to the actual loader
* @param {any} dirName Base directory for content
* @param {any} reload Is content being reloaded
* @param {any} index Index of content in {localContent}
*/
static async preloadContent(dirName, reload = false, index) {
try {
const unsafeAllowed = Settings.getSetting('security', 'default', 'unsafe-content').value;
const packed = typeof dirName === 'object' && dirName.packed;
// Block any unpacked content as they can't be verified
if (!packed && !unsafeAllowed) {
throw 'Blocked unsafe content';
}
const contentPath = packed ? dirName.contentPath : path.join(this.contentPath, dirName);
await FileUtils.directoryExists(contentPath);
if (!reload && this.getContentByPath(contentPath))
throw { 'message': `Attempted to load already loaded user content: ${path}` };
const configPath = path.resolve(contentPath, 'config.json');
const readConfig = packed ? dirName.config : await FileUtils.readJsonFromFile(configPath);
const mainPath = path.join(contentPath, readConfig.main || 'index.js');
const defaultConfig = new SettingsSet({
settings: readConfig.defaultConfig,
schemes: readConfig.configSchemes
});
const userConfig = {
enabled: false,
config: undefined,
data: {}
};
try {
const id = readConfig.info.id || readConfig.info.name.toLowerCase().replace(/[^a-zA-Z0-9-]/g, '-').replace(/--/g, '-');
const readUserConfig = await Database.find({ type: `${this.contentType}-config`, id });
if (readUserConfig.length) {
userConfig.enabled = readUserConfig[0].enabled || false;
userConfig.config = readUserConfig[0].config;
userConfig.data = readUserConfig[0].data || {};
}
} catch (err) {
// We don't care if this fails it either means that user config doesn't exist or there's something wrong with it so we revert to default config
Logger.warn(this.moduleName, [`Failed reading config for ${this.contentType} ${readConfig.info.name} in ${packed ? dirName.pkg : dirName}`, err]);
}
userConfig.config = defaultConfig.clone({ settings: userConfig.config });
userConfig.config.setSaved();
for (const setting of userConfig.config.findSettings(() => true)) {
// This will load custom settings
// Setting the content's path on only the live config (and not the default config) ensures that custom settings will not be loaded on the default settings
setting.setContentPath(contentPath);
}
for (const scheme of userConfig.config.schemes) {
scheme.setContentPath(contentPath);
}
Utils.deepfreeze(defaultConfig, object => object instanceof Combokeys);
const configs = {
defaultConfig,
schemes: userConfig.schemes,
userConfig
};
const paths = {
contentPath,
dirName,
mainPath
};
const content = await this.loadContent(paths, configs, readConfig.info, readConfig.main, readConfig.dependencies, readConfig.permissions, readConfig.mainExport, packed ? dirName : false);
if (!content) return undefined;
if (!reload && this.getContentById(content.id))
throw { message: `A ${this.contentType} with the ID ${content.id} already exists.` };
if (reload) this.localContent.splice(index, 1, content);
else this.localContent.push(content);
return content;
} catch (err) {
throw err;
}
}
/**
* Delete content.
* @param {Content|String} content Content to delete
* @param {Boolean} force If true the content will be deleted even if an exception is thrown when disabling/unloading/deleting
*/
static async deleteContent(content, force) {
content = this.findContent(content);
if (!content) throw {message: `Could not find a ${this.contentType} from ${content}.`};
try {
await Modals.confirm(`Delete ${this.contentType}?`, `Are you sure you want to delete ${content.info.name} ?`, 'Delete').promise;
} catch (err) {
return false;
}
try {
const unload = this.unloadContent(content, force, false);
if (!force)
await unload;
await FileUtils.recursiveDeleteDirectory(content.paths.contentPath);
if (content.packed) await FileUtils.recursiveDeleteDirectory(content.packagePath);
return true;
} catch (err) {
Logger.err(this.moduleName, err);
throw err;
}
}
/**
* Unload content.
* @param {Content|String} content Content to unload
* @param {Boolean} force If true the content will be unloaded even if an exception is thrown when disabling/unloading
* @param {Boolean} reload Whether to reload the content after
* @return {Content}
*/
static async unloadContent(content, force, reload) {
content = this.findContent(content);
if (!content) throw {message: `Could not find a ${this.contentType} from ${content}.`};
try {
const disablePromise = content.disable(false);
const unloadPromise = content.emit('unload', reload);
if (!force) {
await disablePromise;
await unloadPromise;
}
const index = this.getContentIndex(content);
if (this.unloadContentHook) this.unloadContentHook(content);
if (reload) return content.packed ? this.preloadPackedContent(content.packagePath, true, index) : this.preloadContent(content.dirName, true, index);
this.localContent.splice(index, 1);
} catch (err) {
Logger.err(this.moduleName, err);
throw err;
}
}
/**
* Reload content.
* @param {Content|String} content Content to reload
* @param {Boolean} force If true the content will be unloaded even if an exception is thrown when disabling/unloading
* @return {Content}
*/
static reloadContent(content, force) {
return this.unloadContent(content, force, true);
}
/**
* Checks if the passed object is an instance of this content type.
* @param {Any} content Object to check
* @return {Boolean}
*/
static isThisContent(content) {
return content instanceof Content;
}
/**
* Returns the first content where calling {function} returns true.
* @param {Function} function A function to call to filter content
*/
static find(f) {
return this.localContent.find(f);
}
/**
* Wildcard content finder
* @param {String} wild Content ID / directory name / path / name
* @param {Boolean} nonunique Allow searching attributes that may not be unique
* @return {Content}
*/
static findContent(wild, nonunique) {
if (this.isThisContent(wild)) return wild;
let content;
content = this.getContentById(wild); if (content) return content;
content = this.getContentByDirName(wild); if (content) return content;
content = this.getContentByPath(wild); if (content) return content;
content = this.getContentByName(wild); if (content && nonunique) return content;
}
static getContentIndex(content) { return this.localContent.findIndex(c => c === content) }
static getContentById(id) { return this.localContent.find(c => c.id === id) }
static getContentByDirName(dirName) { return this.localContent.find(c => c.dirName === dirName) }
static getContentByPath(path) { return this.localContent.find(c => c.contentPath === path) }
static getContentByName(name) { return this.localContent.find(c => c.name === name) }
/**
* Wait for content to load
* @param {String} content_id
* @return {Promise => Content}
*/
static waitForContent(content_id) {
return Utils.until(() => this.getContentById(content_id), 100);
}
}

View File

@ -0,0 +1,318 @@
/**
* BetterDiscord CSS Editor Module
* Copyright (c) 2015-present Jiiks/JsSucks - https://github.com/Jiiks / https://github.com/JsSucks
* All rights reserved.
* https://betterdiscord.net
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import { DOM } from 'ui';
import { FileUtils, ClientLogger as Logger, ClientIPC } from 'common';
import path from 'path';
import electron from 'electron';
import filewatcher from 'filewatcher';
import Settings from './settings';
/**
* Custom css editor communications
*/
export default new class {
constructor() {
this._scss = '';
this._css = '';
this._error = undefined;
this.editor_bounds = undefined;
this._files = undefined;
this._filewatcher = undefined;
this._watchfiles = undefined;
this.compiling = false;
}
/**
* Init css editor.
*/
init() {
ClientIPC.on('bd-get-scss', () => this.scss, true);
ClientIPC.on('bd-update-scss', (e, scss) => this.updateScss(scss));
ClientIPC.on('bd-save-csseditor-bounds', (e, bounds) => this.saveEditorBounds(bounds));
ClientIPC.on('bd-editor-runScript', (e, script) => {
try {
new Function(script)();
e.reply('ok');
} catch (err) {
e.reply({ err: err.stack || err });
}
});
ClientIPC.on('bd-save-scss', async (e, scss) => {
await this.updateScss(scss);
await this.save();
}, true);
this.liveupdate = Settings.getSetting('css', 'default', 'live-update');
this.liveupdate.on('setting-updated', event => {
this.sendToEditor('set-liveupdate', event.value);
});
ClientIPC.on('bd-get-liveupdate', () => this.liveupdate.value, true);
ClientIPC.on('bd-set-liveupdate', (e, value) => this.liveupdate.value = value);
this.watchfilessetting = Settings.getSetting('css', 'default', 'watch-files');
this.watchfilessetting.on('setting-updated', event => {
if (event.value) this.watchfiles = this.files;
else this.watchfiles = [];
});
}
/**
* Show css editor, flashes if already visible.
*/
async show() {
await ClientIPC.send('openCssEditor', this.editor_bounds);
}
/**
* Update css in client.
* @param {String} scss SCSS to compile
* @param {bool} sendSource Whether to send to css editor instance
*/
async updateScss(scss, sendSource) {
if (sendSource)
this.sendToEditor('set-scss', scss);
if (!scss && !await this.fileExists()) {
this._scss = this.css = '';
this.sendToEditor('scss-error', null);
return;
}
try {
this.compiling = true;
const result = await this.compile(scss);
this.css = result.css.toString();
this._scss = scss;
this.files = result.stats.includedFiles;
this.error = null;
this.compiling = false;
} catch (err) {
this.compiling = false;
this.error = err;
throw err;
}
}
/**
* Save css to file.
* @return {Promise}
*/
save() {
return Settings.saveSettings();
}
/**
* Save current editor bounds.
* @param {Rectangle} bounds Editor bounds
* @return {Promise}
*/
saveEditorBounds(bounds) {
this.editor_bounds = bounds;
return Settings.saveSettings();
}
/**
* Send SCSS to core for compilation.
* @param {String} scss SCSS string
*/
async compile(scss) {
return ClientIPC.send('bd-compileSass', {
data: scss,
path: await this.fileExists() ? this.filePath : undefined
});
}
/**
* Recompile the current SCSS.
* @return {Promise}
*/
async recompile() {
return this.updateScss(this.scss);
}
/**
* Send data to open editor.
* @param {String} channel
* @param {Any} data
* @return {Promise}
*/
async sendToEditor(channel, data) {
return ClientIPC.sendToCssEditor(channel, data);
}
/**
* Opens an SCSS file in a system editor.
* @return {Promise}
*/
async openSystemEditor() {
try {
await FileUtils.fileExists(this.filePath);
} catch (err) {
// File doesn't exist
// Create it
await FileUtils.writeFile(this.filePath, '');
}
Logger.log('CSS Editor', `Opening file ${this.filePath} in the user's default editor.`);
// For some reason this doesn't work
// if (!electron.shell.openItem(this.filePath))
if (!electron.shell.openExternal(`file://${this.filePath}`))
throw {message: 'Failed to open system editor.'};
}
/**
* Set current state
* @param {String} scss Current uncompiled SCSS
* @param {String} css Current compiled CSS
* @param {String} files Files imported in the SCSS
* @param {String} err Current compiler error
*/
setState(scss, css, files, err) {
this._scss = scss;
this.sendToEditor('set-scss', scss);
this.css = css;
this.files = files;
this.error = err;
}
/**
* Current uncompiled scss.
*/
get scss() {
return this._scss || '';
}
/**
* Set current scss.
*/
set scss(scss) {
this.updateScss(scss, true);
}
/**
* Current compiled css.
*/
get css() {
return this._css || '';
}
/**
* Inject compiled css to head.
*/
set css(css) {
this._css = css;
DOM.injectStyle(css, 'bd-customcss');
}
/**
* Current error.
*/
get error() {
return this._error || undefined;
}
/**
* Set current error.
*/
set error(err) {
this._error = err;
this.sendToEditor('scss-error', err);
}
/**
* An array of files that are imported in custom CSS.
* @return {Array} Files being watched
*/
get files() {
return this._files || (this._files = []);
}
/**
* Sets all files that are imported in custom CSS.
* @param {Array} files Files to watch
*/
set files(files) {
this._files = files;
if (Settings.get('css', 'default', 'watch-files'))
this.watchfiles = files;
}
/**
* A filewatcher instance.
*/
get filewatcher() {
if (this._filewatcher) return this._filewatcher;
this._filewatcher = filewatcher();
this._filewatcher.on('change', (file, stat) => {
// Recompile SCSS
this.recompile();
});
return this._filewatcher;
}
/**
* An array of files that are being watched for changes.
* @return {Array} Files being watched
*/
get watchfiles() {
return this._watchfiles || (this._watchfiles = []);
}
/**
* Sets all files to be watched.
* @param {Array} files Files to watch
*/
set watchfiles(files) {
for (const file of files) {
if (!this.watchfiles.includes(file)) {
this.filewatcher.add(file);
this.watchfiles.push(file);
Logger.log('CSS Editor', `Watching file ${file} for changes`);
}
}
for (const index in this.watchfiles) {
let file = this.watchfiles[index];
while (file && !files.find(f => f === file)) {
this.filewatcher.remove(file);
this.watchfiles.splice(index, 1);
Logger.log('CSS Editor', `No longer watching file ${file} for changes`);
file = this.watchfiles[index];
}
}
}
/**
* The path of the file the system editor should save to.
* @return {String}
*/
get filePath() {
return path.join(Settings.dataPath, 'user.scss');
}
/**
* Checks if the system editor's file exists.
* @return {Promise}
*/
async fileExists() {
try {
await FileUtils.fileExists(this.filePath);
return true;
} catch (err) {
return false;
}
}
}

View File

@ -0,0 +1,61 @@
/**
* BetterDiscord Database Module
* Copyright (c) 2015-present Jiiks/JsSucks - https://github.com/Jiiks / https://github.com/JsSucks
* All rights reserved.
* https://betterdiscord.net
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import { ClientIPC } from 'common';
export default class {
static async init() {
return true;
}
/**
* Inserts or updates data in the database.
* @param {Object} args The record to find
* @param {Object} data The new record
* @return {Promise}
*/
static async insertOrUpdate(args, data) {
try {
return ClientIPC.send('bd-dba', { action: 'update', args, data });
} catch (err) {
throw err;
}
}
/**
* Finds data in the database.
* @param {Object} args The record to find
* @return {Promise}
*/
static async find(args) {
try {
return ClientIPC.send('bd-dba', { action: 'find', args });
} catch (err) {
throw err;
}
}
/**
* Find first in the database
* @param {Object} args The record to find
* @return {Promise} null if record was not found
*/
static async findOne(args) {
try {
const find = await this.find(args);
if (find && find.length) return find[0];
return null;
} catch (err) {
throw err;
}
}
}

View File

@ -0,0 +1,335 @@
/**
* BetterDiscord Discord API
* Copyright (c) 2015-present Jiiks/JsSucks - https://github.com/Jiiks / https://github.com/JsSucks
* All rights reserved.
* https://betterdiscord.net
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import { List } from 'structs';
import { User, Channel, Guild, Message } from 'discordstructs';
import Reflection from './reflection/index';
export const Modules = {
_getModule(name) {
const foundModule = Reflection.module.byName(name);
if (!foundModule) return null;
delete this[name];
return this[name] = foundModule;
},
get ChannelSelector() { return this._getModule('ChannelSelector'); },
get MessageActions() { return this._getModule('MessageActions'); },
get MessageParser() { return this._getModule('MessageParser'); },
get MessageStore() { return this._getModule('MessageStore'); },
get EmojiUtils() { return this._getModule('EmojiUtils'); },
get PermissionUtils() { return this._getModule('Permissions'); },
get SortedGuildStore() { return this._getModule('SortedGuildStore'); },
get PrivateChannelActions() { return this._getModule('PrivateChannelActions'); },
get GuildMemberStore() { return this._getModule('GuildMemberStore'); },
get GuildChannelsStore() { return this._getModule('GuildChannelsStore'); },
get MemberCountStore() { return this._getModule('MemberCountStore'); },
get GuildActions() { return this._getModule('GuildActions'); },
get NavigationUtils() { return this._getModule('NavigationUtils'); },
get GuildPermissions() { return this._getModule('GuildPermissions'); },
get DiscordConstants() { return this._getModule('DiscordConstants'); },
get ChannelStore() { return this._getModule('ChannelStore'); },
get GuildStore() { return this._getModule('GuildStore'); },
get SelectedGuildStore() { return this._getModule('SelectedGuildStore'); },
get SelectedChannelStore() { return this._getModule('SelectedChannelStore'); },
get UserStore() { return this._getModule('UserStore'); },
get RelationshipStore() { return this._getModule('RelationshipStore'); },
get RelationshipManager() { return this._getModule('RelationshipManager'); },
get ChangeNicknameModal() { return this._getModule('ChangeNicknameModal'); },
get UserSettingsStore() { return this._getModule('UserSettingsStore'); },
get UserSettingsWindow() { return this._getModule('UserSettingsWindow'); },
get UserStatusStore() { return this._getModule('UserStatusStore'); },
get ChannelSettingsWindow() { return this._getModule('ChannelSettingsWindow'); },
get GuildSettingsWindow() { return this._getModule('GuildSettingsWindow'); },
get CreateChannelModal() { return this._getModule('CreateChannelModal'); },
get PruneMembersModal() { return this._getModule('PruneMembersModal'); },
get NotificationSettingsModal() { return this._getModule('NotificationSettingsModal'); },
get PrivacySettingsModal() { return this._getModule('PrivacySettingsModal'); },
get UserProfileModal() { return this._getModule('UserProfileModal'); },
get APIModule() { return this._getModule('APIModule'); },
get UserNoteStore() { return this._getModule('UserNoteStore'); },
get DiscordPermissions() { return this.DiscordConstants.Permissions; }
};
export default class DiscordApi {
static get modules() { return Modules }
static get User() { return User }
static get Channel() { return Channel }
static get Guild() { return Guild }
static get Message() { return Message }
/**
* A list of loaded guilds.
* @type {List<Guild>}
*/
static get guilds() {
const guilds = Modules.GuildStore.getGuilds();
return List.from(Object.entries(guilds), ([i, g]) => Guild.from(g));
}
/**
* A list of loaded channels.
* @type {List<Channel>}
*/
static get channels() {
const channels = Modules.ChannelStore.getChannels();
return List.from(Object.entries(channels), ([i, c]) => Channel.from(c));
}
/**
* A list of loaded users.
* @type {List<User>}
*/
static get users() {
const users = Modules.UserStore.getUsers();
return List.from(Object.entries(users), ([i, u]) => User.from(u));
}
/**
* An object mapping guild IDs to their member counts.
* @type {Object}
*/
static get memberCounts() {
return Modules.MemberCountStore.getMemberCounts();
}
/**
* A list of guilds in the order they appear in the server list.
* @type {List<Guild>}
*/
static get sortedGuilds() {
const guilds = Modules.SortedGuildStore.getSortedGuilds();
return List.from(guilds, g => Guild.from(g));
}
/**
* An array of guild IDs in the order they appear in the server list.
* @type {Number[]}
*/
static get guildPositions() {
return Modules.SortedGuildStore.guildPositions;
}
/**
* The currently selected guild.
* @type {Guild}
*/
static get currentGuild() {
const guild = Modules.GuildStore.getGuild(Modules.SelectedGuildStore.getGuildId());
if (guild) return Guild.from(guild);
return null;
}
/**
* The currently selected channel.
* @type {Channel}
*/
static get currentChannel() {
const channel = Modules.ChannelStore.getChannel(Modules.SelectedChannelStore.getChannelId());
if (channel) return Channel.from(channel);
return null;
}
/**
* The current user.
* @type {User}
*/
static get currentUser() {
const user = Modules.UserStore.getCurrentUser();
if (user) return User.from(user);
return null;
}
/**
* A list of the current user's friends.
* @type {List<User>}
*/
static get friends() {
const friends = Modules.RelationshipStore.getFriendIDs();
return List.from(friends, id => User.fromId(id));
}
/**
* User settings
*/
static get UserSettings() {
return UserSettings;
}
}
export class UserSettings {
/**
* Opens Discord's settings UI.
*/
static open(section = 'ACCOUNT') {
Modules.UserSettingsWindow.setSection(section);
Modules.UserSettingsWindow.open();
}
/**
* The user's current status. Either "online", "idle", "dnd" or "invisible".
* @type {String}
*/
static get status() { return Modules.UserSettingsStore.status }
/**
* The user's selected explicit content filter level.
* 0 == off, 1 == everyone except friends, 2 == everyone
* Configurable in the privacy and safety panel.
* @type {Number}
*/
static get explicitContentFilter() { return Modules.UserSettingsStore.explicitContentFilter }
/**
* Whether to disallow direct messages from server members by default.
* @type {Boolean}
*/
static get defaultGuildsRestricted() { return Modules.UserSettingsStore.defaultGuildsRestricted }
/**
* An array of guilds to disallow direct messages from their members.
* This is bypassed if the member is has another mutual guild with this disabled, or the member is friends with the current user.
* Configurable in each server's privacy settings.
* @type {Guild[]}
*/
static get restrictedGuildIds() { return Modules.UserSettingsStore.restrictedGuilds }
static get restrictedGuilds() {
return List.from(this.restrictedGuildIds, id => Guild.fromId(id) || id);
}
/**
* An array of flags specifying who should be allowed to add the current user as a friend.
* If everyone is checked, this will only have one item, "all". Otherwise it has either "mutual_friends", "mutual_guilds", both or neither.
* Configurable in the privacy and safety panel.
* @type {Array}
*/
static get friendSourceFlags() { return Object.keys(Modules.UserSettingsStore.friendSourceFlags) }
static get friendSourceEveryone() { return this.friendSourceFlags.include('all') }
static get friendSourceMutual_friends() { return this.friendSourceFlags.include('all') || this.friendSourceFlags.include('mutual_friends') }
static get friendSourceMutual_guilds() { return this.friendSourceFlags.include('all') || this.friendSourceFlags.include('mutual_guilds') }
static get friendSourceAnyone() { return this.friendSourceFlags.length > 0 }
/**
* Whether to automatically add accounts from other platforms running on the user's computer.
* Configurable in the connections panel.
* @type {Boolean}
*/
static get detectPlatformAccounts() { return Modules.UserSettingsStore.detectPlatformAccounts }
/**
* The number of seconds Discord will wait for activity before sending mobile push notifications.
* Configurable in the notifications panel.
* @type {Number}
*/
static get afkTimeout() { return Modules.UserSettingsStore.afkTimeout }
/**
* Whether to display the currently running game as a status message.
* Configurable in the games panel.
* @type {Boolean}
*/
static get showCurrentGame() { return Modules.UserSettingsStore.showCurrentGame }
/**
* Whether to show images uploaded directly to Discord.
* Configurable in the text and images panel.
* @type {Boolean}
*/
static get inlineAttachmentMedia() { return Modules.UserSettingsStore.inlineAttachmentMedia }
/**
* Whether to show images linked in Discord.
* Configurable in the text and images panel.
* @type {Boolean}
*/
static get inlineEmbedMedia() { return Modules.UserSettingsStore.inlineEmbedMedia }
/**
* Whether to automatically play GIFs when the Discord window is active without having to hover the mouse over the image.
* Configurable in the text and images panel.
* @type {Boolean}
*/
static get autoplayGifs() { return Modules.UserSettingsStore.gifAutoPlay }
/**
* Whether to show content from HTTP[s] links as embeds.
* Configurable in the text and images panel.
* @type {Boolean}
*/
static get showEmbeds() { return Modules.UserSettingsStore.renderEmbeds }
/**
* Whether to show a message's reactions.
* Configurable in the text and images panel.
* @type {Boolean}
*/
static get showReactions() { return Modules.UserSettingsStore.renderReactions }
/**
* Whether to play animated emoji.
* Configurable in the text and images panel.
* @type {Boolean}
*/
static get animateEmoji() { return Modules.UserSettingsStore.animateEmoji }
/**
* Whether to convert ASCII emoticons to emoji.
* Configurable in the text and images panel.
* @type {Boolean}
*/
static get convertEmoticons() { return Modules.UserSettingsStore.convertEmoticons }
/**
* Whether to allow playing text-to-speech messages.
* Configurable in the text and images panel.
* @type {Boolean}
*/
static get allowTts() { return Modules.UserSettingsStore.enableTTSCommand }
/**
* The user's selected theme. Either "dark" or "light".
* Configurable in the appearance panel.
* @type {String}
*/
static get theme() { return Modules.UserSettingsStore.theme }
/**
* Whether the user has enabled compact mode.
* `true` if compact mode is enabled, `false` if cozy mode is enabled.
* Configurable in the appearance panel.
* @type {Boolean}
*/
static get displayCompact() { return Modules.UserSettingsStore.messageDisplayCompact }
/**
* Whether the user has enabled developer mode.
* Currently only adds a "Copy ID" option to the context menu on users, guilds and channels.
* Configurable in the appearance panel.
* @type {Boolean}
*/
static get developerMode() { return Modules.UserSettingsStore.developerMode }
/**
* The user's selected language code.
* Configurable in the language panel.
* @type {String}
*/
static get locale() { return Modules.UserSettingsStore.locale }
/**
* The user's timezone offset in hours.
* This is not configurable.
* @type {Number}
*/
static get timezoneOffset() { return Modules.UserSettingsStore.timezoneOffset }
}

View File

@ -0,0 +1,66 @@
/**
* BetterDiscord Editor Module
* Copyright (c) 2015-present Jiiks/JsSucks - https://github.com/Jiiks / https://github.com/JsSucks
* All rights reserved.
* https://betterdiscord.net
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import Module from './imodule';
import { DOM } from 'ui';
export default new class extends Module {
get name() { return 'Editor' }
get delay() { return false; }
setInitialState(state) {
return {
editorBounds: undefined
};
}
initialize() {
super.initialize();
(async () => {
try {
// TODO this is temporary
const userScss = await this.send('readDataFile', 'user.scss');
const compiled = await this.send('compileSass', { data: userScss });
this.injectStyle('customcss', compiled.css.toString());
} catch (err) {
console.warn('SCSS Compilation error', err);
}
})();
}
events(ipc) {
ipc.on('editor-runScript', (e, script) => {
try {
new Function(script)();
e.reply('ok');
} catch (err) {
e.reply({ err: err.stack || err });
}
});
ipc.on('editor-injectStyle', (e, { id, style }) => {
this.injectStyle(id, style);
e.reply('ok');
});
}
injectStyle(id, style) {
return DOM.injectStyle(style, `userstyle-${id}`);
}
/**
* Show editor, flashes if already visible.
*/
async show() {
await this.send('editor-open', this.state.editorBounds);
}
}

View File

@ -0,0 +1,159 @@
/**
* BetterDiscord Event Hook
* Copyright (c) 2015-present Jiiks/JsSucks - https://github.com/Jiiks / https://github.com/JsSucks
* All rights reserved.
* https://betterdiscord.net
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import Reflection from './reflection/index';
import { MonkeyPatch } from './patcher';
import Events from './events';
import EventListener from './eventlistener';
import * as SocketStructs from '../structs/socketstructs';
/**
* Discord socket event hook
* @extends {EventListener}
*/
export default class extends EventListener {
init() {
this.ignoreMultiple = -1;
this.hook();
}
bindings() {
this.hook = this.hook.bind(this);
}
get eventBindings() {
return [
{ id: 'discord-ready', callback: this.hook }
];
}
hook() {
const { Events } = Reflection.modules;
MonkeyPatch('BD:EVENTS', Events.prototype).after('emit', (obj, args, retVal) => {
const eventId = args.length >= 3 ? args[2].id || -1 : -1;
if (eventId === this.ignoreMultiple) return;
this.ignoreMultiple = eventId;
if (obj.webSocket) this.wsc = obj.webSocket;
this.emit(...args);
});
/*
const orig = Events.prototype.emit;
Events.prototype.emit = function (...args) {
orig.call(this, ...args);
self.wsc = this;
self.emit(...args);
};*/
}
/**
* Discord emit overload
* @param {any} event
* @param {any} action
* @param {any} data
*/
emit(e, action, data) {
switch (e) {
case 'dispatch':
return this.dispatch(action, data);
}
}
/**
* Emit callback
* @param {any} event Event
* @param {any} data Event data
*/
dispatch(type, data) {
Events.emit('raw-event', { type, data });
if (type === this.actions.READY || type === this.actions.RESUMED) {
Events.emit(type, data);
return;
}
if (!Object.keys(SocketStructs).includes(type)) return;
Events.emit(`discord:${type}`, new SocketStructs[type](data));
}
get SocketStructs() {
return SocketStructs;
}
/**
* All known socket actions
*/
get actions() {
if (this._actions) return this._actions;
return this._actions = {
READY: 'READY', // Socket ready
RESUMED: 'RESUMED', // Socket resumed
TYPING_START: 'TYPING_START', // User typing start
ACTIVITY_START: 'ACTIVITY_START', // ??
MESSAGE_CREATE: 'MESSAGE_CREATE', // New message
MESSAGE_UPDATE: 'MESSAGE_UPDATE', // Edit
MESSAGE_DELETE: 'MESSAGE_DELETE', // Message deleted
MESSAGE_DELETE_BULK: 'MESSAGE_DELETE_BULK', // Bulk messages deleted
MESSAGE_ACK: 'MESSAGE_ACK', // Message fetch
MESSAGE_REACTION_ADD: 'MESSAGE_REACTION_ADD', // eww reactions
MESSAGE_REACTION_REMOVE: 'MESSAGE_REACTION_REMOVE', // ^^
MESSAGE_REACTION_REMOVE_ALL: 'MESSAGE_REACTION_REMOVE_ALL', // ^^
CHANNEL_PINS_ACK: 'CHANNEL_PINS_ACK', // Pinned messages fetch
CHANNEL_PINS_UPDATE: 'CHANNEL_PINS_UPDATE', // Message pinned/unpinned, does not trigger when message is deleted
CHANNEL_CREATE: 'CHANNEL_CREATE', // Channel created
CHANNEL_DELETE: 'CHANNEL_DELETE', // Channel deleted
CHANNEL_UPDATE: 'CHANNEL_UPDATE', // Channel updated
GUILD_CREATE: 'GUILD_CREATE', // Guild create
GUILD_DELETE: 'GUILD_DELETE', // Guild delete
GUILD_SYNC: 'GUILD_SYNC', // Synced when switching to server that's not loaded
GUILD_MEMBERS_CHUNK: 'GUILD_MEMBERS_CHUNK', // ??
GUILD_BAN_ADD: 'GUILD_BAN_ADD', // User banned
GUILD_BAN_REMOVE: 'GUILD_BAN_REMOVE', // User unbanned
GUILD_MEMBER_ADD: 'GUILD_MEMBER_ADD', // User joins guild
GUILD_MEMBER_UPDATE: 'GUILD_MEMBER_UPDATE', // Roles etc
GUILD_MEMBER_REMOVE: 'GUILD_MEMBER_REMOVE', // Kick
GUILD_ROLE_CREATE: 'GUILD_ROLE_CREATE', // Roles
GUILD_ROLE_UPDATE: 'GUILD_ROLE_UPDATE', // Roles
GUILD_ROLE_DELETE: 'GUILD_ROLE_DELETE', // Roles,
GUILD_EMOJIS_UPDATE: 'GUILD_EMOJIS_UPDATE', // No emojis pls
GUILD_INTEGRATIONS_UPDATE: 'GUILD_INTEGRATIONS_UPDATE', // Twitch etc?
USER_UPDATE: 'USER_UPDATE', // Name change etc?
USER_SETTINGS_UPDATE: 'USER_SETTINGS_UPDATE', // Any setting change
USER_GUILD_SETTINGS_UPDATE: 'USER_GUILD_SETTINGS_UPDATE', // Guild notification/privacy etc
USER_CONNECTIONS_UPDATE: 'USER_CONNECTIONS_UPDATE', // Steam etc
USER_REQUIRED_ACTION_UPDATE: 'USER_REQUIRED_ACTION_UPDATE', // ??
USER_NOTE_UPDATE: 'USER_NOTE_UPDATE', // Not edits
RELATIONSHIP_ADD: 'RELATIONSHIP_ADD', // Friends
RELATIONSHIP_REMOVE: 'RELATIONSHIP_REMOVE', // Friends
PRESENCE_UPDATE: 'PRESENCE_UPDATE', // Status
PRESENCES_REPLACE: 'PRESENCES_REPLACE', // ??
VOICE_STATE_UPDATE: 'VOICE_STATE_UPDATE', // Speaking?
VOICE_SERVER_UPDATE: 'VOICE_SERVER_UPDATE', // ??
CALL_CREATE: 'CALL_CREATE', // Don't call me
CALL_UPDATE: 'CALL_UPDATE', // ^^^^^^^^^^^^
CALL_DELETE: 'CALL_DELETE', // ^^^^^^^^^^^^
OAUTH2_TOKEN_REVOKE: 'OAUTH2_TOKEN_REVOKE', // Logged out elsewhere?
RECENT_MENTION_DELETE: 'RECENT_MENTION_DELETE', // No idea what triggers this?
FRIEND_SUGGESTION_CREATE: 'FRIEND_SUGGESTION_CREATE', // Connected account stuff?
FRIEND_SUGGESTION_DELETE: 'FRIEND_SUGGESTION_DELETE', // ^^
WEBHOOKS_UPDATE: 'WEBHOOKS_UPDATE', // Any webhook change on any server
USER_PAYMENTS_UPDATE: 'USER_PAYMENTS_UPDATE', // Won't test
USER_BILLING_PROFILE_UPDATE: 'USER_BILLING_PROFILE_UPDATE', // Won't test
ACTIVITY_JOIN_REQUEST: 'ACTIVITY_JOIN_REQUEST', // Nothing seems to trigger this
ACTIVITY_JOIN_INVITE: 'ACTIVITY_JOIN_INVITE', // Same
LFG_LISTING_CREATE: 'LFG_LISTING_CREATE', // No groups here
LFG_LISTING_DELETE: 'LFG_LISTING_DELETE', // Thank you
BRAINTREE_POPUP_BRIDGE_CALLBACK: 'BRAINTREE_POPUP_BRIDGE_CALLBACK' // What
};
}
}

View File

@ -0,0 +1,22 @@
/**
* BetterDiscord Event Listener Module
* Copyright (c) 2015-present Jiiks/JsSucks - https://github.com/Jiiks / https://github.com/JsSucks
* All rights reserved.
* https://betterdiscord.net
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import Module from './module';
import Events from './events';
export default class extends Module {
events() {
for (const event of this.eventBindings) {
Events.on(event.id, event.callback);
}
}
}

View File

@ -0,0 +1,54 @@
/**
* BetterDiscord Events Module
* Copyright (c) 2015-present Jiiks/JsSucks - https://github.com/Jiiks / https://github.com/JsSucks
* All rights reserved.
* https://betterdiscord.net
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import { EventEmitter } from 'events';
const emitter = new EventEmitter();
export default class {
/**
* Adds an event listener.
* @param {String} event The event to listen for
* @param {Function} callback The function to call when the event is emitted
*/
static on(event, callback) {
emitter.on(event, callback);
}
/**
* Adds an event listener that is only called once.
* @param {String} event The event to listen for
* @param {Function} callback The function to call when the event is emitted
*/
static once(event, callback) {
emitter.once(event, callback);
}
/**
* Removes an event listener.
* @param {String} event The event to remove
* @param {Function} callback The listener to remove
*/
static off(event, callback) {
emitter.removeListener(event, callback);
}
static get removeListener() { return this.off }
/**
* Emits an event
* @param {String} event The event to emit
* @param {Any} ...data Data to pass to the event listeners
*/
static emit(event, ...data) {
emitter.emit(event, ...data);
}
}

View File

@ -0,0 +1,55 @@
/**
* BetterDiscord Events Wrapper Module
* Copyright (c) 2015-present Jiiks/JsSucks - https://github.com/Jiiks / https://github.com/JsSucks
* All rights reserved.
* https://betterdiscord.net
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
const eventemitters = new WeakMap();
export default class EventsWrapper {
constructor(eventemitter, bind) {
eventemitters.set(this, eventemitter);
this.bind = bind || this;
}
get eventSubs() {
return this._eventSubs || (this._eventSubs = []);
}
get on() { return this.subscribe }
subscribe(event, callback) {
if (this.eventSubs.find(e => e.event === event && e.callback === callback)) return;
const boundCallback = (...args) => callback.apply(this.bind, args);
this.eventSubs.push({ event, callback, boundCallback });
eventemitters.get(this).on(event, boundCallback);
}
once(event, callback) {
if (this.eventSubs.find(e => e.event === event && e.callback === callback)) return;
const boundCallback = (...args) => this.off(event, callback) && callback.apply(this.bind, args);
this.eventSubs.push({ event, callback, boundCallback });
eventemitters.get(this).on(event, boundCallback);
}
get off() { return this.unsubscribe }
unsubscribe(event, callback) {
for (const index in this.eventSubs) {
if (this.eventSubs[index].event !== event || (callback && this.eventSubs[index].callback === callback)) continue;
eventemitters.get(this).removeListener(event, this.eventSubs[index].boundCallback);
this.eventSubs.splice(index, 1);
}
}
unsubscribeAll() {
for (const event of this.eventSubs) {
eventemitters.get(this).removeListener(event.event, event.boundCallback);
}
this.eventSubs.splice(0, this.eventSubs.length);
}
}

View File

@ -0,0 +1,23 @@
/**
* BetterDiscord External Module Base
* Copyright (c) 2015-present Jiiks/JsSucks - https://github.com/Jiiks / https://github.com/JsSucks
* All rights reserved.
* https://betterdiscord.net
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import Globals from './globals';
import Content from './content';
export default class ExtModule extends Content {
constructor(internals) {
super(internals);
this.__require = Globals.require(this.paths.mainPath);
}
get type() { return 'module' }
}

View File

@ -0,0 +1,62 @@
/**
* BetterDiscord External Module Manager Module
* Copyright (c) 2015-present Jiiks/JsSucks - https://github.com/Jiiks / https://github.com/JsSucks
* All rights reserved.
* https://betterdiscord.net
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import ContentManager from './contentmanager';
import ExtModule from './extmodule';
export default class extends ContentManager {
static get localModules() {
return this.localContent;
}
static get contentType() {
return 'module';
}
static get moduleName() {
return 'Ext Module Manager';
}
static get pathId() {
return 'modules';
}
static get loadAllModules() {
return this.loadAllContent;
}
static get refreshModules() { return this.refreshContent }
static get loadContent() { return this.loadModule }
static async loadModule(paths, configs, info, main) {
return new ExtModule({
configs, info, main,
paths: {
contentPath: paths.contentPath,
dirName: paths.dirName,
mainPath: paths.mainPath
}
});
}
static get isExtModule() { return this.isThisContent }
static isThisContent(module) {
return module instanceof ExtModule;
}
static get findModule() { return this.findContent }
static get getModuleIndex() { return this.getContentIndex }
static get getModuleByName() { return this.getContentByName }
static get getModuleById() { return this.getContentById }
static get getModuleByPath() { return this.getContentByPath }
static get getModuleByDirName() { return this.getContentByDirName }
}

View File

@ -0,0 +1,104 @@
/**
* BetterDiscord Globals Module
* Copyright (c) 2015-present Jiiks/JsSucks - https://github.com/Jiiks / https://github.com/JsSucks
* All rights reserved.
* https://betterdiscord.net
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import path from 'path';
import sparkplug from 'sparkplug';
import { ClientIPC } from 'common';
import Module from './module';
import Events from './events';
export default new class extends Module {
constructor(args) {
super(args);
// webpack replaces this with the normal require function
// eslint-disable-next-line no-undef
this.require = __non_webpack_require__;
}
initg() {
this.first();
}
bindings() {
this.first = this.first.bind(this);
this.setWS = this.setWS.bind(this);
this.getObject = this.getObject.bind(this);
}
async first() {
const config = await ClientIPC.send('getConfig');
this.setState({ config });
// This is for Discord to stop error reporting :3
window.BetterDiscord = {
version: config.version,
v: config.version
};
window.jQuery = {};
if (sparkplug.bd) {
this.setState({ bd: sparkplug.bd });
sparkplug.bd.setWS = this.setWS;
}
Events.emit('global-ready');
Events.emit('socket-created', this.state.wsHook);
}
setWS(wSocket) {
const state = this.state;
state.wsHook = wSocket;
this.setState(state);
Events.emit('socket-created');
}
getObject(name) {
return this.config[name] || this.bd[name];
}
get bd() {
return this.state.bd;
}
get localStorage() {
return this.bd.localStorage;
}
get webSocket() {
return this.bd.wsHook;
}
get WebSocket() {
return this.bd.wsOrig;
}
get ignited() {
return this.bd.ignited;
}
get config() {
return this.state.config;
}
get paths() {
return this.config.paths;
}
getPath(id) {
return this.paths.find(path => path.id === id).path;
}
get version() {
return this.config.versions.core;
}
}

View File

@ -0,0 +1,73 @@
/**
* BetterDiscord Module Base
* Copyright (c) 2015-present JsSucks - https://github.com/JsSucks
* All rights reserved.
* https://github.com/JsSucks - https://betterdiscord.net
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/**
* Base Module that every non-static module should extend
*/
import { ClientLogger as Logger, ClientIPC } from 'common';
export default class Module {
constructor(args) {
this.__ = {
state: args || {},
args
};
this.setState = this.setState.bind(this);
if (this.delay) { // If delay is set then module is set to load delayed from modulemanager
this.initialize = this.initialize.bind(this);
this.init = this.initialize;
} else {
this.initialize();
this.init = () => { };
}
}
initialize() {
if (this.bindings) this.bindings();
if (this.setInitialState) this.setState(this.setInitialState(this.state));
if (this.events) this.events(ClientIPC);
}
setState(newState) {
const oldState = Object.assign({}, this.state);
Object.assign(this.state, newState);
if (this.stateChanged) this.stateChanged(oldState, newState);
}
set args(t) { }
get args() { return this.__.args; }
set state(state) { return this.__.state = state; }
get state() { return this.__.state; }
async send(channel, message) {
return ClientIPC.send(channel, message);
}
log(msg) {
Logger.log(this.name, msg);
}
warn(msg) {
Logger.log(this.name, msg);
}
err(msg) {
Logger.log(this.name, msg);
}
info(msg) {
Logger.log(this.name, msg);
}
}

View File

@ -0,0 +1,43 @@
/**
* BetterDiscord Module Base
* Copyright (c) 2015-present JsSucks - https://github.com/JsSucks
* All rights reserved.
* https://github.com/JsSucks - https://betterdiscord.net
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/**
* Base Module that every non-static module should extend
*/
export default class Module {
constructor(args) {
this.__ = {
state: args || {},
args
};
this.setState = this.setState.bind(this);
this.initialize();
}
initialize() {
if (this.bindings) this.bindings();
if (this.setInitialState) this.setInitialState(this.state);
if (this.events) this.events();
}
setState(newState) {
const oldState = this.state;
Object.assign(this.state, newState);
if (this.stateChanged) this.stateChanged(oldState, newState);
}
set args(t) { }
get args() { return this.__.args; }
set state(state) { return this.__.state = state; }
get state() { return this.__.state; }
}

View File

@ -0,0 +1,49 @@
/**
* BetterDiscord Module Manager
* Copyright (c) 2015-present Jiiks/JsSucks - https://github.com/Jiiks / https://github.com/JsSucks
* All rights reserved.
* https://betterdiscord.net
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import { ClientLogger as Logger } from 'common';
import { SocketProxy, EventHook } from 'modules';
import { ProfileBadges, ClassNormaliser } from 'ui';
import Updater from './updater';
/**
* Module Manager initializes all modules when everything is ready
*/
export default class {
/**
* An array of modules.
*/
static get modules() {
return this._modules ? this._modules : (this._modules = [
new ProfileBadges(),
new ClassNormaliser(),
new SocketProxy(),
new EventHook(),
Updater
]);
}
/**
* Initializes all modules.
* @return {Promise}
*/
static async initModules() {
for (const module of this.modules) {
try {
if (module.init && module.init instanceof Function) module.init();
} catch (err) {
Logger.err('Module Manager', ['Failed to initialize module:', err]);
}
}
return true;
}
}

View File

@ -0,0 +1,31 @@
export { default as Events } from './events';
export { default as CssEditor } from './csseditor';
export { default as Editor } from './editor';
export { default as Globals } from './globals';
export { default as Settings } from './settings';
export { default as Database } from './database';
export { default as Updater } from './updater';
export { default as ModuleManager } from './modulemanager';
export { default as PluginManager } from './pluginmanager';
export { default as ThemeManager } from './thememanager';
export { default as ExtModuleManager } from './extmodulemanager';
export { default as Permissions } from './permissionmanager';
export { default as EventsWrapper } from './eventswrapper';
export { default as Vendor } from './vendor';
export * from './webpackmodules';
export * from './patcher';
export * from './reactcomponents';
export { default as Module } from './module';
export { default as EventListener } from './eventlistener';
export { default as SocketProxy } from './socketproxy';
export { default as EventHook } from './eventhook';
export { default as DiscordApi, Modules as DiscordApiModules } from './discordapi';
export { default as BdWebApi } from './bdwebapi';
export { default as Connectivity } from './connectivity';
export { default as Security } from './security';
export { default as Cache } from './cache';
export { default as Reflection } from './reflection/index';
export { default as PackageInstaller } from './packageinstaller';

View File

@ -0,0 +1,178 @@
import EventListener from './eventlistener';
import asar from 'asar';
import fs from 'fs';
import path from 'path';
import rimraf from 'rimraf';
import { request } from 'vendor';
import { Modals } from 'ui';
import { Utils, FileUtils } from 'common';
import PluginManager from './pluginmanager';
import Globals from './globals';
import Security from './security';
import Reflection from './reflection';
import DiscordApi from './discordapi';
import ThemeManager from './thememanager';
import { MonkeyPatch } from './patcher';
import { DOM } from 'ui';
export default class PackageInstaller {
/**
* Handler for drag and drop package install
* @param {String} filePath Path to local file
* @param {Boolean} canUpload If the user can upload files in current window
* @returns {Number} returns action code from modal
*/
static async dragAndDropHandler(filePath, canUpload) {
try {
const config = JSON.parse(asar.extractFile(filePath, 'config.json').toString());
const { info, main } = config;
let icon = null;
if (info.icon && info.icon_type) {
const extractIcon = asar.extractFile(filePath, info.icon);
icon = `data:${info.icon_type};base64,${Utils.arrayBufferToBase64(extractIcon)}`;
}
const isPlugin = info.type && info.type === 'plugin' || main.endsWith('.js');
// Show install modal
const modalResult = await Modals.installModal(isPlugin ? 'plugin' : 'theme', config, filePath, icon, canUpload).promise;
return modalResult;
} catch (err) {
console.log(err);
}
}
/**
* Hash and verify a package
* @param {Byte[]|String} bytesOrPath byte array of binary or path to local file
* @param {String} id Package id
*/
static async verifyPackage(bytesOrPath, id) {
const bytes = typeof bytesOrPath === 'string' ? fs.readFileSync(bytesOrPath) : bytesOrPath;
// Temporary hash to simulate response from server
const tempVerified = ['2e3532ee366816adc37b0f478bfef35e03f96e7aeee9b115f5918ef6a4e94de8', '06a2eb4e37b926354ab80cd83207db67e544c932e9beddce545967a21f8db5aa'];
const hashBytes = Security.hash('sha256', bytes, 'hex');
return tempVerified.includes(hashBytes);
}
// TODO lots of stuff
/**
* Installs or updates defined package
* @param {Byte[]|String} bytesOrPath byte array of binary or path to local file
* @param {String} nameOrId Package name
* @param {Boolean} update Does an older version already exist
*/
static async installPackage(bytesOrPath, nameOrId, contentType, update = false) {
let outputPath = null;
try {
const bytes = typeof bytesOrPath === 'string' ? fs.readFileSync(bytesOrPath) : bytesOrPath;
const outputName = `${nameOrId}.bd`;
outputPath = path.join(Globals.getPath(`${contentType}s`), outputName);
fs.writeFileSync(outputPath, bytes);
const manager = contentType === 'plugin' ? PluginManager : ThemeManager;
if (!update) return manager.preloadPackedContent(outputName);
const oldContent = manager.findContent(nameOrId);
await oldContent.unload(true);
if (oldContent.packed && oldContent.packageName !== nameOrId) {
await FileUtils.deleteFile(oldContent.packagePath).catch(err => null);
}
await FileUtils.recursiveDeleteDirectory(oldContent.contentPath).catch(err => null);
return manager.preloadPackedContent(outputName);
} catch (err) {
throw err;
}
}
/**
* Install package from remote location. Only github/bdapi is supported.
* @param {String} remoteLocation Remote resource location
*/
static async installRemotePackage(remoteLocation) {
try {
const { hostname } = Object.assign(document.createElement('a'), { href: remoteLocation });
if (hostname !== 'api.github.com' && hostname !== 'secretbdapi') throw 'Invalid host!';
const options = {
uri: remoteLocation,
encoding: null,
headers: {
'User-Agent': 'BetterDiscordClient',
'Accept': 'application/octet-stream'
}
};
const response = await request.get(options);
const outputPath = path.join(Globals.getPath('tmp'), Security.hash('sha256', response, 'hex'));
fs.writeFileSync(outputPath, response);
console.log('response', response);
console.log('output', outputPath);
await this.dragAndDropHandler(outputPath);
rimraf(outputPath, err => {
if (err) console.log(err);
});
} catch (err) {
throw err;
}
}
static async handleDrop(stateNode, e, original) {
if (!e.dataTransfer.files.length || !e.dataTransfer.files[0].name.endsWith('.bd')) return original && original.call(stateNode, e);
e.preventDefault();
e.stopPropagation();
e.stopImmediatePropagation();
if (stateNode) stateNode.clearDragging();
const currentChannel = DiscordApi.currentChannel;
const canUpload = currentChannel ?
currentChannel.checkPermissions(Reflection.modules.DiscordConstants.Permissions.SEND_MESSAGES) &&
currentChannel.checkPermissions(Reflection.modules.DiscordConstants.Permissions.ATTACH_FILES) : false;
const files = Array.from(e.dataTransfer.files).slice(0);
const actionCode = await this.dragAndDropHandler(e.dataTransfer.files[0].path, canUpload);
if (actionCode === 0 && stateNode) stateNode.promptToUpload(files, currentChannel.id, true, !e.shiftKey);
}
/**
* Patches Discord upload area for .bd files
*/
static async uploadAreaPatch(UploadArea) {
// Add a listener to root for when not in a channel
const root = DOM.getElement('#app-mount');
const rootHandleDrop = this.handleDrop.bind(this, undefined);
root.addEventListener('drop', rootHandleDrop);
const unpatchUploadAreaHandleDrop = MonkeyPatch('BD:ReactComponents', UploadArea.component.prototype).instead('handleDrop', (component, [e], original) => this.handleDrop(component, e, original));
this.unpatchUploadArea = () => {
unpatchUploadAreaHandleDrop();
root.removeEventListener('drop', rootHandleDrop);
this.unpatchUploadArea = undefined;
};
for (const element of document.querySelectorAll(UploadArea.important.selector)) {
const stateNode = Reflection.DOM(element).getComponentStateNode(UploadArea);
element.removeEventListener('drop', stateNode.handleDrop);
stateNode.handleDrop = UploadArea.component.prototype.handleDrop.bind(stateNode);
element.addEventListener('drop', stateNode.handleDrop);
stateNode.forceUpdate();
}
}
}

View File

@ -0,0 +1,221 @@
/**
* BetterDiscord Component Patcher
* Copyright (c) 2015-present JsSucks - https://github.com/JsSucks
* All rights reserved.
* https://github.com/JsSucks - https://betterdiscord.net
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import Reflection from './reflection/index';
import { ClientLogger as Logger } from 'common';
/**
* Function with no arguments and no return value that may be called to revert changes made by {@link Patcher}, restoring (unpatching) original method.
* @callback Patcher~unpatch
*/
/**
* A callback that modifies method logic. This callback is called on each call of the original method and is provided all data about original call. Any of the data can be modified if necessary, but do so wisely.
*
* The third argument for the callback will be `undefined` for `before` patches. `originalFunction` for `instead` patches and `returnValue` for `after` patches.
*
* @callback Patcher~patchCallback
* @param {object} thisObject - `this` in the context of the original function.
* @param {arguments} arguments - The original arguments of the original function.
* @param {(function|*)} extraValue - For `instead` patches, this is the original function from the module. For `after` patches, this is the return value of the function.
* @return {*} Makes sense only when using an `instead` or `after` patch. If something other than `undefined` is returned, the returned value replaces the value of `returnValue`. If used for `before` the return value is ignored.
*/
export class Patcher {
static get patches() { return this._patches || (this._patches = []) }
/**
* Returns all the patches done by a specific caller
* @param {string} id - Name of the patch caller
* @method
*/
static getPatchesByCaller(id) {
if (!id) return [];
const patches = [];
for (const patch of this.patches) {
for (const childPatch of patch.children) {
if (childPatch.caller === id) patches.push(childPatch);
}
}
return patches;
}
/**
* Unpatches all patches passed, or when a string is passed unpatches all
* patches done by that specific caller.
* @param {Array|string} patches - Either an array of patches to unpatch or a caller name
*/
static unpatchAll(patches) {
if (typeof patches === 'string')
patches = this.getPatchesByCaller(patches);
for (const patch of patches) {
patch.unpatch();
}
}
static resolveModule(module) {
if (module instanceof Function || (module instanceof Object)) return module;
if (typeof module === 'string') return Reflection.module.byName(module);
return null;
}
static overrideFn(patch) {
return function () {
let retVal = undefined;
if (!patch.children || !patch.children.length) return patch.originalFunction.apply(this, arguments);
for (const superPatch of patch.children.filter(c => c.type === 'before')) {
try {
superPatch.callback(this, arguments);
} catch (err) {
Logger.err(`Patcher:${patch.id}`, err);
}
}
const insteads = patch.children.filter(c => c.type === 'instead');
if (!insteads.length) {
retVal = patch.originalFunction.apply(this, arguments);
} else {
for (const insteadPatch of insteads) {
try {
const tempReturn = insteadPatch.callback(this, arguments, patch.originalFunction.bind(this));
if (typeof tempReturn !== 'undefined') retVal = tempReturn;
} catch (err) {
Logger.err(`Patcher:${patch.id}`, err);
}
}
}
for (const slavePatch of patch.children.filter(c => c.type === 'after')) {
try {
const tempReturn = slavePatch.callback(this, arguments, retVal, r => retVal = r);
if (typeof tempReturn !== 'undefined') retVal = tempReturn;
} catch (err) {
Logger.err(`Patcher:${patch.id}`, err);
}
}
return retVal;
}
}
static rePatch(patch) {
if (patch.module instanceof Array && typeof patch.functionName === 'number')
patch.module.splice(patch.functionName, 1, patch.proxyFunction = this.overrideFn(patch));
else patch.proxyFunction = patch.module[patch.functionName] = this.overrideFn(patch);
}
static pushPatch(caller, id, module, functionName) {
const patch = {
caller,
id,
module,
functionName,
originalFunction: module[functionName],
proxyFunction: null,
revert: () => { // Calling revert will destroy any patches added to the same module after this
patch.module[patch.functionName] = patch.originalFunction;
patch.proxyFunction = null;
patch.children = [];
},
counter: 0,
children: []
};
patch.proxyFunction = module[functionName] = this.overrideFn(patch);
return this.patches.push(patch), patch;
}
/**
* This method patches onto another function, allowing your code to run beforehand.
* Using this, you are also able to modify the incoming arguments before the original method is run.
*
* @param {string} caller - Name of the caller of the patch function. Using this you can undo all patches with the same name using {@link Patcher#unpatchAll}.
* @param {object} unresolvedModule - Object with the function to be patched. Can also patch an object's prototype.
* @param {string} functionName - Name of the method to be patched
* @param {Patcher~patchCallback} callback - Function to run before the original method
* @param {string} [displayName] You can provide meaningful name for class/object provided in `what` param for logging purposes. By default, this function will try to determine name automatically.
* @return {Patcher~unpatch} Function with no arguments and no return value that should be called to cancel (unpatch) this patch. You should save and run it when your plugin is stopped.
*/
static before(caller, unresolvedModule, functionName, callback, displayName) { return this.pushChildPatch(caller, unresolvedModule, functionName, callback, displayName, 'before') }
/**
* This method patches onto another function, allowing your code to run afterwards.
* Using this, you are also able to modify the return value, using the return of your code instead.
*
* @param {string} caller - Name of the caller of the patch function. Using this you can undo all patches with the same name using {@link Patcher#unpatchAll}.
* @param {object} unresolvedModule - Object with the function to be patched. Can also patch an object's prototype.
* @param {string} functionName - Name of the method to be patched
* @param {Patcher~patchCallback} callback - Function to run after the original method
* @param {string} [displayName] You can provide meaningful name for class/object provided in `what` param for logging purposes. By default, this function will try to determine name automatically.
* @return {Patcher~unpatch} Function with no arguments and no return value that should be called to cancel (unpatch) this patch. You should save and run it when your plugin is stopped.
*/
static after(caller, unresolvedModule, functionName, callback, displayName) { return this.pushChildPatch(caller, unresolvedModule, functionName, callback, displayName, 'after') }
/**
* This method patches onto another function, allowing your code to run instead, preventing the running of the original code.
* Using this, you are also able to modify the return value, using the return of your code instead.
*
* @param {string} caller - Name of the caller of the patch function. Using this you can undo all patches with the same name using {@link Patcher#unpatchAll}.
* @param {object} unresolvedModule - Object with the function to be patched. Can also patch an object's prototype.
* @param {string} functionName - Name of the method to be patched
* @param {Patcher~patchCallback} callback - Function to run instead of the original method
* @param {string} [displayName] You can provide meaningful name for class/object provided in `what` param for logging purposes. By default, this function will try to determine name automatically.
* @return {Patcher~unpatch} Function with no arguments and no return value that should be called to cancel (unpatch) this patch. You should save and run it when your plugin is stopped.
*/
static instead(caller, unresolvedModule, functionName, callback, displayName) { return this.pushChildPatch(caller, unresolvedModule, functionName, callback, displayName, 'instead') }
/**
* This method patches onto another function, allowing your code to run before, instead or after the original function.
* Using this you are able to modify the incoming arguments before the original function is run as well as the return
* value before the original function actually returns.
*
* @param {string} caller - Name of the caller of the patch function. Using this you can undo all patches with the same name using {@link Patcher#unpatchAll}.
* @param {object} unresolvedModule - Object with the function to be patched. Can also patch an object's prototype.
* @param {string} functionName - Name of the method to be patched
* @param {Patcher~patchCallback} callback - Function to run after the original method
* @param {string} [displayName] You can provide meaningful name for class/object provided in `what` param for logging purposes. By default, this function will try to determine name automatically.
* @param {string} [type=after] - Determines whether to run the function `before`, `instead`, or `after` the original.
* @return {Patcher~unpatch} Function with no arguments and no return value that should be called to cancel (unpatch) this patch. You should save and run it when your plugin is stopped.
*/
static pushChildPatch(caller, unresolvedModule, functionName, callback, displayName, type = 'after') {
const module = this.resolveModule(unresolvedModule);
if (!module || !module[functionName] || !(module[functionName] instanceof Function)) return null;
displayName = typeof unresolvedModule === 'string' ? unresolvedModule :
displayName || module.displayName || module.name || module.constructor.displayName || module.constructor.name;
const patchId = `${displayName}:${functionName}:${caller}`;
const patch = this.patches.find(p => p.module == module && p.functionName == functionName) || this.pushPatch(caller, patchId, module, functionName);
if (!patch.proxyFunction) this.rePatch(patch);
const child = {
caller,
type,
id: patch.counter,
callback,
unpatch: () => {
patch.children.splice(patch.children.findIndex(cpatch => cpatch.id === child.id && cpatch.type === type), 1);
if (patch.children.length <= 0) {
const patchNum = this.patches.findIndex(p => p.module == module && p.functionName == functionName);
this.patches[patchNum].revert();
this.patches.splice(patchNum, 1);
}
}
};
patch.children.push(child);
patch.counter++;
return child.unpatch;
}
}
export const MonkeyPatch = (caller, module, displayName) => ({
before: (functionName, callBack) => Patcher.before(caller, module, functionName, callBack, displayName),
after: (functionName, callBack) => Patcher.after(caller, module, functionName, callBack, displayName),
instead: (functionName, callBack) => Patcher.instead(caller, module, functionName, callBack, displayName)
});

View File

@ -0,0 +1,44 @@
/**
* BetterDiscord Permission Manager
* Copyright (c) 2015-present Jiiks/JsSucks - https://github.com/Jiiks / https://github.com/JsSucks
* All rights reserved.
* https://betterdiscord.net
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
const PermissionMap = {
IDENTIFY: {
HEADER: 'Access your account information',
BODY: 'Allows :NAME: to read your account information (excluding user token).'
},
READ_MESSAGES: {
HEADER: 'Read all messages',
BODY: 'Allows :NAME: to read all messages accessible through your Discord account.'
},
SEND_MESSAGES: {
HEADER: 'Send messages',
BODY: 'Allows :NAME: to send messages on your behalf.'
},
DELETE_MESSAGES: {
HEADER: 'Delete messages',
BODY: 'Allows :NAME: to delete messages on your behalf.'
},
EDIT_MESSAGES: {
HEADER: 'Edit messages',
BODY: 'Allows :NAME: to edit messages on your behalf.'
},
JOIN_SERVERS: {
HEADER: 'Join servers for you',
BODY: 'Allows :NAME: to join servers on your behalf.'
}
}
export default class {
static permissionText(permission) {
return PermissionMap[permission];
}
}

View File

@ -0,0 +1,29 @@
/**
* BetterDiscord Plugin Base
* Copyright (c) 2015-present Jiiks/JsSucks - https://github.com/Jiiks / https://github.com/JsSucks
* All rights reserved.
* https://betterdiscord.net
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import PluginManager from './pluginmanager';
import Content from './content';
export default class Plugin extends Content {
get type() { return 'plugin' }
get start() { return this.enable }
get stop() { return this.disable }
reload(force) {
return PluginManager.reloadPlugin(this, force);
}
unload(force) {
return PluginManager.unloadPlugin(this, force);
}
}

View File

@ -0,0 +1,624 @@
/**
* BetterDiscord Plugin API
* Copyright (c) 2015-present Jiiks/JsSucks - https://github.com/Jiiks / https://github.com/JsSucks
* All rights reserved.
* https://betterdiscord.net
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import { EmoteModule } from 'builtin';
import { SettingsSet, SettingsCategory, Setting, SettingsScheme } from 'structs';
import { BdMenu, Modals, DOM, DOMObserver, VueInjector, Toasts, Notifications, BdContextMenu, DiscordContextMenu } from 'ui';
import * as CommonComponents from 'commoncomponents';
import { default as Components } from '../ui/components/generic';
import { Utils, Filters, ClientLogger as Logger, ClientIPC, AsyncEventEmitter } from 'common';
import Settings from './settings';
import ExtModuleManager from './extmodulemanager';
import PluginManager from './pluginmanager';
import ThemeManager from './thememanager';
import Events from './events';
import EventsWrapper from './eventswrapper';
import Reflection from './reflection/index';
import DiscordApi from './discordapi';
import { ReactComponents, ReactHelpers } from './reactcomponents';
import { Patcher, MonkeyPatch } from './patcher';
import GlobalAc from '../ui/autocomplete';
import Vue from 'vue';
import path from 'path';
import Globals from './globals';
export default class PluginApi {
constructor(pluginInfo, pluginPath) {
this.pluginInfo = pluginInfo;
this.pluginPath = pluginPath;
this.Events = new EventsWrapper(Events);
Utils.defineSoftGetter(this.Events, 'bind', () => this.plugin);
this._menuItems = undefined;
this._injectedStyles = undefined;
this._modalStack = undefined;
}
get plugin() {
return PluginManager.getPluginByPath(this.pluginPath);
}
async bridge(plugin_id) {
const plugin = await PluginManager.waitForPlugin(plugin_id);
return plugin.bridge;
}
get require() { return this.import }
import(m) {
const module = ExtModuleManager.findModule(m);
if (module && module.__require) return module.__require;
return null;
}
get Api() { return this }
get AsyncEventEmitter() { return AsyncEventEmitter }
get EventsWrapper() { return EventsWrapper }
get CommonComponents() { return CommonComponents }
get Components() { return Components }
get Filters() { return Filters }
get Discord() { return DiscordApi }
get DiscordApi() { return DiscordApi }
get ReactComponents() { return ReactComponents }
get ReactHelpers() { return ReactHelpers }
get Reflection() { return Reflection }
get DOM() { return DOM }
get VueInjector() { return VueInjector }
get observer() {
return this._observer || (this._observer = new DOMObserver());
}
/**
* Logger
*/
get Logger() {
return {
log: (...message) => Logger.log(this.plugin.name, message),
error: (...message) => Logger.err(this.plugin.name, message),
err: (...message) => Logger.err(this.plugin.name, message),
warn: (...message) => Logger.warn(this.plugin.name, message),
info: (...message) => Logger.info(this.plugin.name, message),
debug: (...message) => Logger.dbg(this.plugin.name, message),
dbg: (...message) => Logger.dbg(this.plugin.name, message)
};
}
/**
* Utils
*/
get Utils() {
return {
overload: (...args) => Utils.overload.apply(Utils, args),
tryParseJson: (...args) => Utils.tryParseJson.apply(Utils, args),
toCamelCase: (...args) => Utils.toCamelCase.apply(Utils, args),
compare: (...args) => Utils.compare.apply(Utils, args),
deepclone: (...args) => Utils.deepclone.apply(Utils, args),
deepfreeze: (...args) => Utils.deepfreeze.apply(Utils, args),
removeFromArray: (...args) => Utils.removeFromArray.apply(Utils, args),
defineSoftGetter: (...args) => Utils.defineSoftGetter.apply(Utils, args),
wait: (...args) => Utils.wait.apply(Utils, args),
until: (...args) => Utils.until.apply(Utils, args),
findInTree: (...args) => Utils.findInTree.apply(Utils, args),
findInReactTree: (...args) => Utils.findInReactTree.apply(Utils, args)
};
}
/**
* Settings
*/
createSettingsSet(args, ...merge) {
return new SettingsSet(args || {}, ...merge);
}
createSettingsCategory(args, ...merge) {
return new SettingsCategory(args, ...merge);
}
createSetting(args, ...merge) {
return new Setting(args, ...merge);
}
createSettingsScheme(args) {
return new SettingsScheme(args);
}
get Settings() {
return {
createSet: this.createSettingsSet.bind(this),
createCategory: this.createSettingsCategory.bind(this),
createSetting: this.createSetting.bind(this),
createScheme: this.createSettingsScheme.bind(this)
};
}
/**
* InternalSettings
*/
getInternalSetting(set, category, setting) {
return Settings.get(set, category, setting);
}
get InternalSettings() {
return {
get: this.getInternalSetting.bind(this)
};
}
/**
* BdMenu
*/
get BdMenu() {
return {
open: BdMenu.open.bind(BdMenu),
close: BdMenu.close.bind(BdMenu),
items: this.BdMenuItems,
BdMenuItems: this.BdMenuItems
};
}
/**
* BdMenuItems
*/
get menuItems() {
return this._menuItems || (this._menuItems = []);
}
addMenuItem(item) {
return BdMenu.items.add(item);
}
addMenuSettingsSet(category, set, text) {
const item = BdMenu.items.addSettingsSet(category, set, text);
return this.menuItems.push(item);
}
addMenuVueComponent(category, text, component) {
const item = BdMenu.items.addVueComponent(category, text, component);
return this.menuItems.push(item);
}
removeMenuItem(item) {
BdMenu.items.remove(item);
Utils.removeFromArray(this.menuItems, item);
}
removeAllMenuItems() {
for (const item of this.menuItems)
BdMenu.items.remove(item);
}
get BdMenuItems() {
return Object.defineProperty({
add: this.addMenuItem.bind(this),
addSettingsSet: this.addMenuSettingsSet.bind(this),
addVueComponent: this.addMenuVueComponent.bind(this),
remove: this.removeMenuItem.bind(this),
removeAll: this.removeAllMenuItems.bind(this)
}, 'items', {
get: () => this.menuItems
});
}
/**
* BdContextMenu
*/
showContextMenu(event, groups) {
BdContextMenu.show(event, groups);
this.activeMenu.menu = BdContextMenu.activeMenu.menu;
}
get activeMenu() {
return this._activeMenu || (this._activeMenu = { menu: null });
}
get BdContextMenu() {
return Object.defineProperty({
show: this.showContextMenu.bind(this)
}, 'activeMenu', {
get: () => this.activeMenu
});
}
/**
* CssUtils
*/
get injectedStyles() {
return this._injectedStyles || (this._injectedStyles = []);
}
compileSass(scss, options) {
return ClientIPC.send('bd-compileSass', Object.assign({ data: scss }, options));
}
getConfigAsSCSS(settingsset) {
return ThemeManager.getConfigAsSCSS(settingsset ? settingsset : this.plugin.settings);
}
getConfigAsSCSSMap(settingsset) {
return ThemeManager.getConfigAsSCSSMap(settingsset ? settingsset : this.plugin.settings);
}
injectStyle(id, css) {
if (id && !css) css = id, id = undefined;
this.deleteStyle(id);
const styleid = `plugin-${this.plugin.id}-${id}`;
this.injectedStyles.push(id);
DOM.injectStyle(css, styleid);
}
async injectSass(id, scss, options) {
// In most cases a plugin's styles should be precompiled instead of using this
if (id && !scss && !options) scss = id, id = undefined;
const css = (await this.compileSass(scss, options)).css.toString();
this.injectStyle(id, css, options);
}
deleteStyle(id) {
const styleid = `plugin-${this.plugin.id}-${id}`;
this.injectedStyles.splice(this.injectedStyles.indexOf(styleid), 1);
DOM.deleteStyle(styleid);
}
deleteAllStyles(id) {
for (const id of this.injectedStyles) {
this.deleteStyle(id);
}
}
get CssUtils() {
return {
compileSass: this.compileSass.bind(this),
getConfigAsSCSS: this.getConfigAsSCSS.bind(this),
getConfigAsSCSSMap: this.getConfigAsSCSSMap.bind(this),
injectStyle: this.injectStyle.bind(this),
injectSass: this.injectSass.bind(this),
deleteStyle: this.deleteStyle.bind(this),
deleteAllStyles: this.deleteAllStyles.bind(this)
};
}
/**
* Modals
*/
get modalStack() {
return this._modalStack || (this._modalStack = []);
}
addModal(_modal, component) {
const modal = Modals.add(_modal, component);
modal.on('close', () => Utils.removeFromArray(this.modalStack, modal));
this.modalStack.push(modal);
return modal;
}
closeModal(modal, force) {
return Modals.close(modal, force);
}
closeAllModals(force) {
const promises = [];
for (const modal of this.modalStack)
promises.push(modal.close(force));
return Promise.all(promises);
}
closeLastModal(force) {
if (!this.modalStack.length) return;
return this.modalStack[this.modalStack.length - 1].close(force);
}
basicModal(title, text) {
return this.addModal(Modals.createBasicModal(title, text));
}
settingsModal(settingsset, headertext, options) {
return this.addModal(Modals.createSettingsModal(settingsset, headertext, options));
}
get Modals() {
return Object.defineProperties({
add: this.addModal.bind(this),
close: this.closeModal.bind(this),
closeAll: this.closeAllModals.bind(this),
closeLast: this.closeLastModal.bind(this),
basic: this.basicModal.bind(this),
settings: this.settingsModal.bind(this)
}, {
stack: {
get: () => this.modalStack
},
baseComponent: {
get: () => Modals.baseComponent
}
});
}
/**
* Toasts
*/
showToast(message, options = {}) {
return Toasts.push(message, options);
}
showSuccessToast(message, options = {}) {
return Toasts.success(message, options);
}
showInfoToast(message, options = {}) {
return Toasts.info(message, options);
}
showErrorToast(message, options = {}) {
return Toasts.error(message, options);
}
showWarningToast(message, options = {}) {
return Toasts.warning(message, options);
}
get Toasts() {
return {
push: this.showToast.bind(this),
success: this.showSuccessToast.bind(this),
error: this.showErrorToast.bind(this),
info: this.showInfoToast.bind(this),
warning: this.showWarningToast.bind(this),
get enabled() { return Toasts.enabled }
};
}
/**
* Notifications
*/
get notificationStack() {
return this._notificationStack || (this._notificationStack = []);
}
addNotification(title, text, buttons = []) {
if (arguments.length <= 1) text = title, title = undefined;
if (arguments[1] instanceof Array) [text, buttons] = arguments, title = undefined;
const notification = Notifications.add(title, text, buttons, () => Utils.removeFromArray(this.notificationStack, notification));
this.notificationStack.push(notification);
return notification;
}
dismissNotification(index) {
index = Notifications.stack.indexOf(this.notificationStack[index]);
if (index) Notifications.dismiss(index);
}
dismissAllNotifications() {
for (const index in this.notificationStack) {
this.dismissNotification(index);
}
}
get Notifications() {
return Object.defineProperty({
add: this.addNotification.bind(this),
dismiss: this.dismissNotification.bind(this),
dismissAll: this.dismissAllNotifications.bind(this)
}, 'stack', {
get: () => this.notificationStack
});
}
/**
* Autocomplete
*/
get autocompleteSets() {
return this._autocompleteSets || (this._autocompleteSets = new Map());
}
addAutocompleteController(prefix, controller) {
if (!controller) controller = this.plugin;
if (GlobalAc.validPrefix(prefix)) return;
GlobalAc.add(prefix, controller);
this.autocompleteSets.set(prefix, controller);
}
removeAutocompleteController(prefix) {
if (this.autocompleteSets.get(prefix) !== GlobalAc.sets.get(prefix)) return;
GlobalAc.remove(prefix);
this.autocompleteSets.delete(prefix);
}
removeAllAutocompleteControllers() {
for (const [prefix] of this.autocompleteSets) {
this.removeAutocompleteController(prefix);
}
}
validAutocompletePrefix(prefix) {
return GlobalAc.validPrefix(prefix);
}
toggleAutocompleteMode(prefix, sterm) {
return GlobalAc.toggle(prefix, sterm);
}
searchAutocomplete(prefix, sterm) {
return GlobalAc.items(prefix, sterm);
}
get Autocomplete() {
return Object.defineProperty({
add: this.addAutocompleteController.bind(this),
remove: this.removeAutocompleteController.bind(this),
removeAll: this.removeAllAutocompleteControllers.bind(this),
validPrefix: this.validAutocompletePrefix.bind(this),
toggle: this.toggleAutocompleteMode.bind(this),
search: this.searchAutocomplete.bind(this)
}, 'sets', {
get: () => this.autocompleteSets
});
}
/**
* Emotes
*/
get emotes() {
return EmoteModule.database;
}
get favouriteEmotes() {
return EmoteModule.favourites;
}
get mostUsedEmotes() {
return EmoteModule.mostUsed;
}
setFavouriteEmote(emote, favourite) {
return EmoteModule[favourite ? 'removeFavourite' : 'addFavourite'](emote);
}
addFavouriteEmote(emote) {
return EmoteModule.addFavourite(emote);
}
removeFavouriteEmote(emote) {
return EmoteModule.removeFavourite(emote);
}
isFavouriteEmote(emote) {
return EmoteModule.isFavourite(emote);
}
getEmote(emote) {
return EmoteModule.findByName(emote, true);
}
getEmoteUseCount(emote) {
const mostUsed = EmoteModule.mostUsed.find(mu => mu.key === emote.name);
return mostUsed ? mostUsed.useCount : 0;
}
incrementEmoteUseCount(emote) {
return EmoteModule.addToMostUsed(emote);
}
searchEmotes(regex, limit) {
return EmoteModule.search(regex, limit);
}
get Emotes() {
return Object.defineProperties({
setFavourite: this.setFavouriteEmote.bind(this),
addFavourite: this.addFavouriteEmote.bind(this),
removeFavourite: this.removeFavouriteEmote.bind(this),
isFavourite: this.isFavouriteEmote.bind(this),
getEmote: this.getEmote.bind(this),
getUseCount: this.getEmoteUseCount.bind(this),
incrementUseCount: this.incrementEmoteUseCount.bind(this),
search: this.searchEmotes.bind(this)
}, {
emotes: {
get: () => this.emotes
},
favourites: {
get: () => this.favouriteEmotes
},
mostused: {
get: () => this.mostUsedEmotes
}
});
}
/**
* Plugins
*/
async getPlugin(plugin_id) {
// This should require extra permissions
return PluginManager.waitForPlugin(plugin_id);
}
listPlugins() {
return PluginManager.localContent.map(plugin => plugin.id);
}
get Plugins() {
return {
getPlugin: this.getPlugin.bind(this),
listPlugins: this.listPlugins.bind(this)
};
}
/**
* Themes
*/
async getTheme(theme_id) {
// This should require extra permissions
return ThemeManager.waitForContent(theme_id);
}
listThemes() {
return ThemeManager.localContent.map(theme => theme.id);
}
get Themes() {
return {
getTheme: this.getTheme.bind(this),
listThemes: this.listThemes.bind(this)
};
}
/**
* ExtModules
*/
async getModule(module_id) {
// This should require extra permissions
return ExtModuleManager.waitForContent(module_id);
}
listModules() {
return ExtModuleManager.localContent.map(module => module.id);
}
get ExtModules() {
return {
getModule: this.getModule.bind(this),
listModules: this.listModules.bind(this)
};
}
/**
* Patcher
*/
get patches() {
return Patcher.getPatchesByCaller(this.plugin.id);
}
patchBefore(...args) { return this.pushChildPatch(...args, 'before') }
patchAfter(...args) { return this.pushChildPatch(...args, 'after') }
patchInstead(...args) { return this.pushChildPatch(...args, 'instead') }
pushChildPatch(...args) {
return Patcher.pushChildPatch(this.plugin.id, ...args);
}
unpatchAll(patches) {
return Patcher.unpatchAll(patches || this.plugin.id);
}
get Patcher() {
return Object.defineProperty({
before: this.patchBefore.bind(this),
after: this.patchAfter.bind(this),
instead: this.patchInstead.bind(this),
pushChildPatch: this.pushChildPatch.bind(this),
unpatchAll: this.unpatchAll.bind(this),
monkeyPatch: this.monkeyPatch.bind(this)
}, 'patches', {
get: () => this.patches
});
}
get monkeyPatch() {
return m => MonkeyPatch(this.plugin.id, m);
}
/**
* DiscordContextMenu
*/
get discordContextMenus() {
return this._discordContextMenus || (this._discordContextMenus = []);
}
addDiscordContextMenu(items, filter) {
const menu = DiscordContextMenu.add(items, filter);
this.discordContextMenus.push(menu);
return menu;
}
removeDiscordContextMenu(menu) {
DiscordContextMenu.remove(menu);
Utils.removeFromArray(this.discordContextMenus, menu);
}
removeAllDiscordContextMenus() {
for (const menu of this.discordContextMenus) {
this.removeDiscordContextMenu(menu);
}
}
get DiscordContextMenu() {
return Object.defineProperty({
add: this.addDiscordContextMenu.bind(this),
remove: this.removeDiscordContextMenu.bind(this),
removeAll: this.removeAllDiscordContextMenus.bind(this)
}, 'menus', {
get: () => this.discordContextMenus
});
}
Vuewrap(id, component, props) {
return VueInjector.createReactElement(Vue.component(id, component), props);
}
}
// Stop plugins from modifying the plugin API for all plugins
// Plugins can still modify their own plugin API object
Object.freeze(PluginApi);
Object.freeze(PluginApi.prototype);

View File

@ -0,0 +1,170 @@
/**
* BetterDiscord Plugin Manager Module
* Copyright (c) 2015-present Jiiks/JsSucks - https://github.com/Jiiks / https://github.com/JsSucks
* All rights reserved.
* https://betterdiscord.net
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import { Permissions } from 'modules';
import { Modals } from 'ui';
import { ErrorEvent } from 'structs';
import { ClientLogger as Logger } from 'common';
import Globals from './globals';
import ContentManager from './contentmanager';
import ExtModuleManager from './extmodulemanager';
import Plugin from './plugin';
import PluginApi from './pluginapi';
import Vendor from './vendor';
export default class extends ContentManager {
static get localPlugins() {
return this.localContent;
}
static get contentType() {
return 'plugin';
}
static get moduleName() {
return 'Plugin Manager';
}
static get pathId() {
return 'plugins';
}
static async loadAllPlugins(suppressErrors) {
this.loaded = false;
const loadAll = await this.loadAllContent(true);
this.loaded = true;
for (const plugin of this.localPlugins) {
if (!plugin.enabled) continue;
plugin.userConfig.enabled = false;
try {
plugin.start(false);
} catch (err) {
// Disable the plugin but don't save it - the next time BetterDiscord is started the plugin will attempt to start again
this.errors.push(new ErrorEvent({
module: this.moduleName,
message: `Failed to start ${plugin.name}`,
err
}));
Logger.err(this.moduleName, [`Failed to start plugin ${plugin.name}:`, err]);
}
}
if (this.errors.length && !suppressErrors) {
Modals.error({
header: `${this.moduleName} - ${this.errors.length} ${this.contentType}${this.errors.length !== 1 ? 's' : ''} failed to load`,
module: this.moduleName,
type: 'err',
content: this.errors
});
this._errors = [];
}
return loadAll;
}
static get refreshPlugins() { return this.refreshContent }
static get loadContent() { return this.loadPlugin }
static async loadPlugin(paths, configs, info, main, dependencies, permissions, mainExport, packed = false) {
if (permissions && permissions.length > 0) {
for (const perm of permissions) {
Logger.log(this.moduleName, `Permission: ${Permissions.permissionText(perm).HEADER} - ${Permissions.permissionText(perm).BODY}`);
}
try {
const allowed = await Modals.permissions(`${info.name} wants to:`, info.name, permissions).promise;
} catch (err) {
return;
}
}
const deps = {};
if (dependencies) {
for (const [key, value] of Object.entries(dependencies)) {
const extModule = ExtModuleManager.findModule(key);
if (!extModule) {
throw {message: `Dependency ${key}:${value} is not loaded.`};
}
deps[key] = extModule.__require;
}
}
const pluginExports = Globals.require(paths.mainPath);
const pluginFunction = mainExport ? pluginExports[mainExport]
: pluginExports.__esModule ? pluginExports.default : pluginExports;
if (typeof pluginFunction !== 'function')
throw {message: `Plugin ${info.name} did not export a function.`};
const plugin = pluginFunction.call(pluginExports, Plugin, new PluginApi(info, paths.contentPath), Vendor, deps);
if (!plugin || !(plugin.prototype instanceof Plugin))
throw {message: `Plugin ${info.name} did not return a class that extends Plugin.`};
const instance = new plugin({
configs, info, main, paths
});
if (instance.enabled && this.loaded) {
instance.userConfig.enabled = false;
instance.start(false);
}
return instance;
}
static get deletePlugin() { return this.deleteContent }
static get unloadPlugin() { return this.unloadContent }
static get reloadPlugin() { return this.reloadContent }
static unloadContentHook(content, reload) {
delete Globals.require.cache[Globals.require.resolve(content.paths.mainPath)];
const uncache = [];
for (const required in Globals.require.cache) {
if (!required.includes(content.paths.contentPath)) continue;
uncache.push(Globals.require.resolve(required));
}
for (const u of uncache) delete Globals.require.cache[u];
}
/**
* Stops a plugin.
* @param {Plugin|String} plugin
* @return {Promise}
*/
static stopPlugin(plugin) {
plugin = this.isPlugin(plugin) ? plugin : this.getPluginById(plugin);
return plugin.stop();
}
/**
* Starts a plugin.
* @param {Plugin|String} plugin
* @return {Promise}
*/
static startPlugin(plugin) {
plugin = this.isPlugin(plugin) ? plugin : this.getPluginById(plugin);
return plugin.start();
}
static get isPlugin() { return this.isThisContent }
static isThisContent(plugin) {
return plugin instanceof Plugin;
}
static get findPlugin() { return this.findContent }
static get getPluginIndex() { return this.getContentIndex }
static get getPluginByName() { return this.getContentByName }
static get getPluginById() { return this.getContentById }
static get getPluginByPath() { return this.getContentByPath }
static get getPluginByDirName() { return this.getContentByDirName }
static get waitForPlugin() { return this.waitForContent }
}

View File

@ -0,0 +1,586 @@
/**
* BetterDiscord React Component Manipulations
* Original concept and some code by samogot - https://github.com/samogot / https://github.com/samogot/betterdiscord-plugins/tree/master/v2/1Lib%20Discord%20Internals
*
* Copyright (c) 2015-present JsSucks - https://github.com/JsSucks
* All rights reserved.
* https://github.com/JsSucks - https://betterdiscord.net
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import { DOM, Modals } from 'ui';
import { Utils, Filters, ClientLogger as Logger } from 'common';
import { MonkeyPatch } from './patcher';
import Reflection from './reflection/index';
import DiscordApi from './discordapi';
import PackageInstaller from './packageinstaller';
class Helpers {
static get plannedActions() {
return this._plannedActions || (this._plannedActions = new Map());
}
static recursiveArray(parent, key, count = 1) {
let index = 0;
function* innerCall(parent, key) {
const item = parent[key];
if (item instanceof Array) {
for (const subKey of item.keys()) {
yield* innerCall(item, subKey)
}
return;
}
yield { item, parent, key, index: index++, count };
}
return innerCall(parent, key);
}
static recursiveArrayCount(parent, key) {
let count = 0;
// eslint-disable-next-line no-empty-pattern
for (let {} of this.recursiveArray(parent, key))
++count;
return this.recursiveArray(parent, key, count);
}
static get recursiveChildren() {
return function* (parent, key, index = 0, count = 1) {
const item = parent[key];
yield { item, parent, key, index, count };
if (item && item.props && item.props.children) {
for (const { parent, key, index, count } of this.recursiveArrayCount(item.props, 'children')) {
yield* this.recursiveChildren(parent, key, index, count);
}
}
}
}
static returnFirst(iterator, process) {
for (const child of iterator) {
const retVal = process(child);
if (retVal !== undefined) return retVal;
}
}
static getFirstChild(rootParent, rootKey, selector) {
const getDirectChild = (item, selector) => {
if (item && item.props && item.props.children) {
return this.returnFirst(this.recursiveArrayCount(item.props, 'children'), checkFilter.bind(null, selector));
}
};
const checkFilter = (selector, { item, parent, key, count, index }) => {
let match = true;
if (match && selector.type)
match = item && selector.type === item.type;
if (match && selector.tag)
match = item && typeof item.type === 'string' && selector.tag === item.type;
if (match && selector.className) {
match = item && item.props && typeof item.props.className === 'string';
if (match) {
const classes = item.props.className.split(' ');
if (selector.className === true)
match = !!classes[0];
else if (typeof selector.className === 'string')
match = classes.includes(selector.className);
else if (selector.className instanceof RegExp)
match = !!classes.find(cls => selector.className.test(cls));
else match = false;
}
}
if (match && selector.text) {
if (selector.text === true)
match = typeof item === 'string';
else if (typeof selector.text === 'string')
match = item === selector.text;
else if (selector.text instanceof RegExp)
match = typeof item === 'string' && selector.text.test(item);
else match = false;
}
if (match && selector.nthChild)
match = index === (selector.nthChild < 0 ? count + selector.nthChild : selector.nthChild);
if (match && selector.hasChild)
match = getDirectChild(item, selector.hasChild);
if (match && selector.hasSuccessor)
match = item && !!this.getFirstChild(parent, key, selector.hasSuccessor).item;
if (match && selector.eq) {
--selector.eq;
return;
}
if (match) {
if (selector.child) {
return getDirectChild(item, selector.child);
} else if (selector.successor) {
return this.getFirstChild(parent, key, selector.successor);
}
return { item, parent, key };
}
};
return this.returnFirst(this.recursiveChildren(rootParent, rootKey), checkFilter.bind(null, selector)) || {};
}
static parseSelector(selector) {
if (selector.startsWith('.')) return { className: selector.substr(1) }
if (selector.startsWith('#')) return { id: selector.substr(1) }
return {}
}
static findByProp(obj, what, value) {
if (obj.hasOwnProperty(what) && obj[what] === value) return obj;
if (obj.props && !obj.children) return this.findByProp(obj.props, what, value);
if (!obj.children) return null;
if (!(obj.children instanceof Array)) return this.findByProp(obj.children, what, value);
for (const child of obj.children) {
if (!child) continue;
const findInChild = this.findByProp(child, what, value);
if (findInChild) return findInChild;
}
return null;
}
static findProp(obj, what) {
if (obj.hasOwnProperty(what)) return obj[what];
if (obj.props && !obj.children) return this.findProp(obj.props, what);
if (!obj.children) return null;
if (!(obj.children instanceof Array)) return this.findProp(obj.children, what);
for (const child of obj.children) {
if (!child) continue;
const findInChild = this.findProp(child, what);
if (findInChild) return findInChild;
}
return null;
}
static get React() {
return Reflection.modules.React;
}
static get ReactDOM() {
return Reflection.modules.ReactDOM;
}
}
export { Helpers as ReactHelpers };
class ReactComponent {
constructor(id, component, retVal, important) {
this.id = id;
this.component = component;
this.retVal = retVal;
this.important = important;
}
get elements() {
if (!this.important || !this.important.selector) return [];
return document.querySelectorAll(this.important.selector);
}
get stateNodes() {
return [...this.elements].map(e => Reflection.DOM(e).getComponentStateNode(this));
}
forceUpdateAll() {
for (const e of this.elements) {
Reflection.DOM(e).forceUpdate(this);
}
}
}
export class ReactComponents {
static get components() { return this._components || (this._components = []) }
static get unknownComponents() { return this._unknownComponents || (this._unknownComponents = []) }
static get listeners() { return this._listeners || (this._listeners = []) }
static get nameSetters() { return this._nameSetters || (this._nameSetters = []) }
static get componentAliases() { return this._componentAliases || (this._componentAliases = []) }
static get ReactComponent() { return ReactComponent }
static push(component, retVal, important) {
if (!(component instanceof Function)) return null;
const { displayName } = component;
if (!displayName) {
return this.processUnknown(component, retVal);
}
const have = this.components.find(comp => comp.id === displayName);
if (have) {
if (!have.important) have.important = important;
return component;
}
const c = new ReactComponent(displayName, component, retVal, important);
this.components.push(c);
const listener = this.listeners.find(listener => listener.id === displayName);
if (listener) {
for (const l of listener.listeners) l(c);
Utils.removeFromArray(this.listeners, listener);
}
return c;
}
/**
* Finds a component from the components array or by waiting for it to be mounted.
* @param {String} name The component's name
* @param {Object} important An object containing a selector to look for
* @param {Function} filter A function to filter components if a single element is rendered by multiple components
* @return {Promise => ReactComponent}
*/
static async getComponent(name, important, filter) {
name = this.getComponentName(name);
const have = this.components.find(c => c.id === name);
if (have) return have;
if (important) {
const callback = () => {
if (this.components.find(c => c.id === name)) {
Logger.info('ReactComponents', `Important component ${name} already found`);
DOM.observer.unsubscribe(observerSubscription);
return;
}
const elements = document.querySelectorAll(important.selector);
if (!elements.length) return;
let component, reflect;
for (const element of elements) {
reflect = Reflection.DOM(element);
component = filter ? reflect.components.find(component => {
try {
return filter.call(undefined, component);
} catch (err) {
return false;
}
}) : reflect.component;
if (component) break;
}
if (!component && filter) {
Logger.log('ReactComponents', ['Found elements matching the query selector but no components passed the filter']);
return;
}
DOM.observer.unsubscribe(observerSubscription);
if (!component) {
Logger.err('ReactComponents', [`FAILED TO GET IMPORTANT COMPONENT ${name} WITH REFLECTION FROM`, elements]);
return;
}
if (!component.displayName) component.displayName = name;
Logger.info('ReactComponents', [`Found important component ${name} with reflection`, reflect]);
important.filter = filter;
this.push(component, undefined, important);
};
const observerSubscription = DOM.observer.subscribeToQuerySelector(callback, important.selector, null, true);
setTimeout(callback, 0);
}
let listener = this.listeners.find(l => l.id === name);
if (!listener) this.listeners.push(listener = {
id: name,
listeners: []
});
return new Promise(resolve => {
listener.listeners.push(resolve);
});
}
static getComponentName(name) {
const resolvedAliases = [];
while (this.componentAliases[name]) {
resolvedAliases.push(name);
name = this.componentAliases[name];
if (resolvedAliases.includes(name)) break;
}
return name;
}
static setName(name, filter) {
const have = this.components.find(c => c.id === name);
if (have) return have;
for (const [rci, rc] of this.unknownComponents.entries()) {
if (filter(rc.component)) {
rc.component.displayName = name;
this.unknownComponents.splice(rci, 1);
return this.push(rc.component);
}
}
return this.nameSetters.push({ name, filter });
}
static processUnknown(component, retVal) {
const have = this.unknownComponents.find(c => c.component === component);
for (const [fi, filter] of this.nameSetters.entries()) {
if (filter.filter.filter(component)) {
Logger.log('ReactComponents', 'Filter match!');
component.displayName = filter.name;
this.nameSetters.splice(fi, 1);
return this.push(component, retVal);
}
}
if (have) return have;
this.unknownComponents.push(component);
return component;
}
}
export class ReactAutoPatcher {
/**
* Wait for React to be loaded and patch it's createElement to store all unknown components.
* Also patches some known components.
*/
static async autoPatch() {
const React = await Reflection.module.waitForModuleByName('React');
this.unpatchCreateElement = MonkeyPatch('BD:ReactComponents:createElement', React).before('createElement', (component, args) => ReactComponents.push(args[0]));
this.patchComponents();
}
/**
* Patches a few known components.
*/
static patchComponents() {
const componentPatchFunctions = Object.getOwnPropertyNames(this).filter(p => p.startsWith('patch') && p !== 'patchComponents');
return Promise.all(componentPatchFunctions.map(p => this[p].call(this)));
}
static async patchMessage() {
const { selector } = Reflection.resolve('message', 'messageCozy', 'messageCompact');
this.Message = await ReactComponents.getComponent('Message', {selector}, m => m.prototype && m.prototype.renderCozy);
this.unpatchMessageRender = MonkeyPatch('BD:ReactComponents', this.Message.component.prototype).after('render', (component, args, retVal) => {
const { message, jumpSequenceId, canFlash } = component.props;
const { id, colorString, bot, author, attachments, embeds } = message;
if (jumpSequenceId && canFlash) retVal = retVal.props.children;
retVal.props['data-message-id'] = id;
retVal.props['data-colourstring'] = colorString;
if (author && author.id) retVal.props['data-user-id'] = author.id;
if (bot || (author && author.bot)) retVal.props.className += ' bd-isBot';
if (attachments && attachments.length) retVal.props.className += ' bd-hasAttachments';
if (embeds && embeds.length) retVal.props.className += ' bd-hasEmbeds';
if (author && author.id === DiscordApi.currentUser.id) retVal.props.className += ' bd-isCurrentUser';
const dapiMessage = DiscordApi.Message.from(message);
if (dapiMessage.guild && author.id === dapiMessage.guild.ownerId) retVal.props.className += ' bd-isGuildOwner';
if (dapiMessage.guild && dapiMessage.guild.isMember(author.id)) retVal.props.className += ' bd-isGuildMember';
});
this.Message.forceUpdateAll();
}
static async patchMessageContent() {
const { selector } = Reflection.resolve('container', 'containerCozy', 'containerCompact', 'edited');
this.MessageContent = await ReactComponents.getComponent('MessageContent', {selector}, c => c.defaultProps && c.defaultProps.hasOwnProperty('disableButtons'));
}
static async patchSpoiler() {
const { selector } = Reflection.resolve('spoilerText', 'spoilerContainer');
this.Spoiler = await ReactComponents.getComponent('Spoiler', {selector}, c => c.prototype.renderSpoilerText);
}
static async patchMessageAccessories() {
const { selector } = Reflection.resolve('container', 'containerCozy', 'embedWrapper');
this.MessageAccessories = await ReactComponents.getComponent('MessageAccessories', {selector});
}
static async patchMessageGroup() {
const { selector } = Reflection.resolve('container', 'message', 'messageCozy');
this.MessageGroup = await ReactComponents.getComponent('MessageGroup', {selector});
this.unpatchMessageGroupRender = MonkeyPatch('BD:ReactComponents', this.MessageGroup.component.prototype).after('render', (component, args, retVal) => {
const { author, type } = component.props.messages[0];
retVal.props['data-author-id'] = author.id;
if (author.id === DiscordApi.currentUser.id) retVal.props.className += ' bd-isCurrentUser';
if (type !== 0) retVal.props.className += ' bd-isSystemMessage';
const dapiMessage = DiscordApi.Message.from(component.props.messages[0]);
if (dapiMessage.guild && author.id === dapiMessage.guild.ownerId) retVal.props.className += ' bd-isGuildOwner';
if (dapiMessage.guild && dapiMessage.guild.isMember(author.id)) retVal.props.className += ' bd-isGuildMember';
});
this.MessageGroup.forceUpdateAll();
}
static async patchImageWrapper() {
ReactComponents.componentAliases.ImageWrapper = 'Image';
const { selector } = Reflection.resolve('imageWrapper');
this.ImageWrapper = await ReactComponents.getComponent('ImageWrapper', {selector}, c => typeof c.defaultProps.children === 'function');
}
static async patchChannelMember() {
ReactComponents.componentAliases.ChannelMember = 'MemberListItem';
const { selector } = Reflection.resolve('member', 'memberInner', 'activity');
this.ChannelMember = await ReactComponents.getComponent('ChannelMember', {selector}, m => m.prototype.renderActivity);
this.unpatchChannelMemberRender = MonkeyPatch('BD:ReactComponents', this.ChannelMember.component.prototype).after('render', (component, args, retVal) => {
if (!retVal.props || !retVal.props.children) return;
const user = Helpers.findProp(component, 'user');
if (!user) return;
retVal.props['data-user-id'] = user.id;
retVal.props['data-colourstring'] = component.props.colorString;
if (component.props.isOwner) retVal.props.className += ' bd-isGuildOwner';
});
this.ChannelMember.forceUpdateAll();
}
static async patchNameTag() {
const { selector } = Reflection.resolve('nameTag', 'username', 'discriminator', 'ownerIcon');
this.NameTag = await ReactComponents.getComponent('NameTag', {selector});
}
static async patchGuild() {
const selector = `div.${Reflection.resolve('container', 'guildIcon', 'selected', 'unread').className}:not(:first-child)`;
this.Guild = await ReactComponents.getComponent('Guild', {selector}, m => m.prototype.renderBadge);
this.unpatchGuild = MonkeyPatch('BD:ReactComponents', this.Guild.component.prototype).after('render', (component, args, retVal) => {
const { guild } = component.props;
if (!guild) return;
retVal.props['data-guild-id'] = guild.id;
retVal.props['data-guild-name'] = guild.name;
});
this.Guild.forceUpdateAll();
}
/**
* The Channel component contains the header, message scroller, message form and member list.
*/
static async patchChannel() {
const { selector } = Reflection.resolve('chat', 'title', 'channelName');
this.Channel = await ReactComponents.getComponent('Channel', {selector});
this.unpatchChannel = MonkeyPatch('BD:ReactComponents', this.Channel.component.prototype).after('render', (component, args, retVal) => {
const channel = component.props.channel || component.state.channel;
if (!channel) return;
retVal.props['data-channel-id'] = channel.id;
retVal.props['data-channel-name'] = channel.name;
if ([0, 2, 4].includes(channel.type)) retVal.props.className += ' bd-isGuildChannel';
if ([1, 3].includes(channel.type)) retVal.props.className += ' bd-isPrivateChannel';
if (channel.type === 3) retVal.props.className += ' bd-isGroupChannel';
});
this.Channel.forceUpdateAll();
}
static async patchChannelTextArea() {
const { selector } = Reflection.resolve('channelTextArea', 'autocomplete');
this.ChannelTextArea = await ReactComponents.getComponent('ChannelTextArea', {selector});
}
/**
* The GuildTextChannel component represents a text channel in the guild channel list.
*/
static async patchGuildTextChannel() {
ReactComponents.componentAliases.GuildTextChannel = 'TextChannel';
const { selector } = Reflection.resolve('containerDefault', 'actionIcon');
this.GuildTextChannel = await ReactComponents.getComponent('GuildTextChannel', {selector}, c => c.prototype.renderMentionBadge);
this.unpatchGuildTextChannel = MonkeyPatch('BD:ReactComponents', this.GuildTextChannel.component.prototype).after('render', this._afterChannelRender);
this.GuildTextChannel.forceUpdateAll();
}
/**
* The GuildVoiceChannel component represents a voice channel in the guild channel list.
*/
static async patchGuildVoiceChannel() {
ReactComponents.componentAliases.GuildVoiceChannel = 'VoiceChannel';
const { selector } = Reflection.resolve('containerDefault', 'actionIcon');
this.GuildVoiceChannel = await ReactComponents.getComponent('GuildVoiceChannel', {selector}, c => c.prototype.handleVoiceConnect);
this.unpatchGuildVoiceChannel = MonkeyPatch('BD:ReactComponents', this.GuildVoiceChannel.component.prototype).after('render', this._afterChannelRender);
this.GuildVoiceChannel.forceUpdateAll();
}
/**
* The DirectMessage component represents a channel in the direct messages list.
*/
static async patchDirectMessage() {
ReactComponents.componentAliases.DirectMessage = 'PrivateChannel';
const { selector } = Reflection.resolve('channel', 'avatar', 'name');
this.DirectMessage = await ReactComponents.getComponent('DirectMessage', {selector}, c => c.prototype.renderAvatar);
this.unpatchDirectMessage = MonkeyPatch('BD:ReactComponents', this.DirectMessage.component.prototype).after('render', this._afterChannelRender);
this.DirectMessage.forceUpdateAll();
}
static _afterChannelRender(component, args, retVal) {
const { channel } = component.props;
if (!channel) return;
retVal.props['data-channel-id'] = channel.id;
retVal.props['data-channel-name'] = channel.name;
if ([0, 2, 4].includes(channel.type)) retVal.props.className += ' bd-isGuildChannel';
if (channel.type === 2) retVal.props.className += ' bd-isVoiceChannel';
// if (channel.type === 4) retVal.props.className += ' bd-isChannelCategory';
if ([1, 3].includes(channel.type)) retVal.props.className += ' bd-isPrivateChannel';
if (channel.type === 3) retVal.props.className += ' bd-isGroupChannel';
}
static async patchUserProfileModal() {
ReactComponents.componentAliases.UserProfileModal = 'UserProfileBody';
const { selector } = Reflection.resolve('root', 'topSectionNormal');
this.UserProfileModal = await ReactComponents.getComponent('UserProfileModal', {selector}, c => c.prototype.renderHeader && c.prototype.renderBadges);
this.unpatchUserProfileModal = MonkeyPatch('BD:ReactComponents', this.UserProfileModal.component.prototype).after('render', (component, args, retVal) => {
const root = retVal.props.children[0] || retVal.props.children;
const { user } = component.props;
if (!user) return;
root.props['data-user-id'] = user.id;
if (user.bot) root.props.className += ' bd-isBot';
if (user.id === DiscordApi.currentUser.id) root.props.className += ' bd-isCurrentUser';
});
this.UserProfileModal.forceUpdateAll();
}
static async patchUserPopout() {
const { selector } = Reflection.resolve('userPopout', 'headerNormal');
this.UserPopout = await ReactComponents.getComponent('UserPopout', {selector}, c => c.prototype.renderHeader);
this.unpatchUserPopout = MonkeyPatch('BD:ReactComponents', this.UserPopout.component.prototype).after('render', (component, args, retVal) => {
const root = retVal.props.children[0] || retVal.props.children;
const { user, guild, guildMember } = component.props;
if (!user) return;
root.props['data-user-id'] = user.id;
if (user.bot) root.props.className += ' bd-isBot';
if (user.id === DiscordApi.currentUser.id) root.props.className += ' bd-isCurrentUser';
if (guild) root.props['data-guild-id'] = guild.id;
if (guild && user.id === guild.ownerId) root.props.className += ' bd-isGuildOwner';
if (guild && guildMember) root.props.className += ' bd-isGuildMember';
if (guildMember && guildMember.roles.length) root.props.className += ' bd-hasRoles';
});
this.UserPopout.forceUpdateAll();
}
static async patchUploadArea() {
const { selector } = Reflection.resolve('uploadArea');
this.UploadArea = await ReactComponents.getComponent('UploadArea', {selector});
PackageInstaller.uploadAreaPatch(this.UploadArea);
}
}

View File

@ -0,0 +1,44 @@
/**
* BetterDiscord Reflection Module
* Copyright (c) 2015-present Jiiks/JsSucks - https://github.com/Jiiks / https://github.com/JsSucks
* All rights reserved.
* https://betterdiscord.net
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import { Module, Modules } from './modules';
import { Reflection as DOM } from 'ui';
import Resolver from './resolver';
export default class Reflection {
static get module() {
return Module;
}
static get modules() {
return Modules;
}
static get resolve() {
return Resolver.resolve;
}
static get resolveAsync() {
return Resolver.resolveAsync;
}
static get resolver() {
return Resolver;
}
static get DOM() {
return DOM;
}
static get require() {
return Module.require;
}
}

View File

@ -0,0 +1,433 @@
/**
* BetterDiscord Reflection Modules
* Copyright (c) 2015-present Jiiks/JsSucks - https://github.com/Jiiks / https://github.com/JsSucks
* All rights reserved.
* https://betterdiscord.net
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import { Utils, Filters } from 'common';
import Events from '../events';
const KnownModules = {
React: Filters.byProperties(['createElement', 'cloneElement']),
ReactDOM: Filters.byProperties(['render', 'findDOMNode']),
Events: Filters.byPrototypeFields(['setMaxListeners', 'emit']),
/* Guild Info, Stores, and Utilities */
GuildStore: Filters.byProperties(['getGuild']),
SortedGuildStore: Filters.byProperties(['getSortedGuilds']),
SelectedGuildStore: Filters.byProperties(['getLastSelectedGuildId']),
GuildSync: Filters.byProperties(['getSyncedGuilds']),
GuildInfo: Filters.byProperties(['getAcronym']),
GuildChannelsStore: Filters.byProperties(['getChannels', 'getDefaultChannel']),
GuildMemberStore: Filters.byProperties(['getMember']),
MemberCountStore: Filters.byProperties(['getMemberCounts']),
GuildEmojiStore: Filters.byProperties(['getEmojis']),
GuildActions: Filters.byProperties(['markGuildAsRead']),
GuildPermissions: Filters.byProperties(['getGuildPermissions']),
/* Channel Store & Actions */
ChannelStore: Filters.byProperties(['getChannels', 'getDMFromUserId']),
SelectedChannelStore: Filters.byProperties(['getLastSelectedChannelId']),
ChannelActions: Filters.byProperties(['selectChannel']),
PrivateChannelActions: Filters.byProperties(['openPrivateChannel']),
ChannelSelector: Filters.byProperties(['selectGuild', 'selectChannel']),
VoiceChannelActions: Filters.byProperties(['selectVoiceChannel']),
/* Current User Info, State and Settings */
UserInfoStore: Filters.byProperties(['getToken']),
UserSettingsStore: Filters.byProperties(['guildPositions']),
AccountManager: Filters.byProperties(['register', 'login']),
UserSettingsUpdater: Filters.byProperties(['updateRemoteSettings']),
OnlineWatcher: Filters.byProperties(['isOnline']),
CurrentUserIdle: Filters.byProperties(['getIdleTime']),
RelationshipStore: Filters.byProperties(['isBlocked', 'isFriend']),
RelationshipManager: Filters.byProperties(['addRelationship']),
MentionStore: Filters.byProperties(['getMentions']),
/* User Stores and Utils */
UserStore: Filters.byProperties(['getCurrentUser']),
UserStatusStore: Filters.byProperties(['getStatuses']),
UserTypingStore: Filters.byProperties(['isTyping']),
UserActivityStore: Filters.byProperties(['getActivity']),
UserNameResolver: Filters.byProperties(['getName']),
UserNoteStore: Filters.byProperties(['getNote']),
UserNoteActions: Filters.byProperties(['updateNote']),
DraftActions: Filters.byProperties(['changeDraft']),
/* Emoji Store and Utils */
EmojiInfo: Filters.byProperties(['isEmojiDisabled']),
EmojiUtils: Filters.byProperties(['getGuildEmoji']),
EmojiStore: Filters.byProperties(['getByCategory', 'EMOJI_NAME_RE']),
/* Invite Store and Utils */
InviteStore: Filters.byProperties(['getInvites']),
InviteResolver: Filters.byProperties(['findInvite']),
InviteActions: Filters.byProperties(['acceptInvite']),
/* Discord Objects & Utils */
DiscordConstants: Filters.byProperties(['Permissions', 'ActivityTypes', 'StatusTypes']),
Permissions: Filters.byProperties(['getHighestRole']),
ColorConverter: Filters.byProperties(['hex2int']),
ColorShader: Filters.byProperties(['darken']),
TinyColor: Filters.byPrototypeFields(['toRgb']),
ClassResolver: Filters.byProperties(['getClass']),
ButtonData: Filters.byProperties(['ButtonSizes']),
IconNames: Filters.byProperties(['IconNames']),
NavigationUtils: Filters.byProperties(['transitionTo', 'replaceWith', 'getHistory']),
/* Discord Messages */
MessageStore: Filters.byProperties(['getMessages']),
MessageActions: Filters.byProperties(['jumpToMessage', '_sendMessage']),
MessageQueue: Filters.byProperties(['enqueue']),
MessageParser: Filters.byProperties(['createMessage', 'parse', 'unparse']),
/* In-Game Overlay */
OverlayUserPopoutSettings: Filters.byProperties(['openUserPopout']),
OverlayUserPopoutInfo: Filters.byProperties(['getOpenedUserPopout']),
/* Experiments */
ExperimentStore: Filters.byProperties(['getExperimentOverrides']),
ExperimentsManager: Filters.byProperties(['isDeveloper']),
CurrentExperiment: Filters.byProperties(['getExperimentId']),
/* Images, Avatars and Utils */
ImageResolver: Filters.byProperties(['getUserAvatarURL']),
ImageUtils: Filters.byProperties(['getSizedImageSrc']),
AvatarDefaults: Filters.byProperties(['getUserAvatarURL', 'DEFAULT_AVATARS']),
/* Drag & Drop */
DNDActions: Filters.byProperties(['beginDrag']),
DNDSources: Filters.byProperties(['addTarget']),
DNDObjects: Filters.byProperties(['DragSource']),
/* Electron & Other Internals with Utils */
ElectronModule: Filters.byProperties(['_getMainWindow']),
Dispatcher: Filters.byProperties(['dirtyDispatch']),
PathUtils: Filters.byProperties(['hasBasename']),
NotificationModule: Filters.byProperties(['showNotification']),
RouterModule: Filters.byProperties(['Router']),
APIModule: Filters.byProperties(['getAPIBaseURL']),
AnalyticEvents: Filters.byProperties(['AnalyticEventConfigs']),
KeyGenerator: Filters.byCode(/"binary"/),
Buffers: Filters.byProperties(['Buffer', 'kMaxLength']),
DeviceStore: Filters.byProperties(['getDevices']),
SoftwareInfo: Filters.byProperties(['os']),
CurrentContext: Filters.byProperties(['setTagsContext']),
/* Media Stuff (Audio/Video) */
MediaDeviceInfo: Filters.byProperties(['Codecs', 'SUPPORTED_BROWSERS']),
MediaInfo: Filters.byProperties(['getOutputVolume']),
MediaEngineInfo: Filters.byProperties(['MediaEngineFeatures']),
VoiceInfo: Filters.byProperties(['EchoCancellation']),
VideoStream: Filters.byProperties(['getVideoStream']),
SoundModule: Filters.byProperties(['playSound']),
/* Window, DOM, HTML */
WindowInfo: Filters.byProperties(['isFocused', 'windowSize']),
TagInfo: Filters.byProperties(['VALID_TAG_NAMES']),
DOMInfo: Filters.byProperties(['canUseDOM']),
/* Locale/Location and Time */
LocaleManager: Filters.byProperties(['setLocale']),
Moment: Filters.byProperties(['parseZone']),
LocationManager: Filters.byProperties(['createLocation']),
Timestamps: Filters.byProperties(['fromTimestamp']),
TimeFormatter: Filters.byProperties(['dateFormat']),
/* Strings and Utils */
Strings: Filters.byProperties(['TEXT', 'TEXTAREA_PLACEHOLDER']),
StringFormats: Filters.byProperties(['a', 'z']),
StringUtils: Filters.byProperties(['toASCII']),
/* URLs and Utils */
URLParser: Filters.byProperties(['Url', 'parse']),
ExtraURLs: Filters.byProperties(['getArticleURL']),
/* Text Processing */
hljs: Filters.byProperties(['highlight', 'highlightBlock']),
SimpleMarkdown: Filters.byProperties(['parseBlock', 'parseInline', 'defaultOutput']),
/* DOM/React Components */
/* ==================== */
LayerManager: Filters.byProperties(['popLayer', 'pushLayer']),
UserSettingsWindow: Filters.byProperties(['open', 'updateAccount']),
ChannelSettingsWindow: Filters.byProperties(['open', 'updateChannel']),
GuildSettingsWindow: Filters.byProperties(['open', 'updateGuild']),
/* Modals */
ModalStack: Filters.byProperties(['push', 'update', 'pop', 'popWithKey']),
ConfirmModal: Filters.byPrototypeFields(['handleCancel', 'handleSubmit', 'handleMinorConfirm']),
UserProfileModal: Filters.byProperties(['fetchMutualFriends', 'setSection']),
ChangeNicknameModal: Filters.byProperties(['open', 'changeNickname']),
CreateChannelModal: Filters.byProperties(['open', 'createChannel']),
PruneMembersModal: Filters.byProperties(['open', 'prune']),
NotificationSettingsModal: Filters.byProperties(['open', 'updateNotificationSettings']),
PrivacySettingsModal: Filters.byCode(/PRIVACY_SETTINGS_MODAL_OPEN/, m => m.open),
CreateInviteModal: Filters.byProperties(['open', 'createInvite']),
/* Popouts */
PopoutStack: Filters.byProperties(['open', 'close', 'closeAll']),
PopoutOpener: Filters.byProperties(['openPopout']),
EmojiPicker: Filters.byPrototypeFields(['onHoverEmoji', 'selectEmoji']),
/* Context Menus */
ContextMenuActions: Filters.byCode(/CONTEXT_MENU_CLOSE/, c => c.close),
ContextMenuItemsGroup: Filters.byCode(/itemGroup/),
ContextMenuItem: Filters.byCode(/\.label\b.*\.hint\b.*\.action\b/),
/* In-Message Links */
ExternalLink: Filters.byCode(/\.trusted\b/)
};
class Module {
/**
* Finds a module using a filter function.
* @param {Function} filter A function to use to filter modules
* @param {Boolean} first Whether to return only the first matching module
* @param {Array} modules An array of modules to search in
* @return {Any}
*/
static getModule(filter, first = true, _modules) {
const modules = _modules || this.getAllModules();
const rm = [];
for (const index in modules) {
if (!modules.hasOwnProperty(index)) continue;
const module = modules[index];
const { exports } = module;
let foundModule = null;
if (!exports) continue;
if (exports.__esModule && exports.default && filter(exports.default)) foundModule = exports.default;
if (filter(exports)) foundModule = exports;
if (!foundModule) continue;
if (first) return foundModule;
rm.push(foundModule);
}
return first ? undefined : rm;
}
/**
* Finds a module by it's name.
* @param {String} name The name of the module
* @param {Function} fallback A function to use to filter modules if not finding a known module
* @return {Any}
*/
static byName(name, fallback) {
if (Cache.hasOwnProperty(name)) return Cache[name];
if (KnownModules.hasOwnProperty(name)) fallback = KnownModules[name];
if (!fallback) return undefined;
const module = this.getModule(fallback, true);
return module ? Cache[name] = module : undefined;
}
/**
* Finds a module by it's display name.
* @param {String} name The display name of the module
* @return {Any}
*/
static byDisplayName(name) {
return this.getModule(Filters.byDisplayName(name), true);
}
/**
* Finds a module using it's code.
* @param {RegEx} regex A regular expression to use to filter modules
* @param {Boolean} first Whether to return the only the first matching module
* @return {Any}
*/
static byRegex(regex, first = true) {
return this.getModule(Filters.byCode(regex), first);
}
/**
* Finds the first module using properties on it's prototype.
* @param {any} props Properties to use to filter modules
* @return {Any}
*/
static byPrototypes(...prototypes) {
return this.getModule(Filters.byPrototypeFields(prototypes), true);
}
/**
* Finds all modules using properties on it's prototype.
* @param {any} props Properties to use to filter modules
* @return {Any}
*/
static allByPrototypes(...prototypes) {
return this.getModule(Filters.byPrototypeFields(prototypes), false);
}
/**
* Finds the first module using it's own properties.
* @param {any} props Properties to use to filter modules
* @return {Any}
*/
static byProps(...props) {
return this.getModule(Filters.byProperties(props), true);
}
/**
* Finds all modules using it's own properties.
* @param {any} props Properties to use to filter modules
* @return {Any}
*/
static allByProps(...props) {
return this.getModule(Filters.byProperties(props), false);
}
/**
* Discord's __webpack_require__ function.
*/
static get require() {
if (this._require) return this._require;
const __webpack_require__ = this.getWebpackRequire();
if (!__webpack_require__) return null;
this.hookWebpackRequireCache(__webpack_require__);
return this._require = __webpack_require__;
}
static getWebpackRequire() {
const id = 'bd-webpackmodules';
if (typeof window.webpackJsonp === 'function') {
const __webpack_require__ = window['webpackJsonp']([], {
[id]: (module, exports, __webpack_require__) => exports.default = __webpack_require__
}, [id]).default;
delete __webpack_require__.m[id];
delete __webpack_require__.c[id];
return __webpack_require__;
} else if (window.webpackJsonp && window.webpackJsonp.push) {
const __webpack_require__ = window['webpackJsonp'].push([[], {
[id]: (module, exports, req) => exports.default = req
}, [[id]]]).default;
window['webpackJsonp'].pop();
delete __webpack_require__.m[id];
delete __webpack_require__.c[id];
return __webpack_require__;
}
}
static hookWebpackRequireCache(__webpack_require__) {
__webpack_require__.c = new Proxy(__webpack_require__.c, {
set(module_cache, module_id, module) {
// Add it to our emitter cache and emit a module-loading event
this.moduleLoading(module_id, module);
Events.emit('module-loading', module);
// Add the module to the cache as normal
module_cache[module_id] = module;
}
});
}
static moduleLoading(module_id, module) {
if (this.require.c[module_id]) return;
if (!this.moduleLoadedEventTimeout) {
this.moduleLoadedEventTimeout = setTimeout(() => {
this.moduleLoadedEventTimeout = undefined;
// Emit a module-loaded event for every module
for (const module of this.modulesLoadingCache) {
Events.emit('module-loaded', module);
}
// Emit a modules-loaded event
Events.emit('modules-loaded', this.modulesLoadingCache);
this.modulesLoadedCache = [];
}, 0);
}
// Add this to our own cache
if (!this.modulesLoadingCache) this.modulesLoadingCache = [];
this.modulesLoadingCache.push(module);
}
static waitForWebpackRequire() {
return Utils.until(() => this.require, 10);
}
/**
* Waits for a module to load.
* This only returns a single module, as it can't guarentee there are no more modules that could
* match the filter, which is pretty much what that would be asking for.
* @param {Function} filter The name of a known module or a filter function
* @return {Any}
*/
static async waitForModule(filter) {
const module = this.getModule(filter);
if (module) return module;
while (this.require.m.length > this.require.c.length) {
const additionalModules = await Events.once('modules-loaded');
const module = this.getModule(filter, true, additionalModules);
if (module) return module;
}
throw new Error('All modules have now been loaded. None match the passed filter.');
}
/**
* Finds a module by it's name.
* @param {String} name The name of the module
* @param {Function} fallback A function to use to filter modules if not finding a known module
* @return {Any}
*/
static async waitForModuleByName(name, fallback) {
if (Cache.hasOwnProperty(name)) return Cache[name];
if (KnownModules.hasOwnProperty(name)) fallback = KnownModules[name];
if (!fallback) return undefined;
const module = await this.waitForModule(fallback, true);
return module ? Cache[name] = module : undefined;
}
static waitForModuleByDisplayName(props) {
return this.waitForModule(Filters.byDisplayName(props));
}
static waitForModuleByRegex(props) {
return this.waitForModule(Filters.byCode(props));
}
static waitForModuleByProps(props) {
return this.waitForModule(Filters.byProperties(props));
}
static waitForModuleByPrototypes(props) {
return this.waitForModule(Filters.byPrototypeFields(props));
}
/**
* Returns all loaded modules.
* @return {Array}
*/
static getAllModules() {
return this.require.c;
}
/**
* Returns an array of known modules.
* @return {Array}
*/
static listKnownModules() {
return Object.keys(KnownModules);
}
static get KnownModules() { return KnownModules }
}
const Modules = new Proxy(Module, {
get(Module, name) {
return Module.byName(name);
}
});
export { Module, Modules }

View File

@ -0,0 +1,59 @@
/**
* BetterDiscord Reflection Resolver
* Copyright (c) 2015-present Jiiks/JsSucks - https://github.com/Jiiks / https://github.com/JsSucks
* All rights reserved.
* https://betterdiscord.net
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import { Module } from './modules';
class Resolved {
constructor(module, ...classes) {
this.module = Module.byProps(...classes);
this.classes = classes;
}
get className() {
return this.module && this.module[this.classes[0]] ? this.module[this.classes[0]].split(' ')[0] : this.classes[0];
}
get selector() {
return `.${this.className}`;
}
}
export default class Resolver {
static resolve(...classes) {
return new Resolved(Module.byProps(...classes), ...classes);
}
static async resolveAsync(...classes) {
const module = await Module.waitForModuleByProps([...classes]);
return new Resolved(module, ...classes);
}
/**
* Searches for a class module and returns a class from it.
* @param {String} base The first part of the class to find
* @param {String} ...additional_classes Additional classes to look for to filter duplicate class modules
* @return {String}
*/
static getClassName(base, ...additional_classes) {
const class_module = Module.byProps([base, ...additional_classes]);
if (class_module && class_module[base]) return class_module[base].split(' ')[0];
}
static async waitForClassName(base, ...additional_classes) {
const class_module = await Module.waitForModuleByProps([base, ...additional_classes]);
if (class_module && class_module[base]) return class_module[base].split(' ')[0];
}
static getSelector(base, ...additional_classes) {
const gcn = this.getClassName(base, ...additional_classes);
if (gcn) return `.${gcn}`;
}
}

View File

@ -0,0 +1,430 @@
/**
* BetterDiscord WebpackModules Module
* Copyright (c) 2015-present Jiiks/JsSucks - https://github.com/Jiiks / https://github.com/JsSucks
* All rights reserved.
* https://betterdiscord.net
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import { Utils, Filters } from 'common';
import Events from '../events';
const KnownModules = {
React: Filters.byProperties(['createElement', 'cloneElement']),
ReactDOM: Filters.byProperties(['render', 'findDOMNode']),
Events: Filters.byPrototypeFields(['setMaxListeners', 'emit']),
/* Guild Info, Stores, and Utilities */
GuildStore: Filters.byProperties(['getGuild']),
SortedGuildStore: Filters.byProperties(['getSortedGuilds']),
SelectedGuildStore: Filters.byProperties(['getLastSelectedGuildId']),
GuildSync: Filters.byProperties(['getSyncedGuilds']),
GuildInfo: Filters.byProperties(['getAcronym']),
GuildChannelsStore: Filters.byProperties(['getChannels', 'getDefaultChannel']),
GuildMemberStore: Filters.byProperties(['getMember']),
MemberCountStore: Filters.byProperties(['getMemberCounts']),
GuildEmojiStore: Filters.byProperties(['getEmojis']),
GuildActions: Filters.byProperties(['markGuildAsRead']),
GuildPermissions: Filters.byProperties(['getGuildPermissions']),
/* Channel Store & Actions */
ChannelStore: Filters.byProperties(['getChannels', 'getDMFromUserId']),
SelectedChannelStore: Filters.byProperties(['getLastSelectedChannelId']),
ChannelActions: Filters.byProperties(['selectChannel']),
PrivateChannelActions: Filters.byProperties(['openPrivateChannel']),
ChannelSelector: Filters.byProperties(['selectGuild', 'selectChannel']),
VoiceChannelActions: Filters.byProperties(['selectVoiceChannel']),
/* Current User Info, State and Settings */
UserInfoStore: Filters.byProperties(['getToken']),
UserSettingsStore: Filters.byProperties(['guildPositions']),
AccountManager: Filters.byProperties(['register', 'login']),
UserSettingsUpdater: Filters.byProperties(['updateRemoteSettings']),
OnlineWatcher: Filters.byProperties(['isOnline']),
CurrentUserIdle: Filters.byProperties(['getIdleTime']),
RelationshipStore: Filters.byProperties(['isBlocked', 'isFriend']),
RelationshipManager: Filters.byProperties(['addRelationship']),
MentionStore: Filters.byProperties(['getMentions']),
/* User Stores and Utils */
UserStore: Filters.byProperties(['getCurrentUser']),
UserStatusStore: Filters.byProperties(['getStatuses']),
UserTypingStore: Filters.byProperties(['isTyping']),
UserActivityStore: Filters.byProperties(['getActivity']),
UserNameResolver: Filters.byProperties(['getName']),
UserNoteStore: Filters.byProperties(['getNote']),
UserNoteActions: Filters.byProperties(['updateNote']),
DraftActions: Filters.byProperties(['changeDraft']),
/* Emoji Store and Utils */
EmojiInfo: Filters.byProperties(['isEmojiDisabled']),
EmojiUtils: Filters.byProperties(['getGuildEmoji']),
EmojiStore: Filters.byProperties(['getByCategory', 'EMOJI_NAME_RE']),
/* Invite Store and Utils */
InviteStore: Filters.byProperties(['getInvites']),
InviteResolver: Filters.byProperties(['findInvite']),
InviteActions: Filters.byProperties(['acceptInvite']),
/* Discord Objects & Utils */
DiscordConstants: Filters.byProperties(['Permissions', 'ActivityTypes', 'StatusTypes']),
Permissions: Filters.byProperties(['getHighestRole']),
ColorConverter: Filters.byProperties(['hex2int']),
ColorShader: Filters.byProperties(['darken']),
TinyColor: Filters.byPrototypeFields(['toRgb']),
ClassResolver: Filters.byProperties(['getClass']),
ButtonData: Filters.byProperties(['ButtonSizes']),
IconNames: Filters.byProperties(['IconNames']),
NavigationUtils: Filters.byProperties(['transitionTo', 'replaceWith', 'getHistory']),
/* Discord Messages */
MessageStore: Filters.byProperties(['getMessages']),
MessageActions: Filters.byProperties(['jumpToMessage', '_sendMessage']),
MessageQueue: Filters.byProperties(['enqueue']),
MessageParser: Filters.byProperties(['createMessage', 'parse', 'unparse']),
/* In-Game Overlay */
OverlayUserPopoutSettings: Filters.byProperties(['openUserPopout']),
OverlayUserPopoutInfo: Filters.byProperties(['getOpenedUserPopout']),
/* Experiments */
ExperimentStore: Filters.byProperties(['getExperimentOverrides']),
ExperimentsManager: Filters.byProperties(['isDeveloper']),
CurrentExperiment: Filters.byProperties(['getExperimentId']),
/* Images, Avatars and Utils */
ImageResolver: Filters.byProperties(['getUserAvatarURL']),
ImageUtils: Filters.byProperties(['getSizedImageSrc']),
AvatarDefaults: Filters.byProperties(['getUserAvatarURL', 'DEFAULT_AVATARS']),
/* Drag & Drop */
DNDActions: Filters.byProperties(['beginDrag']),
DNDSources: Filters.byProperties(['addTarget']),
DNDObjects: Filters.byProperties(['DragSource']),
/* Electron & Other Internals with Utils */
ElectronModule: Filters.byProperties(['_getMainWindow']),
Dispatcher: Filters.byProperties(['dirtyDispatch']),
PathUtils: Filters.byProperties(['hasBasename']),
NotificationModule: Filters.byProperties(['showNotification']),
RouterModule: Filters.byProperties(['Router']),
APIModule: Filters.byProperties(['getAPIBaseURL']),
AnalyticEvents: Filters.byProperties(['AnalyticEventConfigs']),
KeyGenerator: Filters.byCode(/"binary"/),
Buffers: Filters.byProperties(['Buffer', 'kMaxLength']),
DeviceStore: Filters.byProperties(['getDevices']),
SoftwareInfo: Filters.byProperties(['os']),
CurrentContext: Filters.byProperties(['setTagsContext']),
/* Media Stuff (Audio/Video) */
MediaDeviceInfo: Filters.byProperties(['Codecs', 'SUPPORTED_BROWSERS']),
MediaInfo: Filters.byProperties(['getOutputVolume']),
MediaEngineInfo: Filters.byProperties(['MediaEngineFeatures']),
VoiceInfo: Filters.byProperties(['EchoCancellation']),
VideoStream: Filters.byProperties(['getVideoStream']),
SoundModule: Filters.byProperties(['playSound']),
/* Window, DOM, HTML */
WindowInfo: Filters.byProperties(['isFocused', 'windowSize']),
TagInfo: Filters.byProperties(['VALID_TAG_NAMES']),
DOMInfo: Filters.byProperties(['canUseDOM']),
/* Locale/Location and Time */
LocaleManager: Filters.byProperties(['setLocale']),
Moment: Filters.byProperties(['parseZone']),
LocationManager: Filters.byProperties(['createLocation']),
Timestamps: Filters.byProperties(['fromTimestamp']),
TimeFormatter: Filters.byProperties(['dateFormat']),
/* Strings and Utils */
Strings: Filters.byProperties(['TEXT', 'TEXTAREA_PLACEHOLDER']),
StringFormats: Filters.byProperties(['a', 'z']),
StringUtils: Filters.byProperties(['toASCII']),
/* URLs and Utils */
URLParser: Filters.byProperties(['Url', 'parse']),
ExtraURLs: Filters.byProperties(['getArticleURL']),
/* Text Processing */
hljs: Filters.byProperties(['highlight', 'highlightBlock']),
SimpleMarkdown: Filters.byProperties(['parseBlock', 'parseInline', 'defaultOutput']),
/* DOM/React Components */
/* ==================== */
LayerManager: Filters.byProperties(['popLayer', 'pushLayer']),
UserSettingsWindow: Filters.byProperties(['open', 'updateAccount']),
ChannelSettingsWindow: Filters.byProperties(['open', 'updateChannel']),
GuildSettingsWindow: Filters.byProperties(['open', 'updateGuild']),
/* Modals */
ModalStack: Filters.byProperties(['push', 'update', 'pop', 'popWithKey']),
ConfirmModal: Filters.byPrototypeFields(['handleCancel', 'handleSubmit', 'handleMinorConfirm']),
UserProfileModal: Filters.byProperties(['fetchMutualFriends', 'setSection']),
ChangeNicknameModal: Filters.byProperties(['open', 'changeNickname']),
CreateChannelModal: Filters.byProperties(['open', 'createChannel']),
PruneMembersModal: Filters.byProperties(['open', 'prune']),
NotificationSettingsModal: Filters.byProperties(['open', 'updateNotificationSettings']),
PrivacySettingsModal: Filters.byCode(/PRIVACY_SETTINGS_MODAL_OPEN/, m => m.open),
CreateInviteModal: Filters.byProperties(['open', 'createInvite']),
/* Popouts */
PopoutStack: Filters.byProperties(['open', 'close', 'closeAll']),
PopoutOpener: Filters.byProperties(['openPopout']),
EmojiPicker: Filters.byPrototypeFields(['onHoverEmoji', 'selectEmoji']),
/* Context Menus */
ContextMenuActions: Filters.byCode(/CONTEXT_MENU_CLOSE/, c => c.close),
ContextMenuItemsGroup: Filters.byCode(/itemGroup/),
ContextMenuItem: Filters.byCode(/\.label\b.*\.hint\b.*\.action\b/),
/* In-Message Links */
ExternalLink: Filters.byCode(/\.trusted\b/)
};
class WebpackModules {
/**
* Finds a module using a filter function.
* @param {Function} filter A function to use to filter modules
* @param {Boolean} first Whether to return only the first matching module
* @param {Array} modules An array of modules to search in
* @return {Any}
*/
static getModule(filter, first = true, _modules) {
const modules = _modules || this.getAllModules();
const rm = [];
for (const index in modules) {
if (!modules.hasOwnProperty(index)) continue;
const module = modules[index];
const { exports } = module;
let foundModule = null;
if (!exports) continue;
if (exports.__esModule && exports.default && filter(exports.default)) foundModule = exports.default;
if (filter(exports)) foundModule = exports;
if (!foundModule) continue;
if (first) return foundModule;
rm.push(foundModule);
}
return first ? undefined : rm;
}
/**
* Finds a module by it's name.
* @param {String} name The name of the module
* @param {Function} fallback A function to use to filter modules if not finding a known module
* @return {Any}
*/
static getModuleByName(name, fallback) {
if (Cache.hasOwnProperty(name)) return Cache[name];
if (KnownModules.hasOwnProperty(name)) fallback = KnownModules[name];
if (!fallback) return undefined;
const module = this.getModule(fallback, true);
return module ? Cache[name] = module : undefined;
}
/**
* Finds a module by it's display name.
* @param {String} name The display name of the module
* @return {Any}
*/
static getModuleByDisplayName(name) {
return this.getModule(Filters.byDisplayName(name), true);
}
/**
* Finds a module using it's code.
* @param {RegEx} regex A regular expression to use to filter modules
* @param {Boolean} first Whether to return the only the first matching module
* @return {Any}
*/
static getModuleByRegex(regex, first = true) {
return this.getModule(Filters.byCode(regex), first);
}
/**
* Finds a module using properties on it's prototype.
* @param {Array} props Properties to use to filter modules
* @param {Boolean} first Whether to return only the first matching module
* @return {Any}
*/
static getModuleByPrototypes(prototypes, first = true) {
return this.getModule(Filters.byPrototypeFields(prototypes), first);
}
/**
* Finds a module using it's own properties.
* @param {Array} props Properties to use to filter modules
* @param {Boolean} first Whether to return only the first matching module
* @return {Any}
*/
static getModuleByProps(props, first = true) {
return this.getModule(Filters.byProperties(props), first);
}
/**
* Discord's __webpack_require__ function.
*/
static get require() {
if (this._require) return this._require;
const __webpack_require__ = this.getWebpackRequire();
if (!__webpack_require__) return null;
this.hookWebpackRequireCache(__webpack_require__);
return this._require = __webpack_require__;
}
static getWebpackRequire() {
const id = 'bd-webpackmodules';
if (typeof window.webpackJsonp === 'function') {
const __webpack_require__ = window['webpackJsonp']([], {
[id]: (module, exports, __webpack_require__) => exports.default = __webpack_require__
}, [id]).default;
delete __webpack_require__.m[id];
delete __webpack_require__.c[id];
return __webpack_require__;
} else if (window.webpackJsonp && window.webpackJsonp.push) {
const __webpack_require__ = window['webpackJsonp'].push([[], {
[id]: (module, exports, req) => exports.default = req
}, [[id]]]).default;
window['webpackJsonp'].pop();
delete __webpack_require__.m[id];
delete __webpack_require__.c[id];
return __webpack_require__;
}
}
static hookWebpackRequireCache(__webpack_require__) {
__webpack_require__.c = new Proxy(__webpack_require__.c, {
set(module_cache, module_id, module) {
// Add it to our emitter cache and emit a module-loading event
this.moduleLoading(module_id, module);
Events.emit('module-loading', module);
// Add the module to the cache as normal
module_cache[module_id] = module;
}
});
}
static moduleLoading(module_id, module) {
if (this.require.c[module_id]) return;
if (!this.moduleLoadedEventTimeout) {
this.moduleLoadedEventTimeout = setTimeout(() => {
this.moduleLoadedEventTimeout = undefined;
// Emit a module-loaded event for every module
for (const module of this.modulesLoadingCache) {
Events.emit('module-loaded', module);
}
// Emit a modules-loaded event
Events.emit('modules-loaded', this.modulesLoadingCache);
this.modulesLoadedCache = [];
}, 0);
}
// Add this to our own cache
if (!this.modulesLoadingCache) this.modulesLoadingCache = [];
this.modulesLoadingCache.push(module);
}
static waitForWebpackRequire() {
return Utils.until(() => this.require, 10);
}
/**
* Waits for a module to load.
* This only returns a single module, as it can't guarentee there are no more modules that could
* match the filter, which is pretty much what that would be asking for.
* @param {Function} filter The name of a known module or a filter function
* @return {Any}
*/
static async waitForModule(filter) {
const module = this.getModule(filter);
if (module) return module;
while (this.require.m.length > this.require.c.length) {
const additionalModules = await Events.once('modules-loaded');
const module = this.getModule(filter, true, additionalModules);
if (module) return module;
}
throw new Error('All modules have now been loaded. None match the passed filter.');
}
/**
* Finds a module by it's name.
* @param {String} name The name of the module
* @param {Function} fallback A function to use to filter modules if not finding a known module
* @return {Any}
*/
static async waitForModuleByName(name, fallback) {
if (Cache.hasOwnProperty(name)) return Cache[name];
if (KnownModules.hasOwnProperty(name)) fallback = KnownModules[name];
if (!fallback) return undefined;
const module = await this.waitForModule(fallback, true);
return module ? Cache[name] = module : undefined;
}
static waitForModuleByDisplayName(props) {
return this.waitForModule(Filters.byDisplayName(props));
}
static waitForModuleByRegex(props) {
return this.waitForModule(Filters.byCode(props));
}
static waitForModuleByProps(props) {
return this.waitForModule(Filters.byProperties(props));
}
static waitForModuleByPrototypes(props) {
return this.waitForModule(Filters.byPrototypeFields(props));
}
/**
* Searches for a class module and returns a class from it.
* @param {String} base The first part of the class to find
* @param {String} ...additional_classes Additional classes to look for to filter duplicate class modules
* @return {String}
*/
static getClassName(base, ...additional_classes) {
const class_module = this.getModuleByProps([base, ...additional_classes]);
if (class_module && class_module[base]) return class_module[base].split(' ')[0];
}
static async waitForClassName(base, ...additional_classes) {
const class_module = await this.waitForModuleByProps([base, ...additional_classes]);
if (class_module && class_module[base]) return class_module[base].split(' ')[0];
}
static getSelector(base, ...additional_classes) {
const gcn = this.getClassName(base, ...additional_classes);
if (gcn) return `.${gcn}`;
}
/**
* Returns all loaded modules.
* @return {Array}
*/
static getAllModules() {
return this.require.c;
}
/**
* Returns an array of known modules.
* @return {Array}
*/
static listKnownModules() {
return Object.keys(KnownModules);
}
static get KnownModules() { return KnownModules }
}
export { WebpackModules }

View File

@ -0,0 +1,111 @@
/**
* BetterDiscord Security Module
* Copyright (c) 2015-present Jiiks/JsSucks - https://github.com/Jiiks / https://github.com/JsSucks
* All rights reserved.
* https://betterdiscord.net
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import nodecrypto from 'node-crypto';
import aes256 from 'aes256';
export default class Security {
static encrypt(key, content, prefix = '') {
if (key instanceof Array || content instanceof Array) return this.deepEncrypt(key, content, prefix);
return `${prefix}${aes256.encrypt(key, content)}`;
}
static decrypt(key, content, prefix = '') {
if (key instanceof Array || content instanceof Array) {
return this.deepDecrypt(key, content, prefix);
}
return aes256.decrypt(key, content.replace(prefix, ''));
}
static deepEncrypt(keys, content, prefix = '') {
if (content && content instanceof Array) return this.deepEncryptContent(keys, content, prefix);
let encrypt = null;
for (const key of keys) {
if (encrypt === null) encrypt = this.encrypt(key, content, prefix);
else encrypt = this.encrypt(key, encrypt, prefix);
}
return encrypt;
}
static deepEncryptContent(key, contents, prefix = '') {
let encrypt = null;
for (const content of contents) {
if (encrypt === null) encrypt = this.encrypt(key, content, prefix);
else encrypt = this.encrypt(encrypt, content, prefix);
}
return encrypt;
}
static deepDecrypt(keys, content, prefix = '') {
if (content && content instanceof Array) return this.deepDecryptContent(keys, content, prefix);
let decrypt = null;
for (const key of keys.reverse()) {
if (decrypt === null) decrypt = this.decrypt(key, content, prefix);
else decrypt = this.decrypt(key, decrypt, prefix);
}
return decrypt;
}
static deepDecryptContent(key, contents, prefix = '') {
let decrypt = null;
for (const content of contents) {
if (decrypt === null) decrypt = this.decrypt(key, content, prefix);
else decrypt = this.decrypt(decrypt, content, prefix);
}
return decrypt;
}
static randomBytes(length = 64, to = 'hex') {
return nodecrypto.randomBytes(length).toString(to);
}
static async createHmac(key, data, algorithm = 'sha256') {
const hmac = nodecrypto.createHmac(algorithm, key);
return new Promise((resolve, reject) => {
hmac.on('readable', () => {
const data = hmac.read();
if (data) return resolve(data.toString('hex'));
reject(null);
});
hmac.write(data);
hmac.end();
});
}
static createECDH(curve = 'secp384r1') {
return nodecrypto.createECDH(curve);
}
static hash(algorithm, data, encoding) {
const hash = nodecrypto.createHash(algorithm);
hash.update(data);
return hash.digest(encoding);
}
static sha256(text) {
const hash = nodecrypto.createHash('sha256');
hash.update(text);
return hash.digest('base64');
}
static generateECDHKeys(ecdh) {
return ecdh.generateKeys('base64');
}
static getECDHPublicKey(ecdh) {
return ecdh.getPublicKey('base64');
}
static computeECDHSecret(ecdh, otherPublicKey) {
return ecdh.computeSecret(otherPublicKey, 'base64', 'base64');
}
}

View File

@ -0,0 +1,165 @@
/**
* BetterDiscord Settings Module
* Copyright (c) 2015-present Jiiks/JsSucks - https://github.com/Jiiks / https://github.com/JsSucks
* All rights reserved.
* https://betterdiscord.net
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import { Toasts } from 'ui';
import { SettingsSet } from 'structs';
import { FileUtils, ClientLogger as Logger } from 'common';
import path from 'path';
import process from 'process';
import Globals from './globals';
import CssEditor from './csseditor';
import Events from './events';
import defaultSettings from '../data/user.settings.default';
export default new class Settings {
constructor() {
this.settings = defaultSettings.map(_set => {
const set = new SettingsSet(_set);
set.on('setting-updated', event => {
const { category, setting, value, old_value } = event;
Logger.log('Settings', [`${set.id}/${category.id}/${setting.id} was changed from`, old_value, 'to', value]);
Events.emit('setting-updated', event);
Events.emit(`setting-updated-${set.id}_${category.id}_${setting.id}`, event);
Toasts.success(`${set.id}/${category.id}/${setting.id} was changed from ${old_value} to ${value}`); // Just for debugging purposes remove in prod
});
set.on('settings-updated', async event => {
if (!event.data || !event.data.dont_save) await this.saveSettings();
Events.emit('settings-updated', event);
});
return set;
});
// Set a hint for each platform for the use-keytar setting
const useKeytarSetting = this.getSetting('security', 'default', 'use-keytar');
if (process.platform === 'win32') useKeytarSetting.hint = 'Store the master password in Credential Manager';
if (process.platform === 'darwin') useKeytarSetting.hint = 'Store the master password in the default keychain';
if (process.platform === 'linux') useKeytarSetting.hint = 'Store the master password in libsecret';
}
/**
* Loads BetterDiscord's settings.
*/
async loadSettings() {
Logger.log('Settings', ['Loading settings']);
try {
await FileUtils.ensureDirectory(this.dataPath);
const settingsPath = path.resolve(this.dataPath, 'user.settings.json');
const user_config = await FileUtils.readJsonFromFile(settingsPath);
const { settings, scss, css, css_editor_files, scss_error, css_editor_bounds, favourite_emotes } = user_config;
for (const set of this.settings) {
const newSet = settings.find(s => s.id === set.id);
if (!newSet) continue;
await set.merge(newSet, {dont_save: true});
set.setSaved();
}
CssEditor.setState(scss, css, css_editor_files, scss_error);
CssEditor.editor_bounds = css_editor_bounds || {};
} catch (err) {
// There was an error loading settings
// This probably means that the user doesn't have any settings yet
Logger.warn('Settings', ['Failed to load internal settings', err]);
}
}
/**
* Saves BetterDiscord's settings including CSS editor data.
*/
async saveSettings() {
Logger.log('Settings', ['Saving settings']);
try {
await FileUtils.ensureDirectory(this.dataPath);
const settingsPath = path.resolve(this.dataPath, 'user.settings.json');
await FileUtils.writeJsonToFile(settingsPath, {
settings: this.settings.map(set => set.strip()),
scss: CssEditor.scss,
css: CssEditor.css,
css_editor_files: CssEditor.files,
scss_error: CssEditor.error,
css_editor_bounds: CssEditor.editor_bounds
});
for (const set of this.settings) {
set.setSaved();
}
} catch (err) {
// There was an error saving settings
Logger.err('Settings', ['Failed to save internal settings', err]);
throw err;
}
}
/**
* Finds one of BetterDiscord's settings sets.
* @param {String} set_id The ID of the set to find
* @return {SettingsSet}
*/
getSet(set_id) {
return this.settings.find(s => s.id === set_id);
}
get core() { return this.getSet('core') }
get ui() { return this.getSet('ui') }
get emotes() { return this.getSet('emotes') }
get css() { return this.getSet('css') }
get security() { return this.getSet('security') }
/**
* Finds a category in one of BetterDiscord's settings sets.
* @param {String} set_id The ID of the set to look in
* @param {String} category_id The ID of the category to find
* @return {SettingsCategory}
*/
getCategory(set_id, category_id) {
const set = this.getSet(set_id);
return set ? set.getCategory(category_id) : undefined;
}
/**
* Finds a setting in one of BetterDiscord's settings sets.
* @param {String} set_id The ID of the set to look in
* @param {String} category_id The ID of the category to look in
* @param {String} setting_id The ID of the setting to find
* @return {Setting}
*/
getSetting(set_id, category_id, setting_id) {
const set = this.getSet(set_id);
return set ? set.getSetting(category_id, setting_id) : undefined;
}
/**
* Returns a setting's value in one of BetterDiscord's settings sets.
* @param {String} set_id The ID of the set to look in
* @param {String} category_id The ID of the category to look in
* @param {String} setting_id The ID of the setting to find
* @return {Any}
*/
get(set_id, category_id, setting_id) {
const set = this.getSet(set_id);
return set ? set.get(category_id, setting_id) : undefined;
}
/**
* The path to store user data in.
*/
get dataPath() {
return Globals.getPath('data');
}
}

View File

@ -0,0 +1,40 @@
/**
* BetterDiscord Discord Socket Proxy Module
* Copyright (c) 2015-present Jiiks/JsSucks - https://github.com/Jiiks / https://github.com/JsSucks
* All rights reserved.
* https://betterdiscord.net
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import { ClientLogger as Logger } from 'common';
import EventListener from './eventlistener';
export default class SocketProxy extends EventListener {
bindings() {
this.socketCreated = this.socketCreated.bind(this);
this.onMessage = this.onMessage.bind(this);
}
get eventBindings() {
return [
{ id: 'socket-created', callback: this.socketCreated }
];
}
get socket() {
return this.activeSocket;
}
socketCreated(socket) {
this.activeSocket = socket;
// socket.addEventListener('message', this.onMessage);
}
onMessage(e) {
Logger.info('SocketProxy', e);
}
}

176
client/src/modules/theme.js Normal file
View File

@ -0,0 +1,176 @@
/**
* BetterDiscord Theme Module
* Copyright (c) 2015-present Jiiks/JsSucks - https://github.com/Jiiks / https://github.com/JsSucks
* All rights reserved.
* https://betterdiscord.net
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import Content from './content';
import Settings from './settings';
import ThemeManager from './thememanager';
import { DOM } from 'ui';
import { FileUtils, ClientIPC, ClientLogger as Logger } from 'common';
import filewatcher from 'filewatcher';
export default class Theme extends Content {
constructor(internals) {
super(internals);
const watchfiles = Settings.getSetting('css', 'default', 'watch-files');
if (watchfiles.value) this.watchfiles = this.files;
watchfiles.on('setting-updated', event => {
if (event.value) this.watchfiles = this.files;
else this.watchfiles = [];
});
}
get type() { return 'theme' }
get css() { return this.data.css }
/**
* Called when settings are updated.
* This can be overridden by other content types.
*/
__settingsUpdated(event) {
return this.recompile();
}
/**
* This is called when the theme is enabled.
*/
async onstart() {
if (!this.css) await this.recompile();
DOM.injectTheme(this.css, this.id);
}
/**
* This is called when the theme is disabled.
*/
onstop() {
DOM.deleteTheme(this.id);
}
/**
* Compiles the theme and returns an object containing the CSS and an array of files that were included.
* @return {Promise}
*/
async compile() {
Logger.log(this.name, 'Compiling CSS');
if (this.info.type === 'sass') {
const config = await ThemeManager.getConfigAsSCSS(this.settings);
const result = await ClientIPC.send('bd-compileSass', {
data: config,
path: this.paths.mainPath.replace(/\\/g, '/')
});
// Why are these getters?
Logger.log(this.name, ['Finished compiling theme', new class Info {
get SCSS_variables() { console.log(config); return ''; }
get Compiled_SCSS() { console.log(result.css.toString()); return ''; }
get Result() { console.log(result); return ''; }
}]);
return {
css: result.css.toString(),
files: result.stats.includedFiles
};
}
return { css: await FileUtils.readFile(this.paths.mainPath) }
}
/**
* Compiles the theme and updates and saves the CSS and the list of include files.
* @return {Promise}
*/
async recompile() {
const data = await this.compile();
this.data.css = data.css;
this.files = data.files;
await this.saveConfiguration();
if (this.enabled) {
DOM.deleteTheme(this.id);
DOM.injectTheme(this.css, this.id);
}
}
/**
* An array of files that are imported in the theme's SCSS.
* @return {Array} Files being watched
*/
get files() {
return this.data.files || (this.data.files = []);
}
/**
* Sets all files that are imported in the theme's SCSS.
* @param {Array} files Files to watch
*/
set files(files) {
this.data.files = files;
if (Settings.get('css', 'default', 'watch-files'))
this.watchfiles = files;
}
/**
* A filewatcher instance.
*/
get filewatcher() {
if (this._filewatcher) return this._filewatcher;
this._filewatcher = filewatcher();
this._filewatcher.on('change', (file, stat) => {
// Recompile SCSS
this.recompile();
});
return this._filewatcher;
}
/**
* An array of files that are being watched for changes.
* @return {Array} Files being watched
*/
get watchfiles() {
return this._watchfiles || (this._watchfiles = []);
}
/**
* Sets all files to be watched.
* @param {Array} files Files to watch
*/
set watchfiles(files) {
if (this.packed) {
// Don't watch files for packed themes
return;
}
if (!files) files = [];
for (const file of files) {
if (!this.watchfiles.includes(file)) {
this.filewatcher.add(file);
this.watchfiles.push(file);
Logger.log(this.name, `Watching file ${file} for changes`);
}
}
for (const index in this.watchfiles) {
let file = this.watchfiles[index];
while (file && !files.find(f => f === file)) {
this.filewatcher.remove(file);
this.watchfiles.splice(index, 1);
Logger.log(this.name, `No longer watching file ${file} for changes`);
file = this.watchfiles[index];
}
}
}
}

View File

@ -0,0 +1,129 @@
/**
* BetterDiscord Theme Manager Module
* Copyright (c) 2015-present Jiiks/JsSucks - https://github.com/Jiiks / https://github.com/JsSucks
* All rights reserved.
* https://betterdiscord.net
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import ContentManager from './contentmanager';
import Theme from './theme';
export default class ThemeManager extends ContentManager {
static get localThemes() {
return this.localContent;
}
static get contentType() {
return 'theme';
}
static get moduleName() {
return 'Theme Manager';
}
static get pathId() {
return 'themes';
}
static get loadAllThemes() { return this.loadAllContent }
static get refreshThemes() { return this.refreshContent }
static get loadContent() { return this.loadTheme }
static async loadTheme(paths, configs, info, main) {
try {
const instance = new Theme({
configs, info, main, paths
});
if (instance.enabled) {
instance.userConfig.enabled = false;
instance.enable();
}
return instance;
} catch (err) {
throw err;
}
}
static get deleteTheme() { return this.deleteContent }
static get unloadTheme() { return this.unloadContent }
static async reloadTheme(theme) {
theme = await this.reloadContent(theme);
theme.recompile();
}
static enableTheme(theme) {
return theme.enable();
}
static disableTheme(theme) {
return theme.disable();
}
static get isTheme() { return this.isThisContent }
static isThisContent(theme) {
return theme instanceof Theme;
}
/**
* Returns a representation of a settings set's values in SCSS.
* @param {SettingsSet} settingsset The set to convert to SCSS
* @return {Promise}
*/
static async getConfigAsSCSS(settingsset) {
const variables = [];
for (const category of settingsset.categories) {
for (const setting of category.settings) {
const setting_scss = await this.parseSetting(setting);
if (setting_scss) variables.push(`$${setting_scss[0]}: ${setting_scss[1]};`);
}
}
return variables.join('\n');
}
/**
* Returns a representation of a settings set's values as an SCSS map.
* @param {SettingsSet} settingsset The set to convert to an SCSS map
* @return {Promise}
*/
static async getConfigAsSCSSMap(settingsset) {
const variables = [];
for (const category of settingsset.categories) {
for (const setting of category.settings) {
const setting_scss = await this.parseSetting(setting);
if (setting_scss) variables.push(`${setting_scss[0]}: (${setting_scss[1]})`);
}
}
return `(${variables.join(', ')})`;
}
/**
* Returns a setting's name and value as a string that can be included in SCSS.
* @param {Setting} setting The setting to convert to SCSS
* @return {Promise}
*/
static async parseSetting(setting) {
const name = setting.id.replace(/[^a-zA-Z0-9-]/g, '-').replace(/--/g, '-');
const scss = await setting.toSCSS();
if (scss) return [name, scss];
}
/**
* Escapes a string so it can be included in SCSS.
* @param {String} value The string to escape
* @return {String}
*/
static toSCSSString(value) {
if (typeof value !== 'string' && value.toString) value = value.toString();
return `'${typeof value === 'string' ? value.replace(/\\/g, '\\\\').replace(/'/g, '\\\'') : ''}'`;
}
}

View File

@ -0,0 +1,190 @@
/**
* BetterDiscord Updater Module
* Copyright (c) 2015-present Jiiks/JsSucks - https://github.com/Jiiks / https://github.com/JsSucks
* All rights reserved.
* https://betterdiscord.net
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import { Notifications } from 'ui';
import { Reflection, Globals } from 'modules';
import Events from './events';
import Module from './imodule';
export default new class extends Module {
get updates() { return this.state.updates }
get bdUpdates() { return this.state.updates.bd }
get error() { return null; }
get updatesAvailable() { return this.state.updatesAvailable; }
constructor() {
super({
updatesAvailable: false,
error: null,
updates: { bd: [] },
updating: false
});
}
bindings() {
this.restartNotif = this.restartNotif.bind(this);
this.reloadNotif = this.reloadNotif.bind(this);
this.startUpdate = this.startUpdate.bind(this);
this.setUpdateStatus = this.setUpdateStatus.bind(this);
this.testUi = this.testUi.bind(this);
}
restartNotif() {
Notifications.add('Updates Finished!', 'Restart required.', [
{
text: 'Restart Later',
onClick: () => { setTimeout(this.restartNotif, 5 * 60000); return true; }
},
{
text: 'Restart Now',
onClick: () => {
try {
const { remote } = Globals.require('electron');
window.close();
Reflection.module.byProps('showToken', 'hideToken').showToken();
remote.app.relaunch();
remote.app.exit(0);
} catch (err) {
console.err(err);
return true;
}
}
}
]);
}
reloadNotif() {
Notifications.add('Updates Finished!', 'Reload required.', [
{
text: 'Reload Later',
onClick: () => { setTimeout(this.reloadNotif, 5 * 60000); return true; }
},
{
text: 'Reload Now',
onClick: () => {
document.location.reload();
}
}
]);
}
events(ipc) {
ipc.on('updater-checkForUpdates', () => {
if (this.state.updating) return; // We're already updating. Updater should be paused anyways at this point.
Events.emit('update-check-start');
});
ipc.on('updater-noUpdates', () => {
if (this.state.updatesAvailable) return; // If for some reason we get this even though we have updates already.
this.setState({
updatesAvailable: false,
updates: {}
});
});
ipc.on('updater-updatesAvailable', (_, updates) => {
console.log(updates);
if (this.state.updating) return; // If for some reason we get more updates when we're already updating
updates.bd = updates.bd.map(update => {
update.text = `${update.id.charAt(0).toUpperCase()}${update.id.slice(1)}`;
update.hint = `Current: ${update.currentVersion} | Latest: ${update.version}`;
update.status = {
update: true,
updating: false,
updated: false,
error: null
};
return update;
});
this.setState({
updates,
updatesAvailable: true
});
});
ipc.on('updater-updated', (_, info) => {
const { reloadRequired, restartRequired } = info;
if (restartRequired) {
this.restartNotif();
return;
}
if (reloadRequired) {
this.reloadNotif();
return;
}
});
ipc.on('updater-updateFinished', (_, update) => {
this.setUpdateStatus(update.id, 'updated', true);
});
ipc.on('updater-updateError', (_, update) => {
this.setUpdateStatus(update.id, 'error', update.error);
});
}
stateChanged(oldState, newState) {
if (!newState.updatesAvailable) return Events.emit('update-check-end');
if (!oldState.updatesAvailable && newState.updatesAvailable) {
Events.emit('updates-available');
Notifications.add('', 'Updates Available!', [
{
text: 'Ignore',
onClick: () => { return true; }
},
{
text: 'Show Updates',
onClick: () => {
Events.emit('bd-open-menu', 'updater');
return true;
}
}
]);
}
}
setUpdateStatus(updateId, statusChild, statusValue) {
for (const u of this.bdUpdates) {
if (u.id === updateId) {
u.status[statusChild] = statusValue;
return;
}
}
}
toggleUpdate(update) {
update.status.update = !update.status.update;
}
async startUpdate() {
console.log('start update');
const updates = { bd: [] };
for (const update of this.bdUpdates) {
if (update.status.update) {
update.status.updating = true;
updates.bd.push(update);
}
}
console.log(updates);
this.send('updater-startUpdate', updates);
}
testUi(updates) {
this.setState({
updates,
updatesAvailable: true
});
}
}

View File

@ -0,0 +1,53 @@
/**
* BetterDiscord Vendor Module
* Copyright (c) 2015-present Jiiks/JsSucks - https://github.com/Jiiks / https://github.com/JsSucks
* All rights reserved.
* https://betterdiscord.net
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import jQuery from 'jquery';
import lodash from 'lodash';
import Vue from 'vue';
import { Axi } from 'common';
import request from 'request-promise-native';
import Combokeys from 'combokeys';
import filetype from 'file-type';
import filewatcher from 'filewatcher';
import VTooltip from 'v-tooltip';
export { jQuery as $, request };
export default class {
/**
* jQuery
*/
static get jQuery() { return jQuery }
static get $() { return this.jQuery }
/**
* Lodash
*/
static get lodash() { return lodash }
static get _() { return this.lodash }
/**
* Vue
*/
static get Vue() { return Vue }
static get axios() { return Axi.axios }
static get request() { return request }
static get Combokeys() { return Combokeys }
static get filetype() { return filetype }
static get filewatcher() { return filewatcher }
static get VTooltip() { return VTooltip }
}

View File

@ -0,0 +1,12 @@
/* Deprecation Notice */
import { WebpackModules } from './reflection/wpm.depr.js';
import { ClientLogger as Logger } from 'common';
const DeprecationWarning = new Proxy(WebpackModules, {
get(WebpackModules, property) {
Logger.warn('DEPR', 'WebpackModules is deprecated. Use Reflection.Modules instead.');
return WebpackModules[property] || WebpackModules.getModuleByName(property);
}
});
export { DeprecationWarning as WebpackModules };

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