wip
This commit is contained in:
		
							parent
							
								
									a1f346a549
								
							
						
					
					
						commit
						8a7264835e
					
				
					 3 changed files with 73 additions and 113 deletions
				
			
		|  | @ -271,6 +271,7 @@ onDeactivated(() => { | |||
| defineExpose({ | ||||
| 	items, | ||||
| 	backed, | ||||
| 	more, | ||||
| 	reload, | ||||
| 	fetchMoreAhead, | ||||
| 	prepend, | ||||
|  |  | |||
|  | @ -35,45 +35,39 @@ | |||
| </div> | ||||
| </template> | ||||
| 
 | ||||
| <script lang="ts"> | ||||
| import { defineComponent } from 'vue'; | ||||
| <script lang="ts" setup> | ||||
| import { } from 'vue'; | ||||
| import * as mfm from 'mfm-js'; | ||||
| import * as Misskey from 'misskey-js'; | ||||
| import { extractUrlFromMfm } from '@/scripts/extract-url-from-mfm'; | ||||
| import MkUrlPreview from '@/components/url-preview.vue'; | ||||
| import * as os from '@/os'; | ||||
| import { $i } from '@/account'; | ||||
| 
 | ||||
| export default defineComponent({ | ||||
| 	components: { | ||||
| 		MkUrlPreview | ||||
| 	}, | ||||
| 	props: { | ||||
| 		message: { | ||||
| 			required: true | ||||
| 		}, | ||||
| 		isGroup: { | ||||
| 			required: false | ||||
| const props = defineProps<{ | ||||
| 	message: Misskey.entities.MessagingMessage; | ||||
| 	isGroup?: boolean; | ||||
| 	connection?: Misskey.ChannelConnection<Misskey.Channels['messaging']>; | ||||
| }>(); | ||||
| 
 | ||||
| const isMe = $computed(() => props.message.userId === $i?.id); | ||||
| const urls = $computed(() => props.message.text ? extractUrlFromMfm(mfm.parse(props.message.text)) : []); | ||||
| 
 | ||||
| if (props.connection) { | ||||
| 	props.connection?.on('read', (x) => { | ||||
| 		if (!props.isGroup) { | ||||
| 			props.message.isRead = true; | ||||
| 		} else { | ||||
| 			props.message.reads = [...props.message.reads, x.userId]; | ||||
| 		} | ||||
| 	}, | ||||
| 	computed: { | ||||
| 		isMe(): boolean { | ||||
| 			return this.message.userId === this.$i.id; | ||||
| 		}, | ||||
| 		urls(): string[] { | ||||
| 			if (this.message.text) { | ||||
| 				return extractUrlFromMfm(mfm.parse(this.message.text)); | ||||
| 			} else { | ||||
| 				return []; | ||||
| 			} | ||||
| 		} | ||||
| 	}, | ||||
| 	methods: { | ||||
| 		del() { | ||||
| 			os.api('messaging/messages/delete', { | ||||
| 				messageId: this.message.id | ||||
| 			}); | ||||
| 		} | ||||
| 	} | ||||
| }); | ||||
| 	}); | ||||
| } | ||||
| 
 | ||||
| function del() { | ||||
| 	os.api('messaging/messages/delete', { | ||||
| 		messageId: props.message.id | ||||
| 	}); | ||||
| } | ||||
| </script> | ||||
| 
 | ||||
| <style lang="scss" scoped> | ||||
|  |  | |||
|  | @ -6,15 +6,18 @@ | |||
| > | ||||
| 	<div class="_content mk-messaging-room"> | ||||
| 		<div class="body"> | ||||
| 			<MkPagination v-if="pagination" ref="pagingComponent" :pagination="pagination"> | ||||
| 				<template #empty> | ||||
| 					<i class="fas fa-info-circle"></i>{{ $ts.noMessagesYet }}</p> | ||||
| 				</template> | ||||
| 
 | ||||
| 				<template #defalut="{ items: messages }"> | ||||
| 					<XList v-slot="{ item: message }" class="messages" :items="messages" direction="up" reversed> | ||||
| 						<XMessage :key="message.id" :message="message" :is-group="group != null"/> | ||||
| 					</XList> | ||||
| 				</template> | ||||
| 			</MkPagination> | ||||
| 			<MkLoading v-if="fetching"/> | ||||
| 			<p v-if="!fetching && messages.length == 0" class="empty"><i class="fas fa-info-circle"></i>{{ $ts.noMessagesYet }}</p> | ||||
| 			<p v-if="!fetching && messages.length > 0 && !existMoreMessages" class="no-history"><i class="fas fa-flag"></i>{{ $ts.noMoreHistory }}</p> | ||||
| 			<button v-show="existMoreMessages" ref="loadMore" class="more _button" :class="{ fetching: fetchingMoreMessages }" :disabled="fetchingMoreMessages" @click="fetchMoreMessages"> | ||||
| 				<template v-if="fetchingMoreMessages"><i class="fas fa-spinner fa-pulse fa-fw"></i></template>{{ fetchingMoreMessages ? $ts.loading : $ts.loadMore }} | ||||
| 			</button> | ||||
| 			<XList v-slot="{ item: message }" class="messages" :items="messages" direction="up" reversed> | ||||
| 				<XMessage :key="message.id" :message="message" :is-group="group != null"/> | ||||
| 			</XList> | ||||
| 		</div> | ||||
| 		<footer> | ||||
| 			<div v-if="typers.length > 0" class="typers"> | ||||
|  | @ -39,7 +42,9 @@ | |||
| <script lang="ts" setup> | ||||
| import { computed, watch, onMounted, nextTick, onBeforeUnmount } from 'vue'; | ||||
| import * as Misskey from 'misskey-js'; | ||||
| import XList from '@/components/date-separated-list.vue'; | ||||
| import MkPagination from '@/components/ui/pagination.vue'; | ||||
| import { Paging } from '@/components/ui/pagination.vue'; | ||||
| import XMessage from './messaging-room.message.vue'; | ||||
| import XForm from './messaging-room.form.vue'; | ||||
| import * as Acct from 'misskey-js/built/acct'; | ||||
|  | @ -52,33 +57,42 @@ import * as symbols from '@/symbols'; | |||
| import { i18n } from '@/i18n'; | ||||
| import { defaultStore } from '@/store'; | ||||
| import { $i } from '@/account'; | ||||
| import { router } from '@/router'; | ||||
| 
 | ||||
| const props = defineProps<{ | ||||
| 	userAcct?: string; | ||||
| 	groupId?: string; | ||||
| }>(); | ||||
| 
 | ||||
| let fetching = $ref(true); | ||||
| let user: Misskey.entities.UserDetailed | null = $ref(null); | ||||
| let group: Misskey.entities.UserGroup | null = $ref(null); | ||||
| let fetchingMoreMessages = $ref(false); | ||||
| let messages = $ref<Misskey.entities.MessagingMessage[]>([]); | ||||
| let existMoreMessages = $ref(false); | ||||
| let connection: Misskey.ChannelConnection<Misskey.Channels['messaging']> | null = $ref(null); | ||||
| let showIndicator = $ref(false); | ||||
| let timer: number | null = $ref(null); | ||||
| const ilObserver = new IntersectionObserver( | ||||
| 	(entries) => entries.some((entry) => entry.isIntersecting) | ||||
| 		&& !fetching | ||||
| 		&& !fetchingMoreMessages | ||||
| 		&& existMoreMessages | ||||
| 		&& fetchMoreMessages() | ||||
| ); | ||||
| 
 | ||||
| let rootEl = $ref<Element>(); | ||||
| let form = $ref<InstanceType<typeof XForm>>(); | ||||
| let loadMore = $ref<HTMLDivElement>(); | ||||
| let pagingComponent = $ref<InstanceType<typeof MkPagination>>(); | ||||
| 
 | ||||
| let fetching = $ref(true); | ||||
| let user: Misskey.entities.UserDetailed | null = $ref(null); | ||||
| let group: Misskey.entities.UserGroup | null = $ref(null); | ||||
| let connection: Misskey.ChannelConnection<Misskey.Channels['messaging']> | null = $ref(null); | ||||
| let showIndicator = $ref(false); | ||||
| let timer: number | null = $ref(null); | ||||
| 
 | ||||
| let pagination: Paging = $computed(() => { | ||||
| 	return { | ||||
| 		endpoint: 'messaging/messages', | ||||
| 		limit: pagingComponent?.more ? 20 : 10, | ||||
| 		params: { | ||||
| 			userId: user ? user.id : undefined, | ||||
| 			groupId: group ? group.id : undefined, | ||||
| 		}, | ||||
| 		reversed: true, | ||||
| 	}; | ||||
| }); | ||||
| 
 | ||||
| const ilObserver = new IntersectionObserver( | ||||
| 	(entries) => entries.some((entry) => entry.isIntersecting) | ||||
| 		&& !fetching | ||||
| 		&& pagingComponent?.more | ||||
| 		&& fetchMoreMessages() | ||||
| ); | ||||
| 
 | ||||
| watch([() => props.userAcct, () => props.groupId], () => { | ||||
| 	if (connection) connection.dispose(); | ||||
|  | @ -94,7 +108,6 @@ async function fetch() { | |||
| 	}); | ||||
| 
 | ||||
| 	connection?.on('message', onMessage); | ||||
| 	connection?.on('read', onRead); | ||||
| 	connection?.on('deleted', onDeleted); | ||||
| 	connection?.on('typers', typers => { | ||||
| 		typers = typers.filter(u => u.id !== $i.id); | ||||
|  | @ -102,7 +115,7 @@ async function fetch() { | |||
| 
 | ||||
| 	document.addEventListener('visibilitychange', onVisibilitychange); | ||||
| 
 | ||||
| 	fetchMessages().then(() => { | ||||
| 	pagingComponent.fetchMoreAhead().then(() => { | ||||
| 		scrollToBottom(); | ||||
| 
 | ||||
| 		// もっと見るの交差検知を発火させないためにfetchは | ||||
|  | @ -149,33 +162,10 @@ function onDrop(e: DragEvent): void { | |||
| 	//#endregion | ||||
| } | ||||
| 
 | ||||
| function fetchMessages() { | ||||
| 	return new Promise<void>((resolve, reject) => { | ||||
| 		const max = existMoreMessages ? 20 : 10; | ||||
| 
 | ||||
| 		os.api('messaging/messages', { | ||||
| 			userId: user ? user.id : undefined, | ||||
| 			groupId: group ? group.id : undefined, | ||||
| 			limit: max + 1, | ||||
| 			untilId: existMoreMessages ? messages[0].id : undefined | ||||
| 		}).then(messages => { | ||||
| 			if (messages.length == max + 1) { | ||||
| 				existMoreMessages = true; | ||||
| 				messages.pop(); | ||||
| 			} else { | ||||
| 				existMoreMessages = false; | ||||
| 			} | ||||
| 
 | ||||
| 			messages.unshift.apply(messages, messages.reverse()); | ||||
| 			resolve(); | ||||
| 		}); | ||||
| 	}); | ||||
| } | ||||
| 
 | ||||
| function fetchMoreMessages() { | ||||
| 	fetchingMoreMessages = true; | ||||
| 	fetchMessages().then(() => { | ||||
| 		fetchingMoreMessages = false; | ||||
| 	fetching = true; | ||||
| 	pagingComponent.fetchMoreAhead().then(() => { | ||||
| 		fetching = false; | ||||
| 	}); | ||||
| } | ||||
| 
 | ||||
|  | @ -184,7 +174,7 @@ function onMessage(message) { | |||
| 
 | ||||
| 	const _isBottom = isBottom(rootEl, 64); | ||||
| 
 | ||||
| 	messages.push(message); | ||||
| 	pagingComponent.append(message); | ||||
| 	if (message.userId != $i.id && !document.hidden) { | ||||
| 		connection?.send('read', { | ||||
| 			id: message.id | ||||
|  | @ -202,31 +192,6 @@ function onMessage(message) { | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| function onRead(x) { | ||||
| 	if (user) { | ||||
| 		if (!Array.isArray(x)) x = [x]; | ||||
| 		for (const id of x) { | ||||
| 			if (messages.some(x => x.id == id)) { | ||||
| 				const exist = messages.map(x => x.id).indexOf(id); | ||||
| 				messages[exist] = { | ||||
| 					...messages[exist], | ||||
| 					isRead: true, | ||||
| 				}; | ||||
| 			} | ||||
| 		} | ||||
| 	} else if (group) { | ||||
| 		for (const id of x.ids) { | ||||
| 			if (messages.some(x => x.id == id)) { | ||||
| 				const exist = messages.map(x => x.id).indexOf(id); | ||||
| 				messages[exist] = { | ||||
| 					...messages[exist], | ||||
| 					reads: [...messages[exist].reads, x.userId] | ||||
| 				}; | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| function onDeleted(id) { | ||||
| 	const msg = messages.find(m => m.id === id); | ||||
| 	if (msg) { | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue