Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 34 additions & 3 deletions src/Components/NotificationItem.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,27 @@
ignoreSeconds
:format="{ timeStyle: 'short', dateStyle: 'long' }"
:timestamp="timestamp" />
<NcActions
v-if="timestamp"
class="notification-snooze-button"
:aria-label="t('notifications', 'Snooze')"
force-menu>

Check failure on line 23 in src/Components/NotificationItem.vue

View workflow job for this annotation

GitHub Actions / NPM lint

Attribute 'force-menu' can't be hyphenated
<template #icon>
<IconClockOutline :size="18" />
</template>
<NcActionButton @click="onSnooze(60)">
<template #icon><IconClockOutline :size="20" /></template>

Check warning on line 28 in src/Components/NotificationItem.vue

View workflow job for this annotation

GitHub Actions / NPM lint

Expected 1 line break before closing tag (`</template>`), but no line breaks found

Check warning on line 28 in src/Components/NotificationItem.vue

View workflow job for this annotation

GitHub Actions / NPM lint

Expected 1 line break after opening tag (`<template>`), but no line breaks found
{{ t('notifications', '1 hour') }}
</NcActionButton>
<NcActionButton @click="onSnooze(4 * 60)">
<template #icon><IconClockOutline :size="20" /></template>

Check warning on line 32 in src/Components/NotificationItem.vue

View workflow job for this annotation

GitHub Actions / NPM lint

Expected 1 line break before closing tag (`</template>`), but no line breaks found

Check warning on line 32 in src/Components/NotificationItem.vue

View workflow job for this annotation

GitHub Actions / NPM lint

Expected 1 line break after opening tag (`<template>`), but no line breaks found
{{ t('notifications', '4 hours') }}
</NcActionButton>
<NcActionButton @click="onSnooze(24 * 60)">
<template #icon><IconClockOutline :size="20" /></template>

Check warning on line 36 in src/Components/NotificationItem.vue

View workflow job for this annotation

GitHub Actions / NPM lint

Expected 1 line break before closing tag (`</template>`), but no line breaks found

Check warning on line 36 in src/Components/NotificationItem.vue

View workflow job for this annotation

GitHub Actions / NPM lint

Expected 1 line break after opening tag (`<template>`), but no line breaks found
{{ t('notifications', 'Tomorrow') }}
</NcActionButton>
</NcActions>
<NcButton
v-if="timestamp"
class="notification-dismiss-button"
Expand Down Expand Up @@ -96,9 +117,12 @@
import { emit } from '@nextcloud/event-bus'
import { t } from '@nextcloud/l10n'
import { generateOcsUrl } from '@nextcloud/router'
import NcActionButton from '@nextcloud/vue/components/NcActionButton'
import NcActions from '@nextcloud/vue/components/NcActions'
import NcButton from '@nextcloud/vue/components/NcButton'
import NcDateTime from '@nextcloud/vue/components/NcDateTime'
import NcRichText from '@nextcloud/vue/components/NcRichText'
import IconClockOutline from 'vue-material-design-icons/ClockOutline.vue'
import IconClose from 'vue-material-design-icons/Close.vue'
import IconMessageOutline from 'vue-material-design-icons/MessageOutline.vue'
import ActionButton from './ActionButton.vue'
Expand Down Expand Up @@ -139,10 +163,13 @@

components: {
ActionButton,
NcButton,
NcDateTime,
IconClockOutline,
IconClose,
IconMessageOutline,
NcActionButton,
NcActions,
NcButton,
NcDateTime,
NcRichText,
},

Expand All @@ -154,7 +181,7 @@
},
},

emits: ['remove'],
emits: ['remove', 'snooze'],

data() {
return {
Expand Down Expand Up @@ -224,6 +251,10 @@
return richParameters
},

onSnooze(minutes) {
this.$emit('snooze', { notification: this.notification, minutes })
},

onClickMessage(e) {
if (e.target.closest('.rich-text--wrapper')) {
// Vue RichText
Expand Down
43 changes: 37 additions & 6 deletions src/NotificationsApp.vue
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@
<template #trigger>
<IconNotification
:size="20"
:showDot="notifications.length !== 0 || webNotificationsGranted === null"
:showDot="visibleNotifications.length !== 0 || webNotificationsGranted === null"
:showWarning="hasThrottledPushNotifications" />
</template>

<!-- Notifications list content -->
<div class="notification-container">
<transition name="fade" mode="out-in">
<transition-group
v-if="notifications.length > 0"
v-if="visibleNotifications.length > 0"
class="notification-wrapper"
name="list"
tag="ul">
Expand All @@ -32,10 +32,11 @@
:key="-2016"
:notification="fairUsePolicyNotification" />
<NotificationItem
v-for="(notification, index) in notifications"
v-for="notification in visibleNotifications"
:key="notification.notificationId"
:notification="notification"
@remove="onRemove(index)" />
@remove="onRemove(notification)"
@snooze="onSnooze" />
</transition-group>

<!-- No notifications -->
Expand Down Expand Up @@ -187,6 +188,9 @@
pushEndpoints: null,

open: false,

/** Map of notificationId → timestamp when the snooze expires */
snoozed: JSON.parse(localStorage.getItem('notifications:snoozed') ?? '{}'),
}
},

Expand Down Expand Up @@ -217,6 +221,11 @@

return ''
},

visibleNotifications() {
const now = Date.now()
return this.notifications.filter(n => (this.snoozed[n.notificationId] ?? 0) <= now)

Check failure on line 227 in src/NotificationsApp.vue

View workflow job for this annotation

GitHub Actions / NPM lint

Expected parentheses around arrow function argument
},
},

mounted() {
Expand Down Expand Up @@ -342,11 +351,31 @@
})
},

onRemove(index) {
this.notifications.splice(index, 1)
onRemove(notification) {
const idx = this.notifications.findIndex(n => n.notificationId === notification.notificationId)

Check failure on line 355 in src/NotificationsApp.vue

View workflow job for this annotation

GitHub Actions / NPM lint

Expected parentheses around arrow function argument
if (idx !== -1) {
this.notifications.splice(idx, 1)
}
setCurrentTabAsActive(this.tabId)
},

onSnooze({ notification, minutes }) {
const wakeAt = Date.now() + minutes * 60 * 1000
this.snoozed = { ...this.snoozed, [notification.notificationId]: wakeAt }
localStorage.setItem('notifications:snoozed', JSON.stringify(this.snoozed))
},

_clearExpiredSnooze() {
const now = Date.now()
const active = Object.fromEntries(

Check failure on line 370 in src/NotificationsApp.vue

View workflow job for this annotation

GitHub Actions / NPM lint

Unexpected newline after '('
Object.entries(this.snoozed).filter(([, wakeAt]) => wakeAt > now),
)

Check failure on line 372 in src/NotificationsApp.vue

View workflow job for this annotation

GitHub Actions / NPM lint

Unexpected newline before ')'
if (Object.keys(active).length !== Object.keys(this.snoozed).length) {
this.snoozed = active
localStorage.setItem('notifications:snoozed', JSON.stringify(active))
}
},

/**
* Update the title to show * if there are new notifications
*
Expand Down Expand Up @@ -404,10 +433,12 @@
this._fetch(true)
},

/**

Check warning on line 436 in src/NotificationsApp.vue

View workflow job for this annotation

GitHub Actions / NPM lint

Missing JSDoc @param "force" declaration
* Performs the AJAX request to retrieve the notifications
*/
async _fetch(force = false) {
this._clearExpiredSnooze()

if (this.notifications.length && this.notifications[0].notificationId > this.webNotificationsThresholdId) {
this.webNotificationsThresholdId = this.notifications[0].notificationId
}
Expand Down
5 changes: 5 additions & 0 deletions src/styles/styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -123,3 +123,8 @@ svg {
}
}
}

// Snooze action menu — keep the clock button subtle and compact
.notification-snooze-button {
margin-inline-end: 2px;
}
Loading