🎨
This commit is contained in:
		
							parent
							
								
									50043047aa
								
							
						
					
					
						commit
						86e88647fd
					
				
					 3 changed files with 90 additions and 74 deletions
				
			
		|  | @ -1,68 +0,0 @@ | |||
| <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"/> | ||||
| 	</Transition> | ||||
| </div> | ||||
| </template> | ||||
| 
 | ||||
| <script lang="ts" setup> | ||||
| import { onMounted } from 'vue'; | ||||
| import XNotification from '@/components/MkNotification.vue'; | ||||
| import * as os from '@/os'; | ||||
| 
 | ||||
| defineProps<{ | ||||
| 	notification: any; // TODO | ||||
| }>(); | ||||
| 
 | ||||
| const emit = defineEmits<{ | ||||
| 	(ev: 'closed'): void; | ||||
| }>(); | ||||
| 
 | ||||
| const zIndex = os.claimZIndex('high'); | ||||
| let showing = $ref(true); | ||||
| 
 | ||||
| onMounted(() => { | ||||
| 	window.setTimeout(() => { | ||||
| 		showing = false; | ||||
| 	}, 6000); | ||||
| }); | ||||
| </script> | ||||
| 
 | ||||
| <style lang="scss" scoped> | ||||
| .notification-toast-enter-active, .notification-toast-leave-active { | ||||
| 	transition: opacity 0.3s, transform 0.3s !important; | ||||
| } | ||||
| .notification-toast-enter-from, .notification-toast-leave-to { | ||||
| 	opacity: 0; | ||||
| 	transform: translateX(-250px); | ||||
| } | ||||
| 
 | ||||
| .mk-notification-toast { | ||||
| 	position: fixed; | ||||
| 	left: 0; | ||||
| 	width: 250px; | ||||
| 	top: 32px; | ||||
| 	padding: 0 32px; | ||||
| 	pointer-events: none; | ||||
| 	container-type: inline-size; | ||||
| 
 | ||||
| 	@media (max-width: 700px) { | ||||
| 		top: initial; | ||||
| 		bottom: 112px; | ||||
| 		padding: 0 16px; | ||||
| 	} | ||||
| 
 | ||||
| 	@media (max-width: 500px) { | ||||
| 		bottom: calc(env(safe-area-inset-bottom, 0px) + 92px); | ||||
| 		padding: 0 8px; | ||||
| 	} | ||||
| 
 | ||||
| 	> .notification { | ||||
| 		height: 100%; | ||||
| 		box-shadow: 0 4px 16px rgba(0, 0, 0, 0.3); | ||||
| 		border-radius: 8px; | ||||
| 		overflow: hidden; | ||||
| 	} | ||||
| } | ||||
| </style> | ||||
|  | @ -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; } | ||||
|  |  | |||
							
								
								
									
										24
									
								
								packages/frontend/src/ui/_common_/notification.vue
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								packages/frontend/src/ui/_common_/notification.vue
									
										
									
									
									
										Normal file
									
								
							|  | @ -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> | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue