Merge pull request #173 from samuelthomas2774/add-guild-setting
Add guild setting
This commit is contained in:
commit
f6d994e6a4
|
@ -47,10 +47,9 @@
|
|||
{
|
||||
"id": "developer-mode",
|
||||
"type": "bool",
|
||||
"text": "Developer Mode",
|
||||
"hint": "BetterDiscord developer mode",
|
||||
"value": false,
|
||||
"disabled": true
|
||||
"text": "Developer mode",
|
||||
"hint": "Adds some of BetterDiscord's internal modules to `global._bd`.",
|
||||
"value": false
|
||||
},
|
||||
{
|
||||
"id": "ignore-content-manager-errors",
|
||||
|
|
|
@ -19,33 +19,37 @@ const DEV = true;
|
|||
class BetterDiscord {
|
||||
|
||||
constructor() {
|
||||
window.BDDEVMODE = function () {
|
||||
if (!DEV) return null;
|
||||
return window._bd = {
|
||||
DOM,
|
||||
BdUI,
|
||||
Modals,
|
||||
Reflection,
|
||||
Patcher,
|
||||
Vendor,
|
||||
Events,
|
||||
CssEditor,
|
||||
Globals,
|
||||
ExtModuleManager,
|
||||
PluginManager,
|
||||
ThemeManager,
|
||||
ModuleManager,
|
||||
WebpackModules,
|
||||
Settings,
|
||||
Database,
|
||||
ReactComponents,
|
||||
DiscordApi,
|
||||
Logger,
|
||||
ClientIPC,
|
||||
Utils,
|
||||
EmoteModule
|
||||
}
|
||||
}
|
||||
this._bd = {
|
||||
DOM,
|
||||
BdUI,
|
||||
Modals,
|
||||
Reflection,
|
||||
Patcher,
|
||||
Vendor,
|
||||
Events,
|
||||
CssEditor,
|
||||
Globals,
|
||||
ExtModuleManager,
|
||||
PluginManager,
|
||||
ThemeManager,
|
||||
ModuleManager,
|
||||
WebpackModules,
|
||||
Settings,
|
||||
Database,
|
||||
ReactComponents,
|
||||
DiscordApi,
|
||||
Logger,
|
||||
ClientIPC,
|
||||
Utils,
|
||||
EmoteModule
|
||||
};
|
||||
|
||||
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;
|
||||
});
|
||||
|
||||
DOM.injectStyle(BdCss, 'bdmain');
|
||||
this.globalReady = this.globalReady.bind(this);
|
||||
|
@ -79,16 +83,13 @@ class BetterDiscord {
|
|||
this.vueInstance = BdUI.injectUi();
|
||||
this.init();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (window.BetterDiscord) {
|
||||
Logger.log('main', 'Attempting to inject again?');
|
||||
} else {
|
||||
let instance = null;
|
||||
// eslint-disable-next-line no-inner-declarations
|
||||
function init() {
|
||||
instance = new BetterDiscord();
|
||||
}
|
||||
Events.on('autopatcher', init);
|
||||
Events.on('autopatcher', () => instance = new BetterDiscord());
|
||||
ReactAutoPatcher.autoPatch().then(() => Events.emit('autopatcher'));
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ import SliderSetting from './types/slider';
|
|||
import ColourSetting from './types/colour';
|
||||
import KeybindSetting from './types/keybind';
|
||||
import FileSetting from './types/file';
|
||||
import GuildSetting from './types/guild';
|
||||
import ArraySetting from './types/array';
|
||||
import CustomSetting from './types/custom';
|
||||
|
||||
|
@ -38,6 +39,7 @@ export default class Setting {
|
|||
else if (args.type === 'colour') return new ColourSetting(args, ...merge);
|
||||
else if (args.type === 'keybind') return new KeybindSetting(args, ...merge);
|
||||
else if (args.type === 'file') return new FileSetting(args, ...merge);
|
||||
else if (args.type === 'guild') return new GuildSetting(args, ...merge);
|
||||
else if (args.type === 'array') return new ArraySetting(args, ...merge);
|
||||
else if (args.type === 'custom') return new CustomSetting(args, ...merge);
|
||||
else throw {message: `Setting type ${args.type} unknown`};
|
||||
|
|
|
@ -215,11 +215,6 @@ export default class ArraySetting extends Setting {
|
|||
if (error) throw error;
|
||||
}
|
||||
|
||||
// emit(...args) {
|
||||
// console.log('Emitting event', args[0], 'with data', args[1]);
|
||||
// return this.emitter.emit(...args);
|
||||
// }
|
||||
|
||||
/**
|
||||
* Updates the value of this array setting.
|
||||
* This only exists for use by array settings.
|
||||
|
|
|
@ -0,0 +1,140 @@
|
|||
/**
|
||||
* BetterDiscord Guild Setting Struct
|
||||
* 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 { DiscordApi } from 'modules';
|
||||
import { Utils, ClientLogger as Logger } from 'common';
|
||||
import Setting from './basesetting';
|
||||
|
||||
export default class GuildSetting extends Setting {
|
||||
|
||||
constructor(args, ...merge) {
|
||||
super(args, ...merge);
|
||||
|
||||
this.args.guilds = this.value ? this.value.map(id => DiscordApi.guilds.get({ id })) : [];
|
||||
}
|
||||
|
||||
/**
|
||||
* The value to use when the setting doesn't have a value.
|
||||
*/
|
||||
get defaultValue() {
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* An array of currently selected guilds.
|
||||
*/
|
||||
get guilds() {
|
||||
return this.args.guilds;
|
||||
}
|
||||
|
||||
/**
|
||||
* The minimum amount of guilds the user may select.
|
||||
* This only restricts removing guilds when there is less or equal guilds than this, and does not ensure that this number of guilds actually exists.
|
||||
*/
|
||||
get min() {
|
||||
return this.args.min || 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* The maximum amount of guilds the user may select.
|
||||
*/
|
||||
get max() {
|
||||
return this.args.max || null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a guild to the list of selected guilds.
|
||||
* @param {Number} guild_id The ID of the guild to add
|
||||
* @return {Promise}
|
||||
*/
|
||||
addGuild(guild_id) {
|
||||
return this.setValue(this.value.concat([guild_id]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a guild from the list of selected guilds.
|
||||
* @param {Number} guild_id The ID of the guild to remove
|
||||
* @return {Promise}
|
||||
*/
|
||||
removeGuild(guild_id) {
|
||||
return this.setValue(this.value.filter(g => g !== guild_id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to be called after the value changes.
|
||||
* This can be overridden by other settings types.
|
||||
* This function is used when the value needs to be updated synchronously (basically just in the constructor - so there won't be any events to emit anyway).
|
||||
* @param {SettingUpdatedEvent} updatedSetting
|
||||
*/
|
||||
setValueHookSync(updatedSetting) {
|
||||
this.args.guilds = updatedSetting.value ? updatedSetting.value.map(id => DiscordApi.guilds.get({ id })) : [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to be called after the value changes.
|
||||
* This can be overridden by other settings types.
|
||||
* @param {SettingUpdatedEvent} updatedSetting
|
||||
*/
|
||||
async setValueHook(updatedSetting) {
|
||||
this.value.sort();
|
||||
this.changed = !Utils.compare(this.args.value, this.args.saved_value);
|
||||
|
||||
const newGuilds = [];
|
||||
let error;
|
||||
|
||||
for (let newGuild of updatedSetting.value) {
|
||||
try {
|
||||
const guild = updatedSetting.old_value.find(g => g === newGuild);
|
||||
|
||||
if (guild) {
|
||||
// Guild was already selected
|
||||
newGuilds.push(guild);
|
||||
} else {
|
||||
// Add a new guild
|
||||
Logger.log('GuildSetting', ['Adding guild', newGuild, 'to', this]);
|
||||
newGuilds.push(newGuild);
|
||||
await this.emit('guild-added', { id: newGuild });
|
||||
}
|
||||
} catch (e) { error = e; }
|
||||
}
|
||||
|
||||
for (let guild_id of updatedSetting.old_value) {
|
||||
if (newGuilds.find(g => g === guild_id)) continue;
|
||||
|
||||
try {
|
||||
// Guild removed
|
||||
Logger.log('GuildSetting', ['Removing guild', guild_id, 'from', this]);
|
||||
await this.emit('guild-removed', { id: guild_id });
|
||||
} catch (e) { error = e; }
|
||||
}
|
||||
|
||||
this.args.guilds = newGuilds.map(id => DiscordApi.guilds.get({ id }));
|
||||
|
||||
// We can't throw anything before the guilds array is updated, otherwise the guild setting would be in an inconsistent state where the values in this.guilds wouldn't match the values in this.value
|
||||
if (error) throw error;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a representation of this setting's value in SCSS.
|
||||
* @return {String}
|
||||
*/
|
||||
toSCSS() {
|
||||
if (!this.value || !this.value.length) return '()';
|
||||
|
||||
const guilds = [];
|
||||
for (let guild_id of this.value) {
|
||||
if (guild_id)
|
||||
guilds.push(guild_id);
|
||||
}
|
||||
|
||||
return guilds.length ? guilds.join(', ') : '()';
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
.bd-guilds {
|
||||
.bd-guild {
|
||||
$size: 36px;
|
||||
|
||||
display: inline-block;
|
||||
width: $size;
|
||||
height: $size;
|
||||
background-color: rgb(47, 49, 54);
|
||||
background-size: cover;
|
||||
margin: 10px 10px 0 0;
|
||||
border-radius: 50%;
|
||||
cursor: pointer;
|
||||
transition: border-radius .4s cubic-bezier(0.5, 0, 0.27, 1.55), background-color .4s cubic-bezier(0.5, 0, 0.27, 1.55), box-shadow .3s cubic-bezier(0.5, 0, 0.27, 1.55);
|
||||
|
||||
.bd-guild-text {
|
||||
float: left;
|
||||
display: block;
|
||||
width: $size;
|
||||
height: $size;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
line-height: $size;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
border-radius: 30%;
|
||||
background-color: $colbdblue;
|
||||
|
||||
&.bd-guild-has-icon {
|
||||
background-color: rgb(47, 49, 54);
|
||||
}
|
||||
}
|
||||
|
||||
&.bd-active {
|
||||
background-color: $colbdblue;
|
||||
box-shadow: 0 0 7px 2px $colbdblue;
|
||||
|
||||
&.bd-guild-has-icon {
|
||||
background-color: rgb(47, 49, 54);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,10 +1,11 @@
|
|||
@import './main.scss';
|
||||
@import './switches.scss';
|
||||
@import './text.scss';
|
||||
@import './files.scss';
|
||||
@import './dropdowns.scss';
|
||||
@import './radios.scss';
|
||||
@import './sliders.scss';
|
||||
@import './colourpickers.scss';
|
||||
@import './keybinds.scss';
|
||||
@import './files.scss';
|
||||
@import './guilds.scss';
|
||||
@import './arrays.scss';
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
.bd-form-colourpicker,
|
||||
.bd-form-keybind,
|
||||
.bd-form-fileinput,
|
||||
.bd-form-guildinput,
|
||||
.bd-form-settingsarray {
|
||||
.bd-title {
|
||||
display: flex;
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
/**
|
||||
* BetterDiscord Setting Guild 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-form-guildinput">
|
||||
<div class="bd-title">
|
||||
<h3>{{ setting.text }}</h3>
|
||||
</div>
|
||||
<div class="bd-hint">{{ setting.hint }}</div>
|
||||
<div class="bd-guilds">
|
||||
<div class="bd-guild" :class="{'bd-active': isGuildSelected(guild), 'bd-guild-has-icon': guild.icon}" :style="{backgroundImage: `url('${getGuildIconURL(guild)}')`}" @click="() => isGuildSelected(guild) ? unselectGuild(guild) : selectGuild(guild)" v-for="guild in guilds" v-if="guild" v-tooltip="guild.name">
|
||||
<div class="bd-guild-text" v-if="!guild.icon">{{ getGuildIconText(guild) }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { DiscordApi } from 'modules';
|
||||
|
||||
export default {
|
||||
props: ['setting'],
|
||||
data() {
|
||||
return {
|
||||
user_guilds: []
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
guilds() {
|
||||
const guilds = ([]).concat(this.user_guilds);
|
||||
|
||||
for (let guild of this.setting.guilds) {
|
||||
if (!guilds.find(g => g && guild && g.id === guild.id))
|
||||
guilds.push(guild);
|
||||
}
|
||||
|
||||
return guilds.sort(function(a, b) {
|
||||
var nameA = a.name.toUpperCase(); // ignore upper and lowercase
|
||||
var nameB = b.name.toUpperCase(); // ignore upper and lowercase
|
||||
if (nameA < nameB) return -1;
|
||||
if (nameA > nameB) return 1;
|
||||
// names must be equal
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
isGuildSelected(guild) {
|
||||
return this.setting.guilds.find(g => g && g.id === guild.id);
|
||||
},
|
||||
getGuildIconURL(guild) {
|
||||
return `https://cdn.discordapp.com/icons/${guild.id}/${guild.icon}.webp`;
|
||||
},
|
||||
getGuildIconText(guild) {
|
||||
const words = guild.name.split(' ');
|
||||
if (!words.length) return '';
|
||||
const first = words[0].substr(0, 1);
|
||||
if (words.length <= 1) return first;
|
||||
const last = words[words.length - 1].substr(0, 1);
|
||||
return `${first}${last}`;
|
||||
},
|
||||
async selectGuild(guild) {
|
||||
if (this.setting.max && this.setting.guilds.length >= this.setting.max) return;
|
||||
await this.setting.addGuild(guild.id);
|
||||
},
|
||||
async unselectGuild(guild) {
|
||||
if (this.setting.min && this.setting.guilds.length <= this.setting.min) return;
|
||||
await this.setting.removeGuild(guild.id);
|
||||
},
|
||||
refreshGuilds() {
|
||||
this.user_guilds = DiscordApi.guilds;
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.refreshGuilds();
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -20,6 +20,7 @@
|
|||
<ColourSetting v-if="setting.type === 'colour'" :setting="setting" :change="change" />
|
||||
<KeybindSetting v-if="setting.type === 'keybind'" :setting="setting" />
|
||||
<FileSetting v-if="setting.type === 'file'" :setting="setting" :change="change" />
|
||||
<GuildSetting v-if="setting.type === 'guild'" :setting="setting" />
|
||||
<ArraySetting v-if="setting.type === 'array'" :setting="setting" :change="change" />
|
||||
<CustomSetting v-if="setting.type === 'custom'" :setting="setting" :change="change" />
|
||||
<div class="bd-form-divider"></div>
|
||||
|
@ -37,6 +38,7 @@
|
|||
import ColourSetting from './Colour.vue';
|
||||
import KeybindSetting from './Keybind.vue';
|
||||
import FileSetting from './File.vue';
|
||||
import GuildSetting from './Guild.vue';
|
||||
import ArraySetting from './Array.vue';
|
||||
import CustomSetting from './Custom.vue';
|
||||
|
||||
|
@ -55,6 +57,7 @@
|
|||
ColourSetting,
|
||||
KeybindSetting,
|
||||
FileSetting,
|
||||
GuildSetting,
|
||||
ArraySetting,
|
||||
CustomSetting
|
||||
},
|
||||
|
|
|
@ -162,6 +162,19 @@ export class Utils {
|
|||
return object;
|
||||
}
|
||||
|
||||
static filterArray(array, filter) {
|
||||
const indexes = [];
|
||||
for (let index in array) {
|
||||
if (!filter(array[index], index))
|
||||
indexes.push(index);
|
||||
}
|
||||
|
||||
for (let i in indexes)
|
||||
array.splice(indexes[i] - i, 1);
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
static removeFromArray(array, item) {
|
||||
let index;
|
||||
while ((index = array.indexOf(item)) > -1)
|
||||
|
|
|
@ -84,6 +84,15 @@
|
|||
"value": "mod+.",
|
||||
"text": "Test Keybind Setting 1",
|
||||
"hint": "Test Keybind Setting Hint 1"
|
||||
},
|
||||
{
|
||||
"id": "guild-1",
|
||||
"type": "guild",
|
||||
"value": [
|
||||
"280806472928198656"
|
||||
],
|
||||
"text": "Test guild setting",
|
||||
"hint": "Test guild setting hint"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue