feat: Activestorage direct upload (#3768)

This commit is contained in:
Tejaswini Chile
2022-01-27 15:57:22 +05:30
committed by GitHub
parent cd6c9a8fe9
commit 69eaf3ff7f
9 changed files with 84 additions and 14 deletions

View File

@@ -31,7 +31,6 @@ class Messages::MessageBuilder
@attachments.each do |uploaded_attachment| @attachments.each do |uploaded_attachment|
@message.attachments.build( @message.attachments.build(
account_id: @message.account_id, account_id: @message.account_id,
file_type: file_type(uploaded_attachment&.content_type),
file: uploaded_attachment file: uploaded_attachment
) )
end end

View File

@@ -31,7 +31,6 @@ class Api::V1::Widget::MessagesController < Api::V1::Widget::BaseController
params[:message][:attachments].each do |uploaded_attachment| params[:message][:attachments].each do |uploaded_attachment|
@message.attachments.new( @message.attachments.new(
account_id: @message.account_id, account_id: @message.account_id,
file_type: helpers.file_type(uploaded_attachment&.content_type),
file: uploaded_attachment file: uploaded_attachment
) )
end end

View File

@@ -14,12 +14,12 @@ export const buildCreatePayload = ({
let payload; let payload;
if (files && files.length !== 0) { if (files && files.length !== 0) {
payload = new FormData(); payload = new FormData();
files.forEach(file => {
payload.append('attachments[]', file, file.name);
});
if (message) { if (message) {
payload.append('content', message); payload.append('content', message);
} }
files.forEach(file => {
payload.append('attachments[]', file);
});
payload.append('private', isPrivate); payload.append('private', isPrivate);
payload.append('echo_id', echoId); payload.append('echo_id', echoId);
payload.append('cc_emails', ccEmails); payload.append('cc_emails', ccEmails);

View File

@@ -7,7 +7,7 @@
> >
<div class="thumb-wrap"> <div class="thumb-wrap">
<img <img
v-if="isTypeImage(attachment.resource.type)" v-if="isTypeImage(attachment.resource.content_type)"
class="image-thumb" class="image-thumb"
:src="attachment.thumb" :src="attachment.thumb"
/> />
@@ -15,12 +15,12 @@
</div> </div>
<div class="file-name-wrap"> <div class="file-name-wrap">
<span class="item"> <span class="item">
{{ attachment.resource.name }} {{ attachment.resource.filename }}
</span> </span>
</div> </div>
<div class="file-size-wrap"> <div class="file-size-wrap">
<span class="item"> <span class="item">
{{ formatFileSize(attachment.resource.size) }} {{ formatFileSize(attachment.resource.byte_size) }}
</span> </span>
</div> </div>
<div class="remove-file-wrap"> <div class="remove-file-wrap">

View File

@@ -19,7 +19,8 @@
:multiple="enableMultipleFileUpload" :multiple="enableMultipleFileUpload"
:drop="true" :drop="true"
:drop-directory="false" :drop-directory="false"
@input-file="onFileUpload" :data="{ direct_upload_url: '/rails/active_storage/direct_uploads', direct_upload: true }"
@input-file="onDirectFileUpload"
> >
<woot-button <woot-button
v-if="showAttachButton" v-if="showAttachButton"
@@ -80,6 +81,7 @@
<script> <script>
import FileUpload from 'vue-upload-component'; import FileUpload from 'vue-upload-component';
import * as ActiveStorage from "activestorage";
import { import {
hasPressedAltAndWKey, hasPressedAltAndWKey,
hasPressedAltAndAKey, hasPressedAltAndAKey,
@@ -109,7 +111,7 @@ export default {
type: Boolean, type: Boolean,
default: false, default: false,
}, },
onFileUpload: { onDirectFileUpload: {
type: Function, type: Function,
default: () => {}, default: () => {},
}, },
@@ -150,6 +152,9 @@ export default {
default: true, default: true,
}, },
}, },
mounted() {
ActiveStorage.start();
},
computed: { computed: {
isNote() { isNote() {
return this.mode === REPLY_EDITOR_MODES.NOTE; return this.mode === REPLY_EDITOR_MODES.NOTE;

View File

@@ -61,7 +61,7 @@
<reply-bottom-panel <reply-bottom-panel
:mode="replyType" :mode="replyType"
:send-button-text="replyButtonLabel" :send-button-text="replyButtonLabel"
:on-file-upload="onFileUpload" :on-direct-file-upload="onDirectFileUpload"
:show-file-upload="showFileUpload" :show-file-upload="showFileUpload"
:toggle-emoji-picker="toggleEmojiPicker" :toggle-emoji-picker="toggleEmojiPicker"
:show-emoji-picker="showEmojiPicker" :show-emoji-picker="showEmojiPicker"
@@ -104,6 +104,7 @@ import {
import { MESSAGE_MAX_LENGTH } from 'shared/helpers/MessageTypeHelper'; import { MESSAGE_MAX_LENGTH } from 'shared/helpers/MessageTypeHelper';
import inboxMixin from 'shared/mixins/inboxMixin'; import inboxMixin from 'shared/mixins/inboxMixin';
import uiSettingsMixin from 'dashboard/mixins/uiSettings'; import uiSettingsMixin from 'dashboard/mixins/uiSettings';
import { DirectUpload } from 'activestorage';
export default { export default {
components: { components: {
@@ -443,6 +444,35 @@ export default {
isPrivate, isPrivate,
}); });
}, },
onDirectFileUpload(file) {
if (!file) {
return;
}
if (checkFileSizeLimit(file, MAXIMUM_FILE_UPLOAD_SIZE)) {
const upload = new DirectUpload(file.file, '/rails/active_storage/direct_uploads', null, file.file.name);
upload.create((error, blob) => {
if (error) {
this.showAlert(
error
);
} else {
this.attachedFiles.push({
currentChatId: this.currentChat.id,
resource: blob,
isPrivate: this.isPrivate,
thumb: null,
blobSignedId: blob.signed_id,
});
}
});
} else {
this.showAlert(
this.$t('CONVERSATION.FILE_SIZE_LIMIT', {
MAXIMUM_FILE_UPLOAD_SIZE,
})
);
}
},
onFileUpload(file) { onFileUpload(file) {
if (!file) { if (!file) {
return; return;
@@ -486,7 +516,7 @@ export default {
if (this.attachedFiles && this.attachedFiles.length) { if (this.attachedFiles && this.attachedFiles.length) {
messagePayload.files = []; messagePayload.files = [];
this.attachedFiles.forEach(attachment => { this.attachedFiles.forEach(attachment => {
messagePayload.files.push(attachment.resource.file); messagePayload.files.push(attachment.blobSignedId);
}); });
} }

View File

@@ -41,7 +41,7 @@ const sendAttachment = ({ attachment }) => {
const { file } = attachment; const { file } = attachment;
const formData = new FormData(); const formData = new FormData();
formData.append('message[attachments][]', file, file.name); formData.append('message[attachments][]', file);
formData.append('message[referer_url]', referrerURL); formData.append('message[referer_url]', referrerURL);
formData.append('message[timestamp]', timestamp); formData.append('message[timestamp]', timestamp);
return { return {

View File

@@ -2,7 +2,8 @@
<file-upload <file-upload
:size="4096 * 2048" :size="4096 * 2048"
:accept="allowedFileTypes" :accept="allowedFileTypes"
@input-file="onFileUpload" :data="{ direct_upload_url: '', direct_upload: true }"
@input-file="onDirectFileUpload"
> >
<button class="icon-button flex items-center justify-center"> <button class="icon-button flex items-center justify-center">
<fluent-icon v-if="!isUploading.image" icon="attach" /> <fluent-icon v-if="!isUploading.image" icon="attach" />
@@ -21,6 +22,8 @@ import {
} from 'shared/constants/messages'; } from 'shared/constants/messages';
import { BUS_EVENTS } from 'shared/constants/busEvents'; import { BUS_EVENTS } from 'shared/constants/busEvents';
import FluentIcon from 'shared/components/FluentIcon/Index.vue'; import FluentIcon from 'shared/components/FluentIcon/Index.vue';
import { DirectUpload } from 'activestorage';
export default { export default {
components: { FluentIcon, FileUpload, Spinner }, components: { FluentIcon, FileUpload, Spinner },
props: { props: {
@@ -44,6 +47,39 @@ export default {
getFileType(fileType) { getFileType(fileType) {
return fileType.includes('image') ? 'image' : 'file'; return fileType.includes('image') ? 'image' : 'file';
}, },
async onDirectFileUpload(file) {
if (!file) {
return;
}
this.isUploading = true;
try {
if (checkFileSizeLimit(file, MAXIMUM_FILE_UPLOAD_SIZE)) {
const upload = new DirectUpload(file.file, '/rails/active_storage/direct_uploads', null, file.file.name);
upload.create((error, blob) => {
if (error) {
window.bus.$emit(BUS_EVENTS.SHOW_ALERT, {
message: error,
});
} else {
this.onAttach({
fileType: blob.content_type,
file: blob.signed_id
});
}
});
} else {
window.bus.$emit(BUS_EVENTS.SHOW_ALERT, {
message: this.$t('FILE_SIZE_LIMIT', {
MAXIMUM_FILE_UPLOAD_SIZE: this.fileUploadSizeLimit,
}),
});
}
} catch (error) {
// Error
}
this.isUploading = false;
},
async onFileUpload(file) { async onFileUpload(file) {
if (!file) { if (!file) {
return; return;

View File

@@ -24,6 +24,7 @@
"@rails/webpacker": "5.3.0", "@rails/webpacker": "5.3.0",
"@sentry/tracing": "^6.4.1", "@sentry/tracing": "^6.4.1",
"@sentry/vue": "^6.4.1", "@sentry/vue": "^6.4.1",
"activestorage": "^5.2.6",
"axios": "^0.21.2", "axios": "^0.21.2",
"babel-plugin-syntax-jsx": "^6.18.0", "babel-plugin-syntax-jsx": "^6.18.0",
"babel-plugin-transform-vue-jsx": "^3.7.0", "babel-plugin-transform-vue-jsx": "^3.7.0",