chore: Refactor messages to support right click context menu (#6748)

This commit is contained in:
Pranav Raj S
2023-03-24 13:49:44 -07:00
committed by GitHub
parent a6e7737c56
commit d666afd757
7 changed files with 78 additions and 61 deletions

View File

@@ -21,8 +21,8 @@ class MessageFinder
end end
def current_messages def current_messages
if @params[:after].present? if @params[:after].present? && @params[:before].present?
messages.reorder('created_at asc').where('id >= ?', @params[:before].to_i).limit(20) messages.reorder('created_at asc').where('id >= ? AND id < ?', @params[:after].to_i, @params[:before].to_i).limit(1000)
elsif @params[:before].present? elsif @params[:before].present?
messages.reorder('created_at desc').where('id < ?', @params[:before].to_i).limit(20).reverse messages.reorder('created_at desc').where('id < ?', @params[:before].to_i).limit(20).reverse
else else

View File

@@ -75,10 +75,12 @@ class MessageApi extends ApiClient {
return axios.delete(`${this.url}/${conversationID}/messages/${messageId}`); return axios.delete(`${this.url}/${conversationID}/messages/${messageId}`);
} }
getPreviousMessages({ conversationId, before }) { getPreviousMessages({ conversationId, after, before }) {
return axios.get(`${this.url}/${conversationId}/messages`, { const params = { before };
params: { before }, if (after && Number(after) !== Number(before)) {
}); params.after = after;
}
return axios.get(`${this.url}/${conversationId}/messages`, { params });
} }
translateMessage(conversationId, messageId, targetLanguage) { translateMessage(conversationId, messageId, targetLanguage) {

View File

@@ -73,39 +73,12 @@
:created-at="createdAt" :created-at="createdAt"
/> />
</div> </div>
<woot-modal <translate-modal
v-if="showTranslateModal" v-if="showTranslateModal"
modal-type="right-aligned" :content="data.content"
show :content-attributes="contentAttributes"
:on-close="onCloseTranslateModal" @close="onCloseTranslateModal"
> />
<div class="column content">
<p>
<b>{{ $t('TRANSLATE_MODAL.ORIGINAL_CONTENT') }}</b>
</p>
<p v-dompurify-html="data.content" />
<br />
<hr />
<div v-if="translationsAvailable">
<p>
<b>{{ $t('TRANSLATE_MODAL.TRANSLATED_CONTENT') }}</b>
</p>
<div
v-for="(translation, language) in translations"
:key="language"
>
<p>
<strong>{{ language }}:</strong>
</p>
<p v-dompurify-html="translation" />
<br />
</div>
</div>
<p v-else>
{{ $t('TRANSLATE_MODAL.NO_TRANSLATIONS_AVAILABLE') }}
</p>
</div>
</woot-modal>
<spinner v-if="isPending" size="tiny" /> <spinner v-if="isPending" size="tiny" />
<div <div
v-if="showAvatar" v-if="showAvatar"
@@ -173,6 +146,7 @@ import contentTypeMixin from 'shared/mixins/contentTypeMixin';
import { MESSAGE_TYPE, MESSAGE_STATUS } from 'shared/constants/messages'; import { MESSAGE_TYPE, MESSAGE_STATUS } from 'shared/constants/messages';
import { generateBotMessageContent } from './helpers/botMessageContentHelper'; import { generateBotMessageContent } from './helpers/botMessageContentHelper';
import { mapGetters } from 'vuex'; import { mapGetters } from 'vuex';
import TranslateModal from './bubble/TranslateModal.vue';
export default { export default {
components: { components: {
@@ -188,6 +162,7 @@ export default {
ContextMenu, ContextMenu,
Spinner, Spinner,
instagramImageErrorPlaceholder, instagramImageErrorPlaceholder,
TranslateModal,
}, },
mixins: [alertMixin, messageFormatterMixin, contentTypeMixin], mixins: [alertMixin, messageFormatterMixin, contentTypeMixin],
props: { props: {
@@ -239,9 +214,6 @@ export default {
} = this.contentAttributes.email || {}; } = this.contentAttributes.email || {};
return fullHTMLContent || fullTextContent || ''; return fullHTMLContent || fullTextContent || '';
}, },
translations() {
return this.contentAttributes.translations || {};
},
displayQuotedButton() { displayQuotedButton() {
if (this.emailMessageContent.includes('<blockquote')) { if (this.emailMessageContent.includes('<blockquote')) {
return true; return true;
@@ -253,9 +225,6 @@ export default {
return false; return false;
}, },
translationsAvailable() {
return !!Object.keys(this.translations).length;
},
message() { message() {
// If the message is an email, emailMessageContent would be present // If the message is an email, emailMessageContent would be present
// In that case, we would use letter package to render the email // In that case, we would use letter package to render the email
@@ -612,18 +581,10 @@ export default {
margin-top: var(--space-smaller) var(--space-smaller) 0 0; margin-top: var(--space-smaller) var(--space-smaller) 0 0;
} }
.button--delete-message {
visibility: hidden;
}
li.left, li.left,
li.right { li.right {
display: flex; display: flex;
align-items: flex-end; align-items: flex-end;
&:hover .button--delete-message {
visibility: visible;
}
} }
li.left.has-tweet-menu .context-menu { li.left.has-tweet-menu .context-menu {
@@ -652,9 +613,6 @@ li.right {
.has-context-menu { .has-context-menu {
background: var(--color-background); background: var(--color-background);
.button--delete-message {
visibility: visible;
}
} }
.context-menu { .context-menu {

View File

@@ -0,0 +1,59 @@
<template>
<woot-modal
modal-type="right-aligned"
class="text-left"
show
:on-close="onClose"
>
<div class="column content">
<p>
<b>{{ $t('TRANSLATE_MODAL.ORIGINAL_CONTENT') }}</b>
</p>
<p v-dompurify-html="content" />
<br />
<hr />
<div v-if="translationsAvailable">
<p>
<b>{{ $t('TRANSLATE_MODAL.TRANSLATED_CONTENT') }}</b>
</p>
<div v-for="(translation, language) in translations" :key="language">
<p>
<strong>{{ language }}:</strong>
</p>
<p v-dompurify-html="translation" />
<br />
</div>
</div>
<p v-else>
{{ $t('TRANSLATE_MODAL.NO_TRANSLATIONS_AVAILABLE') }}
</p>
</div>
</woot-modal>
</template>
<script>
export default {
props: {
contentAttributes: {
type: Object,
default: () => ({}),
},
content: {
type: String,
default: '',
},
},
computed: {
translationsAvailable() {
return !!Object.keys(this.translations).length;
},
translations() {
return this.contentAttributes.translations || {};
},
},
methods: {
onClose() {
this.$emit('close');
},
},
};
</script>

View File

@@ -1,5 +1,5 @@
<template> <template>
<div class="menu" @click.stop="$emit('click')"> <div class="menu" role="button" @click.stop="$emit('click')">
<fluent-icon <fluent-icon
v-if="variant === 'icon' && option.icon" v-if="variant === 'icon' && option.icon"
:icon="option.icon" :icon="option.icon"

View File

@@ -83,7 +83,7 @@ export default {
} }
&.disabled { &.disabled {
opacity: 50%; opacity: 0.5;
cursor: not-allowed; cursor: not-allowed;
} }
} }

View File

@@ -78,7 +78,7 @@ const actions = {
id: data.conversationId, id: data.conversationId,
data: payload, data: payload,
}); });
if (payload.length < 20) { if (!payload.length) {
commit(types.SET_ALL_MESSAGES_LOADED); commit(types.SET_ALL_MESSAGES_LOADED);
} }
} catch (error) { } catch (error) {
@@ -217,9 +217,7 @@ const actions = {
{ conversationId, messageId } { conversationId, messageId }
) { ) {
try { try {
const response = await MessageApi.delete(conversationId, messageId); const { data } = await MessageApi.delete(conversationId, messageId);
const { data } = response;
// The delete message is actually deleting the content.
commit(types.ADD_MESSAGE, data); commit(types.ADD_MESSAGE, data);
} catch (error) { } catch (error) {
throw new Error(error); throw new Error(error);