It's ugly for now.
This commit is contained in:
parent
c59494f604
commit
45545d86b4
|
@ -15,12 +15,12 @@
|
|||
<div class="bd-autocompleteSelector">
|
||||
<div class="bd-autocompleteTitle">
|
||||
Emotes Matching:
|
||||
<strong>{{title || initial}}</strong>
|
||||
<strong>{{title}}</strong>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-for="emote in emotes" class="bd-autocompleteRow">
|
||||
<div class="bd-autocompleteSelector">
|
||||
<div v-for="(emote, index) in emotes" class="bd-autocompleteRow" :key="emote.id">
|
||||
<div class="bd-autocompleteSelector bd-selectable" :class="{'bd-selected': index === selectedIndex}" @mouseover="() => { selected = emote.id }" @click="() => inject(emote)">
|
||||
<div class="bd-autocompleteField">
|
||||
<img :src="getEmoteSrc(emote)"/>
|
||||
<div>{{emote.id}}</div>
|
||||
|
@ -33,24 +33,46 @@
|
|||
<script>
|
||||
import { EmoteModule } from 'builtin';
|
||||
import { Events } from 'modules';
|
||||
import { DOM } from 'ui';
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
emotes: [],
|
||||
title: null
|
||||
title: '',
|
||||
selIndex: 0,
|
||||
selected: '',
|
||||
open: false,
|
||||
selectedIndex: 0,
|
||||
sterm: ''
|
||||
}
|
||||
},
|
||||
props: ['initial'],
|
||||
beforeMount() {
|
||||
this.emotes = EmoteModule.filter(new RegExp(this.initial, 'i'), 10);
|
||||
// this.emotes = EmoteModule.filter(new RegExp(this.initial, 'i'), 10);
|
||||
// this.open = this.emotes.length;
|
||||
},
|
||||
created() {
|
||||
document.querySelector('.chat textarea').addEventListener('keyup', this.searchEmotes);
|
||||
window.addEventListener('keydown', this.prevents);
|
||||
const ta = document.querySelector('.chat textarea');
|
||||
ta.addEventListener('keydown', this.setCaret);
|
||||
ta.addEventListener('keyup', this.searchEmotes);
|
||||
},
|
||||
destroyed() {
|
||||
document.querySelector('.chat textarea').removeEventListener('keyup', this.searchEmotes);
|
||||
window.removeEventListener('keydown', this.prevents);
|
||||
const ta = document.querySelector('.chat textarea');
|
||||
ta.removeEventListener('keydown', this.setCaret);
|
||||
ta.removeEventListener('keyup', this.searchEmotes);
|
||||
},
|
||||
methods: {
|
||||
prevents(e) {
|
||||
if (!this.open) return;
|
||||
if (e.key !== 'ArrowDown' && e.key !== 'ArrowUp' && e.key !== 'Tab') return;
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
},
|
||||
setCaret(e) {
|
||||
this.caret = e.target.selectionEnd;
|
||||
},
|
||||
getEmoteSrc(emote) {
|
||||
let { id, value } = emote;
|
||||
if (value.id) value = value.id;
|
||||
|
@ -58,13 +80,48 @@
|
|||
return uri.replace(':id', value);
|
||||
},
|
||||
searchEmotes(e) {
|
||||
const sterm = e.target.value.split(' ').slice(-1).pop();
|
||||
if (sterm.length < 3) {
|
||||
this.emotes = null;
|
||||
if (e.key === 'ArrowDown' && this.open && this.caret) {
|
||||
this.selectedIndex = (this.selectedIndex + 1) >= 10 ? 0 : this.selectedIndex + 1;
|
||||
return;
|
||||
} else if (e.key === 'ArrowUp' && this.open && this.caret) {
|
||||
this.selectedIndex = (this.selectedIndex - 1) < 0 ? 9 : this.selectedIndex - 1;
|
||||
return;
|
||||
}
|
||||
this.title = sterm;
|
||||
this.emotes = EmoteModule.filter(new RegExp(sterm, 'i'), 10);
|
||||
if (e.key === 'Tab' && this.open && this.caret) {
|
||||
const selected = this.emotes[this.selectedIndex];
|
||||
if (!selected) return;
|
||||
this.inject(selected);
|
||||
return;
|
||||
}
|
||||
const se = e.target.selectionEnd;
|
||||
this.sterm = e.target.value.substr(0, se).split(' ').slice(-1).pop();
|
||||
|
||||
if (this.sterm.length < 3) {
|
||||
this.emotes = [];
|
||||
this.selected = '';
|
||||
this.selectedIndex = 0;
|
||||
return;
|
||||
}
|
||||
this.title = this.sterm;
|
||||
this.emotes = EmoteModule.filter(new RegExp(this.sterm, ''), 10);
|
||||
this.open = this.emotes.length;
|
||||
},
|
||||
inject(emote) {
|
||||
const ta = document.querySelector('.chat textarea');
|
||||
if (!ta) return;
|
||||
const currentText = document.querySelector('.chat textarea').value;
|
||||
const se = ta.selectionEnd;
|
||||
const split = currentText.substr(0, se).split(' ');
|
||||
split.pop();
|
||||
split.push(`:${emote.id}:`);
|
||||
const join = split.join(' ');
|
||||
const rest = currentText.substr(se, currentText.length);
|
||||
DOM.manip.setText(join + ' ' + rest, false);
|
||||
this.emotes = [];
|
||||
this.open = false;
|
||||
this.selectedIndex = 0;
|
||||
this.selected = '';
|
||||
ta.selectionEnd = ta.selectionStart = se + `:${emote.id}:`.length - this.title.length;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -85,8 +85,29 @@ class DOMObserver {
|
|||
|
||||
}
|
||||
|
||||
class Manip {
|
||||
static setText(text, refocus) {
|
||||
const activeElement = document.activeElement;
|
||||
const txt = document.querySelector('.chat form textarea');
|
||||
if (!txt) return;
|
||||
txt.focus();
|
||||
txt.select();
|
||||
document.execCommand('insertText', false, text);
|
||||
if (activeElement && refocus) activeElement.focus();
|
||||
}
|
||||
static getText() {
|
||||
const txt = document.querySelector('.chat form textarea');
|
||||
if (!txt) return '';
|
||||
return txt.value;
|
||||
}
|
||||
}
|
||||
|
||||
export default class DOM {
|
||||
|
||||
static get manip() {
|
||||
return Manip;
|
||||
}
|
||||
|
||||
static get observer() {
|
||||
return this._observer || (this._observer = new DOMObserver());
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue