pages/messaging/messaging-room.vue
This commit is contained in:
		
							parent
							
								
									47edc18931
								
							
						
					
					
						commit
						a1f346a549
					
				
					 2 changed files with 220 additions and 276 deletions
				
			
		| 
						 | 
					@ -62,10 +62,6 @@ function dragClear(fn) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default defineComponent({
 | 
					export default defineComponent({
 | 
				
			||||||
	provide: {
 | 
					 | 
				
			||||||
		inWindow: true
 | 
					 | 
				
			||||||
	},
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	props: {
 | 
						props: {
 | 
				
			||||||
		padding: {
 | 
							padding: {
 | 
				
			||||||
			type: Boolean,
 | 
								type: Boolean,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,6 +2,7 @@
 | 
				
			||||||
<div class="_section"
 | 
					<div class="_section"
 | 
				
			||||||
	@dragover.prevent.stop="onDragover"
 | 
						@dragover.prevent.stop="onDragover"
 | 
				
			||||||
	@drop.prevent.stop="onDrop"
 | 
						@drop.prevent.stop="onDrop"
 | 
				
			||||||
 | 
						ref="rootEl"
 | 
				
			||||||
>
 | 
					>
 | 
				
			||||||
	<div class="_content mk-messaging-room">
 | 
						<div class="_content mk-messaging-room">
 | 
				
			||||||
		<div class="body">
 | 
							<div class="body">
 | 
				
			||||||
| 
						 | 
					@ -35,9 +36,10 @@
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<script lang="ts">
 | 
					<script lang="ts" setup>
 | 
				
			||||||
import { computed, defineComponent, markRaw } from 'vue';
 | 
					import { computed, watch, onMounted, nextTick, onBeforeUnmount } from 'vue';
 | 
				
			||||||
import XList from '@/components/date-separated-list.vue';
 | 
					import * as Misskey from 'misskey-js';
 | 
				
			||||||
 | 
					import MkPagination from '@/components/ui/pagination.vue';
 | 
				
			||||||
import XMessage from './messaging-room.message.vue';
 | 
					import XMessage from './messaging-room.message.vue';
 | 
				
			||||||
import XForm from './messaging-room.form.vue';
 | 
					import XForm from './messaging-room.form.vue';
 | 
				
			||||||
import * as Acct from 'misskey-js/built/acct';
 | 
					import * as Acct from 'misskey-js/built/acct';
 | 
				
			||||||
| 
						 | 
					@ -47,126 +49,72 @@ import { stream } from '@/stream';
 | 
				
			||||||
import { popout } from '@/scripts/popout';
 | 
					import { popout } from '@/scripts/popout';
 | 
				
			||||||
import * as sound from '@/scripts/sound';
 | 
					import * as sound from '@/scripts/sound';
 | 
				
			||||||
import * as symbols from '@/symbols';
 | 
					import * as symbols from '@/symbols';
 | 
				
			||||||
 | 
					import { i18n } from '@/i18n';
 | 
				
			||||||
 | 
					import { defaultStore } from '@/store';
 | 
				
			||||||
 | 
					import { $i } from '@/account';
 | 
				
			||||||
 | 
					import { router } from '@/router';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const Component = defineComponent({
 | 
					const props = defineProps<{
 | 
				
			||||||
	components: {
 | 
						userAcct?: string;
 | 
				
			||||||
		XMessage,
 | 
						groupId?: string;
 | 
				
			||||||
		XForm,
 | 
					}>();
 | 
				
			||||||
		XList,
 | 
					 | 
				
			||||||
	},
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	inject: ['inWindow'],
 | 
					let fetching = $ref(true);
 | 
				
			||||||
 | 
					let user: Misskey.entities.UserDetailed | null = $ref(null);
 | 
				
			||||||
	props: {
 | 
					let group: Misskey.entities.UserGroup | null = $ref(null);
 | 
				
			||||||
		userAcct: {
 | 
					let fetchingMoreMessages = $ref(false);
 | 
				
			||||||
			type: String,
 | 
					let messages = $ref<Misskey.entities.MessagingMessage[]>([]);
 | 
				
			||||||
			required: false,
 | 
					let existMoreMessages = $ref(false);
 | 
				
			||||||
		},
 | 
					let connection: Misskey.ChannelConnection<Misskey.Channels['messaging']> | null = $ref(null);
 | 
				
			||||||
		groupId: {
 | 
					let showIndicator = $ref(false);
 | 
				
			||||||
			type: String,
 | 
					let timer: number | null = $ref(null);
 | 
				
			||||||
			required: false,
 | 
					const ilObserver = new IntersectionObserver(
 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
	},
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	data() {
 | 
					 | 
				
			||||||
		return {
 | 
					 | 
				
			||||||
			[symbols.PAGE_INFO]: computed(() => !this.fetching ? this.user ? {
 | 
					 | 
				
			||||||
				userName: this.user,
 | 
					 | 
				
			||||||
				avatar: this.user,
 | 
					 | 
				
			||||||
				action: {
 | 
					 | 
				
			||||||
					icon: 'fas fa-ellipsis-h',
 | 
					 | 
				
			||||||
					handler: this.menu,
 | 
					 | 
				
			||||||
				},
 | 
					 | 
				
			||||||
			} : {
 | 
					 | 
				
			||||||
				title: this.group.name,
 | 
					 | 
				
			||||||
				icon: 'fas fa-users',
 | 
					 | 
				
			||||||
				action: {
 | 
					 | 
				
			||||||
					icon: 'fas fa-ellipsis-h',
 | 
					 | 
				
			||||||
					handler: this.menu,
 | 
					 | 
				
			||||||
				},
 | 
					 | 
				
			||||||
			} : null),
 | 
					 | 
				
			||||||
			fetching: true,
 | 
					 | 
				
			||||||
			user: null,
 | 
					 | 
				
			||||||
			group: null,
 | 
					 | 
				
			||||||
			fetchingMoreMessages: false,
 | 
					 | 
				
			||||||
			messages: [],
 | 
					 | 
				
			||||||
			existMoreMessages: false,
 | 
					 | 
				
			||||||
			connection: null,
 | 
					 | 
				
			||||||
			showIndicator: false,
 | 
					 | 
				
			||||||
			timer: null,
 | 
					 | 
				
			||||||
			typers: [],
 | 
					 | 
				
			||||||
			ilObserver: new IntersectionObserver(
 | 
					 | 
				
			||||||
	(entries) => entries.some((entry) => entry.isIntersecting)
 | 
						(entries) => entries.some((entry) => entry.isIntersecting)
 | 
				
			||||||
					&& !this.fetching
 | 
							&& !fetching
 | 
				
			||||||
					&& !this.fetchingMoreMessages
 | 
							&& !fetchingMoreMessages
 | 
				
			||||||
					&& this.existMoreMessages
 | 
							&& existMoreMessages
 | 
				
			||||||
					&& this.fetchMoreMessages()
 | 
							&& fetchMoreMessages()
 | 
				
			||||||
			),
 | 
					);
 | 
				
			||||||
		};
 | 
					 | 
				
			||||||
	},
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	computed: {
 | 
					let rootEl = $ref<Element>();
 | 
				
			||||||
		form(): any {
 | 
					let form = $ref<InstanceType<typeof XForm>>();
 | 
				
			||||||
			return this.$refs.form;
 | 
					let loadMore = $ref<HTMLDivElement>();
 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	},
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	watch: {
 | 
					watch([() => props.userAcct, () => props.groupId], () => {
 | 
				
			||||||
		userAcct: 'fetch',
 | 
						if (connection) connection.dispose();
 | 
				
			||||||
		groupId: 'fetch',
 | 
						fetch();
 | 
				
			||||||
	},
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mounted() {
 | 
					async function fetch() {
 | 
				
			||||||
		this.fetch();
 | 
						fetching = true;
 | 
				
			||||||
		if (this.$store.state.enableInfiniteScroll) {
 | 
					 | 
				
			||||||
			this.$nextTick(() => this.ilObserver.observe(this.$refs.loadMore as Element));
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	},
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	beforeUnmount() {
 | 
						connection = stream.useChannel('messaging', {
 | 
				
			||||||
		this.connection.dispose();
 | 
							otherparty: user ? user.id : undefined,
 | 
				
			||||||
 | 
							group: group ? group.id : undefined,
 | 
				
			||||||
		document.removeEventListener('visibilitychange', this.onVisibilitychange);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		this.ilObserver.disconnect();
 | 
					 | 
				
			||||||
	},
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	methods: {
 | 
					 | 
				
			||||||
		async fetch() {
 | 
					 | 
				
			||||||
			this.fetching = true;
 | 
					 | 
				
			||||||
			if (this.userAcct) {
 | 
					 | 
				
			||||||
				const user = await os.api('users/show', Acct.parse(this.userAcct));
 | 
					 | 
				
			||||||
				this.user = user;
 | 
					 | 
				
			||||||
			} else {
 | 
					 | 
				
			||||||
				const group = await os.api('users/groups/show', { groupId: this.groupId });
 | 
					 | 
				
			||||||
				this.group = group;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			this.connection = markRaw(stream.useChannel('messaging', {
 | 
					 | 
				
			||||||
				otherparty: this.user ? this.user.id : undefined,
 | 
					 | 
				
			||||||
				group: this.group ? this.group.id : undefined,
 | 
					 | 
				
			||||||
			}));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			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);
 | 
						connection?.on('message', onMessage);
 | 
				
			||||||
 | 
						connection?.on('read', onRead);
 | 
				
			||||||
 | 
						connection?.on('deleted', onDeleted);
 | 
				
			||||||
 | 
						connection?.on('typers', typers => {
 | 
				
			||||||
 | 
							typers = typers.filter(u => u.id !== $i.id);
 | 
				
			||||||
 | 
						});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			this.fetchMessages().then(() => {
 | 
						document.addEventListener('visibilitychange', onVisibilitychange);
 | 
				
			||||||
				this.scrollToBottom();
 | 
					
 | 
				
			||||||
 | 
						fetchMessages().then(() => {
 | 
				
			||||||
 | 
							scrollToBottom();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// もっと見るの交差検知を発火させないためにfetchは
 | 
							// もっと見るの交差検知を発火させないためにfetchは
 | 
				
			||||||
		// スクロールが終わるまでfalseにしておく
 | 
							// スクロールが終わるまでfalseにしておく
 | 
				
			||||||
		// scrollendのようなイベントはないのでsetTimeoutで
 | 
							// scrollendのようなイベントはないのでsetTimeoutで
 | 
				
			||||||
				window.setTimeout(() => this.fetching = false, 300);
 | 
							window.setTimeout(() => fetching = false, 300);
 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
		},
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function onDragover(e: DragEvent) {
 | 
				
			||||||
 | 
						if (!e.dataTransfer) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		onDragover(e) {
 | 
					 | 
				
			||||||
	const isFile = e.dataTransfer.items[0].kind == 'file';
 | 
						const isFile = e.dataTransfer.items[0].kind == 'file';
 | 
				
			||||||
	const isDriveFile = e.dataTransfer.types[0] == _DATA_TRANSFER_DRIVE_FILE_;
 | 
						const isDriveFile = e.dataTransfer.types[0] == _DATA_TRANSFER_DRIVE_FILE_;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -175,17 +123,19 @@ const Component = defineComponent({
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		e.dataTransfer.dropEffect = 'none';
 | 
							e.dataTransfer.dropEffect = 'none';
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
		},
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function onDrop(e: DragEvent): void {
 | 
				
			||||||
 | 
						if (!e.dataTransfer) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		onDrop(e): void {
 | 
					 | 
				
			||||||
	// ファイルだったら
 | 
						// ファイルだったら
 | 
				
			||||||
	if (e.dataTransfer.files.length == 1) {
 | 
						if (e.dataTransfer.files.length == 1) {
 | 
				
			||||||
				this.form.upload(e.dataTransfer.files[0]);
 | 
							form.upload(e.dataTransfer.files[0]);
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	} else if (e.dataTransfer.files.length > 1) {
 | 
						} else if (e.dataTransfer.files.length > 1) {
 | 
				
			||||||
		os.alert({
 | 
							os.alert({
 | 
				
			||||||
			type: 'error',
 | 
								type: 'error',
 | 
				
			||||||
					text: this.$ts.onlyOneFileCanBeAttached
 | 
								text: i18n.locale.onlyOneFileCanBeAttached
 | 
				
			||||||
		});
 | 
							});
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -194,153 +144,151 @@ const Component = defineComponent({
 | 
				
			||||||
	const driveFile = e.dataTransfer.getData(_DATA_TRANSFER_DRIVE_FILE_);
 | 
						const driveFile = e.dataTransfer.getData(_DATA_TRANSFER_DRIVE_FILE_);
 | 
				
			||||||
	if (driveFile != null && driveFile != '') {
 | 
						if (driveFile != null && driveFile != '') {
 | 
				
			||||||
		const file = JSON.parse(driveFile);
 | 
							const file = JSON.parse(driveFile);
 | 
				
			||||||
				this.form.file = file;
 | 
							form.file = file;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	//#endregion
 | 
						//#endregion
 | 
				
			||||||
		},
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		fetchMessages() {
 | 
					function fetchMessages() {
 | 
				
			||||||
			return new Promise((resolve, reject) => {
 | 
						return new Promise<void>((resolve, reject) => {
 | 
				
			||||||
				const max = this.existMoreMessages ? 20 : 10;
 | 
							const max = existMoreMessages ? 20 : 10;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		os.api('messaging/messages', {
 | 
							os.api('messaging/messages', {
 | 
				
			||||||
					userId: this.user ? this.user.id : undefined,
 | 
								userId: user ? user.id : undefined,
 | 
				
			||||||
					groupId: this.group ? this.group.id : undefined,
 | 
								groupId: group ? group.id : undefined,
 | 
				
			||||||
			limit: max + 1,
 | 
								limit: max + 1,
 | 
				
			||||||
					untilId: this.existMoreMessages ? this.messages[0].id : undefined
 | 
								untilId: existMoreMessages ? messages[0].id : undefined
 | 
				
			||||||
		}).then(messages => {
 | 
							}).then(messages => {
 | 
				
			||||||
			if (messages.length == max + 1) {
 | 
								if (messages.length == max + 1) {
 | 
				
			||||||
						this.existMoreMessages = true;
 | 
									existMoreMessages = true;
 | 
				
			||||||
				messages.pop();
 | 
									messages.pop();
 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
						this.existMoreMessages = false;
 | 
									existMoreMessages = false;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					this.messages.unshift.apply(this.messages, messages.reverse());
 | 
								messages.unshift.apply(messages, messages.reverse());
 | 
				
			||||||
			resolve();
 | 
								resolve();
 | 
				
			||||||
		});
 | 
							});
 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
		},
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		fetchMoreMessages() {
 | 
					function fetchMoreMessages() {
 | 
				
			||||||
			this.fetchingMoreMessages = true;
 | 
						fetchingMoreMessages = true;
 | 
				
			||||||
			this.fetchMessages().then(() => {
 | 
						fetchMessages().then(() => {
 | 
				
			||||||
				this.fetchingMoreMessages = false;
 | 
							fetchingMoreMessages = false;
 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
		},
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		onMessage(message) {
 | 
					function onMessage(message) {
 | 
				
			||||||
	sound.play('chat');
 | 
						sound.play('chat');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			const _isBottom = isBottom(this.$el, 64);
 | 
						const _isBottom = isBottom(rootEl, 64);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			this.messages.push(message);
 | 
						messages.push(message);
 | 
				
			||||||
			if (message.userId != this.$i.id && !document.hidden) {
 | 
						if (message.userId != $i.id && !document.hidden) {
 | 
				
			||||||
				this.connection.send('read', {
 | 
							connection?.send('read', {
 | 
				
			||||||
			id: message.id
 | 
								id: message.id
 | 
				
			||||||
		});
 | 
							});
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (_isBottom) {
 | 
						if (_isBottom) {
 | 
				
			||||||
		// Scroll to bottom
 | 
							// Scroll to bottom
 | 
				
			||||||
				this.$nextTick(() => {
 | 
							nextTick(() => {
 | 
				
			||||||
					this.scrollToBottom();
 | 
								scrollToBottom();
 | 
				
			||||||
		});
 | 
							});
 | 
				
			||||||
			} else if (message.userId != this.$i.id) {
 | 
						} else if (message.userId != $i.id) {
 | 
				
			||||||
		// Notify
 | 
							// Notify
 | 
				
			||||||
				this.notifyNewMessage();
 | 
							notifyNewMessage();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
		},
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		onRead(x) {
 | 
					function onRead(x) {
 | 
				
			||||||
			if (this.user) {
 | 
						if (user) {
 | 
				
			||||||
		if (!Array.isArray(x)) x = [x];
 | 
							if (!Array.isArray(x)) x = [x];
 | 
				
			||||||
		for (const id of x) {
 | 
							for (const id of x) {
 | 
				
			||||||
					if (this.messages.some(x => x.id == id)) {
 | 
								if (messages.some(x => x.id == id)) {
 | 
				
			||||||
						const exist = this.messages.map(x => x.id).indexOf(id);
 | 
									const exist = messages.map(x => x.id).indexOf(id);
 | 
				
			||||||
						this.messages[exist] = {
 | 
									messages[exist] = {
 | 
				
			||||||
							...this.messages[exist],
 | 
										...messages[exist],
 | 
				
			||||||
					isRead: true,
 | 
										isRead: true,
 | 
				
			||||||
				};
 | 
									};
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
			} else if (this.group) {
 | 
						} else if (group) {
 | 
				
			||||||
		for (const id of x.ids) {
 | 
							for (const id of x.ids) {
 | 
				
			||||||
					if (this.messages.some(x => x.id == id)) {
 | 
								if (messages.some(x => x.id == id)) {
 | 
				
			||||||
						const exist = this.messages.map(x => x.id).indexOf(id);
 | 
									const exist = messages.map(x => x.id).indexOf(id);
 | 
				
			||||||
						this.messages[exist] = {
 | 
									messages[exist] = {
 | 
				
			||||||
							...this.messages[exist],
 | 
										...messages[exist],
 | 
				
			||||||
							reads: [...this.messages[exist].reads, x.userId]
 | 
										reads: [...messages[exist].reads, x.userId]
 | 
				
			||||||
				};
 | 
									};
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
		},
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		onDeleted(id) {
 | 
					function onDeleted(id) {
 | 
				
			||||||
			const msg = this.messages.find(m => m.id === id);
 | 
						const msg = messages.find(m => m.id === id);
 | 
				
			||||||
	if (msg) {
 | 
						if (msg) {
 | 
				
			||||||
				this.messages = this.messages.filter(m => m.id !== msg.id);
 | 
							messages = messages.filter(m => m.id !== msg.id);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
		},
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		scrollToBottom() {
 | 
					function scrollToBottom() {
 | 
				
			||||||
			scroll(this.$el, { top: this.$el.offsetHeight });
 | 
						scroll(rootEl, { top: rootEl.offsetHeight });
 | 
				
			||||||
		},
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		onIndicatorClick() {
 | 
					function onIndicatorClick() {
 | 
				
			||||||
			this.showIndicator = false;
 | 
						showIndicator = false;
 | 
				
			||||||
			this.scrollToBottom();
 | 
						scrollToBottom();
 | 
				
			||||||
		},
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		notifyNewMessage() {
 | 
					function notifyNewMessage() {
 | 
				
			||||||
			this.showIndicator = true;
 | 
						showIndicator = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			onScrollBottom(this.$el, () => {
 | 
						onScrollBottom(rootEl, () => {
 | 
				
			||||||
				this.showIndicator = false;
 | 
							showIndicator = false;
 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (this.timer) window.clearTimeout(this.timer);
 | 
						if (timer) window.clearTimeout(timer);
 | 
				
			||||||
 | 
						timer = window.setTimeout(() => {
 | 
				
			||||||
			this.timer = window.setTimeout(() => {
 | 
							showIndicator = false;
 | 
				
			||||||
				this.showIndicator = false;
 | 
					 | 
				
			||||||
	}, 4000);
 | 
						}, 4000);
 | 
				
			||||||
		},
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		onVisibilitychange() {
 | 
					function onVisibilitychange() {
 | 
				
			||||||
	if (document.hidden) return;
 | 
						if (document.hidden) return;
 | 
				
			||||||
			for (const message of this.messages) {
 | 
						for (const message of messages) {
 | 
				
			||||||
				if (message.userId !== this.$i.id && !message.isRead) {
 | 
							if (message.userId !== $i.id && !message.isRead) {
 | 
				
			||||||
					this.connection.send('read', {
 | 
								connection?.send('read', {
 | 
				
			||||||
				id: message.id
 | 
									id: message.id
 | 
				
			||||||
			});
 | 
								});
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
		},
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		menu(ev) {
 | 
					onMounted(() => {
 | 
				
			||||||
			const path = this.groupId ? `/my/messaging/group/${this.groupId}` : `/my/messaging/${this.userAcct}`;
 | 
						fetch();
 | 
				
			||||||
 | 
						if (defaultStore.state.enableInfiniteScroll) {
 | 
				
			||||||
			os.popupMenu([this.inWindow ? undefined : {
 | 
							nextTick(() => ilObserver.observe(loadMore));
 | 
				
			||||||
				text: this.$ts.openInWindow,
 | 
					 | 
				
			||||||
				icon: 'fas fa-window-maximize',
 | 
					 | 
				
			||||||
				action: () => {
 | 
					 | 
				
			||||||
					os.pageWindow(path);
 | 
					 | 
				
			||||||
					this.$router.back();
 | 
					 | 
				
			||||||
				},
 | 
					 | 
				
			||||||
			}, this.inWindow ? undefined : {
 | 
					 | 
				
			||||||
				text: this.$ts.popout,
 | 
					 | 
				
			||||||
				icon: 'fas fa-external-link-alt',
 | 
					 | 
				
			||||||
				action: () => {
 | 
					 | 
				
			||||||
					popout(path);
 | 
					 | 
				
			||||||
					this.$router.back();
 | 
					 | 
				
			||||||
				},
 | 
					 | 
				
			||||||
			}], ev.currentTarget || ev.target);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default Component;
 | 
					onBeforeUnmount(() => {
 | 
				
			||||||
 | 
						connection?.dispose();
 | 
				
			||||||
 | 
						document.removeEventListener('visibilitychange', onVisibilitychange);
 | 
				
			||||||
 | 
						ilObserver.disconnect();
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					defineExpose({
 | 
				
			||||||
 | 
						[symbols.PAGE_INFO]: computed(() => !fetching ? user ? {
 | 
				
			||||||
 | 
								userName: user,
 | 
				
			||||||
 | 
								avatar: user,
 | 
				
			||||||
 | 
							} : {
 | 
				
			||||||
 | 
								title: group?.name,
 | 
				
			||||||
 | 
								icon: 'fas fa-users',
 | 
				
			||||||
 | 
							} : null),
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<style lang="scss" scoped>
 | 
					<style lang="scss" scoped>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue