refactor(client): refactor and performance improve of MkSpacer
This commit is contained in:
		
							parent
							
								
									2184240ef1
								
							
						
					
					
						commit
						6c10588e77
					
				
					 4 changed files with 24 additions and 79 deletions
				
			
		|  | @ -1,5 +1,5 @@ | |||
| <template> | ||||
| <div class="dwzlatin" :class="{ opened }" ref="root"> | ||||
| <div class="dwzlatin" :class="{ opened }"> | ||||
| 	<div class="header _button" @click="toggle"> | ||||
| 		<span class="icon"><slot name="icon"></slot></span> | ||||
| 		<span class="text"><slot name="label"></slot></span> | ||||
|  | @ -19,7 +19,7 @@ | |||
| 		> | ||||
| 			<KeepAlive> | ||||
| 				<div v-show="opened"> | ||||
| 					<MkSpacer :margin-min="14" :margin-max="22" :container="root"> | ||||
| 					<MkSpacer :margin-min="14" :margin-max="22"> | ||||
| 						<slot></slot> | ||||
| 					</MkSpacer> | ||||
| 				</div> | ||||
|  | @ -40,7 +40,6 @@ const props = withDefaults(defineProps<{ | |||
| 
 | ||||
| let opened = $ref(props.defaultOpen); | ||||
| let openedAtLeastOnce = $ref(props.defaultOpen); | ||||
| let root = $shallowRef<HTMLElement>(); | ||||
| 
 | ||||
| function enter(el) { | ||||
| 	const elementHeight = el.getBoundingClientRect().height; | ||||
|  | @ -142,6 +141,7 @@ function toggle() { | |||
| 	> .body { | ||||
| 		background: var(--panel); | ||||
| 		border-radius: 0 0 6px 6px; | ||||
| 		container-type: inline-size; | ||||
| 	} | ||||
| 
 | ||||
| 	&.opened { | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| <template> | ||||
| <div ref="root" :class="$style.root" :style="{ padding: margin + 'px' }"> | ||||
| 	<div ref="content" :class="$style.content"> | ||||
| <div :class="[$style.root, { [$style.rootMin]: forceSpacerMin }]"> | ||||
| 	<div :class="$style.content"> | ||||
| 		<slot></slot> | ||||
| 	</div> | ||||
| </div> | ||||
|  | @ -14,84 +14,13 @@ const props = withDefaults(defineProps<{ | |||
| 	contentMax?: number | null; | ||||
| 	marginMin?: number; | ||||
| 	marginMax?: number; | ||||
| 
 | ||||
| 	// MkFolderとかで開閉アニメーションの際にheightを正しく伝えるため | ||||
| 	container?: HTMLElement, | ||||
| }>(), { | ||||
| 	contentMax: null, | ||||
| 	marginMin: 12, | ||||
| 	marginMax: 24, | ||||
| }); | ||||
| 
 | ||||
| let ro: ResizeObserver; | ||||
| let root = $shallowRef<HTMLElement>(); | ||||
| let content = $shallowRef<HTMLElement>(); | ||||
| let margin = $ref(props.marginMin); | ||||
| const widthHistory = [null, null] as [number | null, number | null]; | ||||
| const heightHistory = [null, null] as [number | null, number | null]; | ||||
| const shouldSpacerMin = inject('shouldSpacerMin', false); | ||||
| 
 | ||||
| const adjust = (rect: { width: number; height: number; }) => { | ||||
| 	if (shouldSpacerMin || deviceKind === 'smartphone') { | ||||
| 		margin = props.marginMin; | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	if (rect.width > (props.contentMax ?? 0) || (rect.width > 360 && window.innerWidth > 400)) { | ||||
| 		margin = props.marginMax; | ||||
| 	} else { | ||||
| 		margin = props.marginMin; | ||||
| 	} | ||||
| }; | ||||
| 
 | ||||
| if (props.container) { | ||||
| 	const width = props.container.offsetWidth; | ||||
| 	const height = props.container.offsetHeight; | ||||
| 	adjust({ | ||||
| 		width, | ||||
| 		height, | ||||
| 	}); | ||||
| } | ||||
| 
 | ||||
| onMounted(() => { | ||||
| 	ro = new ResizeObserver((entries) => { | ||||
| 		/* iOSが対応していない | ||||
| 		adjust({ | ||||
| 			width: entries[0].borderBoxSize[0].inlineSize, | ||||
| 			height: entries[0].borderBoxSize[0].blockSize, | ||||
| 		}); | ||||
| 		*/ | ||||
| 
 | ||||
| 		const width = props.container ? props.container.offsetWidth : root!.offsetWidth; | ||||
| 		const height = props.container ? props.container.offsetHeight : root!.offsetHeight; | ||||
| 
 | ||||
| 		//#region Prevent infinite resizing | ||||
| 		// https://github.com/misskey-dev/misskey/issues/9076 | ||||
| 		const pastWidth = widthHistory.pop(); | ||||
| 		widthHistory.unshift(width); | ||||
| 		const pastHeight = heightHistory.pop(); | ||||
| 		heightHistory.unshift(height); | ||||
| 
 | ||||
| 		if (pastWidth === width && pastHeight === height) { | ||||
| 			return; | ||||
| 		} | ||||
| 		//#endregion | ||||
| 
 | ||||
| 		adjust({ | ||||
| 			width, | ||||
| 			height, | ||||
| 		}); | ||||
| 	}); | ||||
| 	ro.observe(root!); | ||||
| 
 | ||||
| 	if (props.contentMax) { | ||||
| 		content!.style.maxWidth = `${props.contentMax}px`; | ||||
| 	} | ||||
| }); | ||||
| 
 | ||||
| onUnmounted(() => { | ||||
| 	ro.disconnect(); | ||||
| }); | ||||
| const forceSpacerMin = inject('forceSpacerMin', false) || deviceKind === 'smartphone'; | ||||
| </script> | ||||
| 
 | ||||
| <style lang="scss" module> | ||||
|  | @ -99,9 +28,25 @@ onUnmounted(() => { | |||
| 	box-sizing: border-box; | ||||
| 	width: 100%; | ||||
| } | ||||
| .rootMin { | ||||
| 	padding: v-bind('props.marginMin + "px"') !important; | ||||
| } | ||||
| 
 | ||||
| .content { | ||||
| 	margin: 0 auto; | ||||
| 	max-width: v-bind('props.contentMax + "px"'); | ||||
| 	container-type: inline-size; | ||||
| } | ||||
| 
 | ||||
| @container (max-width: 360px) { | ||||
| 	.root { | ||||
| 		padding: v-bind('props.marginMin + "px"'); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| @container (min-width: 361px) { | ||||
| 	.root { | ||||
| 		padding: v-bind('props.marginMax + "px"'); | ||||
| 	} | ||||
| } | ||||
| </style> | ||||
|  |  | |||
|  | @ -76,7 +76,7 @@ provideMetadataReceiver((info) => { | |||
| 	} | ||||
| }); | ||||
| provide('shouldHeaderThin', showMenuOnTop); | ||||
| provide('shouldSpacerMin', true); | ||||
| provide('forceSpacerMin', true); | ||||
| 
 | ||||
| function attachSticky(el) { | ||||
| 	const sticky = new StickySidebar(el, defaultStore.state.menuDisplay === 'top' ? 0 : 16, defaultStore.state.menuDisplay === 'top' ? 60 : 0); // TODO: ヘッダーの高さを60pxと決め打ちしているのを直す | ||||
|  |  | |||
|  | @ -40,7 +40,7 @@ import { MenuItem } from '@/types/menu'; | |||
| 
 | ||||
| provide('shouldHeaderThin', true); | ||||
| provide('shouldOmitHeaderTitle', true); | ||||
| provide('shouldSpacerMin', true); | ||||
| provide('forceSpacerMin', true); | ||||
| 
 | ||||
| const props = withDefaults(defineProps<{ | ||||
| 	column: Column; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue