From 6c10588e77a0b328e33330e39f34756a3157ac7b Mon Sep 17 00:00:00 2001 From: syuilo <Syuilotan@yahoo.co.jp> Date: Tue, 3 Jan 2023 10:46:56 +0900 Subject: [PATCH] refactor(client): refactor and performance improve of MkSpacer --- .../frontend/src/components/form/folder.vue | 6 +- .../src/components/global/MkSpacer.vue | 93 ++++--------------- packages/frontend/src/ui/classic.vue | 2 +- packages/frontend/src/ui/deck/column.vue | 2 +- 4 files changed, 24 insertions(+), 79 deletions(-) diff --git a/packages/frontend/src/components/form/folder.vue b/packages/frontend/src/components/form/folder.vue index 49d3bf93e1..40bbc97002 100644 --- a/packages/frontend/src/components/form/folder.vue +++ b/packages/frontend/src/components/form/folder.vue @@ -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 { diff --git a/packages/frontend/src/components/global/MkSpacer.vue b/packages/frontend/src/components/global/MkSpacer.vue index 88c1daaf23..1ddb230bd6 100644 --- a/packages/frontend/src/components/global/MkSpacer.vue +++ b/packages/frontend/src/components/global/MkSpacer.vue @@ -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> diff --git a/packages/frontend/src/ui/classic.vue b/packages/frontend/src/ui/classic.vue index ba9120a77d..280e69e7dd 100644 --- a/packages/frontend/src/ui/classic.vue +++ b/packages/frontend/src/ui/classic.vue @@ -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と決め打ちしているのを直す diff --git a/packages/frontend/src/ui/deck/column.vue b/packages/frontend/src/ui/deck/column.vue index 0b8d6afe55..775bdf6c1e 100644 --- a/packages/frontend/src/ui/deck/column.vue +++ b/packages/frontend/src/ui/deck/column.vue @@ -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;