Adds some final touches

This commit is contained in:
Zack Rauen 2020-07-29 15:06:54 -04:00
parent f2d4e3e8b7
commit 99d17bf4fe
25 changed files with 110 additions and 1371 deletions

1
.gitignore vendored
View File

@ -1 +1,2 @@
dist/
node_modules

View File

@ -1,4 +1,4 @@
# BandagedBD [![Build Status][travis-badge]][travis-link] [![Language Grade][lgtm-badge]][lgtm-link] ![GitHub Releases][downloads-badge]
# BetterDiscord [![Build Status][travis-badge]][travis-link] [![Language Grade][lgtm-badge]][lgtm-link] ![GitHub Releases][downloads-badge]
[patreon-badge]: https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fshieldsio-patreon.herokuapp.com%2FZerebos&style=flat-square
[patreon-link]: https://patreon.com/Zerebos
@ -9,7 +9,7 @@
[lgtm-badge]: https://img.shields.io/lgtm/grade/javascript/g/rauenzi/BetterDiscordApp.svg?style=flat-square
[lgtm-link]: https://lgtm.com/projects/g/rauenzi/BetterDiscordApp/context:javascript
[travis-badge]: https://img.shields.io/travis/com/rauenzi/BetterDiscordApp.svg?style=flat-square&branch=development
[travis-badge]: https://img.shields.io/travis/com/rauenzi/BetterDiscordApp.svg?style=flat-square&branch=stable
[travis-link]: https://travis-ci.com/rauenzi/BetterDiscordApp
[downloads-badge]: https://img.shields.io/github/downloads/rauenzi/BetterDiscordApp/latest/total?style=flat-square
@ -25,10 +25,10 @@ BetterDiscord is a client modification for Discord. This allows you to add plugi
## Auto Installers
### Windows
Grab the `exe` file from [here](https://github.com/rauenzi/BetterDiscordApp/releases/latest/download/BandagedBD_Windows.exe).
Grab the `exe` file from [here](https://github.com/rauenzi/BBDInstaller/releases/latest/download/BandagedBD.exe).
### macOS/OS X
Grab the `zip` file from [here](https://github.com/rauenzi/BetterDiscordApp/releases/latest/download/BandagedBD_Mac.zip).
Grab the `zip` file from [here](https://github.com/rauenzi/BBDInstaller/releases/latest/download/BandagedBD_Mac.zip).
### Linux
See this [gist](https://gist.github.com/ObserverOfTime/d7e60eb9aa7fe837545c8cb77cf31172).
@ -53,15 +53,29 @@ See this [gist](https://gist.github.com/ObserverOfTime/d7e60eb9aa7fe837545c8cb77
6. Move the `app` folder (the one you downloaded and renamed) inside of `Resources`.
7. Fully quit Discord and restart it.
## Local Installation
By default BD loads majority of the package through a CDN at runtime so you always have the latest version. However, if you'd rather only load something from your PC and update when you want, you can do that too!
**Prerequisites**: [Node.js](https://nodejs.org/en/) 12.x+ and the package manager [npm](https://www.npmjs.com/).
1. Clone this repository `git clone https://github.com/rauenzi/BetterDiscordApp.git`
2. Install dependencies with `npm install`
3. Build both the JavaScript and CSS bundles with `npm run deploy` this will create a `style.css` and `remote.js` in the `dist` folder.
4. Follow the steps for [manual installation](#manual-installation) from before.
5. Inside the `app` folder you created as a part of that process, find the file `betterdiscord\config.json`
6. Edit the file and change the value of `local` to `true` and change the `localPath` value to match the <u>absolute</u> path of the `dist` folder from step 3.
7. Fully quit Discord and restart it.
# FAQ
### What is this?
This is a client modification for Discord. It allows you to add plugins and themes to your client. Plugins can add functionality and useful features. Themes can completely change the look and feel of Discord.
BBD has some other built-in features such as Emotes from Twitch, FFZ, and BBTV, as well as an in-client server browser.
BD has some other built-in features such as Emotes from Twitch, FFZ, and BBTV, as well as an in-client server browser.
### Where can I get plugins and themes?
In our support servers we have channels with lists of official plugins and themes. Please note we do not have an official listing on a website and are **not affiliated with any of those websites**.
In our support servers we have channels with lists of <u>official</u> plugins and themes. Please note we do not have an official listing on a website and are **not affiliated with any of those websites**. However [BetterDiscordLibrary](https://betterdiscordlibrary.com/) is generally trustworthy.
### Support Servers?
There are two: [The main server](https://discord.gg/0Tmfo5ZbORCRqbAd), and [the backup](https://discord.gg/2HScm8j).

File diff suppressed because one or more lines are too long

View File

@ -21,10 +21,6 @@
"name": "Verbindung zum Sprachchat trennen",
"note": "Trennt beim Schließen von Discord die Verbindung zum Sprachchat."
},
"twentyFourHour": {
"name": "24h Zeitstempel",
"note": "Zeigt die Zeitstempel in einem 24h format an."
},
"classNormalizer": {
"name": "Normalisierte klassen",
"note": "Fügt stetige Klassen zu Elementen hinzu (z.B. .da-channels zu .channels-Ie2l6A)"
@ -40,6 +36,10 @@
"name": "Sprachmodus",
"note": "Verbirgt alles, was kein Sprachkanal ist."
},
"twentyFourHour": {
"name": "24h Zeitstempel",
"note": "Zeigt die Zeitstempel in einem 24h format an."
},
"minimalMode": {
"name": "Minimaler Modus",
"note": "Verbirgt Elemente und reduziert die Größe von elementen."

View File

@ -21,10 +21,6 @@
"name": "Voice Disconnect",
"note": "Disconnect from voice server when closing Discord"
},
"twentyFourHour": {
"name": "24-Hour Timestamps",
"note": "Hides channels when in minimal mode"
},
"classNormalizer": {
"name": "Normalize Classes",
"note": "Adds stable classes to elements to help themes. (e.g. adds .da-channels to .channels-Ie2l6A)"
@ -44,6 +40,10 @@
"name": "Minimal Mode",
"note": "Hide elements and reduce the size of elements"
},
"twentyFourHour": {
"name": "24-Hour Timestamps",
"note": "Hides channels when in minimal mode"
},
"hideChannels": {
"name": "Hide Channels",
"note": "Hides channels when in minimal mode"

View File

@ -21,10 +21,6 @@
"name": "ボイスチャンネル自動切断",
"note": "Discordを終了する際、自動的にボイスチャンネルから切断します。"
},
"twentyFourHour": {
"name": "24時間表記",
"note": "時間を24時間表記に変更します。"
},
"classNormalizer": {
"name": "クラス標準化",
"note": "値が変動しないCSSクラスを追加します。"
@ -40,6 +36,10 @@
"name": "ボイスモード",
"note": "ボイスチャンネル以外を表示しないようにします"
},
"twentyFourHour": {
"name": "24時間表記",
"note": "時間を24時間表記に変更します。"
},
"minimalMode": {
"name": "コンパクトモード",
"note": "表示をコンパクトにします。"

View File

@ -21,10 +21,6 @@
"name": "Lämna Röst",
"note": "Lämna röstsamtal när Discord stängs ner"
},
"twentyFourHour": {
"name": "24-Timmars Tidsstämpel",
"note": "Visar 24-timmars tidsstämplar istället för AM/PM"
},
"classNormalizer": {
"name": "Normalisera Klasser",
"note": "Lägger till statiska klasser för att underlätta teman (ex. lägger till .da-channels på .channels-Ie2l6A)"
@ -40,6 +36,10 @@
"name": "Röstläge",
"note": "Gömmer allt förutom röstchatt"
},
"twentyFourHour": {
"name": "24-Timmars Tidsstämpel",
"note": "Visar 24-timmars tidsstämplar istället för AM/PM"
},
"minimalMode": {
"name": "Minimalt Läge",
"note": "Gömmer och förminskar komponenter"

1280
dist/index.js vendored

File diff suppressed because one or more lines are too long

1
dist/index.min.js vendored

File diff suppressed because one or more lines are too long

1
dist/remote.js vendored

File diff suppressed because one or more lines are too long

1
dist/style.css vendored

File diff suppressed because one or more lines are too long

1
dist/style.min.css vendored

File diff suppressed because one or more lines are too long

2
package-lock.json generated
View File

@ -1,5 +1,5 @@
{
"name": "bandagedbd",
"name": "betterdiscord",
"version": "1.0.0",
"lockfileVersion": 1,
"requires": true,

View File

@ -1,5 +1,5 @@
{
"name": "bandagedbd",
"name": "betterdiscord",
"version": "1.0.0",
"description": "Enhances Discord adding functionality and themes.",
"main": "src/index.js",

View File

@ -1,7 +1,6 @@
export default {
local: false,
localPath: "",
localServer: "//localhost:8080",
minified: true,
version: "0.6.0",
branch: "stable",

View File

@ -7,8 +7,7 @@ export default [
{type: "switch", id: "emotes", value: true},
{type: "switch", id: "publicServers", value: true},
{type: "switch", id: "voiceDisconnect", value: false},
{type: "switch", id: "twentyFourHour", value: false},
{type: "switch", id: "classNormalizer", value: true},
{type: "switch", id: "classNormalizer", value: false},
{type: "switch", id: "showToasts", value: true}
]
},
@ -17,10 +16,11 @@ export default [
id: "appearance",
collapsible: true,
settings: [
{type: "switch", id: "twentyFourHour", value: false},
{type: "switch", id: "voiceMode", value: false},
{type: "switch", id: "minimalMode", value: false},
{type: "switch", id: "hideChannels", value: false, enableWith: "minimalMode"},
{type: "switch", id: "darkMode", value: true},
{type: "switch", id: "darkMode", value: false},
{type: "switch", id: "coloredText", value: false}
]
},

View File

@ -21,10 +21,6 @@ export default {
name: "Voice Disconnect",
note: "Disconnect from voice server when closing Discord"
},
twentyFourHour: {
name: "24-Hour Timestamps",
note: "Hides channels when in minimal mode"
},
classNormalizer: {
name: "Normalize Classes",
note: "Adds stable classes to elements to help themes. (e.g. adds .da-channels to .channels-Ie2l6A)"
@ -44,6 +40,10 @@ export default {
name: "Minimal Mode",
note: "Hide elements and reduce the size of elements"
},
twentyFourHour: {
name: "24-Hour Timestamps",
note: "Hides channels when in minimal mode"
},
hideChannels: {
name: "Hide Channels",
note: "Hides channels when in minimal mode"

View File

@ -11,4 +11,4 @@ window.BdApi = BdApi;
// Add loading icon at the bottom right
LoadingIcon.show();
new BetterDiscord(); // eslint-disable-line no-new
BetterDiscord.startup();

View File

@ -22,13 +22,17 @@ import Utilities from "./utilities";
const {ipcRenderer} = require("electron");
const GuildClasses = DiscordModules.GuildClasses;
export default class Core {
constructor() {
export default new class Core {
startup() {
ipcRenderer.invoke("bd-config", "get").then(injectorConfig => {
if (this.hasStarted) return;
Object.assign(Config, injectorConfig);
this.init();
});
ipcRenderer.invoke("bd-injector-info").then(injectorInfo => {
Config.version = injectorInfo.version;
this.checkInjectorUpdate();
});
}
get dependencies() {
@ -42,7 +46,7 @@ export default class Core {
{
name: "bd-stylesheet",
type: "style",
url: "//betterdiscord.zerebos.com/dist/style.css",
url: "https://gitcdn.xyz/repo/rauenzi/BetterDiscordApp/gh-pages/dist/style.css",
backup: "//rauenzi.github.io/BetterDiscordApp/dist/style.css",
localPath: "style.css"
}
@ -69,27 +73,6 @@ export default class Core {
if (window.ED) return Modals.alert(Strings.Startup.notSupported, Strings.Startup.incompatibleApp.format({app: "EnhancedDiscord"}));
if (window.WebSocket && window.WebSocket.name && window.WebSocket.name.includes("Patched")) return Modals.alert(Strings.Startup.notSupported, Strings.Startup.incompatibleApp.format({app: "Powercord"}));
const latestLocalVersion = Config.updater ? Config.updater.LatestVersion : Config.latestVersion;
if (latestLocalVersion > Config.version) {
Modals.showConfirmationModal(Strings.Startup.updateAvailable, Strings.Startup.updateInfo.format({version: latestLocalVersion}), {
confirmText: Strings.Startup.updateNow,
cancelText: Strings.Startup.maybeLater,
onConfirm: async () => {
const onUpdateFailed = () => {Modals.alert(Strings.Startup.updateFailed, Strings.Startup.manualUpdate);};
try {
const didUpdate = await this.updateInjector();
if (!didUpdate) return onUpdateFailed();
const app = require("electron").remote.app;
app.relaunch();
app.exit();
}
catch (err) {
onUpdateFailed();
}
}
});
}
Logger.log("Startup", "Initializing Settings");
Settings.initialize();
@ -168,6 +151,37 @@ export default class Core {
}
}
async checkInjectorUpdate() {
const request = require("request");
const latestVersion = await new Promise(resolve => {
request.get({url: `https://gitcdn.xyz/repo/rauenzi/BetterDiscordApp/injector/package.json`, json: true}, (err, resp, body) => {
let remoteVersion = "0.6.1";
if (!err && resp.statusCode == 200) remoteVersion = body.version || remoteVersion;
return resolve(remoteVersion);
});
});
if (latestVersion > Config.version) {
Modals.showConfirmationModal(Strings.Startup.updateAvailable, Strings.Startup.updateInfo.format({version: latestVersion}), {
confirmText: Strings.Startup.updateNow,
cancelText: Strings.Startup.maybeLater,
onConfirm: async () => {
const onUpdateFailed = () => {Modals.alert(Strings.Startup.updateFailed, Strings.Startup.manualUpdate);};
try {
const didUpdate = await this.updateInjector();
if (!didUpdate) return onUpdateFailed();
const app = require("electron").remote.app;
app.relaunch();
app.exit();
}
catch (err) {
onUpdateFailed();
}
}
});
}
}
async updateInjector() {
const injectionPath = DataStore.injectionPath;
if (!injectionPath) return false;
@ -258,4 +272,4 @@ export default class Core {
Logger.log("InjectorUpdate", "Injector Updated!");
return success;
}
}
};

View File

@ -21,7 +21,8 @@ export default new class DataStore {
}
initialize() {
if (!fs.existsSync(this.baseFolder)) fs.mkdirSync(this.baseFolder);
const newStorageExists = fs.existsSync(this.baseFolder);
if (!newStorageExists) fs.mkdirSync(this.baseFolder);
if (!fs.existsSync(this.dataFolder)) fs.mkdirSync(this.dataFolder);
if (!fs.existsSync(this.localeFolder)) fs.mkdirSync(this.localeFolder);
if (!fs.existsSync(this.emoteFolder)) fs.mkdirSync(this.emoteFolder);
@ -33,7 +34,7 @@ export default new class DataStore {
}
this.cacheData = Utilities.testJSON(fs.readFileSync(this.cacheFile).toString()) || {};
this.convertOldData(); // Convert old data if it exists (routine checks existence and removes existence)
if (!newStorageExists) this.convertOldData(); // Convert old data if it exists (routine checks existence and removes existence)
}
convertOldData() {
@ -56,8 +57,8 @@ export default new class DataStore {
if (!channelData) continue;
const oldSettings = channelData.settings;
const newSettings = {
general: {publicServers: oldSettings["bda-gs-1"], voiceDisconnect: oldSettings["bda-dc-0"], twentyFourHour: oldSettings["bda-gs-6"], classNormalizer: oldSettings["fork-ps-4"], showToasts: oldSettings["fork-ps-2"]},
appearance: {voiceMode: oldSettings["bda-gs-4"], minimalMode: oldSettings["bda-gs-2"], hideChannels: oldSettings["bda-gs-3"], darkMode: oldSettings["bda-gs-5"], coloredText: oldSettings["bda-gs-7"]},
general: {publicServers: oldSettings["bda-gs-1"], voiceDisconnect: oldSettings["bda-dc-0"], classNormalizer: oldSettings["fork-ps-4"], showToasts: oldSettings["fork-ps-2"]},
appearance: {twentyFourHour: oldSettings["bda-gs-6"], voiceMode: oldSettings["bda-gs-4"], minimalMode: oldSettings["bda-gs-2"], hideChannels: oldSettings["bda-gs-3"], darkMode: oldSettings["bda-gs-5"], coloredText: oldSettings["bda-gs-7"]},
addons: {addonErrors: oldSettings["fork-ps-1"], autoScroll: oldSettings["fork-ps-3"], autoReload: oldSettings["fork-ps-5"]},
developer: {debuggerHotkey: oldSettings["bda-gs-8"], copySelector: oldSettings["fork-dm-1"], reactDevTools: oldSettings.reactDevTools}
};

View File

@ -13,7 +13,7 @@ export default new class LocaleManager {
constructor() {
this.locale = "";
this.strings = {};
this.strings = Utilities.extend({}, DefaultStrings);
}
async initialize() {

View File

@ -1,7 +1,6 @@
import {Config} from "data";
import Logger from "./logger";
import AddonManager from "./addonmanager";
import Utilities from "./utilities";
import AddonError from "../structs/addonerror";
import Settings from "./settingsmanager";
import Strings from "./strings";
@ -70,17 +69,17 @@ export default new class PluginManager extends AddonManager {
/* Overrides */
initializeAddon(addon) {
if (!addon.type) return new AddonError(addon.name, addon.filename, "Plugin had no exports", {message: "Plugin had no exports or no name property.", stack: ""});
if (!addon.exports) return new AddonError(addon.name, addon.filename, "Plugin had no exports", {message: "Plugin had no exports or no name property.", stack: ""});
try {
const PluginClass = addon.type;
const PluginClass = addon.exports;
const thePlugin = new PluginClass();
addon.plugin = thePlugin;
addon.instance = thePlugin;
addon.name = thePlugin.getName() || addon.name;
addon.author = thePlugin.getAuthor() || addon.author || "No author";
addon.description = thePlugin.getDescription() || addon.description || "No description";
addon.version = thePlugin.getVersion() || addon.version || "No version";
try {
if (typeof(addon.plugin.load) == "function") addon.plugin.load();
if (typeof(addon.instance.load) == "function") addon.instance.load();
}
catch (error) {
this.state[addon.id] = false;
@ -91,16 +90,11 @@ export default new class PluginManager extends AddonManager {
}
getFileModification(module, fileContent, meta) {
fileContent += `\nif (!module.exports || !module.exports.prototype || !module.exports.prototype.start) {module.exports = ${meta.exports || meta.name};}`;
module._compile(fileContent, module.filename);
const didExport = !Utilities.isEmpty(module.exports);
if (didExport) {
meta.type = module.exports;
module.exports = meta;
return "";
}
Logger.warn(this.name, `${meta.name}, please start assigning module.exports`);
fileContent += `\nmodule.exports = ${JSON.stringify(meta)};\nmodule.exports.type = ${meta.exports || meta.name};`;
return fileContent;
meta.exports = module.exports;
module.exports = meta;
return "";
}
startAddon(id) {return this.startPlugin(id);}
@ -110,7 +104,7 @@ export default new class PluginManager extends AddonManager {
startPlugin(idOrAddon) {
const addon = typeof(idOrAddon) == "string" ? this.addonList.find(p => p.id == idOrAddon) : idOrAddon;
if (!addon) return;
const plugin = addon.plugin;
const plugin = addon.instance;
try {
plugin.start();
}
@ -127,7 +121,7 @@ export default new class PluginManager extends AddonManager {
stopPlugin(idOrAddon) {
const addon = typeof(idOrAddon) == "string" ? this.addonList.find(p => p.id == idOrAddon) : idOrAddon;
if (!addon) return;
const plugin = addon.plugin;
const plugin = addon.instance;
try {
plugin.stop();
}
@ -144,7 +138,7 @@ export default new class PluginManager extends AddonManager {
getPlugin(idOrFile) {
const addon = this.addonList.find(c => c.id == idOrFile || c.filename == idOrFile);
if (!addon) return;
return addon.plugin;
return addon.instance;
}
setupFunctions() {
@ -158,7 +152,7 @@ export default new class PluginManager extends AddonManager {
onSwitch() {
this.emit("page-switch");
for (let i = 0; i < this.addonList.length; i++) {
const plugin = this.addonList[i].plugin;
const plugin = this.addonList[i].instance;
if (!this.state[this.addonList[i].id]) continue;
if (typeof(plugin.onSwitch) === "function") {
try {plugin.onSwitch();}
@ -169,7 +163,7 @@ export default new class PluginManager extends AddonManager {
onMutation(mutation) {
for (let i = 0; i < this.addonList.length; i++) {
const plugin = this.addonList[i].plugin;
const plugin = this.addonList[i].instance;
if (!this.state[this.addonList[i].id]) continue;
if (typeof plugin.observer === "function") {
try {plugin.observer(mutation);}

View File

@ -4,7 +4,7 @@ import DOM from "./domtools";
export default class Utilities {
static repoUrl(path) {
return `https://betterdiscord.zerebos.com/${path}`;
return `https://gitcdn.xyz/repo/rauenzi/BetterDiscordApp/gh-pages/${path}`;
}
/**

View File

@ -246,7 +246,7 @@ export default class WebpackModules {
*/
static get require() {
if (this._require) return this._require;
const id = "bbd-webpackmodules";
const id = "bd-webpackmodules";
const __webpack_require__ = window.webpackJsonp.push([[], {
[id]: (module, exports, __internal_require__) => module.exports = __internal_require__
}, [[id]]]);

View File

@ -110,8 +110,8 @@ export default class AddonList extends React.Component {
matches = matches || addon.description.toLocaleLowerCase().includes(this.state.query);
if (!matches) return null;
}
const hasSettings = addon.type && typeof(addon.plugin.getSettingsPanel) === "function";
const getSettings = hasSettings && addon.plugin.getSettingsPanel.bind(addon.plugin);
const hasSettings = addon.type && typeof(addon.instance.getSettingsPanel) === "function";
const getSettings = hasSettings && addon.instance.getSettingsPanel.bind(addon.instance);
return <ErrorBoundary><AddonCard editAddon={this.editAddon.bind(this, addon.id)} deleteAddon={this.deleteAddon.bind(this, addon.id)} showReloadIcon={showReloadIcon} key={addon.id} enabled={addonState[addon.id]} addon={addon} onChange={onChange} reload={reload} hasSettings={hasSettings} getSettingsPanel={getSettings} /></ErrorBoundary>;
})}
</div>