Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/polls.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordartcafe <github@dartcafe.de>2021-02-28 01:16:51 +0300
committerdartcafe <github@dartcafe.de>2021-02-28 01:16:51 +0300
commit25df7307ee5374dc076b793177334bb4bd3a0287 (patch)
tree90fb3d167351ba2665829ee8fad09510a617ecd1
parent9a7b8f7b4e41e1dd40d6e7e01939afeac00c25d8 (diff)
load poll list via long poll and remove timed polling
Signed-off-by: dartcafe <github@dartcafe.de>
-rw-r--r--lib/Db/WatchMapper.php11
-rw-r--r--src/js/App.vue19
-rw-r--r--src/js/components/Navigation/Navigation.vue12
-rw-r--r--src/js/mixins/watchPolls.js83
-rw-r--r--src/js/views/Vote.vue9
5 files changed, 69 insertions, 65 deletions
diff --git a/lib/Db/WatchMapper.php b/lib/Db/WatchMapper.php
index 38bf18b9..31b00222 100644
--- a/lib/Db/WatchMapper.php
+++ b/lib/Db/WatchMapper.php
@@ -44,12 +44,11 @@ class WatchMapper extends QBMapper {
$qb->select('*')
->from($this->getTableName())
- ->where(
- $qb->expr()->eq('poll_id', $qb->createNamedParameter($pollId))
- )
- ->andWhere(
- $qb->expr()->gt('updated', $qb->createNamedParameter($offset))
- );
+ ->where($qb->expr()->gt('updated', $qb->createNamedParameter($offset)))
+ ->andWhere($qb->expr()->orX(
+ $qb->expr()->eq('poll_id', $qb->createNamedParameter($pollId)),
+ $qb->expr()->eq('table', $qb->createNamedParameter('polls'))
+ ));
return $this->findEntities($qb);
}
diff --git a/src/js/App.vue b/src/js/App.vue
index a1ec59c2..b9c64d1e 100644
--- a/src/js/App.vue
+++ b/src/js/App.vue
@@ -51,6 +51,7 @@ import './assets/scss/colors.scss'
// import './assets/scss/colors-dark.scss'
import './assets/scss/transitions.scss'
import './assets/scss/experimental.scss'
+import { watchPolls } from './mixins/watchPolls'
export default {
name: 'App',
@@ -62,13 +63,14 @@ export default {
SideBar,
},
+ mixins: [watchPolls],
+
data() {
return {
sideBarOpen: (window.innerWidth > 920),
activeTab: 'comments',
transitionClass: 'transitions-active',
loading: false,
- reloadInterval: 30000,
}
},
@@ -95,6 +97,7 @@ export default {
watch: {
$route(to, from) {
+ this.watchPollsRestart()
this.loadPoll()
},
},
@@ -105,11 +108,13 @@ export default {
if (this.$route.name !== 'publicVote') {
this.updatePolls()
}
- if (this.$route.params.id && !this.$oute.params.token) {
+ if (this.$route.params.id && !this.$route.params.token) {
this.loadPoll(true)
}
}
+ this.watchPolls()
+
subscribe('transitions-off', (delay) => {
this.transitionsOff(delay)
})
@@ -141,12 +146,10 @@ export default {
}
})
-
- this.timedReload()
},
beforeDestroy() {
- window.clearInterval(this.reloadTimer)
+ this.cancelToken.cancel()
unsubscribe('load-poll')
unsubscribe('update-polls')
unsubscribe('toggle-sidebar')
@@ -159,12 +162,6 @@ export default {
this.transitionClass = 'transitions-active'
},
- timedReload() {
- this.reloadTimer = window.setInterval(() => {
- this.updatePolls()
- }, this.reloadInterval)
- },
-
transitionsOff(delay) {
this.transitionClass = ''
if (delay) {
diff --git a/src/js/components/Navigation/Navigation.vue b/src/js/components/Navigation/Navigation.vue
index f57c12c2..e3a4b651 100644
--- a/src/js/components/Navigation/Navigation.vue
+++ b/src/js/components/Navigation/Navigation.vue
@@ -72,7 +72,6 @@ export default {
return {
showSettingsDlg: false,
createDlg: false,
- reloadInterval: 30000,
pollCategories: [
{
id: 'relevant',
@@ -124,10 +123,6 @@ export default {
},
},
- created() {
- this.timedReload()
- },
-
beforeDestroy() {
window.clearInterval(this.reloadTimer)
},
@@ -137,13 +132,6 @@ export default {
this.createDlg = false
},
- timedReload() {
- // reload poll list periodically
- this.reloadTimer = window.setInterval(() => {
- emit('update-polls')
- }, this.reloadInterval)
- },
-
toggleCreateDlg() {
this.createDlg = !this.createDlg
if (this.createDlg) {
diff --git a/src/js/mixins/watchPolls.js b/src/js/mixins/watchPolls.js
index 9d71e6a7..9d8916d0 100644
--- a/src/js/mixins/watchPolls.js
+++ b/src/js/mixins/watchPolls.js
@@ -3,22 +3,33 @@ import axios from '@nextcloud/axios'
import { generateUrl } from '@nextcloud/router'
export const watchPolls = {
+ data() {
+ return {
+ cancelToken: null,
+ restart: false,
+ watching: true,
+ lastUpdated: Math.round(Date.now() / 1000),
+ }
+ },
+
methods: {
+ watchPollsRestart() {
+ this.restart = true
+ this.cancelToken.cancel()
+ },
+
async watchPolls() {
console.debug('polls', 'Watch for updates')
-
this.cancelToken = axios.CancelToken.source()
- let endPoint = 'apps/polls'
-
- if (this.$route.name === 'publicVote') {
- endPoint = endPoint + '/s/' + this.$route.params.token
- } else if (this.$route.name === 'vote') {
- endPoint = endPoint + '/poll/' + this.$route.params.id
- } else {
- this.watching = false
- }
while (this.watching) {
+ let endPoint = 'apps/polls'
+ if (this.$route.name === 'publicVote') {
+ endPoint = endPoint + '/s/' + this.$route.params.token
+ } else {
+ endPoint = endPoint + '/poll/' + (this.$route.params.id ?? 0)
+ }
+
try {
const response = await axios.get(generateUrl(endPoint + '/watch'), {
params: { offset: this.lastUpdated },
@@ -30,45 +41,63 @@ export const watchPolls = {
response.data.updates.forEach((item) => {
this.lastUpdated = (item.updated > this.lastUpdated) ? item.updated : this.lastUpdated
+ // an updated poll table is reported
if (item.table === 'polls') {
- dispatches.push('poll/get')
+ if (this.$route.name !== 'publicVote') {
+ // load poll list only, when not in public poll
+ dispatches.push('polls/load')
+ }
+ if (item.pollId === parseInt(this.$route.params.id)) {
+ // if current poll is affected, load current poll configuration
+ dispatches.push('poll/get')
+ }
} else {
+ // a table of the current poll was reported, load
+ // corresponding stores
dispatches.push(item.table + '/list')
}
})
+
+ // execute all loads within one promise
const requests = dispatches.map(dispatches => this.$store.dispatch(dispatches))
await Promise.all(requests)
this.watching = true
- } catch (error) {
+ } catch (e) {
this.watching = false
- if (axios.isCancel(error)) {
- console.debug('Watch canceld')
- } else if (error.response) {
-
- if (error.response.status === 304) {
-
+ if (axios.isCancel(e)) {
+ if (this.restart) {
+ console.debug('restart watch')
this.watching = true
+ this.restart = false
+ this.cancelToken = axios.CancelToken.source()
+ } else {
+ console.debug('Watch canceled')
+ this.watching = true
+ this.restart = false
+ return
+ }
+ } else if (e.response) {
- } else if (error.response.status === 503) {
-
+ if (e.response.status === 304) {
+ this.watching = true
+ continue
+ } else if (e.response.status === 503) {
console.debug('Server not available, reconnect watch in 30 sec')
await new Promise(resolve => setTimeout(resolve, 30000))
this.watching = true
-
+ continue
} else {
-
- console.error('Unhandled error watching polls', error)
-
+ console.error('Unhandled error watching polls', e)
+ return
}
- } else if (error.request) {
-
+ } else if (e.request) {
console.debug('Watch aborted')
this.watching = true
-
+ return
}
}
}
diff --git a/src/js/views/Vote.vue b/src/js/views/Vote.vue
index 0871dde5..fa5295d6 100644
--- a/src/js/views/Vote.vue
+++ b/src/js/views/Vote.vue
@@ -111,7 +111,6 @@ import PublicRegisterModal from '../components/Base/PublicRegisterModal'
import PublicEmail from '../components/Base/PublicEmail'
import Subscription from '../components/Subscription/Subscription'
import VoteTable from '../components/VoteTable/VoteTable'
-import { watchPolls } from '../mixins/watchPolls'
export default {
name: 'Vote',
@@ -131,19 +130,14 @@ export default {
VoteTable,
},
- mixins: [watchPolls],
-
data() {
return {
- cancelToken: null,
delay: 50,
isLoading: false,
manualViewDatePoll: '',
manualViewTextPoll: '',
ranked: false,
voteSaved: false,
- watching: true,
- lastUpdated: Math.round(Date.now() / 1000),
}
},
@@ -303,12 +297,9 @@ export default {
} else {
emit('toggle-sidebar', { open: (window.innerWidth > 920) })
}
- this.watchPolls()
},
beforeDestroy() {
- console.debug('destroy votes')
- this.cancelToken.cancel()
this.$store.dispatch({ type: 'poll/reset' })
},