mirror of
				https://github.com/lingble/chatwoot.git
				synced 2025-11-04 04:57:51 +00:00 
			
		
		
		
	feat: Update reply box UI 👀 (#1623)
Co-authored-by: Pranav Raj S <pranav@chatwoot.com>
This commit is contained in:
		
				
					committed by
					
						
						GitHub
					
				
			
			
				
	
			
			
			
						parent
						
							2d5aa9d3bd
						
					
				
				
					commit
					fd181f18a1
				
			@@ -96,9 +96,9 @@
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.conversation-wrap {
 | 
					.conversation-wrap {
 | 
				
			||||||
  @include background-gray;
 | 
					 | 
				
			||||||
  @include margin(0);
 | 
					  @include margin(0);
 | 
				
			||||||
  @include border-normal-left;
 | 
					  @include border-normal-left;
 | 
				
			||||||
 | 
					  background: var(--color-background-light);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  .current-chat {
 | 
					  .current-chat {
 | 
				
			||||||
    @include flex;
 | 
					    @include flex;
 | 
				
			||||||
@@ -140,8 +140,8 @@
 | 
				
			|||||||
  flex-direction: column;
 | 
					  flex-direction: column;
 | 
				
			||||||
  // Firefox flexbox fix
 | 
					  // Firefox flexbox fix
 | 
				
			||||||
  height: 100%;
 | 
					  height: 100%;
 | 
				
			||||||
  margin-bottom: $space-small;
 | 
					 | 
				
			||||||
  overflow-y: auto;
 | 
					  overflow-y: auto;
 | 
				
			||||||
 | 
					  padding-bottom: var(--space-normal);
 | 
				
			||||||
  position: relative;
 | 
					  position: relative;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,28 +1,13 @@
 | 
				
			|||||||
.reply-box {
 | 
					.reply-box {
 | 
				
			||||||
  @include light-shadow;
 | 
					 | 
				
			||||||
  border-bottom: 0;
 | 
					 | 
				
			||||||
  border-radius: $space-small;
 | 
					 | 
				
			||||||
  margin: $space-normal;
 | 
					 | 
				
			||||||
  margin-top: 0;
 | 
					 | 
				
			||||||
  max-height: $space-mega * 3;
 | 
					 | 
				
			||||||
  transition: box-shadow .35s $swift-ease-out-function,
 | 
					  transition: box-shadow .35s $swift-ease-out-function,
 | 
				
			||||||
    height 2s $swift-ease-out-function;
 | 
					    height 2s $swift-ease-out-function;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  &.is-focused {
 | 
					  &.is-focused {
 | 
				
			||||||
    @include shadow;
 | 
					    box-shadow: var(--shadow);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  .reply-box__top {
 | 
					  .reply-box__top {
 | 
				
			||||||
    @include flex;
 | 
					 | 
				
			||||||
    @include flex-align($x: left, $y: middle);
 | 
					 | 
				
			||||||
    @include padding($space-one $space-normal);
 | 
					 | 
				
			||||||
    @include background-white;
 | 
					 | 
				
			||||||
    @include margin(0);
 | 
					 | 
				
			||||||
    border-top-left-radius: $space-small;
 | 
					 | 
				
			||||||
    border-top-right-radius: $space-small;
 | 
					 | 
				
			||||||
    position: relative;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .canned {
 | 
					    .canned {
 | 
				
			||||||
      @include elegant-card;
 | 
					      @include elegant-card;
 | 
				
			||||||
      background: $color-white;
 | 
					      background: $color-white;
 | 
				
			||||||
@@ -41,19 +26,6 @@
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    &.is-active {
 | 
					 | 
				
			||||||
      border-bottom-left-radius: $space-small;
 | 
					 | 
				
			||||||
      border-bottom-right-radius: $space-small;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    &.is-private {
 | 
					 | 
				
			||||||
      background: lighten($warning-color, 38%);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      >input {
 | 
					 | 
				
			||||||
        background: lighten($warning-color, 38%);
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .icon {
 | 
					    .icon {
 | 
				
			||||||
      color: $medium-gray;
 | 
					      color: $medium-gray;
 | 
				
			||||||
      cursor: pointer;
 | 
					      cursor: pointer;
 | 
				
			||||||
@@ -65,9 +37,6 @@
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    .file-uploads>label {
 | 
					 | 
				
			||||||
      cursor: pointer;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    .attachment {
 | 
					    .attachment {
 | 
				
			||||||
      cursor: pointer;
 | 
					      cursor: pointer;
 | 
				
			||||||
@@ -82,87 +51,45 @@
 | 
				
			|||||||
      // Override min-height : 50px in foundation
 | 
					      // Override min-height : 50px in foundation
 | 
				
			||||||
      //
 | 
					      //
 | 
				
			||||||
      max-height: $space-mega * 2.4;
 | 
					      max-height: $space-mega * 2.4;
 | 
				
			||||||
      min-height: 4rem;
 | 
					      min-height: 4.8rem;
 | 
				
			||||||
 | 
					      padding: var(--space-normal) 0 0;
 | 
				
			||||||
      resize: none;
 | 
					      resize: none;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  .reply-box__bottom {
 | 
					  &.is-private {
 | 
				
			||||||
    @include background-light;
 | 
					    background: var(--y-50);
 | 
				
			||||||
    @include flex;
 | 
					 | 
				
			||||||
    @include flex-align($x: justify, $y: middle);
 | 
					 | 
				
			||||||
    @include border-light-top;
 | 
					 | 
				
			||||||
    border-bottom-left-radius: $space-small;
 | 
					 | 
				
			||||||
    border-bottom-right-radius: $space-small;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    .tabs {
 | 
					    .reply-box__top {
 | 
				
			||||||
      border: 0;
 | 
					      background: var(--y-50);
 | 
				
			||||||
      flex: 1;
 | 
					 | 
				
			||||||
      padding: 0;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
      .tabs-title {
 | 
					      >input {
 | 
				
			||||||
        margin: 0;
 | 
					        background: var(--y-50);
 | 
				
			||||||
        transition: all .2s $swift-ease-out-function;
 | 
					 | 
				
			||||||
        transition-property: color, background;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        a {
 | 
					 | 
				
			||||||
          font-weight: $font-weight-medium;
 | 
					 | 
				
			||||||
          padding: $space-one $space-two;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        &.is-private.is-active {
 | 
					 | 
				
			||||||
          background: lighten($warning-color, 38%);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
          a {
 | 
					 | 
				
			||||||
            border-bottom-color: darken($warning-color, 15%);
 | 
					 | 
				
			||||||
            color: darken($warning-color, 15%);
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      .tabs-title:first-child {
 | 
					 | 
				
			||||||
        border-bottom-left-radius: $space-small;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        &.is-active {
 | 
					 | 
				
			||||||
          @include border-light-right;
 | 
					 | 
				
			||||||
          border-left: 0;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        a {
 | 
					 | 
				
			||||||
          border-bottom-left-radius: $space-small;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      .is-active {
 | 
					 | 
				
			||||||
        @include background-white;
 | 
					 | 
				
			||||||
        @include border-light-left;
 | 
					 | 
				
			||||||
        @include border-light-right;
 | 
					 | 
				
			||||||
        margin-top: -1px;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      .message-length {
 | 
					 | 
				
			||||||
        float: right;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        a {
 | 
					 | 
				
			||||||
          font-size: $font-size-mini;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      .message-error {
 | 
					 | 
				
			||||||
        color: $input-error-color;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .send-button {
 | 
					 | 
				
			||||||
      border-bottom-right-radius: $space-small;
 | 
					 | 
				
			||||||
      height: 3.6rem;
 | 
					 | 
				
			||||||
      padding-left: $space-two;
 | 
					 | 
				
			||||||
      padding-right: $space-two;
 | 
					 | 
				
			||||||
      padding-top: $space-small;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      .icon {
 | 
					 | 
				
			||||||
        margin-left: $space-small;
 | 
					 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  .file-uploads>label {
 | 
				
			||||||
 | 
					    cursor: pointer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    &:hover .button--emoji {
 | 
				
			||||||
 | 
					      background: var(--b-200);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  .bottom-box .button--emoji.button--upload {
 | 
				
			||||||
 | 
					    height: var(--space-large);
 | 
				
			||||||
 | 
					    padding: 0;
 | 
				
			||||||
 | 
					    width: var(--space-large);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .file-uploads {
 | 
				
			||||||
 | 
					      height: 100%;
 | 
				
			||||||
 | 
					      line-height: var(--space-large);
 | 
				
			||||||
 | 
					      width: 100%;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    label {
 | 
				
			||||||
 | 
					      padding: var(--space-small);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -66,7 +66,9 @@ export default {
 | 
				
			|||||||
<style lang="scss" scoped>
 | 
					<style lang="scss" scoped>
 | 
				
			||||||
.preview-item {
 | 
					.preview-item {
 | 
				
			||||||
  display: flex;
 | 
					  display: flex;
 | 
				
			||||||
  padding: 0 var(--space-small) var(--space-smaller);
 | 
					  padding: var(--space-slab) 0 0;
 | 
				
			||||||
 | 
					  background: var(--color-background-light);
 | 
				
			||||||
 | 
					  background: transparent;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.thumb-wrap {
 | 
					.thumb-wrap {
 | 
				
			||||||
@@ -89,13 +91,16 @@ export default {
 | 
				
			|||||||
  height: var(--space-medium);
 | 
					  height: var(--space-medium);
 | 
				
			||||||
  font-size: var(--font-size-medium);
 | 
					  font-size: var(--font-size-medium);
 | 
				
			||||||
  text-align: center;
 | 
					  text-align: center;
 | 
				
			||||||
 | 
					  position: relative;
 | 
				
			||||||
 | 
					  top: -1px;
 | 
				
			||||||
 | 
					  text-align: left;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.file-name-wrap,
 | 
					.file-name-wrap,
 | 
				
			||||||
.file-size-wrap {
 | 
					.file-size-wrap {
 | 
				
			||||||
  display: flex;
 | 
					  display: flex;
 | 
				
			||||||
  align-items: center;
 | 
					  align-items: center;
 | 
				
			||||||
  padding: 0 var(--space-one);
 | 
					  padding: 0 var(--space-smaller);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  > .item {
 | 
					  > .item {
 | 
				
			||||||
    margin: 0;
 | 
					    margin: 0;
 | 
				
			||||||
@@ -109,12 +114,20 @@ export default {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.file-name-wrap {
 | 
					.file-name-wrap {
 | 
				
			||||||
  width: 100%;
 | 
					  max-width: 50%;
 | 
				
			||||||
 | 
					  overflow: hidden;
 | 
				
			||||||
 | 
					  text-overflow: ellipsis;
 | 
				
			||||||
 | 
					  .item {
 | 
				
			||||||
 | 
					    height: var(--space-normal);
 | 
				
			||||||
 | 
					    overflow: hidden;
 | 
				
			||||||
 | 
					    text-overflow: ellipsis;
 | 
				
			||||||
 | 
					    white-space: nowrap;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.file-size-wrap {
 | 
					.file-size-wrap {
 | 
				
			||||||
  width: 20%;
 | 
					  width: 20%;
 | 
				
			||||||
  justify-content: flex-end;
 | 
					  justify-content: center;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.remove-file-wrap {
 | 
					.remove-file-wrap {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -0,0 +1,178 @@
 | 
				
			|||||||
 | 
					<template>
 | 
				
			||||||
 | 
					  <div class="bottom-box" :class="wrapClass">
 | 
				
			||||||
 | 
					    <div class="left-wrap">
 | 
				
			||||||
 | 
					      <button class="button clear button--emoji" @click="toggleEmojiPicker">
 | 
				
			||||||
 | 
					        <emoji-or-icon icon="ion-happy-outline" emoji="😊" />
 | 
				
			||||||
 | 
					      </button>
 | 
				
			||||||
 | 
					      <button
 | 
				
			||||||
 | 
					        v-if="showAttachButton"
 | 
				
			||||||
 | 
					        class="button clear button--emoji button--upload"
 | 
				
			||||||
 | 
					      >
 | 
				
			||||||
 | 
					        <file-upload
 | 
				
			||||||
 | 
					          :size="4096 * 4096"
 | 
				
			||||||
 | 
					          accept="image/*, application/pdf, audio/mpeg, video/mp4, audio/ogg, text/csv"
 | 
				
			||||||
 | 
					          @input-file="onFileUpload"
 | 
				
			||||||
 | 
					        >
 | 
				
			||||||
 | 
					          <emoji-or-icon icon="ion-android-attach" emoji="📎" />
 | 
				
			||||||
 | 
					        </file-upload>
 | 
				
			||||||
 | 
					      </button>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					    <div class="right-wrap">
 | 
				
			||||||
 | 
					      <button
 | 
				
			||||||
 | 
					        class="button nice primary button--send"
 | 
				
			||||||
 | 
					        :class="buttonClass"
 | 
				
			||||||
 | 
					        @click="onSend"
 | 
				
			||||||
 | 
					      >
 | 
				
			||||||
 | 
					        {{ sendButtonText }}
 | 
				
			||||||
 | 
					      </button>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					  </div>
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<script>
 | 
				
			||||||
 | 
					import FileUpload from 'vue-upload-component';
 | 
				
			||||||
 | 
					import EmojiOrIcon from 'shared/components/EmojiOrIcon';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { REPLY_EDITOR_MODES } from './constants';
 | 
				
			||||||
 | 
					export default {
 | 
				
			||||||
 | 
					  name: 'ReplyTopPanel',
 | 
				
			||||||
 | 
					  components: { EmojiOrIcon, FileUpload },
 | 
				
			||||||
 | 
					  props: {
 | 
				
			||||||
 | 
					    mode: {
 | 
				
			||||||
 | 
					      type: String,
 | 
				
			||||||
 | 
					      default: REPLY_EDITOR_MODES.REPLY,
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    onSend: {
 | 
				
			||||||
 | 
					      type: Function,
 | 
				
			||||||
 | 
					      default: () => {},
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    sendButtonText: {
 | 
				
			||||||
 | 
					      type: String,
 | 
				
			||||||
 | 
					      default: '',
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    showFileUpload: {
 | 
				
			||||||
 | 
					      type: Boolean,
 | 
				
			||||||
 | 
					      default: false,
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    onFileUpload: {
 | 
				
			||||||
 | 
					      type: Function,
 | 
				
			||||||
 | 
					      default: () => {},
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    showEmojiPicker: {
 | 
				
			||||||
 | 
					      type: Boolean,
 | 
				
			||||||
 | 
					      default: false,
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    toggleEmojiPicker: {
 | 
				
			||||||
 | 
					      type: Function,
 | 
				
			||||||
 | 
					      default: () => {},
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    isSendDisabled: {
 | 
				
			||||||
 | 
					      type: Boolean,
 | 
				
			||||||
 | 
					      default: false,
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  computed: {
 | 
				
			||||||
 | 
					    isNote() {
 | 
				
			||||||
 | 
					      return this.mode === REPLY_EDITOR_MODES.NOTE;
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    wrapClass() {
 | 
				
			||||||
 | 
					      return {
 | 
				
			||||||
 | 
					        'is-note-mode': this.isNote,
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    buttonClass() {
 | 
				
			||||||
 | 
					      return {
 | 
				
			||||||
 | 
					        'button--note': this.isNote,
 | 
				
			||||||
 | 
					        'button--disabled': this.isSendDisabled,
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    showAttachButton() {
 | 
				
			||||||
 | 
					      return this.showFileUpload || this.isNote;
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<style lang="scss" scoped>
 | 
				
			||||||
 | 
					@import '~widget/assets/scss/variables.scss';
 | 
				
			||||||
 | 
					@import '~widget/assets/scss/mixins.scss';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.bottom-box {
 | 
				
			||||||
 | 
					  display: flex;
 | 
				
			||||||
 | 
					  justify-content: space-between;
 | 
				
			||||||
 | 
					  padding: var(--space-slab) var(--space-normal);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  &.is-note-mode {
 | 
				
			||||||
 | 
					    background: var(--y-50);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.button {
 | 
				
			||||||
 | 
					  font-size: var(--font-size-small);
 | 
				
			||||||
 | 
					  font-weight: var(--font-weight-medium);
 | 
				
			||||||
 | 
					  padding: var(--space-one) var(--space-slab);
 | 
				
			||||||
 | 
					  display: flex;
 | 
				
			||||||
 | 
					  align-items: center;
 | 
				
			||||||
 | 
					  justify-content: space-between;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  &:hover {
 | 
				
			||||||
 | 
					    background: var(--w-300);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  &.is-active {
 | 
				
			||||||
 | 
					    background: white;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  &.button--emoji {
 | 
				
			||||||
 | 
					    font-size: var(--font-size-small);
 | 
				
			||||||
 | 
					    padding: var(--space-small);
 | 
				
			||||||
 | 
					    border-radius: 9px;
 | 
				
			||||||
 | 
					    background: var(--b-50);
 | 
				
			||||||
 | 
					    border: 1px solid var(--color-border-light);
 | 
				
			||||||
 | 
					    margin-right: var(--space-small);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    &:hover {
 | 
				
			||||||
 | 
					      background: var(--b-200);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  &.button--note {
 | 
				
			||||||
 | 
					    background: var(--y-800);
 | 
				
			||||||
 | 
					    color: white;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    &:hover {
 | 
				
			||||||
 | 
					      background: var(--y-700);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  &.button--disabled {
 | 
				
			||||||
 | 
					    background: var(--b-100);
 | 
				
			||||||
 | 
					    color: var(--b-400);
 | 
				
			||||||
 | 
					    cursor: default;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    &:hover {
 | 
				
			||||||
 | 
					      background: var(--b-100);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.bottom-box.is-note-mode {
 | 
				
			||||||
 | 
					  .button--emoji {
 | 
				
			||||||
 | 
					    background: white;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.left-wrap {
 | 
				
			||||||
 | 
					  display: flex;
 | 
				
			||||||
 | 
					  align-items: center;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.button--reply {
 | 
				
			||||||
 | 
					  border-right: 1px solid var(--color-border-light);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.icon--font {
 | 
				
			||||||
 | 
					  color: var(--s-600);
 | 
				
			||||||
 | 
					  font-size: var(--font-size-default);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					</style>
 | 
				
			||||||
@@ -0,0 +1,117 @@
 | 
				
			|||||||
 | 
					<template>
 | 
				
			||||||
 | 
					  <div class="top-box">
 | 
				
			||||||
 | 
					    <div class="mode-wrap button-group">
 | 
				
			||||||
 | 
					      <button
 | 
				
			||||||
 | 
					        class="button clear button--reply"
 | 
				
			||||||
 | 
					        :class="replyButtonClass"
 | 
				
			||||||
 | 
					        @click="handleReplyClick"
 | 
				
			||||||
 | 
					      >
 | 
				
			||||||
 | 
					        <emoji-or-icon icon="" emoji="💬" />
 | 
				
			||||||
 | 
					        {{ $t('CONVERSATION.REPLYBOX.REPLY') }}
 | 
				
			||||||
 | 
					      </button>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      <button
 | 
				
			||||||
 | 
					        class="button clear button--note"
 | 
				
			||||||
 | 
					        :class="noteButtonClass"
 | 
				
			||||||
 | 
					        @click="handleNoteClick"
 | 
				
			||||||
 | 
					      >
 | 
				
			||||||
 | 
					        <emoji-or-icon icon="" emoji="📝" />
 | 
				
			||||||
 | 
					        {{ $t('CONVERSATION.REPLYBOX.PRIVATE_NOTE') }}
 | 
				
			||||||
 | 
					      </button>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					    <div class="action-wrap"></div>
 | 
				
			||||||
 | 
					  </div>
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<script>
 | 
				
			||||||
 | 
					import { REPLY_EDITOR_MODES } from './constants';
 | 
				
			||||||
 | 
					import EmojiOrIcon from 'shared/components/EmojiOrIcon';
 | 
				
			||||||
 | 
					export default {
 | 
				
			||||||
 | 
					  name: 'ReplyTopPanel',
 | 
				
			||||||
 | 
					  components: {
 | 
				
			||||||
 | 
					    EmojiOrIcon,
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  props: {
 | 
				
			||||||
 | 
					    mode: {
 | 
				
			||||||
 | 
					      type: String,
 | 
				
			||||||
 | 
					      default: REPLY_EDITOR_MODES.REPLY,
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    setReplyMode: {
 | 
				
			||||||
 | 
					      type: Function,
 | 
				
			||||||
 | 
					      default: () => {},
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  computed: {
 | 
				
			||||||
 | 
					    replyButtonClass() {
 | 
				
			||||||
 | 
					      return {
 | 
				
			||||||
 | 
					        'is-active': this.mode === REPLY_EDITOR_MODES.REPLY,
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    noteButtonClass() {
 | 
				
			||||||
 | 
					      return {
 | 
				
			||||||
 | 
					        'is-active': this.mode === REPLY_EDITOR_MODES.NOTE,
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  methods: {
 | 
				
			||||||
 | 
					    handleReplyClick() {
 | 
				
			||||||
 | 
					      this.setReplyMode(REPLY_EDITOR_MODES.REPLY);
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    handleNoteClick() {
 | 
				
			||||||
 | 
					      this.setReplyMode(REPLY_EDITOR_MODES.NOTE);
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<style lang="scss" scoped>
 | 
				
			||||||
 | 
					.top-box {
 | 
				
			||||||
 | 
					  display: flex;
 | 
				
			||||||
 | 
					  justify-content: space-between;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  background: var(--b-100);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.button-group {
 | 
				
			||||||
 | 
					  border: 0;
 | 
				
			||||||
 | 
					  padding: 0;
 | 
				
			||||||
 | 
					  margin: 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  .button {
 | 
				
			||||||
 | 
					    font-size: var(--font-size-small);
 | 
				
			||||||
 | 
					    font-weight: var(--font-weight-medium);
 | 
				
			||||||
 | 
					    padding: var(--space-one) var(--space-normal);
 | 
				
			||||||
 | 
					    margin: 0;
 | 
				
			||||||
 | 
					    position: relative;
 | 
				
			||||||
 | 
					    z-index: 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    &.is-active {
 | 
				
			||||||
 | 
					      background: white;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  .button--reply {
 | 
				
			||||||
 | 
					    border-right: 1px solid var(--color-border);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    &:hover {
 | 
				
			||||||
 | 
					      border-right: 1px solid var(--color-border);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  .button--note {
 | 
				
			||||||
 | 
					    &.is-active {
 | 
				
			||||||
 | 
					      border-right: 1px solid var(--color-border);
 | 
				
			||||||
 | 
					      background: var(--y-50);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.button--note {
 | 
				
			||||||
 | 
					  color: var(--y-900);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.action-wrap {
 | 
				
			||||||
 | 
					  display: flex;
 | 
				
			||||||
 | 
					  align-items: center;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					</style>
 | 
				
			||||||
@@ -0,0 +1,4 @@
 | 
				
			|||||||
 | 
					export const REPLY_EDITOR_MODES = {
 | 
				
			||||||
 | 
					  REPLY: 'REPLY',
 | 
				
			||||||
 | 
					  NOTE: 'NOTE',
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
@@ -1,102 +1,61 @@
 | 
				
			|||||||
<template>
 | 
					<template>
 | 
				
			||||||
  <div>
 | 
					  <div class="reply-box" :class="replyBoxClass">
 | 
				
			||||||
 | 
					    <reply-top-panel :mode="replyType" :set-reply-mode="setReplyMode" />
 | 
				
			||||||
 | 
					    <div class="reply-box__top">
 | 
				
			||||||
 | 
					      <canned-response
 | 
				
			||||||
 | 
					        v-if="showCannedResponsesList"
 | 
				
			||||||
 | 
					        v-on-clickaway="hideCannedResponse"
 | 
				
			||||||
 | 
					        data-dropdown-menu
 | 
				
			||||||
 | 
					        :on-keyenter="replaceText"
 | 
				
			||||||
 | 
					        :on-click="replaceText"
 | 
				
			||||||
 | 
					      />
 | 
				
			||||||
 | 
					      <emoji-input
 | 
				
			||||||
 | 
					        v-if="showEmojiPicker"
 | 
				
			||||||
 | 
					        v-on-clickaway="hideEmojiPicker"
 | 
				
			||||||
 | 
					        :on-click="emojiOnClick"
 | 
				
			||||||
 | 
					      />
 | 
				
			||||||
 | 
					      <resizable-text-area
 | 
				
			||||||
 | 
					        ref="messageInput"
 | 
				
			||||||
 | 
					        v-model="message"
 | 
				
			||||||
 | 
					        class="input"
 | 
				
			||||||
 | 
					        :placeholder="messagePlaceHolder"
 | 
				
			||||||
 | 
					        :min-height="4"
 | 
				
			||||||
 | 
					        @typing-off="onTypingOff"
 | 
				
			||||||
 | 
					        @typing-on="onTypingOn"
 | 
				
			||||||
 | 
					        @focus="onFocus"
 | 
				
			||||||
 | 
					        @blur="onBlur"
 | 
				
			||||||
 | 
					      />
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
    <div v-if="hasAttachments" class="attachment-preview-box">
 | 
					    <div v-if="hasAttachments" class="attachment-preview-box">
 | 
				
			||||||
      <attachment-preview
 | 
					      <attachment-preview
 | 
				
			||||||
        :attachments="attachedFiles"
 | 
					        :attachments="attachedFiles"
 | 
				
			||||||
        :remove-attachment="removeAttachment"
 | 
					        :remove-attachment="removeAttachment"
 | 
				
			||||||
      />
 | 
					      />
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
    <div class="reply-box" :class="replyBoxClass">
 | 
					    <reply-bottom-panel
 | 
				
			||||||
      <div class="reply-box__top" :class="{ 'is-private': isPrivate }">
 | 
					      :mode="replyType"
 | 
				
			||||||
        <canned-response
 | 
					      :send-button-text="replyButtonLabel"
 | 
				
			||||||
          v-if="showCannedResponsesList"
 | 
					      :on-file-upload="onFileUpload"
 | 
				
			||||||
          v-on-clickaway="hideCannedResponse"
 | 
					      :show-file-upload="showFileUpload"
 | 
				
			||||||
          data-dropdown-menu
 | 
					      :toggle-emoji-picker="toggleEmojiPicker"
 | 
				
			||||||
          :on-keyenter="replaceText"
 | 
					      :show-emoji-picker="showEmojiPicker"
 | 
				
			||||||
          :on-click="replaceText"
 | 
					      :on-send="sendMessage"
 | 
				
			||||||
        />
 | 
					      :is-send-disabled="isReplyButtonDisabled"
 | 
				
			||||||
        <emoji-input
 | 
					    />
 | 
				
			||||||
          v-if="showEmojiPicker"
 | 
					 | 
				
			||||||
          v-on-clickaway="hideEmojiPicker"
 | 
					 | 
				
			||||||
          :on-click="emojiOnClick"
 | 
					 | 
				
			||||||
        />
 | 
					 | 
				
			||||||
        <resizable-text-area
 | 
					 | 
				
			||||||
          ref="messageInput"
 | 
					 | 
				
			||||||
          v-model="message"
 | 
					 | 
				
			||||||
          class="input"
 | 
					 | 
				
			||||||
          :placeholder="messagePlaceHolder"
 | 
					 | 
				
			||||||
          :min-height="4"
 | 
					 | 
				
			||||||
          @typing-off="onTypingOff"
 | 
					 | 
				
			||||||
          @typing-on="onTypingOn"
 | 
					 | 
				
			||||||
          @focus="onFocus"
 | 
					 | 
				
			||||||
          @blur="onBlur"
 | 
					 | 
				
			||||||
        />
 | 
					 | 
				
			||||||
        <file-upload
 | 
					 | 
				
			||||||
          v-if="showFileUpload"
 | 
					 | 
				
			||||||
          :size="4096 * 4096"
 | 
					 | 
				
			||||||
          accept="image/*, application/pdf, audio/mpeg, video/mp4, audio/ogg, text/csv"
 | 
					 | 
				
			||||||
          @input-file="onFileUpload"
 | 
					 | 
				
			||||||
        >
 | 
					 | 
				
			||||||
          <i class="icon ion-android-attach attachment" />
 | 
					 | 
				
			||||||
        </file-upload>
 | 
					 | 
				
			||||||
        <i
 | 
					 | 
				
			||||||
          class="icon ion-happy-outline"
 | 
					 | 
				
			||||||
          :class="{ active: showEmojiPicker }"
 | 
					 | 
				
			||||||
          @click="toggleEmojiPicker"
 | 
					 | 
				
			||||||
        />
 | 
					 | 
				
			||||||
      </div>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      <div class="reply-box__bottom">
 | 
					 | 
				
			||||||
        <ul class="tabs">
 | 
					 | 
				
			||||||
          <li class="tabs-title" :class="{ 'is-active': !isPrivate }">
 | 
					 | 
				
			||||||
            <a href="#" @click="setReplyMode">{{
 | 
					 | 
				
			||||||
              $t('CONVERSATION.REPLYBOX.REPLY')
 | 
					 | 
				
			||||||
            }}</a>
 | 
					 | 
				
			||||||
          </li>
 | 
					 | 
				
			||||||
          <li class="tabs-title is-private" :class="{ 'is-active': isPrivate }">
 | 
					 | 
				
			||||||
            <a href="#" @click="setPrivateReplyMode">
 | 
					 | 
				
			||||||
              {{ $t('CONVERSATION.REPLYBOX.PRIVATE_NOTE') }}
 | 
					 | 
				
			||||||
            </a>
 | 
					 | 
				
			||||||
          </li>
 | 
					 | 
				
			||||||
          <li v-if="message.length" class="tabs-title message-length">
 | 
					 | 
				
			||||||
            <a :class="{ 'message-error': isMessageLengthReachingThreshold }">
 | 
					 | 
				
			||||||
              {{ characterCountIndicator }}
 | 
					 | 
				
			||||||
            </a>
 | 
					 | 
				
			||||||
          </li>
 | 
					 | 
				
			||||||
        </ul>
 | 
					 | 
				
			||||||
        <button
 | 
					 | 
				
			||||||
          type="button"
 | 
					 | 
				
			||||||
          class="button send-button"
 | 
					 | 
				
			||||||
          :disabled="isReplyButtonDisabled"
 | 
					 | 
				
			||||||
          :class="{
 | 
					 | 
				
			||||||
            disabled: isReplyButtonDisabled,
 | 
					 | 
				
			||||||
            warning: isPrivate,
 | 
					 | 
				
			||||||
          }"
 | 
					 | 
				
			||||||
          @click="sendMessage"
 | 
					 | 
				
			||||||
        >
 | 
					 | 
				
			||||||
          {{ replyButtonLabel }}
 | 
					 | 
				
			||||||
          <i
 | 
					 | 
				
			||||||
            class="icon"
 | 
					 | 
				
			||||||
            :class="{
 | 
					 | 
				
			||||||
              'ion-android-send': !isPrivate,
 | 
					 | 
				
			||||||
              'ion-android-lock': isPrivate,
 | 
					 | 
				
			||||||
            }"
 | 
					 | 
				
			||||||
          />
 | 
					 | 
				
			||||||
        </button>
 | 
					 | 
				
			||||||
      </div>
 | 
					 | 
				
			||||||
    </div>
 | 
					 | 
				
			||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<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 FileUpload from 'vue-upload-component';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
import EmojiInput from 'shared/components/emoji/EmojiInput';
 | 
					import EmojiInput from 'shared/components/emoji/EmojiInput';
 | 
				
			||||||
import CannedResponse from './CannedResponse';
 | 
					import CannedResponse from './CannedResponse';
 | 
				
			||||||
import ResizableTextArea from 'shared/components/ResizableTextArea';
 | 
					import ResizableTextArea from 'shared/components/ResizableTextArea';
 | 
				
			||||||
import AttachmentPreview from 'dashboard/components/widgets/AttachmentsPreview';
 | 
					import AttachmentPreview from 'dashboard/components/widgets/AttachmentsPreview';
 | 
				
			||||||
 | 
					import ReplyTopPanel from 'dashboard/components/widgets/WootWriter/ReplyTopPanel';
 | 
				
			||||||
 | 
					import ReplyBottomPanel from 'dashboard/components/widgets/WootWriter/ReplyBottomPanel';
 | 
				
			||||||
 | 
					import { REPLY_EDITOR_MODES } from 'dashboard/components/widgets/WootWriter/constants';
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
  isEscape,
 | 
					  isEscape,
 | 
				
			||||||
  isEnter,
 | 
					  isEnter,
 | 
				
			||||||
@@ -109,9 +68,10 @@ export default {
 | 
				
			|||||||
  components: {
 | 
					  components: {
 | 
				
			||||||
    EmojiInput,
 | 
					    EmojiInput,
 | 
				
			||||||
    CannedResponse,
 | 
					    CannedResponse,
 | 
				
			||||||
    FileUpload,
 | 
					 | 
				
			||||||
    ResizableTextArea,
 | 
					    ResizableTextArea,
 | 
				
			||||||
    AttachmentPreview,
 | 
					    AttachmentPreview,
 | 
				
			||||||
 | 
					    ReplyTopPanel,
 | 
				
			||||||
 | 
					    ReplyBottomPanel,
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  mixins: [clickaway, inboxMixin],
 | 
					  mixins: [clickaway, inboxMixin],
 | 
				
			||||||
  props: {
 | 
					  props: {
 | 
				
			||||||
@@ -123,18 +83,19 @@ export default {
 | 
				
			|||||||
  data() {
 | 
					  data() {
 | 
				
			||||||
    return {
 | 
					    return {
 | 
				
			||||||
      message: '',
 | 
					      message: '',
 | 
				
			||||||
      isPrivateTabActive: false,
 | 
					 | 
				
			||||||
      isFocused: false,
 | 
					      isFocused: false,
 | 
				
			||||||
      showEmojiPicker: false,
 | 
					      showEmojiPicker: false,
 | 
				
			||||||
      showCannedResponsesList: false,
 | 
					      showCannedResponsesList: false,
 | 
				
			||||||
      attachedFiles: [],
 | 
					      attachedFiles: [],
 | 
				
			||||||
 | 
					      isUploading: false,
 | 
				
			||||||
 | 
					      replyType: REPLY_EDITOR_MODES.REPLY,
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  computed: {
 | 
					  computed: {
 | 
				
			||||||
    ...mapGetters({ currentChat: 'getSelectedChat' }),
 | 
					    ...mapGetters({ currentChat: 'getSelectedChat' }),
 | 
				
			||||||
    isPrivate() {
 | 
					    isPrivate() {
 | 
				
			||||||
      if (this.currentChat.can_reply) {
 | 
					      if (this.currentChat.can_reply) {
 | 
				
			||||||
        return this.isPrivateTabActive;
 | 
					        return this.replyType === REPLY_EDITOR_MODES.NOTE;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      return true;
 | 
					      return true;
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
@@ -207,6 +168,7 @@ export default {
 | 
				
			|||||||
    },
 | 
					    },
 | 
				
			||||||
    replyBoxClass() {
 | 
					    replyBoxClass() {
 | 
				
			||||||
      return {
 | 
					      return {
 | 
				
			||||||
 | 
					        'is-private': this.isPrivate,
 | 
				
			||||||
        'is-focused': this.isFocused || this.hasAttachments,
 | 
					        'is-focused': this.isFocused || this.hasAttachments,
 | 
				
			||||||
      };
 | 
					      };
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
@@ -216,10 +178,11 @@ export default {
 | 
				
			|||||||
  },
 | 
					  },
 | 
				
			||||||
  watch: {
 | 
					  watch: {
 | 
				
			||||||
    currentChat(conversation) {
 | 
					    currentChat(conversation) {
 | 
				
			||||||
      if (conversation.can_reply) {
 | 
					      const { can_reply: canReply } = conversation;
 | 
				
			||||||
        this.isPrivateTabActive = false;
 | 
					      if (canReply) {
 | 
				
			||||||
 | 
					        this.replyType = REPLY_EDITOR_MODES.REPLY;
 | 
				
			||||||
      } else {
 | 
					      } else {
 | 
				
			||||||
        this.isPrivateTabActive = true;
 | 
					        this.replyType = REPLY_EDITOR_MODES.NOTE;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    message(updatedMessage) {
 | 
					    message(updatedMessage) {
 | 
				
			||||||
@@ -282,12 +245,10 @@ export default {
 | 
				
			|||||||
        this.message = message;
 | 
					        this.message = message;
 | 
				
			||||||
      }, 100);
 | 
					      }, 100);
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    setPrivateReplyMode() {
 | 
					    setReplyMode(mode = REPLY_EDITOR_MODES.REPLY) {
 | 
				
			||||||
      this.isPrivateTabActive = true;
 | 
					      const { can_reply: canReply } = this.currentChat;
 | 
				
			||||||
      this.$refs.messageInput.focus();
 | 
					
 | 
				
			||||||
    },
 | 
					      if (canReply) this.replyType = mode;
 | 
				
			||||||
    setReplyMode() {
 | 
					 | 
				
			||||||
      this.isPrivateTabActive = false;
 | 
					 | 
				
			||||||
      this.$refs.messageInput.focus();
 | 
					      this.$refs.messageInput.focus();
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    emojiOnClick(emoji) {
 | 
					    emojiOnClick(emoji) {
 | 
				
			||||||
@@ -373,20 +334,45 @@ export default {
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<style lang="scss">
 | 
					<style lang="scss" scoped>
 | 
				
			||||||
@import '~widget/assets/scss/mixins';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.send-button {
 | 
					.send-button {
 | 
				
			||||||
  margin-bottom: 0;
 | 
					  margin-bottom: 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.attachment-preview-box {
 | 
					.attachment-preview-box {
 | 
				
			||||||
  margin: 0 var(--space-normal);
 | 
					  padding: 0 var(--space-normal);
 | 
				
			||||||
  background: var(--white);
 | 
					  background: transparent;
 | 
				
			||||||
  margin-bottom: var(--space-minus-slab);
 | 
					}
 | 
				
			||||||
  padding-top: var(--space-small);
 | 
					
 | 
				
			||||||
  padding-bottom: var(--space-normal);
 | 
					.reply-box {
 | 
				
			||||||
  border-top-left-radius: var(--border-radius-medium);
 | 
					  border-top: 1px solid var(--color-border);
 | 
				
			||||||
  border-top-right-radius: var(--border-radius-medium);
 | 
					  background: white;
 | 
				
			||||||
  @include shadow;
 | 
					
 | 
				
			||||||
 | 
					  &.is-private {
 | 
				
			||||||
 | 
					    background: var(--y-50);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					.send-button {
 | 
				
			||||||
 | 
					  margin-bottom: 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.reply-box__top {
 | 
				
			||||||
 | 
					  padding: 0 var(--space-normal);
 | 
				
			||||||
 | 
					  border-top: 1px solid var(--color-border);
 | 
				
			||||||
 | 
					  margin-top: -1px;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.emoji-dialog {
 | 
				
			||||||
 | 
					  top: unset;
 | 
				
			||||||
 | 
					  bottom: 12px;
 | 
				
			||||||
 | 
					  left: -320px;
 | 
				
			||||||
 | 
					  right: unset;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  &::before {
 | 
				
			||||||
 | 
					    right: -16px;
 | 
				
			||||||
 | 
					    bottom: 10px;
 | 
				
			||||||
 | 
					    transform: rotate(270deg);
 | 
				
			||||||
 | 
					    filter: drop-shadow(0px 4px 4px rgba(0, 0, 0, 0.08));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
</style>
 | 
					</style>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -23,7 +23,7 @@
 | 
				
			|||||||
  --g-800: #009000;
 | 
					  --g-800: #009000;
 | 
				
			||||||
  --g-900: #007000;
 | 
					  --g-900: #007000;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  --y-50: #FFFEE8;
 | 
					  --y-50: #FFFCF4;
 | 
				
			||||||
  --y-100: #FFFAC5;
 | 
					  --y-100: #FFFAC5;
 | 
				
			||||||
  --y-200: #FFF69E;
 | 
					  --y-200: #FFF69E;
 | 
				
			||||||
  --y-300: #FEF176;
 | 
					  --y-300: #FEF176;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -83,6 +83,7 @@ $font-size-medium: 18px;
 | 
				
			|||||||
  right: 0;
 | 
					  right: 0;
 | 
				
			||||||
  top: -22 * $space-one;
 | 
					  top: -22 * $space-one;
 | 
				
			||||||
  width: 32 * $space-one;
 | 
					  width: 32 * $space-one;
 | 
				
			||||||
 | 
					  z-index: 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  &::before {
 | 
					  &::before {
 | 
				
			||||||
    @include arrow(bottom, $color-white, $space-slab);
 | 
					    @include arrow(bottom, $color-white, $space-slab);
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user