feat: Creates pop out reply box (#2832)

* enhancement: Creates draggable pop out replay box

* Review fixes

* Minor fixes

* codeclimate fixes

* Update z-index.scss

* Minor fixes

* Review fixes

* Minor fixes

* Update MessagesView.vue

* Review fixes

* Review fixes

Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com>
Co-authored-by: Nithin David Thomas <1277421+nithindavid@users.noreply.github.com>
Co-authored-by: Pranav Raj S <pranav@chatwoot.com>
This commit is contained in:
Sivin Varghese 2021-09-01 19:12:22 +05:30 committed by GitHub
parent afdf1c70c1
commit 8b841596a5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 105 additions and 2 deletions

View file

@ -5,6 +5,7 @@
@import 'shared/assets/stylesheets/font-weights'; @import 'shared/assets/stylesheets/font-weights';
@import 'shared/assets/stylesheets/shadows'; @import 'shared/assets/stylesheets/shadows';
@import 'shared/assets/stylesheets/border-radius'; @import 'shared/assets/stylesheets/border-radius';
@import 'shared/assets/stylesheets/z-index';
@import 'variables'; @import 'variables';

View file

@ -26,6 +26,24 @@
</span> </span>
</div> </div>
</div> </div>
<woot-button
v-if="popoutReplyBox"
variant="clear"
size="large"
icon="ion-android-close"
color-scheme="secondary"
class-names="popout-button"
@click="$emit('click')"
/>
<woot-button
v-else
variant="clear"
size="large"
icon="ion-arrow-resize"
color-scheme="secondary"
class-names="popout-button"
@click="$emit('click')"
/>
</div> </div>
</template> </template>
@ -60,6 +78,10 @@ export default {
type: Number, type: Number,
default: () => 0, default: () => 0,
}, },
popoutReplyBox: {
type: Boolean,
default: false,
},
}, },
computed: { computed: {
replyButtonClass() { replyButtonClass() {
@ -167,4 +189,11 @@ export default {
color: var(--s-600); color: var(--s-600);
} }
} }
.popout-button {
display: flex;
justify-content: flex-end;
height: auto;
padding-right: var(--space-normal);
}
</style> </style>

View file

@ -78,7 +78,10 @@
:is-a-tweet="isATweet" :is-a-tweet="isATweet"
/> />
</ul> </ul>
<div class="conversation-footer"> <div
class="conversation-footer"
:class="{ 'modal-mask': isPopoutReplyBox }"
>
<div v-if="isAnyoneTyping" class="typing-indicator-wrap"> <div v-if="isAnyoneTyping" class="typing-indicator-wrap">
<div class="typing-indicator"> <div class="typing-indicator">
{{ typingUserNames }} {{ typingUserNames }}
@ -90,9 +93,12 @@
</div> </div>
</div> </div>
<reply-box <reply-box
v-on-clickaway="closePopoutReplyBox"
:conversation-id="currentChat.id" :conversation-id="currentChat.id"
:is-a-tweet="isATweet" :is-a-tweet="isATweet"
:selected-tweet="selectedTweet" :selected-tweet="selectedTweet"
:popout-reply-box="isPopoutReplyBox"
@click="showPopoutReplyBox"
@scrollToMessage="scrollToBottom" @scrollToMessage="scrollToBottom"
/> />
</div> </div>
@ -110,13 +116,16 @@ import { BUS_EVENTS } from 'shared/constants/busEvents';
import { REPLY_POLICY } from 'shared/constants/links'; import { REPLY_POLICY } from 'shared/constants/links';
import inboxMixin from 'shared/mixins/inboxMixin'; import inboxMixin from 'shared/mixins/inboxMixin';
import { calculateScrollTop } from './helpers/scrollTopCalculationHelper'; import { calculateScrollTop } from './helpers/scrollTopCalculationHelper';
import { isEscape } from 'shared/helpers/KeyboardHelpers';
import eventListenerMixins from 'shared/mixins/eventListenerMixins';
import { mixin as clickaway } from 'vue-clickaway';
export default { export default {
components: { components: {
Message, Message,
ReplyBox, ReplyBox,
}, },
mixins: [conversationMixin, inboxMixin], mixins: [conversationMixin, inboxMixin, eventListenerMixins, clickaway],
props: { props: {
isContactPanelOpen: { isContactPanelOpen: {
type: Boolean, type: Boolean,
@ -130,6 +139,7 @@ export default {
heightBeforeLoad: null, heightBeforeLoad: null,
conversationPanel: null, conversationPanel: null,
selectedTweetId: null, selectedTweetId: null,
isPopoutReplyBox: false,
}; };
}, },
@ -252,6 +262,17 @@ export default {
}, },
methods: { methods: {
showPopoutReplyBox() {
this.isPopoutReplyBox = !this.isPopoutReplyBox;
},
closePopoutReplyBox() {
this.isPopoutReplyBox = false;
},
handleKeyEvents(e) {
if (isEscape(e)) {
this.closePopoutReplyBox();
}
},
addScrollListener() { addScrollListener() {
this.conversationPanel = this.$el.querySelector('.conversation-panel'); this.conversationPanel = this.$el.querySelector('.conversation-panel');
this.setScrollParams(); this.setScrollParams();
@ -361,4 +382,39 @@ export default {
flex-grow: 1; flex-grow: 1;
min-width: 0; min-width: 0;
} }
.modal-mask {
&::v-deep {
.ProseMirror-woot-style {
max-height: 40rem;
}
.reply-box {
border: 1px solid var(--color-border);
max-width: 120rem;
width: 70%;
}
.reply-box .reply-box__top {
position: relative;
min-height: 44rem;
}
.reply-box__top .input {
min-height: 44rem;
}
.emoji-dialog {
position: fixed;
left: unset;
position: absolute;
}
.emoji-dialog::before {
transform: rotate(0deg);
left: 5px;
bottom: var(--space-minus-slab);
}
}
}
</style> </style>

View file

@ -5,6 +5,8 @@
:set-reply-mode="setReplyMode" :set-reply-mode="setReplyMode"
:is-message-length-reaching-threshold="isMessageLengthReachingThreshold" :is-message-length-reaching-threshold="isMessageLengthReachingThreshold"
:characters-remaining="charactersRemaining" :characters-remaining="charactersRemaining"
:popout-reply-box="popoutReplyBox"
@click="$emit('click')"
/> />
<div class="reply-box__top"> <div class="reply-box__top">
<canned-response <canned-response
@ -122,6 +124,10 @@ export default {
type: Boolean, type: Boolean,
default: false, default: false,
}, },
popoutReplyBox: {
type: Boolean,
default: false,
},
}, },
data() { data() {
return { return {

View file

@ -0,0 +1,11 @@
:root {
// z-index
--z-index-minus: -1;
--z-index-zero: 0;
--z-index-low: 10;
--z-index-normal: 100;
--z-index-high: 1000;
--z-index-higher: 2000;
--z-index-much-higher: 5000;
--z-index-highest: 10000;
}