Compare commits

...

1 Commits

Author SHA1 Message Date
syuilo 3b585a9020 wip 2020-01-11 15:34:08 +09:00
2 changed files with 50 additions and 21 deletions

View File

@ -1,13 +1,16 @@
<template>
<div class="mk-autocomplete" @contextmenu.prevent="() => {}">
<ol class="users" ref="suggests" v-if="users.length > 0">
<li v-for="user in users" @click="complete(type, user)" @keydown="onKeydown" tabindex="-1">
<ol class="users" ref="suggests" v-if="type === 'user'">
<li v-for="user in users" @click="complete(type, user)" @keydown="onKeydown" tabindex="-1" class="user">
<img class="avatar" :src="user.avatarUrl" alt=""/>
<span class="name">
<mk-user-name :user="user" :key="user.id"/>
</span>
<span class="username">@{{ user | acct }}</span>
</li>
<li @click="chooseUser()" @keydown="onKeydown" tabindex="-1" class="choose">
{{ $t('choose-user') }}
</li>
</ol>
<ol class="hashtags" ref="suggests" v-if="hashtags.length > 0">
<li v-for="hashtag in hashtags" @click="complete(type, hashtag)" @keydown="onKeydown" tabindex="-1">
@ -81,11 +84,11 @@ export default Vue.extend({
q: {
type: String,
required: true,
required: false,
},
textarea: {
type: Object,
type: HTMLTextAreaElement,
required: true,
},
@ -134,24 +137,12 @@ export default Vue.extend({
},
updated() {
//#region 調
if (this.x + this.$el.offsetWidth > window.innerWidth) {
this.$el.style.left = (window.innerWidth - this.$el.offsetWidth) + 'px';
} else {
this.$el.style.left = this.x + 'px';
}
if (this.y + this.$el.offsetHeight > window.innerHeight) {
this.$el.style.top = (this.y - this.$el.offsetHeight) + 'px';
this.$el.style.marginTop = '0';
} else {
this.$el.style.top = this.y + 'px';
this.$el.style.marginTop = 'calc(1em + 8px)';
}
//#endregion
this.setPosition();
},
mounted() {
this.setPosition();
//#region Construct Emoji DB
const customEmojis = (this.$root.getMetaSync() || { emojis: [] }).emojis || [];
const emojiDefinitions: EmojiDef[] = [];
@ -208,6 +199,22 @@ export default Vue.extend({
},
methods: {
setPosition() {
if (this.x + this.$el.offsetWidth > window.innerWidth) {
this.$el.style.left = (window.innerWidth - this.$el.offsetWidth) + 'px';
} else {
this.$el.style.left = this.x + 'px';
}
if (this.y + this.$el.offsetHeight > window.innerHeight) {
this.$el.style.top = (this.y - this.$el.offsetHeight) + 'px';
this.$el.style.marginTop = '0';
} else {
this.$el.style.top = this.y + 'px';
this.$el.style.marginTop = 'calc(1em + 8px)';
}
},
exec() {
this.select = -1;
if (this.$refs.suggests) {
@ -217,6 +224,12 @@ export default Vue.extend({
}
if (this.type == 'user') {
if (this.q == null) {
this.users = [];
this.fetching = false;
return;
}
const cacheKey = `autocomplete:user:${this.q}`;
const cache = sessionStorage.getItem(cacheKey);
if (cache) {
@ -358,6 +371,15 @@ export default Vue.extend({
this.items[this.select].setAttribute('data-selected', 'true');
(this.items[this.select] as any).focus();
},
chooseUser() {
setTimeout(() => {
this.complete('user', {
host: null,
username: 'test'
});
}, 2000);
}
}
});
@ -416,7 +438,7 @@ export default Vue.extend({
&, *
color #fff !important
> .users > li
> .users > li.user
.avatar
min-width 28px
@ -433,6 +455,9 @@ export default Vue.extend({
.username
color var(--autocompleteItemTextSub)
> .users > li.choose
color var(--autocompleteItemText)
> .hashtags > li
.name

View File

@ -99,6 +99,9 @@ class Autocomplete {
if (username != '' && username.match(/^[a-zA-Z0-9_]+$/)) {
this.open('user', username);
opened = true;
} else if (username === '') {
this.open('user', null);
opened = true;
}
}
@ -126,7 +129,7 @@ class Autocomplete {
/**
*
*/
private async open(type, q) {
private async open(type: string, q: string) {
if (type != this.currentType) {
this.close();
}
@ -144,6 +147,7 @@ class Autocomplete {
//#endregion
if (this.suggestion) {
// TODO: Vueの警告が出るのでなんとかする
this.suggestion.x = x;
this.suggestion.y = y;
this.suggestion.q = q;