summaryrefslogtreecommitdiff
path: root/packages/frontend/src/ui/_common_
diff options
context:
space:
mode:
authorsyuilo <Syuilotan@yahoo.co.jp>2023-01-01 11:57:37 +0900
committersyuilo <Syuilotan@yahoo.co.jp>2023-01-01 11:57:37 +0900
commit86e88647fde9ae555fd5d8bc6943cbc421342460 (patch)
tree0b2f81496a45746a6281f05bef7f2ada8a394f68 /packages/frontend/src/ui/_common_
parent:art: (diff)
downloadmisskey-86e88647fde9ae555fd5d8bc6943cbc421342460.tar.gz
misskey-86e88647fde9ae555fd5d8bc6943cbc421342460.tar.bz2
misskey-86e88647fde9ae555fd5d8bc6943cbc421342460.zip
:art:
Diffstat (limited to 'packages/frontend/src/ui/_common_')
-rw-r--r--packages/frontend/src/ui/_common_/common.vue72
-rw-r--r--packages/frontend/src/ui/_common_/notification.vue24
2 files changed, 90 insertions, 6 deletions
diff --git a/packages/frontend/src/ui/_common_/common.vue b/packages/frontend/src/ui/_common_/common.vue
index 7f3fc0e4af..0333e20d0a 100644
--- a/packages/frontend/src/ui/_common_/common.vue
+++ b/packages/frontend/src/ui/_common_/common.vue
@@ -9,6 +9,10 @@
<XUpload v-if="uploads.length > 0"/>
+<TransitionGroup :name="$store.state.animation ? 'notification' : ''" tag="div" class="notifications">
+ <XNotification v-for="notification in notifications" :key="notification.id" :notification="notification" class="notification"/>
+</TransitionGroup>
+
<XStreamIndicator/>
<div v-if="pendingApiRequestsCount > 0" id="wait"></div>
@@ -19,8 +23,10 @@
</template>
<script lang="ts" setup>
-import { defineAsyncComponent } from 'vue';
+import { defineAsyncComponent, nextTick } from 'vue';
+import * as misskey from 'misskey-js';
import { swInject } from './sw-inject';
+import XNotification from './notification.vue';
import { popup, popups, pendingApiRequestsCount } from '@/os';
import { uploads } from '@/scripts/upload';
import * as sound from '@/scripts/sound';
@@ -33,7 +39,9 @@ const XUpload = defineAsyncComponent(() => import('./upload.vue'));
const dev = _DEV_;
-const onNotification = notification => {
+let notifications = $ref<misskey.entities.Notification[]>([]);
+
+function onNotification(notification) {
if ($i.mutingNotificationTypes.includes(notification.type)) return;
if (document.visibilityState === 'visible') {
@@ -41,13 +49,18 @@ const onNotification = notification => {
id: notification.id,
});
- popup(defineAsyncComponent(() => import('@/components/MkNotificationToast.vue')), {
- notification,
- }, {}, 'closed');
+ notifications.unshift(notification);
+ window.setTimeout(() => {
+ if (notifications.length > 3) notifications.pop();
+ }, 500);
+
+ window.setTimeout(() => {
+ notifications = notifications.filter(x => x.id !== notification.id);
+ }, 6000);
}
sound.play('notification');
-};
+}
if ($i) {
const connection = stream.useChannel('main', null, 'UI');
@@ -60,6 +73,53 @@ if ($i) {
}
</script>
+<style lang="scss" scoped>
+.notification-move, .notification-enter-active, .notification-leave-active {
+ transition: opacity 0.3s, transform 0.3s !important;
+}
+.notification-enter-from, .notification-leave-to {
+ opacity: 0;
+ transform: translateX(-250px);
+}
+
+.notifications {
+ position: fixed;
+ z-index: 3900000;
+ left: 0;
+ width: 250px;
+ top: 32px;
+ padding: 0 32px;
+ pointer-events: none;
+ container-type: inline-size;
+
+ > .notification {
+ & + .notification {
+ margin-top: 8px;
+ }
+ }
+
+ @media (max-width: 700px) {
+ top: initial;
+ bottom: 112px;
+ padding: 0 16px;
+ display: flex;
+ flex-direction: column-reverse;
+
+ > .notification {
+ & + .notification {
+ margin-top: 0;
+ margin-bottom: 8px;
+ }
+ }
+ }
+
+ @media (max-width: 500px) {
+ bottom: calc(env(safe-area-inset-bottom, 0px) + 92px);
+ padding: 0 8px;
+ }
+}
+</style>
+
<style lang="scss">
@keyframes dev-ticker-blink {
0% { opacity: 1; }
diff --git a/packages/frontend/src/ui/_common_/notification.vue b/packages/frontend/src/ui/_common_/notification.vue
new file mode 100644
index 0000000000..1f9c675a15
--- /dev/null
+++ b/packages/frontend/src/ui/_common_/notification.vue
@@ -0,0 +1,24 @@
+<template>
+<div :class="$style.root">
+ <XNotification :notification="notification" class="notification _acrylic"/>
+</div>
+</template>
+
+<script lang="ts" setup>
+import { } from 'vue';
+import * as misskey from 'misskey-js';
+import XNotification from '@/components/MkNotification.vue';
+
+defineProps<{
+ notification: misskey.entities.Notification;
+}>();
+</script>
+
+<style lang="scss" module>
+.root {
+ box-shadow: 0 4px 16px rgba(0, 0, 0, 0.3);
+ border-radius: 8px;
+ overflow: clip;
+ contain: content;
+}
+</style>