mirror of
				https://github.com/lingble/chatwoot.git
				synced 2025-11-03 20:48:07 +00:00 
			
		
		
		
	fix: Check uploaded file size in widget and dashboard (#1975)
* File size check logic in widget * set maxium file size * update locale texts * file size check in dashboard * dynamincally set file size limit error message * code climate review fixes * add alert mixin * move attahcment bus event to constants * Move file size check logic to helper * add specs for file size limit check helper * changes as per review
This commit is contained in:
		@@ -11,9 +11,7 @@
 | 
				
			|||||||
          class="image-thumb"
 | 
					          class="image-thumb"
 | 
				
			||||||
          :src="attachment.thumb"
 | 
					          :src="attachment.thumb"
 | 
				
			||||||
        />
 | 
					        />
 | 
				
			||||||
        <span v-else class="attachment-thumb">
 | 
					        <span v-else class="attachment-thumb"> 📄 </span>
 | 
				
			||||||
          📄
 | 
					 | 
				
			||||||
        </span>
 | 
					 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
      <div class="file-name-wrap">
 | 
					      <div class="file-name-wrap">
 | 
				
			||||||
        <span class="item">
 | 
					        <span class="item">
 | 
				
			||||||
@@ -37,8 +35,7 @@
 | 
				
			|||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
<script>
 | 
					<script>
 | 
				
			||||||
import { formatBytes } from 'dashboard/helper/files';
 | 
					import { formatBytes } from 'shared/helpers/FileHelper';
 | 
				
			||||||
 | 
					 | 
				
			||||||
export default {
 | 
					export default {
 | 
				
			||||||
  props: {
 | 
					  props: {
 | 
				
			||||||
    attachments: {
 | 
					    attachments: {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -72,6 +72,7 @@
 | 
				
			|||||||
<script>
 | 
					<script>
 | 
				
			||||||
import { mapGetters } from 'vuex';
 | 
					import { mapGetters } from 'vuex';
 | 
				
			||||||
import { mixin as clickaway } from 'vue-clickaway';
 | 
					import { mixin as clickaway } from 'vue-clickaway';
 | 
				
			||||||
 | 
					import alertMixin from 'shared/mixins/alertMixin';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import EmojiInput from 'shared/components/emoji/EmojiInput';
 | 
					import EmojiInput from 'shared/components/emoji/EmojiInput';
 | 
				
			||||||
import CannedResponse from './CannedResponse';
 | 
					import CannedResponse from './CannedResponse';
 | 
				
			||||||
@@ -81,6 +82,9 @@ import ReplyTopPanel from 'dashboard/components/widgets/WootWriter/ReplyTopPanel
 | 
				
			|||||||
import ReplyBottomPanel from 'dashboard/components/widgets/WootWriter/ReplyBottomPanel';
 | 
					import ReplyBottomPanel from 'dashboard/components/widgets/WootWriter/ReplyBottomPanel';
 | 
				
			||||||
import { REPLY_EDITOR_MODES } from 'dashboard/components/widgets/WootWriter/constants';
 | 
					import { REPLY_EDITOR_MODES } from 'dashboard/components/widgets/WootWriter/constants';
 | 
				
			||||||
import WootMessageEditor from 'dashboard/components/widgets/WootWriter/Editor';
 | 
					import WootMessageEditor from 'dashboard/components/widgets/WootWriter/Editor';
 | 
				
			||||||
 | 
					import { checkFileSizeLimit } from 'shared/helpers/FileHelper';
 | 
				
			||||||
 | 
					import { MAXIMUM_FILE_UPLOAD_SIZE } from 'shared/constants/messages';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
  isEscape,
 | 
					  isEscape,
 | 
				
			||||||
  isEnter,
 | 
					  isEnter,
 | 
				
			||||||
@@ -100,7 +104,7 @@ export default {
 | 
				
			|||||||
    ReplyBottomPanel,
 | 
					    ReplyBottomPanel,
 | 
				
			||||||
    WootMessageEditor,
 | 
					    WootMessageEditor,
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  mixins: [clickaway, inboxMixin, uiSettingsMixin],
 | 
					  mixins: [clickaway, inboxMixin, uiSettingsMixin, alertMixin],
 | 
				
			||||||
  props: {
 | 
					  props: {
 | 
				
			||||||
    inReplyTo: {
 | 
					    inReplyTo: {
 | 
				
			||||||
      type: [String, Number],
 | 
					      type: [String, Number],
 | 
				
			||||||
@@ -351,21 +355,28 @@ export default {
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    onFileUpload(file) {
 | 
					    onFileUpload(file) {
 | 
				
			||||||
      this.attachedFiles = [];
 | 
					 | 
				
			||||||
      if (!file) {
 | 
					      if (!file) {
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      const reader = new FileReader();
 | 
					      if (checkFileSizeLimit(file, MAXIMUM_FILE_UPLOAD_SIZE)) {
 | 
				
			||||||
      reader.readAsDataURL(file.file);
 | 
					        this.attachedFiles = [];
 | 
				
			||||||
 | 
					        const reader = new FileReader();
 | 
				
			||||||
      reader.onloadend = () => {
 | 
					        reader.readAsDataURL(file.file);
 | 
				
			||||||
        this.attachedFiles.push({
 | 
					        reader.onloadend = () => {
 | 
				
			||||||
          currentChatId: this.currentChat.id,
 | 
					          this.attachedFiles.push({
 | 
				
			||||||
          resource: file,
 | 
					            currentChatId: this.currentChat.id,
 | 
				
			||||||
          isPrivate: this.isPrivate,
 | 
					            resource: file,
 | 
				
			||||||
          thumb: reader.result,
 | 
					            isPrivate: this.isPrivate,
 | 
				
			||||||
        });
 | 
					            thumb: reader.result,
 | 
				
			||||||
      };
 | 
					          });
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        this.showAlert(
 | 
				
			||||||
 | 
					          this.$t('CONVERSATION.FILE_SIZE_LIMIT', {
 | 
				
			||||||
 | 
					            MAXIMUM_FILE_UPLOAD_SIZE,
 | 
				
			||||||
 | 
					          })
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    removeAttachment(itemIndex) {
 | 
					    removeAttachment(itemIndex) {
 | 
				
			||||||
      this.attachedFiles = this.attachedFiles.filter(
 | 
					      this.attachedFiles = this.attachedFiles.filter(
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,11 +0,0 @@
 | 
				
			|||||||
export const formatBytes = (bytes, decimals = 2) => {
 | 
					 | 
				
			||||||
  if (bytes === 0) return '0 Bytes';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  const k = 1024;
 | 
					 | 
				
			||||||
  const dm = decimals < 0 ? 0 : decimals;
 | 
					 | 
				
			||||||
  const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  const i = Math.floor(Math.log(bytes) / Math.log(k));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
@@ -1,18 +0,0 @@
 | 
				
			|||||||
import { formatBytes } from '../files';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
describe('#File Helpers', () => {
 | 
					 | 
				
			||||||
  describe('formatBytes', () => {
 | 
					 | 
				
			||||||
    it('should return zero bytes if 0 is passed', () => {
 | 
					 | 
				
			||||||
      expect(formatBytes(0)).toBe('0 Bytes');
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
    it('should return in bytes if 1000 is passed', () => {
 | 
					 | 
				
			||||||
      expect(formatBytes(1000)).toBe('1000 Bytes');
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
    it('should return in KB if 100000 is passed', () => {
 | 
					 | 
				
			||||||
      expect(formatBytes(10000)).toBe('9.77 KB');
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
    it('should return in MB if 10000000 is passed', () => {
 | 
					 | 
				
			||||||
      expect(formatBytes(10000000)).toBe('9.54 MB');
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
@@ -58,6 +58,7 @@
 | 
				
			|||||||
    "CHANGE_STATUS": "Conversation status changed",
 | 
					    "CHANGE_STATUS": "Conversation status changed",
 | 
				
			||||||
    "CHANGE_AGENT": "Conversation Assignee changed",
 | 
					    "CHANGE_AGENT": "Conversation Assignee changed",
 | 
				
			||||||
    "CHANGE_TEAM": "Conversation team changed",
 | 
					    "CHANGE_TEAM": "Conversation team changed",
 | 
				
			||||||
 | 
					    "FILE_SIZE_LIMIT": "File exceeds the {MAXIMUM_FILE_UPLOAD_SIZE} attachment limit",
 | 
				
			||||||
    "SENT_BY": "Sent by:",
 | 
					    "SENT_BY": "Sent by:",
 | 
				
			||||||
    "ASSIGNMENT": {
 | 
					    "ASSIGNMENT": {
 | 
				
			||||||
      "SELECT_AGENT": "Select Agent",
 | 
					      "SELECT_AGENT": "Select Agent",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,5 @@
 | 
				
			|||||||
export const BUS_EVENTS = {
 | 
					export const BUS_EVENTS = {
 | 
				
			||||||
  SET_REFERRER_HOST: 'SET_REFERRER_HOST',
 | 
					  SET_REFERRER_HOST: 'SET_REFERRER_HOST',
 | 
				
			||||||
  SET_TWEET_REPLY: 'SET_TWEET_REPLY',
 | 
					  SET_TWEET_REPLY: 'SET_TWEET_REPLY',
 | 
				
			||||||
 | 
					  ATTACHMENT_SIZE_CHECK_ERROR: 'ATTACHMENT_SIZE_CHECK_ERROR',
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,3 +10,5 @@ export const MESSAGE_TYPE = {
 | 
				
			|||||||
  ACTIVITY: 2,
 | 
					  ACTIVITY: 2,
 | 
				
			||||||
  TEMPLATE: 3,
 | 
					  TEMPLATE: 3,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					// Size in mega bytes
 | 
				
			||||||
 | 
					export const MAXIMUM_FILE_UPLOAD_SIZE = 40;
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										25
									
								
								app/javascript/shared/helpers/FileHelper.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								app/javascript/shared/helpers/FileHelper.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,25 @@
 | 
				
			|||||||
 | 
					export const formatBytes = (bytes, decimals = 2) => {
 | 
				
			||||||
 | 
					  if (bytes === 0) return '0 Bytes';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const k = 1024;
 | 
				
			||||||
 | 
					  const dm = decimals < 0 ? 0 : decimals;
 | 
				
			||||||
 | 
					  const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const i = Math.floor(Math.log(bytes) / Math.log(k));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const fileSizeInMegaBytes = bytes => {
 | 
				
			||||||
 | 
					  if (bytes === 0) {
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  const sizeInMB = (bytes / (1024 * 1024)).toFixed(2);
 | 
				
			||||||
 | 
					  return sizeInMB;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const checkFileSizeLimit = (file, maximumUploadLimit) => {
 | 
				
			||||||
 | 
					  const fileSize = file?.file?.size;
 | 
				
			||||||
 | 
					  const fileSizeInMB = fileSizeInMegaBytes(fileSize);
 | 
				
			||||||
 | 
					  return fileSizeInMB <= maximumUploadLimit;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
							
								
								
									
										38
									
								
								app/javascript/shared/helpers/specs/FileHelper.spec.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								app/javascript/shared/helpers/specs/FileHelper.spec.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,38 @@
 | 
				
			|||||||
 | 
					import {
 | 
				
			||||||
 | 
					  formatBytes,
 | 
				
			||||||
 | 
					  fileSizeInMegaBytes,
 | 
				
			||||||
 | 
					  checkFileSizeLimit,
 | 
				
			||||||
 | 
					} from '../FileHelper';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					describe('#File Helpers', () => {
 | 
				
			||||||
 | 
					  describe('formatBytes', () => {
 | 
				
			||||||
 | 
					    it('should return zero bytes if 0 is passed', () => {
 | 
				
			||||||
 | 
					      expect(formatBytes(0)).toBe('0 Bytes');
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    it('should return in bytes if 1000 is passed', () => {
 | 
				
			||||||
 | 
					      expect(formatBytes(1000)).toBe('1000 Bytes');
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    it('should return in KB if 100000 is passed', () => {
 | 
				
			||||||
 | 
					      expect(formatBytes(10000)).toBe('9.77 KB');
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    it('should return in MB if 10000000 is passed', () => {
 | 
				
			||||||
 | 
					      expect(formatBytes(10000000)).toBe('9.54 MB');
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					  describe('fileSizeInMegaBytes', () => {
 | 
				
			||||||
 | 
					    it('should return zero if 0 is passed', () => {
 | 
				
			||||||
 | 
					      expect(fileSizeInMegaBytes(0)).toBe(0);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    it('should return 19.07 if 20000000 is passed', () => {
 | 
				
			||||||
 | 
					      expect(fileSizeInMegaBytes(20000000)).toBe('19.07');
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					  describe('checkFileSizeLimit', () => {
 | 
				
			||||||
 | 
					    it('should return false if file with size 62208194 and file size limit 40 are passed', () => {
 | 
				
			||||||
 | 
					      expect(checkFileSizeLimit({ file: { size: 62208194 } }, 40)).toBe(false);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    it('should return true if file with size 62208194 and file size limit 40 are passed', () => {
 | 
				
			||||||
 | 
					      expect(checkFileSizeLimit({ file: { size: 199154 } }, 40)).toBe(true);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
@@ -4,7 +4,7 @@
 | 
				
			|||||||
    accept="image/*, application/pdf, audio/mpeg, video/mp4, audio/ogg, text/csv"
 | 
					    accept="image/*, application/pdf, audio/mpeg, video/mp4, audio/ogg, text/csv"
 | 
				
			||||||
    @input-file="onFileUpload"
 | 
					    @input-file="onFileUpload"
 | 
				
			||||||
  >
 | 
					  >
 | 
				
			||||||
    <span class="attachment-button ">
 | 
					    <span class="attachment-button">
 | 
				
			||||||
      <i v-if="!isUploading.image" class="ion-android-attach" />
 | 
					      <i v-if="!isUploading.image" class="ion-android-attach" />
 | 
				
			||||||
      <spinner v-if="isUploading" size="small" />
 | 
					      <spinner v-if="isUploading" size="small" />
 | 
				
			||||||
    </span>
 | 
					    </span>
 | 
				
			||||||
@@ -14,6 +14,9 @@
 | 
				
			|||||||
<script>
 | 
					<script>
 | 
				
			||||||
import FileUpload from 'vue-upload-component';
 | 
					import FileUpload from 'vue-upload-component';
 | 
				
			||||||
import Spinner from 'shared/components/Spinner.vue';
 | 
					import Spinner from 'shared/components/Spinner.vue';
 | 
				
			||||||
 | 
					import { checkFileSizeLimit } from 'shared/helpers/FileHelper';
 | 
				
			||||||
 | 
					import { MAXIMUM_FILE_UPLOAD_SIZE } from 'shared/constants/messages';
 | 
				
			||||||
 | 
					import { BUS_EVENTS } from 'shared/constants/busEvents';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default {
 | 
					export default {
 | 
				
			||||||
  components: { FileUpload, Spinner },
 | 
					  components: { FileUpload, Spinner },
 | 
				
			||||||
@@ -31,14 +34,21 @@ export default {
 | 
				
			|||||||
      return fileType.includes('image') ? 'image' : 'file';
 | 
					      return fileType.includes('image') ? 'image' : 'file';
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    async onFileUpload(file) {
 | 
					    async onFileUpload(file) {
 | 
				
			||||||
 | 
					      if (!file) {
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
      this.isUploading = true;
 | 
					      this.isUploading = true;
 | 
				
			||||||
      try {
 | 
					      try {
 | 
				
			||||||
        const thumbUrl = window.URL.createObjectURL(file.file);
 | 
					        if (checkFileSizeLimit(file, MAXIMUM_FILE_UPLOAD_SIZE)) {
 | 
				
			||||||
        await this.onAttach({
 | 
					          const thumbUrl = window.URL.createObjectURL(file.file);
 | 
				
			||||||
          fileType: this.getFileType(file.type),
 | 
					          await this.onAttach({
 | 
				
			||||||
          file: file.file,
 | 
					            fileType: this.getFileType(file.type),
 | 
				
			||||||
          thumbUrl,
 | 
					            file: file.file,
 | 
				
			||||||
        });
 | 
					            thumbUrl,
 | 
				
			||||||
 | 
					          });
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					          window.bus.$emit(BUS_EVENTS.ATTACHMENT_SIZE_CHECK_ERROR);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
      } catch (error) {
 | 
					      } catch (error) {
 | 
				
			||||||
        // Error
 | 
					        // Error
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -48,5 +48,6 @@
 | 
				
			|||||||
        "ERROR": "Message too short"
 | 
					        "ERROR": "Message too short"
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  },
 | 
				
			||||||
 | 
					  "FILE_SIZE_LIMIT": "File exceeds the {MAXIMUM_FILE_UPLOAD_SIZE} attachment limit"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -34,6 +34,15 @@
 | 
				
			|||||||
        />
 | 
					        />
 | 
				
			||||||
      </transition>
 | 
					      </transition>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
 | 
					    <div v-if="showAttachmentError" class="banner">
 | 
				
			||||||
 | 
					      <span>
 | 
				
			||||||
 | 
					        {{
 | 
				
			||||||
 | 
					          $t('FILE_SIZE_LIMIT', {
 | 
				
			||||||
 | 
					            MAXIMUM_FILE_UPLOAD_SIZE: fileUploadSizeLimit,
 | 
				
			||||||
 | 
					          })
 | 
				
			||||||
 | 
					        }}
 | 
				
			||||||
 | 
					      </span>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
    <div class="flex flex-1 overflow-auto">
 | 
					    <div class="flex flex-1 overflow-auto">
 | 
				
			||||||
      <conversation-wrap
 | 
					      <conversation-wrap
 | 
				
			||||||
        v-if="currentView === 'messageView'"
 | 
					        v-if="currentView === 'messageView'"
 | 
				
			||||||
@@ -80,6 +89,8 @@ import configMixin from '../mixins/configMixin';
 | 
				
			|||||||
import TeamAvailability from 'widget/components/TeamAvailability';
 | 
					import TeamAvailability from 'widget/components/TeamAvailability';
 | 
				
			||||||
import Spinner from 'shared/components/Spinner.vue';
 | 
					import Spinner from 'shared/components/Spinner.vue';
 | 
				
			||||||
import { mapGetters } from 'vuex';
 | 
					import { mapGetters } from 'vuex';
 | 
				
			||||||
 | 
					import { MAXIMUM_FILE_UPLOAD_SIZE } from 'shared/constants/messages';
 | 
				
			||||||
 | 
					import { BUS_EVENTS } from 'shared/constants/busEvents';
 | 
				
			||||||
import PreChatForm from '../components/PreChat/Form';
 | 
					import PreChatForm from '../components/PreChat/Form';
 | 
				
			||||||
export default {
 | 
					export default {
 | 
				
			||||||
  name: 'Home',
 | 
					  name: 'Home',
 | 
				
			||||||
@@ -105,7 +116,7 @@ export default {
 | 
				
			|||||||
    },
 | 
					    },
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  data() {
 | 
					  data() {
 | 
				
			||||||
    return { isOnCollapsedView: false };
 | 
					    return { isOnCollapsedView: false, showAttachmentError: false };
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  computed: {
 | 
					  computed: {
 | 
				
			||||||
    ...mapGetters({
 | 
					    ...mapGetters({
 | 
				
			||||||
@@ -132,6 +143,9 @@ export default {
 | 
				
			|||||||
    isOpen() {
 | 
					    isOpen() {
 | 
				
			||||||
      return this.conversationAttributes.status === 'open';
 | 
					      return this.conversationAttributes.status === 'open';
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    fileUploadSizeLimit() {
 | 
				
			||||||
 | 
					      return MAXIMUM_FILE_UPLOAD_SIZE;
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    showInputTextArea() {
 | 
					    showInputTextArea() {
 | 
				
			||||||
      if (this.hideInputForBotConversations) {
 | 
					      if (this.hideInputForBotConversations) {
 | 
				
			||||||
        if (this.isOpen) {
 | 
					        if (this.isOpen) {
 | 
				
			||||||
@@ -154,6 +168,14 @@ export default {
 | 
				
			|||||||
      );
 | 
					      );
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
 | 
					  mounted() {
 | 
				
			||||||
 | 
					    bus.$on(BUS_EVENTS.ATTACHMENT_SIZE_CHECK_ERROR, () => {
 | 
				
			||||||
 | 
					      this.showAttachmentError = true;
 | 
				
			||||||
 | 
					      setTimeout(() => {
 | 
				
			||||||
 | 
					        this.showAttachmentError = false;
 | 
				
			||||||
 | 
					      }, 3000);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
  methods: {
 | 
					  methods: {
 | 
				
			||||||
    startConversation() {
 | 
					    startConversation() {
 | 
				
			||||||
      this.isOnCollapsedView = !this.isOnCollapsedView;
 | 
					      this.isOnCollapsedView = !this.isOnCollapsedView;
 | 
				
			||||||
@@ -221,5 +243,13 @@ export default {
 | 
				
			|||||||
  .input-wrap {
 | 
					  .input-wrap {
 | 
				
			||||||
    padding: 0 $space-normal;
 | 
					    padding: 0 $space-normal;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					  .banner {
 | 
				
			||||||
 | 
					    background: $color-error;
 | 
				
			||||||
 | 
					    color: $color-white;
 | 
				
			||||||
 | 
					    font-size: $font-size-default;
 | 
				
			||||||
 | 
					    font-weight: $font-weight-bold;
 | 
				
			||||||
 | 
					    padding: $space-slab;
 | 
				
			||||||
 | 
					    text-align: center;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
</style>
 | 
					</style>
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user