feat: Improved to clear notifications by swiping sideways or pressing the x button (x button is desktop only), Notification design improved

This commit is contained in:
NoriDev 2022-09-07 22:02:14 +09:00
parent 9d2ad04774
commit 05d445cfbb
2 changed files with 130 additions and 6 deletions

View file

@ -18,6 +18,8 @@
- 클라이언트: 서버와 연결이 끊어졌을 때 경고를 표시하지 않는 옵션 추가
- 클라이언트: 미디어 우클릭 방지 기능 추가
- 클라이언트: welcomeBack 알림에 프로필 아이콘 추가
- 클라이언트: 알림을 옆으로 스와이프 하거나 x 버튼을 눌러(데스크톱 전용) 지울 수 있도록 개선
- 클라이언트: 알림 디자인 개선
<!--
## 12.x.x-cp-2.x.x (unreleased)_legacy

View file

@ -1,13 +1,18 @@
<template>
<div class="mk-notification-toast" :style="{ zIndex }">
<transition :name="$store.state.animation ? 'notification-toast' : ''" appear @after-leave="$emit('closed')">
<XNotification v-if="showing" :notification="notification" class="notification _acrylic"/>
<div v-if="showing" class="notification _acrylic" :style="isMoving ? `transition: none; transform: translateX(${x}px)` : ''" @mousedown="startSwipe" @touchstart="startSwipe">
<XNotification class="inner" :notification="notification"/>
<button class="_button x _shadow" @click="showing = false">
<i class="fas fa-times"></i>
</button>
</div>
</transition>
</div>
</template>
<script lang="ts" setup>
import { onMounted } from 'vue';
import { onMounted, onBeforeUnmount, nextTick } from 'vue';
import XNotification from './notification.vue';
import * as os from '@/os';
@ -20,22 +25,97 @@ const emit = defineEmits<{
}>();
const zIndex = os.claimZIndex('high');
let showing = $ref(true);
let isMoving = $ref(false);
let x = $ref(0);
let currentTimeout = $ref(0);
let previousTouchX = $ref(0);
onMounted(() => {
/*
window.setTimeout(() => {
showing = false;
}, 6000);
*/
autoTimeout();
window.addEventListener('mouseup', endSwipe, { passive: false });
window.addEventListener('touchend', endSwipe, { passive: false });
window.addEventListener('mousemove', onMouseMove, { passive: false });
window.addEventListener('touchmove', onTouchMove, { passive: false });
});
onBeforeUnmount(() => {
window.removeEventListener('mouseup', endSwipe);
window.removeEventListener('touchend', endSwipe);
window.removeEventListener('mousemove', onMouseMove);
window.removeEventListener('touchmove', onTouchMove);
});
function autoTimeout() {
currentTimeout = window.setTimeout(() => {
showing = false;
}, 6000);
}
function clearTimeout() {
window.clearTimeout(currentTimeout);
}
function timeout() {
clearTimeout();
currentTimeout = window.setTimeout(() => {
showing = false;
}, 6000);
}
function onMouseMove(ev: MouseEvent) {
processSwipe(ev.movementX);
}
function onTouchMove(ev: TouchEvent) {
if (previousTouchX === 0) {
previousTouchX = ev.touches[0].clientX;
}
processSwipe(ev.touches[0].clientX - previousTouchX);
previousTouchX = ev.touches[0].clientX;
}
function startSwipe() {
isMoving = true;
clearTimeout();
}
function processSwipe(movementX: number) {
if (!isMoving) return;
x = Math.max(0, x + movementX);
}
function endSwipe() {
isMoving = false;
if (x > 150) {
x = 0;
nextTick(() => showing = false);
} else {
x = 0;
timeout();
}
previousTouchX = 0;
}
</script>
<style lang="scss" scoped>
.notification-toast-enter-active, .notification-toast-leave-active {
transition: opacity 0.3s, transform 0.3s !important;
// transition: opacity 0.3s, transform 0.3s !important;
}
.notification-toast-enter-from, .notification-toast-leave-to {
opacity: 0;
transform: translateX(-250px);
@media (max-width: 850px) {
transform: translateY(-250px);
}
}
.mk-notification-toast {
@ -44,8 +124,9 @@ onMounted(() => {
width: 250px;
top: 32px;
padding: 0 32px;
pointer-events: none;
// pointer-events: none;
/*
@media (max-width: 700px) {
top: initial;
bottom: 112px;
@ -56,12 +137,53 @@ onMounted(() => {
bottom: calc(env(safe-area-inset-bottom, 0px) + 92px);
padding: 0 8px;
}
*/
@media (max-width: 850px) {
top: 10px;
bottom: initial;
padding: 0 8px;
width: 95%;
right: 0;
margin: 0 auto;
}
> .notification {
height: 100%;
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.3);
border-radius: 8px;
overflow: hidden;
border-radius: 12px;
// overflow: hidden;
user-select: none;
transition: opacity 0.5s, transform 0.5s;
padding: 8px;
> .inner {
pointer-events: none;
overflow: hidden;
}
> .x {
position: absolute;
top: -8px;
left: -8px;
width: 24px;
height: 24px;
opacity: 0;
border-radius: 100%;
background: var(--panel);
border: 1px solid var(--divider);
pointer-events: none;
transition: opacity 0.2s ease;
@media (max-width: 1099px) {
display: none;
}
}
&:hover > .x {
opacity: 1;
pointer-events: unset;
}
}
}
</style>