チャンネルで入力中ユーザーを表示するように、Chat UIでタイムラインでは投稿フォームを上に表示するように

This commit is contained in:
syuilo
2021-02-20 20:20:05 +09:00
parent 5f1a6b6f64
commit 25d37302a8
11 changed files with 143 additions and 41 deletions

View File

@ -1,8 +1,22 @@
<template>
<div class="dbiokgaf">
<div class="dbiokgaf top" v-if="['home', 'local', 'social', 'global'].includes(src)">
<XPostForm/>
</div>
<div class="dbiokgaf tl" ref="body">
<div class="new" v-if="queue > 0" :style="{ width: width + 'px', [pagination.reversed ? 'bottom' : 'top']: pagination.reversed ? bottom + 'px' : top + 'px' }"><button class="_buttonPrimary" @click="goTop()">{{ $ts.newNoteRecived }}</button></div>
<XNotes class="tl" ref="tl" :pagination="pagination" @queue="queueUpdated" v-follow="pagination.reversed"/>
</div>
<div class="dbiokgaf bottom" v-if="src === 'channel'">
<div class="typers" v-if="typers.length > 0">
<I18n :src="$ts.typingUsers" text-tag="span" class="users">
<template #users>
<b v-for="user in typers" :key="user.id" class="user">{{ user.username }}</b>
</template>
</I18n>
<MkEllipsis/>
</div>
<XPostForm :channel="channel"/>
</div>
</template>
<script lang="ts">
@ -12,10 +26,12 @@ import * as os from '@/os';
import * as sound from '@/scripts/sound';
import { scrollToBottom, getScrollPosition, getScrollContainer } from '@/scripts/scroll';
import follow from '@/directives/follow-append';
import XPostForm from './post-form.vue';
export default defineComponent({
components: {
XNotes
XNotes,
XPostForm,
},
directives: {
@ -69,6 +85,7 @@ export default defineComponent({
width: 0,
top: 0,
bottom: 0,
typers: [],
};
},
@ -166,6 +183,9 @@ export default defineComponent({
channelId: this.channel
});
this.connection.on('note', prepend);
this.connection.on('typers', typers => {
this.typers = this.$i ? typers.filter(u => u.id !== this.$i.id) : typers;
});
}
this.pagination = {
@ -190,21 +210,21 @@ export default defineComponent({
methods: {
focus() {
this.$refs.tl.focus();
this.$refs.body.focus();
},
goTop() {
const container = getScrollContainer(this.$el);
const container = getScrollContainer(this.$refs.body);
container.scrollTop = 0;
},
queueUpdated(q) {
if (this.$el.offsetWidth !== 0) {
const rect = this.$el.getBoundingClientRect();
const scrollTop = getScrollPosition(this.$el);
this.width = this.$el.offsetWidth;
if (this.$refs.body.offsetWidth !== 0) {
const rect = this.$refs.body.getBoundingClientRect();
const scrollTop = getScrollPosition(this.$refs.body);
this.width = this.$refs.body.offsetWidth;
this.top = rect.top + scrollTop;
this.bottom = this.$el.offsetHeight;
this.bottom = this.$refs.body.offsetHeight;
}
this.queue = q;
},
@ -213,11 +233,41 @@ export default defineComponent({
</script>
<style lang="scss" scoped>
.dbiokgaf {
padding: 16px 0;
.dbiokgaf.top {
padding: 16px 16px 0 16px;
}
// TODO: これはート追加アニメーションによるスクロール発生を抑えるために必要だが、position stickyが効かなくなるので、両者を両立させる良い方法を考える
overflow: hidden;
.dbiokgaf.bottom {
padding: 0 16px 16px 16px;
position: relative;
> .typers {
position: absolute;
bottom: 100%;
padding: 0 8px 0 8px;
font-size: 0.9em;
background: var(--panel);
border-radius: 0 8px 0 0;
color: var(--fgTransparentWeak);
> .users {
> .user + .user:before {
content: ", ";
font-weight: normal;
}
> .user:last-of-type:after {
content: " ";
}
}
}
}
.dbiokgaf.tl {
padding: 16px 0;
flex: 1;
min-width: 0;
overflow: auto;
> .new {
position: fixed;