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

View File

@@ -1,5 +1,5 @@
<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 style="margin: 0 0 5px 5px">
<el-button

View File

@@ -4,7 +4,6 @@
:visible="galleryDialogVisible"
:title="t('dialog.gallery_icons.header')"
width="97vw"
top="5vh"
append-to-body
@close="closeGalleryDialog">
<el-tabs type="card" ref="galleryTabs">

View File

@@ -4,7 +4,6 @@
:visible.sync="groupDialog.visible"
:show-close="false"
width="770px"
top="10vh"
class="x-dialog x-group-dialog">
<div class="group-banner-image">
<el-popover placement="right" width="500px" trigger="click">

View File

@@ -4,7 +4,6 @@
:visible.sync="groupMemberModeration.visible"
:title="t('dialog.group_member_moderation.header')"
append-to-body
top="5vh"
width="90vw">
<div>
<h3>{{ groupMemberModeration.groupRef.name }}</h3>

View File

@@ -36,6 +36,9 @@
const elDialogRef = ref(null);
const wrapperElement = ref(null);
const mouseDownOnWrapper = ref(false);
const styleObserver = ref(null);
const resizeObserver = ref(null);
let handleResize = null;
const handleOpen = () => {
emit('open');
@@ -43,6 +46,7 @@
nextTick(() => {
addWrapperListeners();
removeTitleAttribute();
centerDialog();
});
};
@@ -56,6 +60,22 @@
const handleClose = () => {
emit('close');
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);
};
@@ -98,7 +118,68 @@
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(() => {
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>

View File

@@ -4,8 +4,7 @@
class="x-dialog x-user-dialog"
:visible.sync="userDialog.visible"
:show-close="false"
width="770px"
top="10vh">
width="770px">
<div v-loading="userDialog.loading">
<div style="display: flex">
<el-popover

View File

@@ -4,7 +4,6 @@
:visible.sync="isVisible"
:title="t('dialog.world_import.header')"
width="650px"
top="10vh"
class="x-dialog">
<div style="display: flex; align-items: center; justify-content: space-between">
<div style="font-size: 12px">{{ t('dialog.world_import.description') }}</div>

View File

@@ -4,7 +4,6 @@
:visible="changeLogDialog.visible"
:title="t('dialog.change_log.header')"
width="800px"
top="5vh"
append-to-body
@close="closeDialog">
<div v-loading="!changeLogDialog.changeLog" class="changelog-dialog">

View File

@@ -3,7 +3,6 @@
:visible="!!feedFiltersDialogMode"
:title="dialogTitle"
width="550px"
top="5vh"
destroy-on-close
@close="handleDialogClose">
<div class="toggle-list" style="height: 75vh; overflow-y: auto">

View File

@@ -4,7 +4,6 @@
:visible="isVRChatConfigDialogVisible"
:title="t('dialog.config_json.header')"
width="420px"
top="10vh"
@close="closeDialog">
<div v-loading="loading">
<div style="font-size: 12px; word-break: keep-all">

View File

@@ -4,7 +4,6 @@
:visible="visible"
:title="t('dialog.group_calendar.header')"
:show-close="false"
top="10vh"
width="90vw"
height="80vh"
@close="closeDialog">

View File

@@ -4,7 +4,6 @@
:visible="isScreenshotMetadataDialogVisible"
:title="t('dialog.screenshot_metadata.header')"
width="1050px"
top="10vh"
@close="closeDialog">
<div
v-loading="screenshotMetadataDialog.loading"