chore(client): tweak ui
This commit is contained in:
		| @@ -12,106 +12,81 @@ | ||||
| </button> | ||||
| </template> | ||||
|  | ||||
| <script lang="ts"> | ||||
| import { computed, defineComponent, onMounted, ref, watch } from 'vue'; | ||||
| <script lang="ts" setup> | ||||
| import { computed, onMounted, ref, watch } from 'vue'; | ||||
| import * as misskey from 'misskey-js'; | ||||
| import XDetails from '@/components/reactions-viewer.details.vue'; | ||||
| import XReactionIcon from '@/components/reaction-icon.vue'; | ||||
| import * as os from '@/os'; | ||||
| import { useTooltip } from '@/scripts/use-tooltip'; | ||||
| import { $i } from '@/account'; | ||||
|  | ||||
| export default defineComponent({ | ||||
| 	components: { | ||||
| 		XReactionIcon | ||||
| 	}, | ||||
| const props = defineProps<{ | ||||
| 	reaction: string; | ||||
| 	count: number; | ||||
| 	isInitial: boolean; | ||||
| 	note: misskey.entities.Note; | ||||
| }>(); | ||||
|  | ||||
| 	props: { | ||||
| 		reaction: { | ||||
| 			type: String, | ||||
| 			required: true, | ||||
| 		}, | ||||
| 		count: { | ||||
| 			type: Number, | ||||
| 			required: true, | ||||
| 		}, | ||||
| 		isInitial: { | ||||
| 			type: Boolean, | ||||
| 			required: true, | ||||
| 		}, | ||||
| 		note: { | ||||
| 			type: Object, | ||||
| 			required: true, | ||||
| 		}, | ||||
| 	}, | ||||
| const buttonRef = ref<HTMLElement>(); | ||||
|  | ||||
| 	setup(props) { | ||||
| 		const buttonRef = ref<HTMLElement>(); | ||||
| const canToggle = computed(() => !props.reaction.match(/@\w/) && $i); | ||||
|  | ||||
| 		const canToggle = computed(() => !props.reaction.match(/@\w/) && $i); | ||||
| const toggleReaction = () => { | ||||
| 	if (!canToggle.value) return; | ||||
|  | ||||
| 		const toggleReaction = () => { | ||||
| 			if (!canToggle.value) return; | ||||
|  | ||||
| 			const oldReaction = props.note.myReaction; | ||||
| 			if (oldReaction) { | ||||
| 				os.api('notes/reactions/delete', { | ||||
| 					noteId: props.note.id | ||||
| 				}).then(() => { | ||||
| 					if (oldReaction !== props.reaction) { | ||||
| 						os.api('notes/reactions/create', { | ||||
| 							noteId: props.note.id, | ||||
| 							reaction: props.reaction | ||||
| 						}); | ||||
| 					} | ||||
| 				}); | ||||
| 			} else { | ||||
| 	const oldReaction = props.note.myReaction; | ||||
| 	if (oldReaction) { | ||||
| 		os.api('notes/reactions/delete', { | ||||
| 			noteId: props.note.id, | ||||
| 		}).then(() => { | ||||
| 			if (oldReaction !== props.reaction) { | ||||
| 				os.api('notes/reactions/create', { | ||||
| 					noteId: props.note.id, | ||||
| 					reaction: props.reaction | ||||
| 					reaction: props.reaction, | ||||
| 				}); | ||||
| 			} | ||||
| 		}; | ||||
|  | ||||
| 		const anime = () => { | ||||
| 			if (document.hidden) return; | ||||
|  | ||||
| 			// TODO: 新しくリアクションが付いたことが視覚的に分かりやすいアニメーション | ||||
| 		}; | ||||
|  | ||||
| 		watch(() => props.count, (newCount, oldCount) => { | ||||
| 			if (oldCount < newCount) anime(); | ||||
| 		}); | ||||
|  | ||||
| 		onMounted(() => { | ||||
| 			if (!props.isInitial) anime(); | ||||
| 	} else { | ||||
| 		os.api('notes/reactions/create', { | ||||
| 			noteId: props.note.id, | ||||
| 			reaction: props.reaction, | ||||
| 		}); | ||||
| 	} | ||||
| }; | ||||
|  | ||||
| 		useTooltip(buttonRef, async (showing) => { | ||||
| 			const reactions = await os.api('notes/reactions', { | ||||
| 				noteId: props.note.id, | ||||
| 				type: props.reaction, | ||||
| 				limit: 11 | ||||
| 			}); | ||||
| const anime = () => { | ||||
| 	if (document.hidden) return; | ||||
|  | ||||
| 			const users = reactions.map(x => x.user); | ||||
| 	// TODO: 新しくリアクションが付いたことが視覚的に分かりやすいアニメーション | ||||
| }; | ||||
|  | ||||
| 			os.popup(XDetails, { | ||||
| 				showing, | ||||
| 				reaction: props.reaction, | ||||
| 				emojis: props.note.emojis, | ||||
| 				users, | ||||
| 				count: props.count, | ||||
| 				targetElement: buttonRef.value, | ||||
| 			}, {}, 'closed'); | ||||
| 		}); | ||||
|  | ||||
| 		return { | ||||
| 			buttonRef, | ||||
| 			canToggle, | ||||
| 			toggleReaction, | ||||
| 		}; | ||||
| 	}, | ||||
| watch(() => props.count, (newCount, oldCount) => { | ||||
| 	if (oldCount < newCount) anime(); | ||||
| }); | ||||
|  | ||||
| onMounted(() => { | ||||
| 	if (!props.isInitial) anime(); | ||||
| }); | ||||
|  | ||||
| useTooltip(buttonRef, async (showing) => { | ||||
| 	const reactions = await os.api('notes/reactions', { | ||||
| 		noteId: props.note.id, | ||||
| 		type: props.reaction, | ||||
| 		limit: 11, | ||||
| 	}); | ||||
|  | ||||
| 	const users = reactions.map(x => x.user); | ||||
|  | ||||
| 	os.popup(XDetails, { | ||||
| 		showing, | ||||
| 		reaction: props.reaction, | ||||
| 		emojis: props.note.emojis, | ||||
| 		users, | ||||
| 		count: props.count, | ||||
| 		targetElement: buttonRef.value, | ||||
| 	}, {}, 'closed'); | ||||
| }, 100); | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
|   | ||||
| @@ -3,6 +3,7 @@ import { Ref, ref, watch, onUnmounted } from 'vue'; | ||||
| export function useTooltip( | ||||
| 	elRef: Ref<HTMLElement | { $el: HTMLElement } | null | undefined>, | ||||
| 	onShow: (showing: Ref<boolean>) => void, | ||||
| 	delay = 300, | ||||
| ): void { | ||||
| 	let isHovering = false; | ||||
|  | ||||
| @@ -40,7 +41,7 @@ export function useTooltip( | ||||
| 		if (isHovering) return; | ||||
| 		if (shouldIgnoreMouseover) return; | ||||
| 		isHovering = true; | ||||
| 		timeoutId = window.setTimeout(open, 300); | ||||
| 		timeoutId = window.setTimeout(open, delay); | ||||
| 	}; | ||||
|  | ||||
| 	const onMouseleave = () => { | ||||
| @@ -54,7 +55,7 @@ export function useTooltip( | ||||
| 		shouldIgnoreMouseover = true; | ||||
| 		if (isHovering) return; | ||||
| 		isHovering = true; | ||||
| 		timeoutId = window.setTimeout(open, 300); | ||||
| 		timeoutId = window.setTimeout(open, delay); | ||||
| 	}; | ||||
|  | ||||
| 	const onTouchend = () => { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 syuilo
					syuilo