fix: apply copilot reviews / remove listeners on unmount

This commit is contained in:
kakkokari-gtyih 2026-01-15 00:44:17 +09:00
parent c8d8d92d82
commit 96e11c1b08
2 changed files with 47 additions and 17 deletions

View File

@ -44,6 +44,19 @@ const pullDistance = ref(0);
let startScreenY: number | null = null; let startScreenY: number | null = null;
let moveBySystemCancel: (() => void) | null = null; let moveBySystemCancel: (() => void) | null = null;
let moveBySystemRafId: number | null = null;
const onMouseMove = (event: MouseEvent) => moving(event);
const onMouseUp = () => {
window.removeEventListener('mousemove', onMouseMove);
onPullRelease();
};
const onTouchMove = (event: TouchEvent) => moving(event);
const onTouchEnd = () => {
window.removeEventListener('touchmove', onTouchMove);
onPullRelease();
};
const rootEl = useTemplateRef('rootEl'); const rootEl = useTemplateRef('rootEl');
let scrollEl: HTMLElement | null = null; let scrollEl: HTMLElement | null = null;
@ -99,11 +112,8 @@ function moveStartByMouse(event: MouseEvent) {
startScreenY = getScreenY(event); startScreenY = getScreenY(event);
pullDistance.value = 0; pullDistance.value = 0;
window.addEventListener('mousemove', moving, { passive: true }); window.addEventListener('mousemove', onMouseMove, { passive: true });
window.addEventListener('mouseup', () => { window.addEventListener('mouseup', onMouseUp, { passive: true, once: true });
window.removeEventListener('mousemove', moving);
onPullRelease();
}, { passive: true, once: true });
} }
function moveStartByTouch(event: TouchEvent) { function moveStartByTouch(event: TouchEvent) {
@ -121,11 +131,8 @@ function moveStartByTouch(event: TouchEvent) {
startScreenY = getScreenY(event); startScreenY = getScreenY(event);
pullDistance.value = 0; pullDistance.value = 0;
window.addEventListener('touchmove', moving, { passive: true }); window.addEventListener('touchmove', onTouchMove, { passive: true });
window.addEventListener('touchend', () => { window.addEventListener('touchend', onTouchEnd, { passive: true, once: true });
window.removeEventListener('touchmove', moving);
onPullRelease();
}, { passive: true, once: true });
} }
function moveBySystem(to: number): Promise<void> { function moveBySystem(to: number): Promise<void> {
@ -143,14 +150,18 @@ function moveBySystem(to: number): Promise<void> {
return; return;
} }
let startTime: number | null = null; let startTime: DOMHighResTimeStamp | null = null;
let cancelled = false; let cancelled = false;
moveBySystemCancel = () => { moveBySystemCancel = () => {
cancelled = true; cancelled = true;
startTime = null; startTime = null;
if (moveBySystemRafId != null) {
window.cancelAnimationFrame(moveBySystemRafId);
moveBySystemRafId = null;
}
}; };
const tick = (now: number) => { const tick = (now: DOMHighResTimeStamp) => {
if (cancelled) { if (cancelled) {
r(); r();
return; return;
@ -163,26 +174,27 @@ function moveBySystem(to: number): Promise<void> {
if (time >= RELEASE_TRANSITION_DURATION) { if (time >= RELEASE_TRANSITION_DURATION) {
pullDistance.value = to; pullDistance.value = to;
moveBySystemCancel = null; moveBySystemCancel = null;
moveBySystemRafId = null;
r(); r();
return; return;
} }
const nextHeight = startHeight - (overHeight / RELEASE_TRANSITION_DURATION) * time; const nextHeight = startHeight - (overHeight / RELEASE_TRANSITION_DURATION) * time;
if (overHeight > 0) { if (overHeight > 0) {
if (pullDistance.value < nextHeight) { if (pullDistance.value < nextHeight) {
window.requestAnimationFrame(tick); moveBySystemRafId = window.requestAnimationFrame(tick);
return; return;
} }
} else { } else {
if (pullDistance.value > nextHeight) { if (pullDistance.value > nextHeight) {
window.requestAnimationFrame(tick); moveBySystemRafId = window.requestAnimationFrame(tick);
return; return;
} }
} }
pullDistance.value = nextHeight; pullDistance.value = nextHeight;
window.requestAnimationFrame(tick); moveBySystemRafId = window.requestAnimationFrame(tick);
}; };
window.requestAnimationFrame(tick); moveBySystemRafId = window.requestAnimationFrame(tick);
}); });
} }
@ -266,6 +278,14 @@ onMounted(() => {
}); });
onUnmounted(() => { onUnmounted(() => {
if (moveBySystemCancel != null) {
moveBySystemCancel();
moveBySystemCancel = null;
}
moveBySystemRafId = null;
// pullwindow
window.removeEventListener('mousemove', onMouseMove);
window.removeEventListener('touchmove', onTouchMove);
unlockDownScroll(); unlockDownScroll();
if (rootEl.value) rootEl.value.removeEventListener('mousedown', moveStartByMouse); if (rootEl.value) rootEl.value.removeEventListener('mousedown', moveStartByMouse);
if (rootEl.value) rootEl.value.removeEventListener('touchstart', moveStartByTouch); if (rootEl.value) rootEl.value.removeEventListener('touchstart', moveStartByTouch);

View File

@ -27,7 +27,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</div> </div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { ref, useTemplateRef, computed, watch } from 'vue'; import { ref, useTemplateRef, computed, watch, onUnmounted } from 'vue';
import type { Tab } from '@/components/global/MkPageHeader.tabs.vue'; import type { Tab } from '@/components/global/MkPageHeader.tabs.vue';
import { isHorizontalSwipeSwiping as isSwiping } from '@/utility/touch.js'; import { isHorizontalSwipeSwiping as isSwiping } from '@/utility/touch.js';
import { prefer } from '@/preferences.js'; import { prefer } from '@/preferences.js';
@ -122,6 +122,16 @@ function cancelMoveBySystem() {
} }
} }
onUnmounted(() => {
// pullDistance
if (rafId != null) {
window.cancelAnimationFrame(rafId);
rafId = null;
}
pendingPullDistance = null;
cancelMoveBySystem();
});
function moveBySystem(to: number, duration = RELEASE_TRANSITION_DURATION): Promise<void> { function moveBySystem(to: number, duration = RELEASE_TRANSITION_DURATION): Promise<void> {
cancelMoveBySystem(); cancelMoveBySystem();