Browse Source

Merge pull request #5531 from nextcloud/techdebt/noid/decouple-fileupload-service-from-store

Decouple fileupload and createTemporaryMessage from the global store module
pull/5544/head
Joas Schilling 5 years ago
committed by GitHub
parent
commit
7f242246be
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      src/components/ChatView.vue
  2. 6
      src/components/NewMessageForm/NewMessageForm.vue
  3. 5
      src/components/UploadEditor.vue
  4. 30
      src/store/fileUploadStore.js
  5. 60
      src/store/messagesStore.js
  6. 25
      src/utils/fileUpload.js
  7. 72
      src/utils/temporaryMessage.js

3
src/components/ChatView.vue

@ -59,7 +59,6 @@
<script>
import MessagesList from './MessagesList/MessagesList'
import NewMessageForm from './NewMessageForm/NewMessageForm'
import { processFiles } from '../utils/fileUpload'
import { CONVERSATION } from '../constants'
export default {
@ -140,7 +139,7 @@ export default {
// Create a unique id for the upload operation
const uploadId = new Date().getTime()
// Uploads and shares the files
processFiles(files, this.token, uploadId)
this.$store.dispatch('initialiseUpload', { files, token: this.token, uploadId })
},
setScrollStatus(payload) {

6
src/components/NewMessageForm/NewMessageForm.vue

@ -125,9 +125,7 @@ import ActionButton from '@nextcloud/vue/dist/Components/ActionButton'
import EmojiPicker from '@nextcloud/vue/dist/Components/EmojiPicker'
import { EventBus } from '../../services/EventBus'
import { shareFile } from '../../services/filesSharingServices'
import { processFiles } from '../../utils/fileUpload'
import { CONVERSATION } from '../../constants'
import createTemporaryMessage from '../../utils/temporaryMessage'
import EmoticonOutline from 'vue-material-design-icons/EmoticonOutline'
import Send from 'vue-material-design-icons/Send'
import CancelableRequest from '../../utils/cancelableRequest'
@ -316,7 +314,7 @@ export default {
*/
async handleSubmit() {
if (this.parsedText !== '') {
const temporaryMessage = createTemporaryMessage(this.parsedText, this.token)
const temporaryMessage = await this.$store.dispatch('createTemporaryMessage', { text: this.parsedText, token: this.token })
this.$store.dispatch('addTemporaryMessage', temporaryMessage)
this.text = ''
this.parsedText = ''
@ -457,7 +455,7 @@ export default {
// Create a unique id for the upload operation
const uploadId = new Date().getTime()
// Uploads and shares the files
await processFiles(files, this.token, uploadId, rename)
await this.$store.dispatch('initialiseUpload', { files, token: this.token, uploadId, rename })
},
/**

5
src/components/UploadEditor.vue

@ -70,7 +70,6 @@
import Modal from '@nextcloud/vue/dist/Components/Modal'
import FilePreview from './MessagesList/MessagesGroup/Message/MessagePart/FilePreview.vue'
import Plus from 'vue-material-design-icons/Plus'
import { processFiles } from '../utils/fileUpload'
export default {
name: 'UploadEditor',
@ -136,9 +135,9 @@ export default {
this.$refs.fileUploadInput.click()
},
handleFileInput(event) {
async handleFileInput(event) {
const files = Object.values(event.target.files)
processFiles(files, this.token, this.currentUploadId)
await this.$store.dispatch('initialiseUpload', { files, token: this.token, uploadId: this.currentUploadId })
},
handleRemoveFileFromSelection(id) {

30
src/store/fileUploadStore.js

@ -24,8 +24,8 @@ import Vue from 'vue'
import client from '../services/DavClient'
import { showError } from '@nextcloud/dialogs'
import fromStateOr from './helper'
import { findUniquePath } from '../utils/fileUpload'
import createTemporaryMessage from '../utils/temporaryMessage'
import { findUniquePath, getFileExtension } from '../utils/fileUpload'
import moment from '@nextcloud/moment'
import { EventBus } from '../services/EventBus'
import { shareFile } from '../services/filesSharingServices'
import { setAttachmentFolder } from '../services/settingsService'
@ -186,11 +186,27 @@ const mutations = {
const actions = {
initialiseUpload({ commit, dispatch }, { uploadId, token, files }) {
/**
* Initialises uploads and shares files to a conversation
*
* @param {object} files the files to be processed
* @param {string} token the conversation's token where to share the files
* @param {number} uploadId a unique id for the upload operation indexing
* @param {bool} rename whether to rename the files (usually after pasting)
*/
async initialiseUpload({ commit, dispatch }, { uploadId, token, files, rename = false }) {
// Set last upload id
commit('setCurrentUploadId', uploadId)
files.forEach(file => {
for (let i = 0; i < files.length; i++) {
const file = files[i]
if (rename) {
// note: can't overwrite the original read-only name attribute
file.newName = moment(file.lastModified || file.lastModifiedDate).format('YYYYMMDD_HHmmss')
+ getFileExtension(file.name)
}
// Get localurl for some image previews
let localUrl = ''
if (file.type === 'image/png' || file.type === 'image/gif' || file.type === 'image/jpeg') {
@ -202,10 +218,12 @@ const actions = {
const date = new Date()
const index = 'temp_' + date.getTime() + Math.random()
// Create temporary message for the file and add it to the message list
const temporaryMessage = createTemporaryMessage('{file}', token, uploadId, index, file, localUrl)
const temporaryMessage = await dispatch('createTemporaryMessage', {
text: '{file}', token, uploadId, index, file, localUrl,
})
console.debug('temporarymessage: ', temporaryMessage, 'uploadId', uploadId)
commit('addFileToBeUploaded', { file, temporaryMessage })
})
}
},
/**

60
src/store/messagesStore.js

@ -24,6 +24,8 @@ import {
deleteMessage,
updateLastReadMessage,
} from '../services/messagesService'
import SHA1 from 'crypto-js/sha1'
import Hex from 'crypto-js/enc-hex'
const state = {
/**
@ -286,6 +288,64 @@ const actions = {
return response.status
},
/**
* Creates a temporary message ready to be posted, based
* on the message to be replied and the current actor
*
* @param {object} context default store context;
* @param {string} text message string;
* @param {string} token conversation token;
* @param {string} uploadId upload id;
* @param {int} index index;
* @param {object} file file to upload;
* @param {string} localUrl local URL of file to upload;
* @returns {object} temporary message
*/
createTemporaryMessage(context, { text, token, uploadId, index, file, localUrl }) {
const messageToBeReplied = context.getters.getMessageToBeReplied(token)
const date = new Date()
let tempId = 'temp-' + date.getTime()
const messageParameters = {}
if (file) {
tempId += '-' + uploadId + '-' + Math.random()
messageParameters.file = {
type: 'file',
file,
mimetype: file.type,
id: tempId,
name: file.newName || file.name,
// index, will be the id from now on
uploadId,
localUrl,
index,
}
}
const message = Object.assign({}, {
id: tempId,
actorId: context.getters.getActorId(),
actorType: context.getters.getActorType(),
actorDisplayName: context.getters.getDisplayName(),
timestamp: 0,
systemMessage: '',
messageType: '',
message: text,
messageParameters,
token,
isReplyable: false,
sendingFailure: '',
referenceId: Hex.stringify(SHA1(tempId)),
})
/**
* If the current message is a quote-reply message, add the parent key to the
* temporary message object.
*/
if (messageToBeReplied) {
message.parent = messageToBeReplied.id
}
return message
},
/**
* Add a temporary message generated in the client to
* the store, these messages are deleted once the full

25
src/utils/fileUpload.js

@ -20,9 +20,6 @@
*
*/
import store from '../store/index'
import moment from '@nextcloud/moment'
/**
* Returns the file extension for the given path
*
@ -71,27 +68,7 @@ const findUniquePath = async function(client, userRoot, path) {
}
}
/**
* Uploads and shares files to a conversation
* @param {object} files the files to be processed
* @param {string} token the conversation's token where to share the files
* @param {number} uploadId a unique id for the upload operation indexing
* @param {bool} rename whether to rename the files (usually after pasting)
*/
const processFiles = async function(files, token, uploadId, rename) {
if (rename) {
files.forEach(file => {
// note: can't overwrite the original read-only name attribute
file.newName = moment(file.lastModified || file.lastModifiedDate).format('YYYYMMDD_HHmmss')
+ getFileExtension(file.name)
})
}
// Process these files in the store
await store.dispatch('initialiseUpload', { uploadId, token, files })
}
export {
findUniquePath,
processFiles,
getFileExtension,
}

72
src/utils/temporaryMessage.js

@ -1,72 +0,0 @@
/**
* @copyright Copyright (c) 2020 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 store from '../store/index'
import SHA1 from 'crypto-js/sha1'
import Hex from 'crypto-js/enc-hex'
const createTemporaryMessage = (text, token, uploadId, index, file, localUrl) => {
const messageToBeReplied = store.getters.getMessageToBeReplied(token)
const date = new Date()
let tempId = 'temp-' + date.getTime()
const messageParameters = {}
if (file) {
tempId += '-' + uploadId + '-' + Math.random()
messageParameters.file = {
'type': 'file',
'file': file,
'mimetype': file.type,
'id': tempId,
'name': file.newName || file.name,
// index, will be the id from now on
uploadId,
localUrl,
index,
}
}
const message = Object.assign({}, {
id: tempId,
actorId: store.getters.getActorId(),
actorType: store.getters.getActorType(),
actorDisplayName: store.getters.getDisplayName(),
timestamp: 0,
systemMessage: '',
messageType: '',
message: text,
messageParameters,
token: token,
isReplyable: false,
sendingFailure: '',
referenceId: Hex.stringify(SHA1(tempId)),
})
/**
* If the current message is a quote-reply message, add the parent key to the
* temporary message object.
*/
if (messageToBeReplied) {
message.parent = messageToBeReplied.id
}
return message
}
export default createTemporaryMessage
Loading…
Cancel
Save