Skip to content

Commit 8760da5

Browse files
committed
refactor(notifications): improved performance
Some small refactors + a performance improvement via the usage of the new useTimeConditionally. Previously a setInterval timer was running all the time, now it's interval is configurable and it only runs when there are timeoutable notifications that aren't paused.
1 parent eb36efe commit 8760da5

2 files changed

Lines changed: 20 additions & 11 deletions

File tree

src/runtime/components/LibNotifications/LibNotifications.vue

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@
5454
-mx-[calc(var(--spacing)*2+2px)]
5555
rounded-none
5656
"
57-
:progress="100 - (((notification.isPaused ? (notification._timer.elapsedBeforePause): (notification._timer.elapsedBeforePause + (time - notification.startTime))) / notification.timeout) * 100)"
57+
:progress="calculateNotificationProgress(notification, time!)"
5858
/>
5959
</template>
6060
</lib-notification>
@@ -136,11 +136,13 @@ import {
136136
AlertDialogRoot,
137137
AlertDialogTitle
138138
} from "reka-ui"
139-
import { computed, ref } from "vue"
139+
import { computed } from "vue"
140140
141+
import { calculateNotificationProgress } from "./calculateNotificationProgress.js"
141142
import LibNotification from "./LibNotification.vue"
142143
143144
import { useNotificationHandler } from "../../composables/useNotificationHandler.js"
145+
import { useTimeConditionally } from "../../composables/useTimeConditionally.js"
144146
import { NotificationHandler } from "../../helpers/NotificationHandler.js"
145147
import { twMerge } from "../../utils/twMerge.js"
146148
import LibProgressBar from "../LibProgressBar/LibProgressBar.vue"
@@ -153,18 +155,16 @@ defineOptions({
153155
154156
const props = defineProps<Props>()
155157
158+
const handler = props.handler ?? useNotificationHandler()
159+
156160
const topNotifications = computed(() => handler.queue.filter(entry => entry.requiresAction).reverse())
157161
const notifications = computed(() => handler.queue.filter(entry => !entry.requiresAction))
158162
159-
const time = ref(Date.now())
160-
setInterval(() => {
161-
requestAnimationFrame(() => {
162-
time.value = Date.now()
163-
})
164-
}, 50)
165-
163+
const fetchTime = computed(() => {
164+
return notifications.value.filter(entry => entry.timeout !== undefined && !entry.isPaused).length > 0
165+
})
166166
167-
const handler = props.handler ?? useNotificationHandler()
167+
const { time } = useTimeConditionally(fetchTime, { refreshInterval: props.progressUpdateInterval })
168168
</script>
169169

170170
<script lang="ts">
@@ -173,8 +173,9 @@ import type { HTMLAttributes } from "vue"
173173
type RealProps
174174
= & LinkableByIdProps
175175
& {
176-
/** If not provided, uses the global handler (this requires useNotificationHandler be called and configured). */
176+
/** If not provided, uses the global handler (this requires useNotificationHandler be called and configured). */
177177
handler?: NotificationHandler
178+
progressUpdateInterval?: number
178179
}
179180
180181
interface Props
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import type { NotificationEntry } from "../../helpers/NotificationHandler.js"
2+
3+
export function calculateNotificationProgress(notification: NotificationEntry, time: number) {
4+
if (notification.timeout === undefined) return 0
5+
6+
return 100 - (((notification.isPaused ? (notification._timer.elapsedBeforePause) : (notification._timer.elapsedBeforePause + (time - notification.startTime))) / notification.timeout) * 100)
7+
}
8+

0 commit comments

Comments
 (0)