Messagingの入力中インジケータを実装
This commit is contained in:
parent
f3aef8df75
commit
78a963fe33
4 changed files with 104 additions and 4 deletions
|
@ -7,6 +7,7 @@
|
|||
v-model="text"
|
||||
ref="text"
|
||||
@keypress="onKeypress"
|
||||
@compositionupdate="onCompositionUpdate"
|
||||
@paste="onPaste"
|
||||
:placeholder="$ts.inputMessageHere"
|
||||
></textarea>
|
||||
|
@ -29,6 +30,7 @@ import { formatTimeString } from '../../../misc/format-time-string';
|
|||
import { selectFile } from '@/scripts/select-file';
|
||||
import * as os from '@/os';
|
||||
import { Autocomplete } from '@/scripts/autocomplete';
|
||||
import { throttle } from 'throttle-debounce';
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
|
@ -46,6 +48,9 @@ export default defineComponent({
|
|||
text: null,
|
||||
file: null,
|
||||
sending: false,
|
||||
typing: throttle(3000, () => {
|
||||
os.stream.send('typingOnMessaging', this.user ? { partner: this.user.id } : { group: this.group.id });
|
||||
}),
|
||||
faPaperPlane, faPhotoVideo, faLaughSquint
|
||||
};
|
||||
},
|
||||
|
@ -147,11 +152,16 @@ export default defineComponent({
|
|||
},
|
||||
|
||||
onKeypress(e) {
|
||||
this.typing();
|
||||
if ((e.which == 10 || e.which == 13) && (e.ctrlKey || e.metaKey) && this.canSend) {
|
||||
this.send();
|
||||
}
|
||||
},
|
||||
|
||||
onCompositionUpdate() {
|
||||
this.typing();
|
||||
},
|
||||
|
||||
chooseFile(e) {
|
||||
selectFile(e.currentTarget || e.target, this.$ts.selectFile, false).then(file => {
|
||||
this.file = file;
|
||||
|
|
|
@ -16,6 +16,14 @@
|
|||
</XList>
|
||||
</div>
|
||||
<footer>
|
||||
<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>
|
||||
<transition name="fade">
|
||||
<div class="new-message" v-show="showIndicator">
|
||||
<button class="_buttonPrimary" @click="onIndicatorClick"><i><Fa :icon="faArrowCircleDown"/></i>{{ $ts.newMessageExists }}</button>
|
||||
|
@ -86,6 +94,7 @@ const Component = defineComponent({
|
|||
connection: null,
|
||||
showIndicator: false,
|
||||
timer: null,
|
||||
typers: [],
|
||||
ilObserver: new IntersectionObserver(
|
||||
(entries) => entries.some((entry) => entry.isIntersecting)
|
||||
&& !this.fetching
|
||||
|
@ -142,6 +151,9 @@ const Component = defineComponent({
|
|||
this.connection.on('message', this.onMessage);
|
||||
this.connection.on('read', this.onRead);
|
||||
this.connection.on('deleted', this.onDeleted);
|
||||
this.connection.on('typers', typers => {
|
||||
this.typers = typers.filter(u => u.id !== this.$i.id);
|
||||
});
|
||||
|
||||
document.addEventListener('visibilitychange', this.onVisibilitychange);
|
||||
|
||||
|
@ -397,6 +409,7 @@ export default Component;
|
|||
|
||||
> footer {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
|
||||
> .new-message {
|
||||
position: absolute;
|
||||
|
@ -422,6 +435,25 @@ export default Component;
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
> .typers {
|
||||
position: absolute;
|
||||
bottom: 100%;
|
||||
padding: 0 8px 0 8px;
|
||||
font-size: 0.9em;
|
||||
color: var(--fgTransparentWeak);
|
||||
|
||||
> .users {
|
||||
> .user + .user:before {
|
||||
content: ", ";
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
> .user:last-of-type:after {
|
||||
content: " ";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue