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

github.com/nextcloud/spreed.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/components/NewMessageForm/NewMessageForm.vue61
-rw-r--r--src/services/filesSharingServices.js37
-rw-r--r--src/store/fileUploadStore.js132
-rw-r--r--src/store/index.js2
4 files changed, 178 insertions, 54 deletions
diff --git a/src/components/NewMessageForm/NewMessageForm.vue b/src/components/NewMessageForm/NewMessageForm.vue
index d7f8695af..f24854147 100644
--- a/src/components/NewMessageForm/NewMessageForm.vue
+++ b/src/components/NewMessageForm/NewMessageForm.vue
@@ -76,13 +76,12 @@
<script>
import AdvancedInput from './AdvancedInput/AdvancedInput'
-import { getFilePickerBuilder, showError } from '@nextcloud/dialogs'
+import { getFilePickerBuilder } from '@nextcloud/dialogs'
import { postNewMessage } from '../../services/messagesService'
import Quote from '../Quote'
import Actions from '@nextcloud/vue/dist/Components/Actions'
import ActionButton from '@nextcloud/vue/dist/Components/ActionButton'
-import client from '../../services/DavClient'
-import { shareFileToRoom } from '../../services/filesSharingServices'
+import { shareFile } from '../../services/filesSharingServices'
const picker = getFilePickerBuilder(t('spreed', 'File to share'))
.setMultiSelect(false)
@@ -243,29 +242,6 @@ export default {
}
},
- /**
- * Appends a file as a message to the messagelist.
- * @param {string} path The file path from the user's root directory
- * e.g. `/myfile.txt`
- */
- async sendFile(path) {
- try {
- await shareFileToRoom(path, this.token)
- } catch (error) {
- if (error.response
- && error.response.data
- && error.response.data.ocs
- && error.response.data.ocs.meta
- && error.response.data.ocs.meta.message) {
- console.error(`Error while sharing file: ${error.response.data.ocs.meta.message || 'Unknown error'}`)
- OCP.Toast.error(error.response.data.ocs.meta.message)
- } else {
- console.error(`Error while sharing file: Unknown error`)
- OCP.Toast.error(t('files', 'Error while sharing file'))
- }
- }
- },
-
async handleFileShare() {
picker.pick()
.then(async(path) => {
@@ -273,7 +249,7 @@ export default {
if (!path.startsWith('/')) {
throw new Error(t('files', 'Invalid path selected'))
}
- this.sendFile(path)
+ shareFile(path, this.token)
})
},
@@ -286,25 +262,26 @@ export default {
},
/**
- * Uploads the files to the root files directory
+ * Uploads and shares the selected files
* @param {object} event the file input event object
*/
async processFiles(event) {
- // The selected files array
+ // Store the token in a variable to prevent changes when changing conversation
+ // when the upload is still running
+ const token = this.token
+ // The selected files array coming from the input
const files = Object.values(event.target.files)
- // process each file in the array
- for (let i = 0; i < files.length; i++) {
- const userId = this.$store.getters.getUserId()
- const path = `/files/${userId}/` + files[i].name
- try {
- // Upload the file
- await client.putFileContents(path, files[i])
- // Share the file to the talk room
- this.sendFile('/' + files[i].name)
- } catch (exception) {
- console.debug('Error while uploading file:' + exception)
- showError(t('spreed', 'Error while uploading file'))
- }
+ // Process these files in the store
+ await this.$store.dispatch('addFilesToBeUploaded', { token, files })
+ // Dispatch the upload action (see uploadStore)
+ await this.$store.dispatch('uploadFiles', token)
+ // Get the files that have successfully been uploaded from the store
+ const shareableFiles = this.$store.getters.getShareableFiles(token)
+ // Share each of those files in the conversation
+ for (const index in shareableFiles) {
+ // The pat of the file to share to the conversation
+ const path = '/' + shareableFiles[index].name
+ shareFile(path, token)
}
},
},
diff --git a/src/services/filesSharingServices.js b/src/services/filesSharingServices.js
index 011570920..3aa1b35fa 100644
--- a/src/services/filesSharingServices.js
+++ b/src/services/filesSharingServices.js
@@ -21,25 +21,38 @@
*/
import axios from '@nextcloud/axios'
import { generateOcsUrl } from '@nextcloud/router'
+import { showError } from '@nextcloud/dialogs'
/**
* Appends a file as a message to the messagelist.
* @param {string} path The file path from the user's root directory
- * e.g. `/myfile.txt`
* @param {string} token The conversation's token
- * @returns {object} the response object
+ * e.g. `/myfile.txt`
*/
-const shareFileToRoom = (path, token) => {
- const response = axios.post(
- generateOcsUrl('apps/files_sharing/api/v1', 2) + 'shares',
- {
- shareType: 10, // OC.Share.SHARE_TYPE_ROOM,
- path: path,
- shareWith: token,
- })
- return response
+const shareFile = async function(path, token) {
+ try {
+ return axios.post(
+ generateOcsUrl('apps/files_sharing/api/v1', 2) + 'shares',
+ {
+ shareType: 10, // OC.Share.SHARE_TYPE_ROOM,
+ path: path,
+ shareWith: token,
+ })
+ } catch (error) {
+ if (error.response
+ && error.response.data
+ && error.response.data.ocs
+ && error.response.data.ocs.meta
+ && error.response.data.ocs.meta.message) {
+ console.error(`Error while sharing file: ${error.response.data.ocs.meta.message || 'Unknown error'}`)
+ showError(error.response.data.ocs.meta.message)
+ } else {
+ console.error(`Error while sharing file: Unknown error`)
+ showError(t('spreed', 'Error while sharing file'))
+ }
+ }
}
export {
- shareFileToRoom
+ shareFile,
}
diff --git a/src/store/fileUploadStore.js b/src/store/fileUploadStore.js
new file mode 100644
index 000000000..845bf2441
--- /dev/null
+++ b/src/store/fileUploadStore.js
@@ -0,0 +1,132 @@
+/**
+ * @copyright Copyright (c) 2019 Marco Ambrosini <marcoambrosini@pm.me>
+ *
+ * @author Marco Ambrosini <marcoambrosini@pm.me>
+ *
+ * @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 Vue from 'vue'
+import client from '../services/DavClient'
+import { showError } from '@nextcloud/dialogs'
+
+const state = {
+ files: {
+ },
+}
+
+const getters = {
+ // Returns all the files that have been marked for upload in a given conversation,
+ // regardless of their upload state
+ getFiles: (state) => (token) => {
+ return state.files[token]
+ },
+ // Returns all the files that have been successfully uploaded
+ getShareableFiles: (state) => (token) => {
+ if (state.files[token]) {
+ const shareableFiles = []
+ for (const index in state.files[token]) {
+ const currentFile = state.files[token][index]
+ if (currentFile.status === 'successUpload') {
+ shareableFiles.push(currentFile.file)
+ }
+ }
+ return shareableFiles
+ } return undefined
+ },
+}
+
+const mutations = {
+ /**
+ * Adds a "file to be shared to the store"
+ * @param {*} state the state object
+ * @param {*} file the file to be added to the store
+ * @param {*} token the conversation's token
+ */
+ addFileToBeUploaded(state, { token, file }) {
+ if (!state.files[token]) {
+ Vue.set(state.files, token, {})
+ }
+ Vue.set(state.files[token], Object.keys(state.files[token]).length, { file, status: 'toBeUploaded' })
+ },
+
+ // Marks a given file as failed uplosd
+ markFileAsFailedUpload(state, { token, index }) {
+ state.files[token][index].status = 'failedUpload'
+ },
+
+ // Marks a given file as uploaded
+ markFileAsSuccessUpload(state, { token, index }) {
+ state.files[token][index].status = 'successUpload'
+ },
+
+ // Marks a given file as uploading
+ markFileAsUploading(state, { token, index }) {
+ state.files[token][index].status = 'uploading'
+ },
+}
+
+const actions = {
+
+ /**
+ *
+ * @param {object} context The context object
+ * @param {string} token The conversation's token
+ * @param {array} files The files to be processed and added to the store
+ */
+ addFilesToBeUploaded(context, { token, files }) {
+ files.forEach(file => {
+ context.commit('addFileToBeUploaded', { token, file })
+ })
+ },
+
+ /**
+ * Uploads the files to the root directory of the user
+ * @param {object} param0 Commit, state and getters
+ * @param {*} token The conversation's token
+ */
+ async uploadFiles({ commit, state, getters }, token) {
+ // Iterate through the previously indexed files for a given conversation (token)
+ for (const index in state.files[token]) {
+ if (state.files[token][index].status !== 'toBeUploaded') {
+ continue
+ }
+ // Mark file as uploading to prevent a second function call to start a
+ // second upload for the same file
+ commit('markFileAsUploading', { token, index })
+ // Get the current user id
+ const userId = getters.getUserId()
+ // currentFile to be uploaded
+ const currentFile = state.files[token][index].file
+ // Destination path on the server
+ const path = `/files/${userId}/` + currentFile.name
+ try {
+ // Upload the file
+ await client.putFileContents(path, currentFile)
+ // Mark the file as uploaded in the store
+ commit('markFileAsSuccessUpload', { token, index })
+ } catch (exception) {
+ console.debug('Error while uploading file:' + exception)
+ showError(t('spreed', 'Error while uploading file'))
+ // Mark the upload as failed in the store
+ commit('markFileAsFailedUpload', { token, index })
+ }
+ }
+ },
+}
+
+export default { state, mutations, getters, actions }
diff --git a/src/store/index.js b/src/store/index.js
index 18e9fb17d..88b93c5f1 100644
--- a/src/store/index.js
+++ b/src/store/index.js
@@ -31,6 +31,7 @@ import quoteReplyStore from './quoteReplyStore'
import sidebarStore from './sidebarStore'
import tokenStore from './tokenStore'
import windowVisibilityStore from './windowVisibilityStore'
+import fileUploadStore from './fileUploadStore'
Vue.use(Vuex)
@@ -47,6 +48,7 @@ export default new Store({
sidebarStore,
tokenStore,
windowVisibilityStore,
+ fileUploadStore,
},
mutations,