Skip to content
Merged
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
55 changes: 37 additions & 18 deletions js/notifications-main.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion js/notifications-main.js.map

Large diffs are not rendered by default.

83 changes: 77 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,12 @@
"dependencies": {
"@juliushaertl/vue-richtext": "^0.3.3",
"@nextcloud/axios": "^1.4.0",
"@nextcloud/browser-storage": "^0.1.1",
"@nextcloud/dialogs": "^2.0.1",
"@nextcloud/event-bus": "^1.2.0",
"@nextcloud/moment": "^1.1.1",
"@nextcloud/router": "^1.2.0",
"@nextcloud/vue": "^2.6.4",
"@nextcloud/vue": "^2.6.5",
"core-js": "^3.6.5",
"regenerator-runtime": "^0.13.7",
"vue": "^2.6.12",
Expand Down
105 changes: 50 additions & 55 deletions src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,10 @@
<script>
import Notification from './Components/Notification'
import axios from '@nextcloud/axios'
import { subscribe } from '@nextcloud/event-bus'
import { subscribe, unsubscribe } from '@nextcloud/event-bus'
import { showError } from '@nextcloud/dialogs'
import { imagePath, generateOcsUrl } from '@nextcloud/router'
import { getNotificationsData } from './services/notificationsService'

export default {
name: 'App',
Expand All @@ -72,7 +73,9 @@ export default {
shutdown: false,
notifications: [],
lastETag: null,
lastTabId: null,
userStatus: null,
tabId: null,

/** @type {number} */
pollInterval: 30000, // milliseconds
Expand Down Expand Up @@ -106,10 +109,12 @@ export default {
return this.backgroundFetching
&& this.webNotificationsGranted
&& this.userStatus !== 'dnd'
&& this.tabId !== this.lastTabId
},
},

mounted() {
this.tabId = OC.requestToken || ('' + Math.random())
this._$icon = $(this.$refs.icon)

// Bind the button click event
Expand All @@ -123,14 +128,13 @@ export default {
// Setup the background checker
this.setupBackgroundFetcher()

subscribe('networkOffline', () => {
this._shutDownNotifications(true)
})
subscribe('networkOnline', () => {
this._fetch()
this._setPollingInterval(30000)
this.setupBackgroundFetcher()
})
subscribe('networkOffline', this.handleNetworkOffline)
subscribe('networkOnline', this.handleNetworkOnline)
},

beforeDestroy() {
unsubscribe('networkOffline', this.handleNetworkOffline)
unsubscribe('networkOnline', this.handleNetworkOnline)
},

updated() {
Expand All @@ -148,9 +152,19 @@ export default {
},

methods: {
handleNetworkOffline() {
this._setPollingInterval(300000)
},

handleNetworkOnline() {
this._fetch()
this._setPollingInterval(30000)
this.setupBackgroundFetcher()
},

setupBackgroundFetcher() {
if (OC.config.session_keepalive) {
this.interval = setInterval(this._backgroundFetch.bind(this), this.pollInterval)
this.interval = window.setInterval(this._backgroundFetch.bind(this), this.pollInterval)
}
},

Expand Down Expand Up @@ -207,52 +221,33 @@ export default {
/**
* Performs the AJAX request to retrieve the notifications
*/
_fetch() {
let requestConfig = {}
if (this.lastETag) {
requestConfig = {
headers: {
'If-None-Match': this.lastETag,
},
}
async _fetch() {
const response = await getNotificationsData(this.tabId, this.lastETag, !this.backgroundFetching)

if (response.status === 204) {
// 204 No Content - Intercept when no notifiers are there.
this._setPollingInterval(300000)
} else if (response.status === 200) {
this.userStatus = response.headers['x-nextcloud-user-status']
this.lastETag = response.headers.etag
this.lastTabId = response.lastTabId
this.notifications = response.data
this._setPollingInterval(30000)
} else if (response.status === 304) {
// 304 - Not modified
this._setPollingInterval(30000)
} else if (response.status === 503) {
// 503 - Maintenance mode
console.info('Slowing down notifications: instance is in maintenance mode.')
this._setPollingInterval(300000)
} else if (response.status === 404) {
// 404 - App disabled
console.info('Slowing down notifications: app is disabled.')
this._setPollingInterval(300000)
} else {
console.info('Slowing down notifications: Status ' + response.status)
this._setPollingInterval(300000)
}

axios
.get(generateOcsUrl('apps/notifications/api/v2', 2) + 'notifications', requestConfig)
.then(response => {
if (response.status === 204) {
// 204 No Content - Intercept when no notifiers are there.
this._setPollingInterval(300000)
return
} else if (response.data !== undefined && response.data.ocs !== undefined && response.data.ocs.data !== undefined && Array.isArray(response.data.ocs.data)) {
this.userStatus = response.headers['x-nextcloud-user-status']
this.lastETag = response.headers.etag
this.notifications = response.data.ocs.data
} else {
console.info('data.ocs.data is undefined or not an array')
}

this._setPollingInterval(30000)
})
.catch(err => {
if (!err.response) {
console.info('No response received, retrying')
return
} else if (err.response.status === 304) {
// 304 - Not modified
return
} else if (err.response.status === 503) {
// 503 - Maintenance mode
console.info('Slowing down notifications: instance is in maintenance mode.')
} else if (err.response.status === 404) {
// 404 - App disabled
console.info('Slowing down notifications: app is disabled.')
} else {
console.info('Slowing down notifications: [' + err.response.status + '] ' + err.response.statusText)
}

this._setPollingInterval(300000)
})
},

_backgroundFetch() {
Expand Down
9 changes: 7 additions & 2 deletions src/Components/Notification.vue
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ import Tooltip from '@nextcloud/vue/dist/Directives/Tooltip'
import { showError } from '@nextcloud/dialogs'
import Action from './Action'
import { generateOcsUrl } from '@nextcloud/router'
import moment from '@nextcloud/moment'
import RichText from '@juliushaertl/vue-richtext'
import DefaultParameter from './Parameters/DefaultParameter'
import File from './Parameters/File'
Expand Down Expand Up @@ -168,10 +169,14 @@ export default {
return (new Date(this.datetime)).valueOf()
},
absoluteDate() {
return OC.Util.formatDate(this.timestamp, 'LLL')
return moment(this.timestamp).format('LLL')
},
relativeDate() {
return OC.Util.relativeModifiedDate(this.timestamp)
const diff = moment().diff(moment(this.timestamp))
if (diff >= 0 && diff < 45000) {
return t('core', 'seconds ago')
}
return moment(this.timestamp).fromNow()
},
useLink() {
if (!this.link) {
Expand Down
23 changes: 23 additions & 0 deletions src/services/BrowserStorage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/**
* @copyright Copyright (c) 2020 Joas Schilling <coding@schilljs.com>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/

import { getBuilder } from '@nextcloud/browser-storage'

export default getBuilder('notifications').clearOnLogout().persist().build()
Loading