It's ugly for now.

This commit is contained in:
Jiiks 2018-03-10 09:58:25 +02:00
parent c59494f604
commit 45545d86b4
2 changed files with 90 additions and 12 deletions

View File

@ -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;
}
}
}

View File

@ -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());
}