Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 17 additions & 7 deletions client/src/builtin/EmoteModule.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,7 @@ export default new class EmoteModule {

const dataPath = Globals.getPath('data');
try {
const emotes = await FileUtils.readJsonFromFile(path.join(dataPath, 'emotes.json'));
for (let emote of emotes) {
const uri = emote.type === 2 ? 'https://cdn.betterttv.net/emote/:id/1x' : emote.type === 1 ? 'https://cdn.frankerfacez.com/emoticon/:id/1' : 'https://static-cdn.jtvnw.net/emoticons/v1/:id/1.0';
emote.name = emote.id;
emote.src = uri.replace(':id', emote.value.id || emote.value);
this.emotes.set(emote.id, emote);
}
await this.load(path.join(dataPath, 'emotes.json'));
} catch (err) {
Logger.err('EmoteModule', [`Failed to load emote data. Make sure you've downloaded the emote data and placed it in ${dataPath}:`, err]);
return;
Expand All @@ -53,6 +47,20 @@ export default new class EmoteModule {
}
}

async load(dataPath) {
const emotes = await FileUtils.readJsonFromFile(dataPath);
for (let [index, emote] of emotes.entries()) {
// Pause every 10000 emotes so the window doesn't freeze
if ((index % 10000) === 0)
await Utils.wait();

const uri = emote.type === 2 ? 'https://cdn.betterttv.net/emote/:id/1x' : emote.type === 1 ? 'https://cdn.frankerfacez.com/emoticon/:id/1' : 'https://static-cdn.jtvnw.net/emoticons/v1/:id/1.0';
emote.name = emote.id;
emote.src = uri.replace(':id', emote.value.id || emote.value);
this.emotes.set(emote.id, emote);
}
}

/**
* Sets an emote as favourite.
* @param {String} emote The name of the emote
Expand All @@ -61,6 +69,7 @@ export default new class EmoteModule {
* @return {Promise}
*/
setFavourite(emote, favourite, save = true) {
emote = emote.id || emote;
if (favourite && !this.favourite_emotes.includes(emote)) this.favourite_emotes.push(emote);
if (!favourite) Utils.removeFromArray(this.favourite_emotes, emote);
if (save) return Settings.saveSettings();
Expand All @@ -75,6 +84,7 @@ export default new class EmoteModule {
}

isFavourite(emote) {
emote = emote.id || emote;
return this.favourite_emotes.includes(emote);
}

Expand Down
2 changes: 1 addition & 1 deletion client/src/modules/csseditor.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ export default new class {
if (sendSource)
this.sendToEditor('set-scss', scss);

if (!scss) {
if (!scss && !await this.fileExists()) {
this._scss = this.css = '';
this.sendToEditor('scss-error', null);
return;
Expand Down
1 change: 1 addition & 0 deletions client/src/modules/pluginapi.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ export default class PluginApi {
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)
};
}
Expand Down
10 changes: 7 additions & 3 deletions client/src/modules/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ export default new class Settings {
Events.emit(`setting-updated-${set.id}_${category.id}_${setting.id}`, event);
});

set.on('settings-updated', async (event) => {
await this.saveSettings();
set.on('settings-updated', async event => {
if (!event.data || !event.data.dont_save) await this.saveSettings();
Events.emit('settings-updated', event);
});

Expand All @@ -43,6 +43,8 @@ export default new class Settings {
* Loads BetterDiscord's settings.
*/
async loadSettings() {
Logger.log('Settings', ['Loading settings']);

try {
await FileUtils.ensureDirectory(this.dataPath);

Expand All @@ -53,7 +55,7 @@ export default new class Settings {
for (let set of this.settings) {
const newSet = settings.find(s => s.id === set.id);
if (!newSet) continue;
await set.merge(newSet);
await set.merge(newSet, {dont_save: true});
set.setSaved();
}

Expand All @@ -71,6 +73,8 @@ export default new class Settings {
* Saves BetterDiscord's settings including CSS editor data.
*/
async saveSettings() {
Logger.log('Settings', ['Saving settings']);

try {
await FileUtils.ensureDirectory(this.dataPath);

Expand Down
2 changes: 2 additions & 0 deletions client/src/modules/theme.js
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,8 @@ export default class Theme extends Content {
* @param {Array} files Files to watch
*/
set watchfiles(files) {
if (!files) files = [];

for (let file of files) {
if (!this.watchfiles.includes(file)) {
this.filewatcher.add(file);
Expand Down
7 changes: 7 additions & 0 deletions client/src/structs/events/event.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,13 @@ export default class Event {
return this.__eventInfo;
}

/**
* Extra data associated with this event.
*/
get data() {
return this.args.data;
}

/**
* The first argument that was passed to the constructor, which contains information about the event.
*/
Expand Down
3 changes: 2 additions & 1 deletion client/src/structs/settings/settingsset.js
Original file line number Diff line number Diff line change
Expand Up @@ -412,7 +412,8 @@ export default class SettingsSet extends AsyncEventEmitter {

if (emit_multi)
await this.emit('settings-updated', new SettingsUpdatedEvent({
updatedSettings
updatedSettings,
data: typeof emit_multi !== 'boolean' ? emit_multi : undefined
}));

return updatedSettings;
Expand Down
16 changes: 16 additions & 0 deletions client/src/styles/partials/emotes.scss
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@
vertical-align: -.4em;
max-height: 32px;
}
}

.bd-emotewrapper,
.bd-autocomplete-selector {
.bd-emote-favourite-button {
display: none;
width: 16px;
Expand All @@ -46,7 +49,20 @@
}
}

&.bd-selected .bd-emote-favourite-button,
&:hover .bd-emote-favourite-button {
display: block;
}
}

.bd-autocomplete-selector {
.bd-emote-favourite-button {
margin-left: 8px;
margin-right: 0;
opacity: .5;

&.bd-active {
display: block;
}
}
}
5 changes: 5 additions & 0 deletions client/src/styles/partials/generic/autocomplete.scss
Original file line number Diff line number Diff line change
Expand Up @@ -77,4 +77,9 @@
}
}
}

&.bd-active + [class*="inner"] {
border-top-left-radius: 0;
border-top-right-radius: 0;
}
}
2 changes: 1 addition & 1 deletion client/src/ui/automanip.js
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ export default class extends EventListener {
const root = document.createElement('span');
const parent = document.querySelector('[class*="channelTextArea"] > [class*="inner"]');
if (!parent) return;
parent.append(root);
parent.parentElement.insertBefore(root, parent);
VueInjector.inject(root, {
components: { Autocomplete },
data: { initial: e.target.value },
Expand Down
6 changes: 6 additions & 0 deletions client/src/ui/components/BdSettingsWrapper.vue
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@
if (this.$refs.settings.activeIndex !== -1) this.$refs.settings.closeContent();
else this.active = false;
e.stopImmediatePropagation();
},
prevent(e) {
if (this.active && e.which === 27)
e.stopImmediatePropagation();
}
},
watch: {
Expand All @@ -68,12 +72,14 @@
Events.on('update-check-end', e => this.updating = 1);
Events.on('updates-available', e => this.updating = 2);
window.addEventListener('keyup', this.keyupListener);
window.addEventListener('keydown', this.prevent, true);

const menuKeybind = Settings.getSetting('core', 'default', 'menu-keybind');
menuKeybind.on('keybind-activated', () => this.active = !this.active);
},
destroyed() {
window.removeEventListener('keyup', this.keyupListener);
window.removeEventListener('keydown', this.prevent);
}
}
</script>
68 changes: 48 additions & 20 deletions client/src/ui/components/common/Autocomplete.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
*/

<template>
<div class="bd-autocomplete">
<div class="bd-autocomplete" :class="{'bd-active': emotes && emotes.length}">
<div v-if="emotes && emotes.length" class="bd-autocomplete-inner">
<div class="bd-autocomplete-row">
<div class="bd-autocomplete-selector">
Expand All @@ -20,10 +20,13 @@
</div>
</div>
<div v-for="(emote, index) in emotes" class="bd-autocomplete-row" :key="index">
<div class="bd-autocomplete-selector bd-selectable" :class="{'bd-selected': index === selectedIndex}" @mouseover="() => { selected = emote.id }" @click="() => inject(emote)">
<div class="bd-autocomplete-selector bd-selectable" :class="{'bd-selected': index === selectedIndex, 'bd-emote-favourite': isFavourite(emote)}" @mouseover="selected = emote.id" @click="inject(emote)">
<div class="bd-autocomplete-field">
<img :src="getEmoteSrc(emote)"/>
<div>{{emote.id}}</div>
<img :src="emote.src" :alt="emote.name" />
<div class="bd-flex-grow">{{emote.id}}</div>
<div class="bd-emote-favourite-button" :class="{'bd-active': isFavourite(emote)}" @click.stop="toggleFavourite(emote)">
<MiStar :size="16" />
</div>
</div>
</div>
</div>
Expand All @@ -33,12 +36,17 @@

<script>
import { EmoteModule } from 'builtin';
import { Events } from 'modules';
import { Events, Settings } from 'modules';
import { DOM } from 'ui';
import { MiStar } from './MaterialIcon';

export default {
components: {
MiStar
},
data() {
return {
EmoteModule,
emotes: [],
title: '',
selIndex: 0,
Expand All @@ -54,24 +62,38 @@
// this.open = this.emotes.length;
},
created() {
window.addEventListener('keydown', this.prevents);
const ta = document.querySelector('.chat textarea');
if(!ta) return;
ta.addEventListener('keydown', this.setCaret);
ta.addEventListener('keyup', this.searchEmotes);
const enabled = Settings.getSetting('emotes', 'default', 'enable');
enabled.on('setting-updated', event => {
if (event.value) return this.addEventListeners();
this.removeEventListeners();
this.reset();
});

if (enabled.value) this.addEventListeners();
},
destroyed() {
window.removeEventListener('keydown', this.prevents);
const ta = document.querySelector('.chat textarea');
if (!ta) return;
ta.removeEventListener('keydown', this.setCaret);
ta.removeEventListener('keyup', this.searchEmotes);
this.removeEventListeners();
},
methods: {
addEventListeners() {
window.addEventListener('keydown', this.prevents);
const ta = document.querySelector('.chat textarea');
if (!ta) return;
ta.addEventListener('keydown', this.setCaret);
ta.addEventListener('keyup', this.searchEmotes);
},
removeEventListeners() {
window.removeEventListener('keydown', this.prevents);
const ta = document.querySelector('.chat textarea');
if (!ta) return;
ta.removeEventListener('keydown', this.setCaret);
ta.removeEventListener('keyup', this.searchEmotes);
},
prevents(e) {
if (!this.open) return;
if (e.key !== 'ArrowDown' && e.key !== 'ArrowUp' && e.key !== 'Tab' && e.key !== 'Enter') return;
this.traverse(e);
if (e.which === 27) this.reset();
else if (e.key === 'ArrowDown' || e.key === 'ArrowUp') this.traverse(e);
else if (e.key !== 'Tab' && e.key !== 'Enter') return;
e.stopPropagation();
e.preventDefault();
},
Expand All @@ -84,8 +106,14 @@
const uri = emote.type === 2 ? 'https://cdn.betterttv.net/emote/:id/1x' : emote.type === 1 ? 'https://cdn.frankerfacez.com/emoticon/:id/1' : 'https://static-cdn.jtvnw.net/emoticons/v1/:id/1.0';
return uri.replace(':id', value);
},
isFavourite(emote) {
return EmoteModule.isFavourite(emote);
},
toggleFavourite(emote) {
return EmoteModule.setFavourite(emote, !this.isFavourite(emote));
},
searchEmotes(e) {
if (e.key === 'ArrowDown' || e.key === 'ArrowUp') return;
if (e.which === 27 || e.key === 'ArrowDown' || e.key === 'ArrowUp') return;
if (e.key === 'Tab' || e.key === 'Enter' && this.open) {
const selected = this.emotes[this.selectedIndex];
if (!selected) return;
Expand Down Expand Up @@ -113,11 +141,11 @@
traverse(e) {
if (!this.open) return;
if (e.key === 'ArrowUp') {
this.selectedIndex = (this.selectedIndex - 1) < 0 ? 9 : this.selectedIndex - 1;
this.selectedIndex = (this.selectedIndex - 1) < 0 ? Math.min(this.emotes.length, 10) - 1 : this.selectedIndex - 1;
return;
}
if (e.key === 'ArrowDown') {
this.selectedIndex = (this.selectedIndex + 1) >= 10 ? 0 : this.selectedIndex + 1;
this.selectedIndex = (this.selectedIndex + 1) >= Math.min(this.emotes.length, 10) ? 0 : this.selectedIndex + 1;
return;
}
return;
Expand Down
6 changes: 3 additions & 3 deletions client/src/ui/components/common/Dropdown.vue
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
</span>
</div>
<div class="bd-dropdown-options bd-flex bd-flex-col" ref="options" v-if="active">
<div class="bd-dropdown-option" v-for="option in options" :class="{'bd-dropdown-option-selected': selected === option.value}" @click="select(option)">{{ option.text }}</div>
<div class="bd-dropdown-option" v-for="option in options" :class="{'bd-dropdown-option-selected': value === option.value}" @click="select(option)">{{ option.text }}</div>
</div>
</div>
</template>
Expand All @@ -32,8 +32,8 @@
},
methods: {
getSelectedText() {
const selected_option = this.options.find(option => option.value === this.selected);
return selected_option ? selected_option.text : this.selected;
const selected_option = this.options.find(option => option.value === this.value);
return selected_option ? selected_option.text : this.value;
},
select(option) {
this.$emit('input', option.value);
Expand Down
13 changes: 11 additions & 2 deletions client/src/ui/profilebadges.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,13 @@ export default class extends Module {
const nameTag = retVal.props.children.props.children[1].props.children[0];
nameTag.type = this.PatchedNameTag || nameTag.type;
});

// Rerender all channel members
if (this.PatchedNameTag) {
for (const channelMember of document.querySelectorAll('.member-2FrNV0')) {
Reflection(channelMember).forceUpdate();
}
}
}

/**
Expand Down Expand Up @@ -135,8 +142,10 @@ export default class extends Module {
};

// Rerender all channel members
for (const channelMember of document.querySelectorAll('.member-2FrNV0')) {
Reflection(channelMember).forceUpdate();
if (this.unpatchChannelMemberRender) {
for (const channelMember of document.querySelectorAll('.member-2FrNV0')) {
Reflection(channelMember).forceUpdate();
}
}

return this.PatchedNameTag;
Expand Down
Loading