diff --git a/CHANGELOG.md b/CHANGELOG.md index 1e38d7e63c..13c2876a82 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -42,6 +42,7 @@ You should also include the user name that made the change. - Client: Implement the button to subscribe push notification @tamaina - Client: Implement the toggle to or not to close push notifications when notifications or messages are read @tamaina - Client: show Unicode emoji tooltip with its name in MkReactionsViewer.reaction @saschanaz +- Client: improve overall performance of client @syuilo ### Bugfixes - Server: 引用内の文章がnyaizeされてしまう問題を修正 @kabo2468 diff --git a/packages/client/src/components/MkContainer.vue b/packages/client/src/components/MkContainer.vue index c097946c19..6d4d5be2bc 100644 --- a/packages/client/src/components/MkContainer.vue +++ b/packages/client/src/components/MkContainer.vue @@ -246,6 +246,17 @@ export default defineComponent({ } } +@container (max-width: 380px) { + .ukygtjoj { + > header { + > .title { + padding: 8px 10px; + font-size: 0.9em; + } + } + } +} + ._forceContainerFull_ .ukygtjoj { > header { > .title { diff --git a/packages/client/src/components/MkDateSeparatedList.vue b/packages/client/src/components/MkDateSeparatedList.vue index 68903f3526..1f88bdf137 100644 --- a/packages/client/src/components/MkDateSeparatedList.vue +++ b/packages/client/src/components/MkDateSeparatedList.vue @@ -108,6 +108,8 @@ export default defineComponent({ <style lang="scss"> .sqadhkmv { + container-type: inline-size; + > *:empty { display: none; } diff --git a/packages/client/src/components/MkNote.vue b/packages/client/src/components/MkNote.vue index 1feb161ada..a4100e1f2c 100644 --- a/packages/client/src/components/MkNote.vue +++ b/packages/client/src/components/MkNote.vue @@ -433,6 +433,8 @@ function readPromo() { min-width: 0; > .body { + container-type: inline-size; + > .cw { cursor: default; display: block; @@ -573,8 +575,10 @@ function readPromo() { > .reply { border-top: solid 0.5px var(--divider); } +} - &.max-width_500px { +@container (max-width: 500px) { + .tkcbzcuz { font-size: 0.9em; > .article { @@ -584,8 +588,10 @@ function readPromo() { } } } +} - &.max-width_450px { +@container (max-width: 450px) { + .tkcbzcuz { > .renote { padding: 8px 16px 0 16px; } @@ -605,8 +611,10 @@ function readPromo() { } } } +} - &.max-width_350px { +@container (max-width: 350px) { + .tkcbzcuz { > .article { > .main { > .footer { @@ -619,8 +627,10 @@ function readPromo() { } } } +} - &.max-width_300px { +@container (max-width: 300px) { + .tkcbzcuz { > .article { > .avatar { width: 44px; diff --git a/packages/client/src/components/MkNoteDetailed.vue b/packages/client/src/components/MkNoteDetailed.vue index 8269906bb0..7ce8e039d9 100644 --- a/packages/client/src/components/MkNoteDetailed.vue +++ b/packages/client/src/components/MkNoteDetailed.vue @@ -444,6 +444,8 @@ if (appearNote.replyId) { > .main { > .body { + container-type: inline-size; + > .cw { cursor: default; display: block; @@ -601,6 +603,72 @@ if (appearNote.replyId) { } } +@container (max-width: 500px) { + .lxwezrsl { + font-size: 0.9em; + } +} + +@container (max-width: 450px) { + .lxwezrsl { + > .renote { + padding: 8px 16px 0 16px; + } + + > .article { + padding: 16px; + + > .header { + > .avatar { + width: 50px; + height: 50px; + } + } + } + } +} + +@container (max-width: 350px) { + .lxwezrsl { + > .article { + > .main { + > .footer { + > .button { + &:not(:last-child) { + margin-right: 18px; + } + } + } + } + } + } +} + +@container (max-width: 300px) { + .lxwezrsl { + font-size: 0.825em; + + > .article { + > .header { + > .avatar { + width: 50px; + height: 50px; + } + } + + > .main { + > .footer { + > .button { + &:not(:last-child) { + margin-right: 12px; + } + } + } + } + } + } +} + .muted { padding: 8px; text-align: center; diff --git a/packages/client/src/components/MkNotePreview.vue b/packages/client/src/components/MkNotePreview.vue index a78b499654..0c81059091 100644 --- a/packages/client/src/components/MkNotePreview.vue +++ b/packages/client/src/components/MkNotePreview.vue @@ -89,4 +89,24 @@ const props = defineProps<{ } } } + +@container (min-width: 350px) { + .fefdfafb { + > .avatar { + margin: 0 10px 0 0; + width: 44px; + height: 44px; + } + } +} + +@container (min-width: 500px) { + .fefdfafb { + > .avatar { + margin: 0 12px 0 0; + width: 48px; + height: 48px; + } + } +} </style> diff --git a/packages/client/src/components/MkNoteSimple.vue b/packages/client/src/components/MkNoteSimple.vue index 1bbbe0e1a6..96d29831d2 100644 --- a/packages/client/src/components/MkNoteSimple.vue +++ b/packages/client/src/components/MkNoteSimple.vue @@ -96,4 +96,24 @@ const showContent = $ref(false); } } } + +@container (min-width: 350px) { + .yohlumlk { + > .avatar { + margin: 0 10px 0 0; + width: 44px; + height: 44px; + } + } +} + +@container (min-width: 500px) { + .yohlumlk { + > .avatar { + margin: 0 12px 0 0; + width: 48px; + height: 48px; + } + } +} </style> diff --git a/packages/client/src/components/MkNoteSub.vue b/packages/client/src/components/MkNoteSub.vue index 95b6b71be9..d03ce7c434 100644 --- a/packages/client/src/components/MkNoteSub.vue +++ b/packages/client/src/components/MkNoteSub.vue @@ -127,4 +127,14 @@ if (props.detail) { padding: 10px 0 0 16px; } } + +@container (max-width: 450px) { + .wrpstxzv { + padding: 14px 16px; + + &.children { + padding: 10px 0 0 8px; + } + } +} </style> diff --git a/packages/client/src/components/MkNotification.vue b/packages/client/src/components/MkNotification.vue index 82965212f3..8b8d3f452d 100644 --- a/packages/client/src/components/MkNotification.vue +++ b/packages/client/src/components/MkNotification.vue @@ -306,4 +306,18 @@ useTooltip(reactionRef, (showing) => { } } } + +@container (max-width: 600px) { + .qglefbjs { + padding: 16px; + font-size: 0.9em; + } +} + +@container (max-width: 500px) { + .qglefbjs { + padding: 12px; + font-size: 0.85em; + } +} </style> diff --git a/packages/client/src/components/MkPostForm.vue b/packages/client/src/components/MkPostForm.vue index eb302ccc96..f79e5a32cd 100644 --- a/packages/client/src/components/MkPostForm.vue +++ b/packages/client/src/components/MkPostForm.vue @@ -990,4 +990,61 @@ onMounted(() => { } } } + +@container (max-width: 500px) { + .gafaadew { + > header { + height: 50px; + + > .cancel { + width: 50px; + line-height: 50px; + } + + > .right { + > .text-count { + line-height: 50px; + } + + > .submit { + margin: 8px; + } + } + } + + > .form { + > .to-specified { + padding: 6px 16px; + } + + > .cw, + > .hashtags, + > .text { + padding: 0 16px; + } + + > .text { + min-height: 80px; + } + + > footer { + padding: 0 8px 8px 8px; + } + } + } +} + +@container (max-width: 310px) { + .gafaadew { + > .form { + > footer { + > button { + font-size: 14px; + width: 44px; + height: 44px; + } + } + } + } +} </style> diff --git a/packages/client/src/components/MkUrlPreview.vue b/packages/client/src/components/MkUrlPreview.vue index ac03559bea..b2d16ddb01 100644 --- a/packages/client/src/components/MkUrlPreview.vue +++ b/packages/client/src/components/MkUrlPreview.vue @@ -313,4 +313,71 @@ onUnmounted(() => { } } } + +@container (max-width: 400px) { + .mk-url-preview { + > .link { + font-size: 12px; + + > .thumbnail { + height: 80px; + } + + > article { + padding: 12px; + } + } + } +} + +@container (max-width: 350px) { + .mk-url-preview { + > .link { + font-size: 10px; + + > .thumbnail { + height: 70px; + } + + > article { + padding: 8px; + + > header { + margin-bottom: 4px; + } + + > footer { + margin-top: 4px; + + > img { + width: 12px; + height: 12px; + } + } + } + + &.compact { + > .thumbnail { + position: absolute; + width: 56px; + height: 100%; + } + + > article { + left: 56px; + width: calc(100% - 56px); + padding: 4px; + + > header { + margin-bottom: 2px; + } + + > footer { + margin-top: 2px; + } + } + } + } + } +} </style> diff --git a/packages/client/src/components/MkWidgets.vue b/packages/client/src/components/MkWidgets.vue index a0c77f91a9..fff89117ce 100644 --- a/packages/client/src/components/MkWidgets.vue +++ b/packages/client/src/components/MkWidgets.vue @@ -111,6 +111,8 @@ function onContextmenu(widget: Widget, ev: MouseEvent) { <style lang="scss" scoped> .vjoppmmu { + container-type: inline-size; + > header { margin: 16px 0; diff --git a/packages/client/src/components/global/MkSpacer.vue b/packages/client/src/components/global/MkSpacer.vue index 53adf07771..c7d53f2ee7 100644 --- a/packages/client/src/components/global/MkSpacer.vue +++ b/packages/client/src/components/global/MkSpacer.vue @@ -72,5 +72,6 @@ onUnmounted(() => { .content { margin: 0 auto; + container-type: inline-size; } </style> diff --git a/packages/client/src/directives/size.ts b/packages/client/src/directives/size.ts index c8f446e3a8..b514f4e38b 100644 --- a/packages/client/src/directives/size.ts +++ b/packages/client/src/directives/size.ts @@ -15,6 +15,8 @@ type ClassOrder = { remove: string[]; }; +const isContainerQueriesSupported = ('container' in document.documentElement.style); + const cache = new Map<string, ClassOrder>(); function getClassOrder(width: number, queue: Value): ClassOrder { @@ -78,6 +80,8 @@ function calc(el: Element) { export default { mounted(src, binding, vn) { + if (isContainerQueriesSupported) return; + const resize = new ResizeObserver((entries, observer) => { calc(src); }); @@ -93,11 +97,15 @@ export default { }, updated(src, binding, vn) { + if (isContainerQueriesSupported) return; + mountings.set(src, Object.assign({}, mountings.get(src), { value: binding.value })); calc(src); }, unmounted(src, binding, vn) { + if (isContainerQueriesSupported) return; + const info = mountings.get(src); if (!info) return; info.resize.disconnect(); diff --git a/packages/client/src/pages/antenna-timeline.vue b/packages/client/src/pages/antenna-timeline.vue index 592131b2a8..0b2c284c99 100644 --- a/packages/client/src/pages/antenna-timeline.vue +++ b/packages/client/src/pages/antenna-timeline.vue @@ -118,4 +118,11 @@ definePageMetadata(computed(() => antenna ? { margin: 0 auto; } } + +@container (min-width: 800px) { + .tqmomfks { + max-width: 800px; + margin: 0 auto; + } +} </style> diff --git a/packages/client/src/pages/messaging/index.vue b/packages/client/src/pages/messaging/index.vue index b4cec5f5e9..0d30998330 100644 --- a/packages/client/src/pages/messaging/index.vue +++ b/packages/client/src/pages/messaging/index.vue @@ -300,4 +300,28 @@ definePageMetadata({ } } } + +@container (max-width: 400px) { + .yweeujhr { + > .history { + > .message { + &:not(.isMe):not(.isRead) { + > div { + background-image: none; + border-left: solid 4px #3aa2dc; + } + } + + > div { + padding: 16px; + font-size: 0.9em; + + > .avatar { + margin: 0 12px 0 0; + } + } + } + } + } +} </style> diff --git a/packages/client/src/pages/messaging/messaging-room.message.vue b/packages/client/src/pages/messaging/messaging-room.message.vue index e7cf54a066..dbf0e37b73 100644 --- a/packages/client/src/pages/messaging/messaging-room.message.vue +++ b/packages/client/src/pages/messaging/messaging-room.message.vue @@ -2,7 +2,7 @@ <div v-size="{ max: [400, 500] }" class="thvuemwp" :class="{ isMe }"> <MkAvatar class="avatar" :user="message.user" :show-indicator="true"/> <div class="content"> - <div class="balloon" :class="{ noText: message.text == null }" > + <div class="balloon" :class="{ noText: message.text == null }"> <button v-if="isMe" class="delete-button" :title="$ts.delete" @click="del"> <img src="/client-assets/remove.png" alt="Delete"/> </button> @@ -331,4 +331,37 @@ function del(): void { } } } + +@container (max-width: 400px) { + .thvuemwp { + > .avatar { + width: 48px; + height: 48px; + } + + > .content { + > .balloon { + > .content { + > .text { + font-size: 0.9em; + } + } + } + } + } +} + +@container (max-width: 500px) { + .thvuemwp { + > .content { + > .balloon { + > .content { + > .text { + padding: 8px 16px; + } + } + } + } + } +} </style> diff --git a/packages/client/src/pages/page.vue b/packages/client/src/pages/page.vue index 7072b8ef03..a95bfe485c 100644 --- a/packages/client/src/pages/page.vue +++ b/packages/client/src/pages/page.vue @@ -3,7 +3,7 @@ <template #header><MkPageHeader :actions="headerActions" :tabs="headerTabs"/></template> <MkSpacer :content-max="700"> <transition :name="$store.state.animation ? 'fade' : ''" mode="out-in"> - <div v-if="page" :key="page.id" v-size="{ max: [450] }" class="xcukqgmh"> + <div v-if="page" :key="page.id" class="xcukqgmh"> <div class="_block main"> <!-- <div class="header"> diff --git a/packages/client/src/pages/user-list-timeline.vue b/packages/client/src/pages/user-list-timeline.vue index aa5c078ab4..fdb3167375 100644 --- a/packages/client/src/pages/user-list-timeline.vue +++ b/packages/client/src/pages/user-list-timeline.vue @@ -111,4 +111,11 @@ definePageMetadata(computed(() => list ? { margin: 0 auto; } } + +@container (min-width: 800px) { + .eqqrhokj { + max-width: 800px; + margin: 0 auto; + } +} </style> diff --git a/packages/client/src/pages/user/home.vue b/packages/client/src/pages/user/home.vue index 55d0aa89a6..43c1b37e1d 100644 --- a/packages/client/src/pages/user/home.vue +++ b/packages/client/src/pages/user/home.vue @@ -475,4 +475,56 @@ onUnmounted(() => { } } } + +@container (max-width: 500px) { + .ftskorzw { + > .main { + > .profile > .main { + > .banner-container { + height: 140px; + + > .fade { + display: none; + } + + > .title { + display: none; + } + } + + > .title { + display: block; + } + + > .avatar { + top: 90px; + left: 0; + right: 0; + width: 92px; + height: 92px; + margin: auto; + } + + > .description { + padding: 16px; + text-align: center; + } + + > .fields { + padding: 16px; + } + + > .status { + padding: 16px; + } + } + + > .contents { + > .nav { + font-size: 80%; + } + } + } + } +} </style>