feat: center dialogs vertically

This commit is contained in:
pa
2025-08-27 21:04:20 +09:00
committed by Natsumi
parent 475c7f4f9c
commit 5e4430e311
12 changed files with 83 additions and 12 deletions
@@ -1,5 +1,5 @@
<template> <template>
<safe-dialog class="x-dialog" :visible.sync="fullscreenImageDialog.visible" append-to-body top="1vh" width="97vw"> <safe-dialog class="x-dialog" :visible.sync="fullscreenImageDialog.visible" append-to-body width="97vw">
<div> <div>
<div style="margin: 0 0 5px 5px"> <div style="margin: 0 0 5px 5px">
<el-button <el-button
-1
View File
@@ -4,7 +4,6 @@
:visible="galleryDialogVisible" :visible="galleryDialogVisible"
:title="t('dialog.gallery_icons.header')" :title="t('dialog.gallery_icons.header')"
width="97vw" width="97vw"
top="5vh"
append-to-body append-to-body
@close="closeGalleryDialog"> @close="closeGalleryDialog">
<el-tabs type="card" ref="galleryTabs"> <el-tabs type="card" ref="galleryTabs">
@@ -4,7 +4,6 @@
:visible.sync="groupDialog.visible" :visible.sync="groupDialog.visible"
:show-close="false" :show-close="false"
width="770px" width="770px"
top="10vh"
class="x-dialog x-group-dialog"> class="x-dialog x-group-dialog">
<div class="group-banner-image"> <div class="group-banner-image">
<el-popover placement="right" width="500px" trigger="click"> <el-popover placement="right" width="500px" trigger="click">
@@ -4,7 +4,6 @@
:visible.sync="groupMemberModeration.visible" :visible.sync="groupMemberModeration.visible"
:title="t('dialog.group_member_moderation.header')" :title="t('dialog.group_member_moderation.header')"
append-to-body append-to-body
top="5vh"
width="90vw"> width="90vw">
<div> <div>
<h3>{{ groupMemberModeration.groupRef.name }}</h3> <h3>{{ groupMemberModeration.groupRef.name }}</h3>
+81
View File
@@ -36,6 +36,9 @@
const elDialogRef = ref(null); const elDialogRef = ref(null);
const wrapperElement = ref(null); const wrapperElement = ref(null);
const mouseDownOnWrapper = ref(false); const mouseDownOnWrapper = ref(false);
const styleObserver = ref(null);
const resizeObserver = ref(null);
let handleResize = null;
const handleOpen = () => { const handleOpen = () => {
emit('open'); emit('open');
@@ -43,6 +46,7 @@
nextTick(() => { nextTick(() => {
addWrapperListeners(); addWrapperListeners();
removeTitleAttribute(); removeTitleAttribute();
centerDialog();
}); });
}; };
@@ -56,6 +60,22 @@
const handleClose = () => { const handleClose = () => {
emit('close'); emit('close');
removeWrapperListeners(); removeWrapperListeners();
if (styleObserver.value) {
styleObserver.value.disconnect();
styleObserver.value = null;
}
if (resizeObserver.value) {
resizeObserver.value.disconnect();
resizeObserver.value = null;
}
if (handleResize) {
window.removeEventListener('resize', handleResize);
handleResize = null;
}
emit('update:visible', false); emit('update:visible', false);
}; };
@@ -98,7 +118,68 @@
mouseDownOnWrapper.value = false; mouseDownOnWrapper.value = false;
}; };
const centerDialog = () => {
const wrapper = elDialogRef.value?.$el;
if (!wrapper) return;
const dialog = wrapper.querySelector('.el-dialog');
if (!dialog) return;
const applyCenterStyle = () => {
const dialogHeight = dialog.offsetHeight;
const viewportHeight = window.innerHeight;
let marginTop;
if (dialogHeight >= viewportHeight) {
marginTop = '25px';
} else {
const topOffset = Math.max(0, (viewportHeight - dialogHeight) / 2);
marginTop = `${topOffset}px`;
}
dialog.style.setProperty('margin-top', marginTop, 'important');
};
applyCenterStyle();
styleObserver.value = new MutationObserver(() => {
applyCenterStyle();
});
styleObserver.value.observe(dialog, {
attributes: true,
attributeFilter: ['style']
});
handleResize = () => {
applyCenterStyle();
};
window.addEventListener('resize', handleResize);
resizeObserver.value = new ResizeObserver(() => {
applyCenterStyle();
});
resizeObserver.value.observe(dialog);
};
onBeforeUnmount(() => { onBeforeUnmount(() => {
removeWrapperListeners(); removeWrapperListeners();
if (styleObserver.value) {
styleObserver.value.disconnect();
styleObserver.value = null;
}
if (resizeObserver.value) {
resizeObserver.value.disconnect();
resizeObserver.value = null;
}
if (handleResize) {
window.removeEventListener('resize', handleResize);
handleResize = null;
}
}); });
</script> </script>
@@ -4,8 +4,7 @@
class="x-dialog x-user-dialog" class="x-dialog x-user-dialog"
:visible.sync="userDialog.visible" :visible.sync="userDialog.visible"
:show-close="false" :show-close="false"
width="770px" width="770px">
top="10vh">
<div v-loading="userDialog.loading"> <div v-loading="userDialog.loading">
<div style="display: flex"> <div style="display: flex">
<el-popover <el-popover
@@ -4,7 +4,6 @@
:visible.sync="isVisible" :visible.sync="isVisible"
:title="t('dialog.world_import.header')" :title="t('dialog.world_import.header')"
width="650px" width="650px"
top="10vh"
class="x-dialog"> class="x-dialog">
<div style="display: flex; align-items: center; justify-content: space-between"> <div style="display: flex; align-items: center; justify-content: space-between">
<div style="font-size: 12px">{{ t('dialog.world_import.description') }}</div> <div style="font-size: 12px">{{ t('dialog.world_import.description') }}</div>
@@ -4,7 +4,6 @@
:visible="changeLogDialog.visible" :visible="changeLogDialog.visible"
:title="t('dialog.change_log.header')" :title="t('dialog.change_log.header')"
width="800px" width="800px"
top="5vh"
append-to-body append-to-body
@close="closeDialog"> @close="closeDialog">
<div v-loading="!changeLogDialog.changeLog" class="changelog-dialog"> <div v-loading="!changeLogDialog.changeLog" class="changelog-dialog">
@@ -3,7 +3,6 @@
:visible="!!feedFiltersDialogMode" :visible="!!feedFiltersDialogMode"
:title="dialogTitle" :title="dialogTitle"
width="550px" width="550px"
top="5vh"
destroy-on-close destroy-on-close
@close="handleDialogClose"> @close="handleDialogClose">
<div class="toggle-list" style="height: 75vh; overflow-y: auto"> <div class="toggle-list" style="height: 75vh; overflow-y: auto">
@@ -4,7 +4,6 @@
:visible="isVRChatConfigDialogVisible" :visible="isVRChatConfigDialogVisible"
:title="t('dialog.config_json.header')" :title="t('dialog.config_json.header')"
width="420px" width="420px"
top="10vh"
@close="closeDialog"> @close="closeDialog">
<div v-loading="loading"> <div v-loading="loading">
<div style="font-size: 12px; word-break: keep-all"> <div style="font-size: 12px; word-break: keep-all">
@@ -4,7 +4,6 @@
:visible="visible" :visible="visible"
:title="t('dialog.group_calendar.header')" :title="t('dialog.group_calendar.header')"
:show-close="false" :show-close="false"
top="10vh"
width="90vw" width="90vw"
height="80vh" height="80vh"
@close="closeDialog"> @close="closeDialog">
@@ -4,7 +4,6 @@
:visible="isScreenshotMetadataDialogVisible" :visible="isScreenshotMetadataDialogVisible"
:title="t('dialog.screenshot_metadata.header')" :title="t('dialog.screenshot_metadata.header')"
width="1050px" width="1050px"
top="10vh"
@close="closeDialog"> @close="closeDialog">
<div <div
v-loading="screenshotMetadataDialog.loading" v-loading="screenshotMetadataDialog.loading"