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:
authorRené Gieling <github@dartcafe.de>2022-11-01 23:26:59 +0300
committerGitHub <noreply@github.com>2022-11-01 23:26:59 +0300
commit8df58e63e2145b2754e94b0d55b77fc8e8131c7c (patch)
tree6ef6bc19680f1aba4bdaee847d7e879eed64453d
parente1074f3fb59d2fc78f9cc2e62ac4d66b0e2bea2e (diff)
Change watch (#2624)
-rw-r--r--lib/AppInfo/Application.php3
-rw-r--r--lib/Command/Db/Rebuild.php2
-rw-r--r--lib/Db/Watch.php5
-rw-r--r--lib/Db/WatchMapper.php16
-rw-r--r--lib/Middleware/RequestAttributesMiddleware.php37
-rw-r--r--lib/Migration/DeleteInvalidRecords.php9
-rw-r--r--lib/Migration/TableSchema.php8
-rw-r--r--lib/Migration/Version040100Date20221030070000.php (renamed from lib/Migration/Version030400Date20211125120000.php)4
-rw-r--r--lib/Service/WatchService.php25
-rw-r--r--src/js/helpers/AxiosDefault.js31
-rw-r--r--src/js/mixins/watchPolls.js79
-rw-r--r--src/js/store/index.js3
-rw-r--r--src/js/store/modules/activity.js2
-rw-r--r--src/js/store/modules/appSettings.js2
-rw-r--r--src/js/store/modules/combo.js2
-rw-r--r--src/js/store/modules/comments.js2
-rw-r--r--src/js/store/modules/options.js34
-rw-r--r--src/js/store/modules/poll.js53
-rw-r--r--src/js/store/modules/polls.js2
-rw-r--r--src/js/store/modules/pollsAdmin.js4
-rw-r--r--src/js/store/modules/settings.js3
-rw-r--r--src/js/store/modules/share.js2
-rw-r--r--src/js/store/modules/shares.js32
-rw-r--r--src/js/store/modules/subscription.js2
-rw-r--r--src/js/store/modules/votes.js2
25 files changed, 244 insertions, 120 deletions
diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php
index 7d4fe3c8..7466a52a 100644
--- a/lib/AppInfo/Application.php
+++ b/lib/AppInfo/Application.php
@@ -66,6 +66,7 @@ use OCA\Polls\Listener\OptionListener;
use OCA\Polls\Listener\PollListener;
use OCA\Polls\Listener\ShareListener;
use OCA\Polls\Listener\VoteListener;
+use OCA\Polls\Middleware\RequestAttributesMiddleware;
use OCA\Polls\Provider\SearchProvider;
class Application extends App implements IBootstrap {
@@ -83,6 +84,8 @@ class Application extends App implements IBootstrap {
public function register(IRegistrationContext $context): void {
include_once __DIR__ . '/../../vendor/autoload.php';
+ $context->registerMiddleWare(RequestAttributesMiddleware::class);
+
$context->registerEventListener(CommentAddEvent::class, CommentListener::class);
$context->registerEventListener(CommentDeleteEvent::class, CommentListener::class);
$context->registerEventListener(OptionConfirmedEvent::class, OptionListener::class);
diff --git a/lib/Command/Db/Rebuild.php b/lib/Command/Db/Rebuild.php
index 5b19be5d..753a74ef 100644
--- a/lib/Command/Db/Rebuild.php
+++ b/lib/Command/Db/Rebuild.php
@@ -215,7 +215,7 @@ class Rebuild extends Command {
if ($schema->hasTable($tableName)) {
$dropped = true;
$schema->dropTable($tableName);
- $output->writeln('<info> - Dropped' . $tableName .'</info>');
+ $output->writeln('<info> - Dropped ' . $tableName .'</info>');
}
}
$this->connection->migrateToSchema($schema->getWrappedSchema());
diff --git a/lib/Db/Watch.php b/lib/Db/Watch.php
index e1e72d83..6c3d026c 100644
--- a/lib/Db/Watch.php
+++ b/lib/Db/Watch.php
@@ -36,6 +36,8 @@ use OCP\AppFramework\Db\Entity;
* @method void setTable(string $value)
* @method int getUpdated()
* @method void setUpdated(integer $value)
+ * @method int getSessionId()
+ * @method void setSessionId(string $value)
*/
class Watch extends Entity implements JsonSerializable {
public const TABLE = 'polls_watch';
@@ -54,6 +56,9 @@ class Watch extends Entity implements JsonSerializable {
/** @var int $updated */
protected $updated;
+ /** @var string $sessionId */
+ protected $sessionId;
+
public function __construct() {
$this->addType('pollId', 'int');
$this->addType('updated', 'int');
diff --git a/lib/Db/WatchMapper.php b/lib/Db/WatchMapper.php
index 5b92933f..f01c753a 100644
--- a/lib/Db/WatchMapper.php
+++ b/lib/Db/WatchMapper.php
@@ -25,6 +25,7 @@ namespace OCA\Polls\Db;
use OCP\IDBConnection;
use OCP\AppFramework\Db\QBMapper;
+use OCP\ISession;
/**
* @template-extends QBMapper<Watch>
@@ -32,8 +33,15 @@ use OCP\AppFramework\Db\QBMapper;
class WatchMapper extends QBMapper {
public const TABLE = Watch::TABLE;
- public function __construct(IDBConnection $db) {
+ /** @var ISession */
+ protected $session = null;
+
+ public function __construct(
+ IDBConnection $db,
+ ISession $session
+ ) {
parent::__construct($db, self::TABLE, Watch::class);
+ $this->session = $session;
}
/**
@@ -46,6 +54,9 @@ class WatchMapper extends QBMapper {
$qb->select('*')
->from($this->getTableName())
->where($qb->expr()->gt('updated', $qb->createNamedParameter($offset)))
+ ->andWhere(
+ $qb->expr()->neq('session_id', $qb->createNamedParameter(hash('md5', $this->session->get('ncPollsClientId'))))
+ )
->andWhere($qb->expr()->orX(
$qb->expr()->eq('poll_id', $qb->createNamedParameter($pollId)),
$qb->expr()->eq('table', $qb->createNamedParameter('polls'))
@@ -68,6 +79,9 @@ class WatchMapper extends QBMapper {
)
->andWhere(
$qb->expr()->eq('table', $qb->createNamedParameter($table))
+ )
+ ->andWhere(
+ $qb->expr()->eq('session_id', $qb->createNamedParameter(hash('md5', $this->session->get('ncPollsClientId'))))
);
return $this->findEntity($qb);
diff --git a/lib/Middleware/RequestAttributesMiddleware.php b/lib/Middleware/RequestAttributesMiddleware.php
new file mode 100644
index 00000000..83d52e8d
--- /dev/null
+++ b/lib/Middleware/RequestAttributesMiddleware.php
@@ -0,0 +1,37 @@
+<?php
+
+namespace OCA\Polls\Middleware;
+
+use OCP\AppFramework\Middleware;
+use OCP\ISession;
+use OCP\IRequest;
+
+class RequestAttributesMiddleware extends Middleware {
+ private const CLIENT_ID_KEY = 'Nc-Polls-Client-Id';
+
+ /** @var ISession */
+ protected $session;
+
+ /** @var IRequest */
+ protected $request;
+
+ public function __construct(
+ IRequest $request,
+ ISession $session
+ ) {
+ $this->request = $request;
+ $this->session = $session;
+ }
+
+ public function beforeController($controller, $methodName) {
+ $clientId = $this->request->getHeader(self::CLIENT_ID_KEY);
+
+ if (!$clientId) {
+ $clientId = $this->session->getId();
+ }
+
+ if ($clientId) {
+ $this->session->set('ncPollsClientId', $clientId);
+ }
+ }
+}
diff --git a/lib/Migration/DeleteInvalidRecords.php b/lib/Migration/DeleteInvalidRecords.php
index bf5bc6f6..562eae29 100644
--- a/lib/Migration/DeleteInvalidRecords.php
+++ b/lib/Migration/DeleteInvalidRecords.php
@@ -38,6 +38,7 @@ use OCA\Polls\Db\Poll;
use OCA\Polls\Db\ShareMapper;
use OCA\Polls\Db\SubscriptionMapper;
use OCA\Polls\Db\VoteMapper;
+use OCA\Polls\Db\WatchMapper;
/**
* Preparation before migration
@@ -68,6 +69,9 @@ class DeleteInvalidRecords implements IRepairStep {
/** @var VoteMapper */
private $voteMapper;
+ /** @var WatchMapper */
+ private $watchMapper;
+
/** @var array */
protected $childTables = [
CommentMapper::TABLE,
@@ -86,7 +90,8 @@ class DeleteInvalidRecords implements IRepairStep {
PreferencesMapper $preferencesMapper,
ShareMapper $shareMapper,
SubscriptionMapper $subscriptionMapper,
- VoteMapper $voteMapper
+ VoteMapper $voteMapper,
+ WatchMapper $watchMapper
) {
$this->config = $config;
$this->connection = $connection;
@@ -96,6 +101,7 @@ class DeleteInvalidRecords implements IRepairStep {
$this->shareMapper = $shareMapper;
$this->subscriptionMapper = $subscriptionMapper;
$this->voteMapper = $voteMapper;
+ $this->watchMapper = $watchMapper;
}
public function getName():string {
@@ -112,6 +118,7 @@ class DeleteInvalidRecords implements IRepairStep {
$this->shareMapper->removeDuplicates($output);
$this->subscriptionMapper->removeDuplicates($output);
$this->voteMapper->removeDuplicates($output);
+ $this->watchMapper->deleteOldEntries(time());
}
}
diff --git a/lib/Migration/TableSchema.php b/lib/Migration/TableSchema.php
index e7bdecc1..a3901fa6 100644
--- a/lib/Migration/TableSchema.php
+++ b/lib/Migration/TableSchema.php
@@ -62,7 +62,7 @@ abstract class TableSchema {
Share::TABLE => ['name' => 'UNIQ_shares', 'unique' => true, 'columns' => ['poll_id', 'user_id']],
Vote::TABLE => ['name' => 'UNIQ_votes', 'unique' => true, 'columns' => ['poll_id', 'user_id', 'vote_option_text']],
Preferences::TABLE => ['name' => 'UNIQ_preferences', 'unique' => true, 'columns' => ['user_id']],
- Watch::TABLE => ['name' => 'UNIQ_watch', 'unique' => true, 'columns' => ['poll_id', 'table']],
+ Watch::TABLE => ['name' => 'UNIQ_watch', 'unique' => true, 'columns' => ['poll_id', 'table', 'session_id']],
];
/**
@@ -101,12 +101,15 @@ abstract class TableSchema {
'0109Date20210323120002',
'030000Date20210611120000',
'030000Date20210704120000',
+ '030200Date20210912120000',
+ '030400Date20211125120000',
];
/**
* define obsolete tables to drop
*/
public const GONE_TABLES = [
+ 'polls_watch', // always drop the watch table for a clean truncation and rely on recreation
'polls_events', // dropped in 1.0
'polls_dts', // dropped in 0.9
'polls_txts', // dropped in 0.9
@@ -222,6 +225,7 @@ abstract class TableSchema {
'poll_id' => ['type' => Types::INTEGER, 'options' => ['notnull' => true, 'default' => 0]],
'table' => ['type' => Types::STRING, 'options' => ['notnull' => false, 'default' => '', 'length' => 64]],
'updated' => ['type' => Types::INTEGER, 'options' => ['notnull' => true, 'default' => 0]],
+ 'session_id' => ['type' => Types::STRING, 'options' => ['notnull' => false, 'default' => null]],
],
Preferences::TABLE => [
'id' => ['type' => Types::INTEGER, 'options' => ['autoincrement' => true, 'notnull' => true]],
@@ -277,7 +281,7 @@ abstract class TableSchema {
foreach (self::GONE_TABLES as $tableName) {
if ($schema->hasTable($tableName)) {
$schema->dropTable($tableName);
- $output->info('Dropped orphaned table ' . $tableName);
+ $output->info('Dropped table ' . $tableName);
}
}
}
diff --git a/lib/Migration/Version030400Date20211125120000.php b/lib/Migration/Version040100Date20221030070000.php
index e71aadb2..6d9f36ab 100644
--- a/lib/Migration/Version030400Date20211125120000.php
+++ b/lib/Migration/Version040100Date20221030070000.php
@@ -23,12 +23,12 @@
namespace OCA\Polls\Migration;
+use OCA\Polls\Db\Poll;
use OCP\DB\ISchemaWrapper;
use OCP\IConfig;
use OCP\IDBConnection;
use OCP\Migration\SimpleMigrationStep;
use OCP\Migration\IOutput;
-use OCA\Polls\Db\Poll;
/**
* Installation class for the polls app.
@@ -36,7 +36,7 @@ use OCA\Polls\Db\Poll;
* Changed class naming: Version[jjmmpp]Date[YYYYMMDDHHMMSS]
* Version: jj = major version, mm = minor, pp = patch
*/
-class Version030400Date20211125120000 extends SimpleMigrationStep {
+class Version040100Date20221030070000 extends SimpleMigrationStep {
/** @var IDBConnection */
protected $connection;
diff --git a/lib/Service/WatchService.php b/lib/Service/WatchService.php
index 81166a76..c873a5e1 100644
--- a/lib/Service/WatchService.php
+++ b/lib/Service/WatchService.php
@@ -28,11 +28,16 @@ use OCA\Polls\Db\WatchMapper;
use OCA\Polls\Exceptions\NoUpdatesException;
use OCA\Polls\Model\Settings\AppSettings;
use OCP\AppFramework\Db\DoesNotExistException;
+use OCP\DB\Exception;
+use OCP\ISession;
class WatchService {
/** @var AppSettings */
private $appSettings;
+ /** @var ISession */
+ protected $session;
+
/** @var WatchMapper */
private $watchMapper;
@@ -40,11 +45,13 @@ class WatchService {
private $watch;
public function __construct(
+ ISession $session,
WatchMapper $watchMapper
) {
- $this->watchMapper = $watchMapper;
$this->appSettings = new AppSettings;
+ $this->session = $session;
$this->watch = new Watch;
+ $this->watchMapper = $watchMapper;
}
/**
@@ -86,13 +93,19 @@ class WatchService {
* @return Watch
*/
public function writeUpdate(int $pollId, string $table): Watch {
+ $sessionId = hash('md5', $this->session->get('ncPollsClientId'));
+ $this->watch = new Watch();
+ $this->watch->setPollId($pollId);
+ $this->watch->setTable($table);
+ $this->watch->setSessionId($sessionId);
+
try {
- $this->watch = $this->watchMapper->findForPollIdAndTable($pollId, $table);
- } catch (DoesNotExistException $e) {
- $this->watch = new Watch();
- $this->watch->setPollId($pollId);
- $this->watch->setTable($table);
$this->watch = $this->watchMapper->insert($this->watch);
+ } catch (Exception $e) {
+ if ($e->getReason() !== Exception::REASON_UNIQUE_CONSTRAINT_VIOLATION) {
+ throw $e;
+ }
+ $this->watch = $this->watchMapper->findForPollIdAndTable($pollId, $table);
}
$this->watch->setUpdated(time());
diff --git a/src/js/helpers/AxiosDefault.js b/src/js/helpers/AxiosDefault.js
new file mode 100644
index 00000000..834b13e6
--- /dev/null
+++ b/src/js/helpers/AxiosDefault.js
@@ -0,0 +1,31 @@
+/**
+ * @copyright Copyright (c) 2022 Rene Gieling <github@dartcafe.de>
+ *
+ * @author Rene Gieling <github@dartcafe.de>
+ *
+ * @license AGPL-3.0-or-later
+ *
+ * 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/>.
+ *
+ */
+
+const clientSessionId = Math.random().toString(36).substring(2)
+const axiosDefaultConfig = {
+ headers: {
+ Accept: 'application/json',
+ 'Nc-Polls-Client-Id': clientSessionId,
+ },
+}
+
+export default axiosDefaultConfig
diff --git a/src/js/mixins/watchPolls.js b/src/js/mixins/watchPolls.js
index 6f545ec6..4e3b4e6d 100644
--- a/src/js/mixins/watchPolls.js
+++ b/src/js/mixins/watchPolls.js
@@ -26,6 +26,7 @@ import { generateUrl } from '@nextcloud/router'
import { getCurrentUser } from '@nextcloud/auth'
import { mapState } from 'vuex'
import { InvalidJSON } from '../Exceptions/Exceptions.js'
+import axiosDefaultConfig from '../helpers/AxiosDefault.js'
const defaultSleepTimeout = 30
@@ -54,48 +55,45 @@ export const watchPolls = {
methods: {
async watchPolls() {
- // quit if polling for updates is disabled
- if (this.updateType === 'noPolling') {
- return
- }
-
if (this.cancelToken) {
- // there is already a cancelToken, so just cancel the previous session and exit
- this.cancelWatch()
- return
+ this.cancelWatch() // there is already a cancelToken, cancel the previous session
}
- this.cancelToken = axios.CancelToken.source()
+ this.cancelToken = axios.CancelToken.source() // get a new cancel token
while (this.retryCounter < this.maxTries) {
- // Avoid requests, if the tab/window is not visible
- if (!document.hidden) {
- // reset sleep timer to default
- this.sleepTimeout = defaultSleepTimeout
- this.gotValidResponse = false
- await this.$store.dispatch('appSettings/get')
-
- if (this.updateType === 'noPolling') {
- console.debug('[polls]', 'Polling for updates is disabled. Cancel watch.')
- this.cancelWatch()
- return
- }
+ this.sleepTimeout = defaultSleepTimeout // reset sleep timer to default
+ this.gotValidResponse = false
+
+ if (this.updateType === 'noPolling') {
+ // leave if polling is disabled
+ console.debug('[polls]', 'Polling for updates is disabled. Cancel watch.')
+ this.cancelWatch()
+ return
+ }
- try {
- console.debug('[polls]', 'Watch for updates')
- await this.handleResponse(await this.fetchUpdates())
+ // loop while tab is hidden and avoid further requests
+ while (document.hidden) {
+ console.debug('[polls]', 'app is in background')
+ await new Promise((resolve) => setTimeout(resolve, 2000))
+ }
+
+ try {
+ console.debug('[polls]', 'Watch for updates')
+ await this.handleResponse(await this.fetchUpdates())
- } catch (e) {
- if (axios.isCancel(e)) {
- this.handleCanceledRequest()
- } else {
- this.handleConnectionError(e)
- }
+ } catch (e) {
+ if (axios.isCancel(e)) {
+ this.handleCanceledRequest()
+ } else {
+ this.handleConnectionError(e)
}
}
- if (this.updateType !== 'longPolling' || !this.gotValidResponse || document.hidden) {
+ // sleep if request was invalid or polling is set to something else than "longPolling"
+ if (this.updateType !== 'longPolling' || !this.gotValidResponse) {
await this.sleep()
+ console.debug('[polls]', 'continue after sleep')
}
}
@@ -114,11 +112,16 @@ export const watchPolls = {
this.endPoint = `apps/polls/poll/${this.$route.params.id ?? 0}/watch`
}
- return await axios.get(generateUrl(this.endPoint), {
+ await this.$store.dispatch('appSettings/get')
+
+ const response = await axios.get(generateUrl(this.endPoint), {
+ ...axiosDefaultConfig,
params: { offset: this.lastUpdated },
cancelToken: this.cancelToken.token,
- headers: { Accept: 'application/json' },
})
+
+ return response
+
},
cancelWatch() {
@@ -128,9 +131,7 @@ export const watchPolls = {
sleep() {
let reason = `Connection error, Attempt: ${this.retryCounter}/${this.maxTries})`
- if (document.hidden) {
- reason = 'app is in background'
- } else if (this.gotValidResponse) {
+ if (this.gotValidResponse) {
reason = this.updateType
}
@@ -147,7 +148,6 @@ export const watchPolls = {
return
}
- // console.debug('[polls]', `No JSON response recieved, got "${response.headers['content-type']}"`)
this.gotValidResponse = false
throw new InvalidJSON(`No JSON response recieved, got "${response.headers['content-type']}"`)
},
@@ -183,22 +183,25 @@ export const watchPolls = {
async loadTables(tables) {
let dispatches = ['activity/list']
+ console.debug('[polls]', 'fetching updates', tables)
tables.forEach((item) => {
this.lastUpdated = Math.max(item.updated, this.lastUpdated)
-
if (item.table === 'polls') {
if (this.isAdmin) {
+ console.debug('[polls]', 'update admin view', item.table)
// If user is an admin, also load admin list
dispatches = [...dispatches, 'pollsAdmin/list']
}
if (item.pollId === parseInt(this.$route.params.id ?? this.$store.state.share.pollId)) {
// if current poll is affected, load current poll configuration
+ console.debug('[polls]', 'current poll', item.table)
dispatches = [...dispatches, 'poll/get']
}
if (this.isLoggedin) {
// if user is an authorized user load polls list
+ console.debug('[polls]', 'update list', item.table)
dispatches = [...dispatches, `${item.table}/list`]
}
} else if (!this.isLoggedin && (item.table === 'shares')) {
diff --git a/src/js/store/index.js b/src/js/store/index.js
index b815c149..456f5088 100644
--- a/src/js/store/index.js
+++ b/src/js/store/index.js
@@ -27,10 +27,9 @@ import modules from './modules/index.js'
Vue.use(Vuex)
-/* eslint-disable-next-line no-unused-vars */
const debug = process.env.NODE_ENV !== 'production'
export default new Store({
modules,
- strict: process.env.NODE_ENV !== 'production',
+ strict: debug,
})
diff --git a/src/js/store/modules/activity.js b/src/js/store/modules/activity.js
index ee924caa..b8ec60bd 100644
--- a/src/js/store/modules/activity.js
+++ b/src/js/store/modules/activity.js
@@ -23,6 +23,7 @@
import axios from '@nextcloud/axios'
import { generateOcsUrl } from '@nextcloud/router'
+import axiosDefaultConfig from '../../helpers/AxiosDefault.js'
const defaultActivities = () => ({
list: [],
@@ -30,7 +31,6 @@ const defaultActivities = () => ({
const namespaced = true
const state = defaultActivities()
-const axiosDefaultConfig = { headers: { Accept: 'application/json' } }
const mutations = {
set(state, payload) {
diff --git a/src/js/store/modules/appSettings.js b/src/js/store/modules/appSettings.js
index 8e9879d1..3e2f23a8 100644
--- a/src/js/store/modules/appSettings.js
+++ b/src/js/store/modules/appSettings.js
@@ -23,6 +23,7 @@
import axios from '@nextcloud/axios'
import { generateUrl } from '@nextcloud/router'
+import axiosDefaultConfig from '../../helpers/AxiosDefault.js'
const defaultAppSettings = () => ({
allAccessGroups: [],
@@ -55,7 +56,6 @@ const defaultAppSettings = () => ({
const namespaced = true
const state = defaultAppSettings()
-const axiosDefaultConfig = { headers: { Accept: 'application/json' } }
const mutations = {
reset(state) {
diff --git a/src/js/store/modules/combo.js b/src/js/store/modules/combo.js
index 334f553d..19128926 100644
--- a/src/js/store/modules/combo.js
+++ b/src/js/store/modules/combo.js
@@ -25,6 +25,7 @@ import axios from '@nextcloud/axios'
import { generateUrl } from '@nextcloud/router'
import { uniqueOptions, uniqueParticipants } from '../../helpers/arrayHelper.js'
import { sortBy } from 'lodash'
+import axiosDefaultConfig from '../../helpers/AxiosDefault.js'
const defaultCombo = () => ({
id: 1,
@@ -36,7 +37,6 @@ const defaultCombo = () => ({
const namespaced = true
const state = defaultCombo()
-const axiosDefaultConfig = { headers: { Accept: 'application/json' } }
const mutations = {
set(state, payload) {
diff --git a/src/js/store/modules/comments.js b/src/js/store/modules/comments.js
index 7e1425f8..487e0f80 100644
--- a/src/js/store/modules/comments.js
+++ b/src/js/store/modules/comments.js
@@ -23,6 +23,7 @@
import axios from '@nextcloud/axios'
import { generateUrl } from '@nextcloud/router'
+import axiosDefaultConfig from '../../helpers/AxiosDefault.js'
const defaultComments = () => ({
list: [],
@@ -30,7 +31,6 @@ const defaultComments = () => ({
const namespaced = true
const state = defaultComments()
-const axiosDefaultConfig = { headers: { Accept: 'application/json' } }
const mutations = {
diff --git a/src/js/store/modules/options.js b/src/js/store/modules/options.js
index 5270d1f8..f59d3bd8 100644
--- a/src/js/store/modules/options.js
+++ b/src/js/store/modules/options.js
@@ -25,6 +25,7 @@ import axios from '@nextcloud/axios'
import { generateUrl } from '@nextcloud/router'
import { orderBy } from 'lodash'
import moment from '@nextcloud/moment'
+import axiosDefaultConfig from '../../helpers/AxiosDefault.js'
const defaultOptions = () => ({
list: [],
@@ -33,7 +34,6 @@ const defaultOptions = () => ({
const namespaced = true
const state = defaultOptions()
-const axiosDefaultConfig = { headers: { Accept: 'application/json' } }
const mutations = {
set(state, payload) {
@@ -184,22 +184,6 @@ const actions = {
}
},
- async addBulk(context, payload) {
- const endPoint = 'apps/polls/option/bulk'
-
- try {
- const response = await axios.post(generateUrl(endPoint), {
- pollId: context.rootState.route.params.id,
- text: payload.text,
- }, axiosDefaultConfig)
- context.commit('set', { options: response.data.options })
- } catch (e) {
- console.error(`Error adding option: ${e.response.data}`, { error: e.response }, { payload })
- context.dispatch('list')
- throw e
- }
- },
-
async update(context, payload) {
const endPoint = `apps/polls/option/${payload.option.id}`
@@ -236,6 +220,22 @@ const actions = {
}
},
+ async addBulk(context, payload) {
+ const endPoint = 'apps/polls/option/bulk'
+
+ try {
+ const response = await axios.post(generateUrl(endPoint), {
+ pollId: context.rootState.route.params.id,
+ text: payload.text,
+ }, axiosDefaultConfig)
+ context.commit('set', { options: response.data.options })
+ } catch (e) {
+ console.error(`Error adding option: ${e.response.data}`, { error: e.response }, { payload })
+ context.dispatch('list')
+ throw e
+ }
+ },
+
async confirm(context, payload) {
const endPoint = `apps/polls/option/${payload.option.id}/confirm`
diff --git a/src/js/store/modules/poll.js b/src/js/store/modules/poll.js
index dcad3e38..aa587336 100644
--- a/src/js/store/modules/poll.js
+++ b/src/js/store/modules/poll.js
@@ -26,6 +26,7 @@ import moment from '@nextcloud/moment'
import { generateUrl } from '@nextcloud/router'
import acl from './subModules/acl.js'
import { uniqueArrayOfObjects } from '../../helpers/arrayHelper.js'
+import axiosDefaultConfig from '../../helpers/AxiosDefault.js'
const defaultPoll = () => ({
id: 0,
@@ -60,7 +61,6 @@ const defaultPoll = () => ({
const namespaced = true
const modules = { acl }
const state = defaultPoll()
-const axiosDefaultConfig = { headers: { Accept: 'application/json' } }
const mutations = {
set(state, payload) {
@@ -200,38 +200,44 @@ const actions = {
async add(context, payload) {
const endPoint = 'apps/polls/poll/add'
try {
- return await axios.post(generateUrl(endPoint), {
+ const response = await axios.post(generateUrl(endPoint), {
title: payload.title,
type: payload.type,
}, axiosDefaultConfig)
+
+ context.dispatch('polls/list', null, { root: true })
+ return response
} catch (e) {
console.error('Error adding poll:', { error: e.response }, { state: context.state })
throw e
}
},
- async clone(context, payload) {
- const endPoint = `apps/polls/poll/${payload.pollId}/clone`
- try {
- return await axios.post(generateUrl(endPoint), null, axiosDefaultConfig)
- } catch (e) {
- console.error('Error cloning poll', { error: e.response }, { payload })
- }
- },
-
async update(context) {
const endPoint = `apps/polls/poll/${context.state.id}`
try {
const response = await axios.put(generateUrl(endPoint), {
poll: context.state,
}, axiosDefaultConfig)
-
context.commit('set', response.data)
context.commit('acl/set', response.data)
- context.dispatch('options/list', null, { root: true })
} catch (e) {
console.error('Error updating poll:', { error: e.response }, { poll: context.state })
+ context.dispatch('get')
throw e
+ } finally {
+ context.dispatch('polls/list', null, { root: true })
+ }
+ },
+
+ async delete(context, payload) {
+ const endPoint = `apps/polls/poll/${payload.pollId}`
+ try {
+ await axios.delete(generateUrl(endPoint), axiosDefaultConfig)
+ } catch (e) {
+ console.error('Error deleting poll', { error: e.response }, { payload })
+ } finally {
+ context.dispatch('polls/list', null, { root: true })
}
},
@@ -241,25 +247,29 @@ const actions = {
await axios.put(generateUrl(endPoint), null, axiosDefaultConfig)
} catch (e) {
console.error('Error archiving/restoring', { error: e.response }, { payload })
+ } finally {
+ context.dispatch('polls/list', null, { root: true })
}
},
- async sendConfirmation(context, payload) {
- const endPoint = `apps/polls/poll/${context.rootState.route.params.id}/confirmation`
+ async clone(context, payload) {
+ const endPoint = `apps/polls/poll/${payload.pollId}/clone`
try {
const response = await axios.post(generateUrl(endPoint), null, axiosDefaultConfig)
- return response.data.confirmations
+ context.dispatch('polls/list', null, { root: true })
+ return response
} catch (e) {
- console.error('Error sending confirmation', { error: e.response }, { payload })
+ console.error('Error cloning poll', { error: e.response }, { payload })
}
},
- async delete(context, payload) {
- const endPoint = `apps/polls/poll/${payload.pollId}`
+ async sendConfirmation(context, payload) {
+ const endPoint = `apps/polls/poll/${context.rootState.route.params.id}/confirmation`
try {
- await axios.delete(generateUrl(endPoint), axiosDefaultConfig)
+ const response = await axios.post(generateUrl(endPoint), null, axiosDefaultConfig)
+ return response.data.confirmations
} catch (e) {
- console.error('Error deleting poll', { error: e.response }, { payload })
+ console.error('Error sending confirmation', { error: e.response }, { payload })
}
},
@@ -271,7 +281,6 @@ const actions = {
console.error('Error retrieving email addresses', { error: e.response })
}
},
-
}
export default { namespaced, state, mutations, getters, actions, modules }
diff --git a/src/js/store/modules/polls.js b/src/js/store/modules/polls.js
index 9095b52c..e188ac7b 100644
--- a/src/js/store/modules/polls.js
+++ b/src/js/store/modules/polls.js
@@ -27,6 +27,7 @@ import axios from '@nextcloud/axios'
import moment from '@nextcloud/moment'
import { generateUrl } from '@nextcloud/router'
import { orderBy } from 'lodash'
+import axiosDefaultConfig from '../../helpers/AxiosDefault.js'
const state = {
list: [],
@@ -138,7 +139,6 @@ const state = {
}
const namespaced = true
-const axiosDefaultConfig = { headers: { Accept: 'application/json' } }
const mutations = {
set(state, payload) {
diff --git a/src/js/store/modules/pollsAdmin.js b/src/js/store/modules/pollsAdmin.js
index a0182d42..d30f1338 100644
--- a/src/js/store/modules/pollsAdmin.js
+++ b/src/js/store/modules/pollsAdmin.js
@@ -4,8 +4,6 @@
*
* @author Rene Gieling <github@dartcafe.de>
*
- * @author Vinzenz Rosenkranz <vinzenz.rosenkranz@gmail.com>
- *
* @license AGPL-3.0-or-later
*
* This program is free software: you can redistribute it and/or modify
@@ -26,12 +24,12 @@
import axios from '@nextcloud/axios'
import { getCurrentUser } from '@nextcloud/auth'
import { generateUrl } from '@nextcloud/router'
+import axiosDefaultConfig from '../../helpers/AxiosDefault.js'
const namespaced = true
const state = {
list: [],
}
-const axiosDefaultConfig = { headers: { Accept: 'application/json' } }
const mutations = {
set(state, payload) {
diff --git a/src/js/store/modules/settings.js b/src/js/store/modules/settings.js
index 7f8fae6f..b5e03338 100644
--- a/src/js/store/modules/settings.js
+++ b/src/js/store/modules/settings.js
@@ -23,6 +23,7 @@
import axios from '@nextcloud/axios'
import { generateUrl } from '@nextcloud/router'
+import axiosDefaultConfig from '../../helpers/AxiosDefault.js'
const defaultSettings = () => ({
user: {
@@ -49,7 +50,6 @@ const defaultSettings = () => ({
const namespaced = true
const state = defaultSettings()
-const axiosDefaultConfig = { headers: { Accept: 'application/json' } }
const mutations = {
reset(state) {
@@ -57,6 +57,7 @@ const mutations = {
},
setPreference(state, payload) {
+ // change values in case of old settings
if (payload.defaultViewTextPoll === 'desktop') {
payload.defaultViewTextPoll = 'table-view'
}
diff --git a/src/js/store/modules/share.js b/src/js/store/modules/share.js
index c5d5e604..43b50adb 100644
--- a/src/js/store/modules/share.js
+++ b/src/js/store/modules/share.js
@@ -24,6 +24,7 @@
import axios from '@nextcloud/axios'
import { generateUrl } from '@nextcloud/router'
import { setCookie } from '../../helpers/cookieHelper.js'
+import axiosDefaultConfig from '../../helpers/AxiosDefault.js'
const defaultShares = () => ({
displayName: '',
@@ -39,7 +40,6 @@ const defaultShares = () => ({
const namespaced = true
const state = defaultShares()
-const axiosDefaultConfig = { headers: { Accept: 'application/json' } }
const mutations = {
set(state, payload) {
diff --git a/src/js/store/modules/shares.js b/src/js/store/modules/shares.js
index 497364d3..8095cb36 100644
--- a/src/js/store/modules/shares.js
+++ b/src/js/store/modules/shares.js
@@ -23,6 +23,7 @@
import axios from '@nextcloud/axios'
import { generateUrl } from '@nextcloud/router'
+import axiosDefaultConfig from '../../helpers/AxiosDefault.js'
const defaultShares = () => ({
list: [],
@@ -30,7 +31,6 @@ const defaultShares = () => ({
const namespaced = true
const state = defaultShares()
-const axiosDefaultConfig = { headers: { Accept: 'application/json' } }
const mutations = {
set(state, payload) {
@@ -99,21 +99,6 @@ const actions = {
}
},
- async delete(context, payload) {
- const endPoint = `apps/polls/share/${payload.share.token}`
-
- context.commit('delete', { share: payload.share })
-
- try {
- await axios.delete(generateUrl(endPoint), axiosDefaultConfig)
- } catch (e) {
- console.error('Error removing share', { error: e.response }, { payload })
- throw e
- } finally {
- context.dispatch('list')
- }
- },
-
async switchAdmin(context, payload) {
let endPoint = `apps/polls/share/${payload.share.token}`
@@ -171,6 +156,21 @@ const actions = {
context.dispatch('list')
}
},
+
+ async delete(context, payload) {
+ const endPoint = `apps/polls/share/${payload.share.token}`
+
+ context.commit('delete', { share: payload.share })
+
+ try {
+ await axios.delete(generateUrl(endPoint), axiosDefaultConfig)
+ } catch (e) {
+ console.error('Error removing share', { error: e.response }, { payload })
+ throw e
+ } finally {
+ context.dispatch('list')
+ }
+ },
}
export default { namespaced, state, mutations, actions, getters }
diff --git a/src/js/store/modules/subscription.js b/src/js/store/modules/subscription.js
index 607f45a6..3a531066 100644
--- a/src/js/store/modules/subscription.js
+++ b/src/js/store/modules/subscription.js
@@ -23,6 +23,7 @@
import axios from '@nextcloud/axios'
import { generateUrl } from '@nextcloud/router'
+import axiosDefaultConfig from '../../helpers/AxiosDefault.js'
const defaultSubscription = () => ({
subscribed: false,
@@ -30,7 +31,6 @@ const defaultSubscription = () => ({
const namespaced = true
const state = defaultSubscription()
-const axiosDefaultConfig = { headers: { Accept: 'application/json' } }
const mutations = {
diff --git a/src/js/store/modules/votes.js b/src/js/store/modules/votes.js
index 9e836df8..9a7fb92d 100644
--- a/src/js/store/modules/votes.js
+++ b/src/js/store/modules/votes.js
@@ -23,6 +23,7 @@
import axios from '@nextcloud/axios'
import { generateUrl } from '@nextcloud/router'
+import axiosDefaultConfig from '../../helpers/AxiosDefault.js'
const defaultVotes = () => ({
list: [],
@@ -30,7 +31,6 @@ const defaultVotes = () => ({
const namespaced = true
const state = defaultVotes()
-const axiosDefaultConfig = { headers: { Accept: 'application/json' } }
const mutations = {
set(state, payload) {