chore: message previews in conversation list
This commit is contained in:
@@ -306,6 +306,7 @@ export default {
|
||||
<MessagePreview
|
||||
v-if="lastMessageInChat"
|
||||
:message="lastMessageInChat"
|
||||
:conversation="chat"
|
||||
class="conversation--message my-0 mx-2 leading-6 h-6 max-w-[96%] w-[16.875rem] text-sm"
|
||||
:class="hasUnread ? 'font-medium text-n-slate-12' : 'text-n-slate-11'"
|
||||
/>
|
||||
|
||||
@@ -10,6 +10,10 @@ export default {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
conversation: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
showMessageType: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
@@ -38,7 +42,127 @@ export default {
|
||||
const { private: isPrivate } = this.message;
|
||||
return isPrivate;
|
||||
},
|
||||
// Simple check: Is this a voice channel conversation?
|
||||
isVoiceChannel() {
|
||||
return this.conversation?.meta?.inbox?.channel_type === 'Channel::Voice';
|
||||
},
|
||||
// Check if this is a voice call message
|
||||
isVoiceCall() {
|
||||
return (
|
||||
this.message?.content_type === 'voice_call' ||
|
||||
this.message?.content_attributes?.type === 'voice_call' ||
|
||||
this.message?.content_attributes?.data?.callType === 'voice_call' ||
|
||||
this.isVoiceChannel
|
||||
);
|
||||
},
|
||||
// Get call direction for voice calls
|
||||
isIncomingCall() {
|
||||
if (!this.isVoiceCall) return false;
|
||||
|
||||
// First check conversation attributes
|
||||
const direction = this.conversation?.additional_attributes?.call_direction;
|
||||
if (direction) {
|
||||
return direction === 'inbound';
|
||||
}
|
||||
|
||||
// Then fall back to message type
|
||||
return this.message.message_type === MESSAGE_TYPE.INCOMING;
|
||||
},
|
||||
// Get normalized call status
|
||||
callStatus() {
|
||||
if (!this.isVoiceCall) return null;
|
||||
|
||||
// Get raw status from conversation
|
||||
const status = this.conversation?.additional_attributes?.call_status;
|
||||
|
||||
// Map status to normalized values
|
||||
if (status === 'in-progress') return 'active';
|
||||
if (status === 'completed') return 'ended';
|
||||
if (status === 'canceled') return 'ended';
|
||||
if (status === 'failed') return 'ended';
|
||||
if (status === 'busy') return 'no-answer';
|
||||
if (status === 'no-answer') return this.isIncomingCall ? 'missed' : 'no-answer';
|
||||
|
||||
// Return explicit status values as-is
|
||||
if (status === 'active') return 'active';
|
||||
if (status === 'missed') return 'missed';
|
||||
if (status === 'ended') return 'ended';
|
||||
if (status === 'ringing') return 'ringing';
|
||||
|
||||
// Default status
|
||||
return 'ended';
|
||||
},
|
||||
// Voice call icon based on status
|
||||
voiceCallIcon() {
|
||||
if (!this.isVoiceCall) return null;
|
||||
|
||||
const status = this.callStatus;
|
||||
const isIncoming = this.isIncomingCall;
|
||||
|
||||
if (status === 'missed' || status === 'no-answer') {
|
||||
return 'phone-missed-call';
|
||||
}
|
||||
|
||||
if (status === 'active') {
|
||||
return 'phone-in-talk';
|
||||
}
|
||||
|
||||
if (status === 'ended') {
|
||||
return isIncoming ? 'phone-incoming' : 'phone-outgoing';
|
||||
}
|
||||
|
||||
if (status === 'ringing') {
|
||||
return isIncoming ? 'phone-incoming' : 'phone-outgoing';
|
||||
}
|
||||
|
||||
// Default based on direction
|
||||
return isIncoming ? 'phone-incoming' : 'phone-outgoing';
|
||||
},
|
||||
parsedLastMessage() {
|
||||
// For voice calls, return status text
|
||||
if (this.isVoiceCall) {
|
||||
// Get status-based text
|
||||
const status = this.callStatus;
|
||||
const isIncoming = this.isIncomingCall;
|
||||
|
||||
// Return appropriate status text based on call status and direction
|
||||
if (status === 'active') {
|
||||
return this.$t('CONVERSATION.VOICE_CALL.CALL_IN_PROGRESS');
|
||||
}
|
||||
|
||||
if (isIncoming) {
|
||||
if (status === 'ringing') {
|
||||
return this.$t('CONVERSATION.VOICE_CALL.INCOMING_CALL');
|
||||
}
|
||||
|
||||
if (status === 'missed') {
|
||||
return this.$t('CONVERSATION.VOICE_CALL.MISSED_CALL');
|
||||
}
|
||||
|
||||
if (status === 'ended') {
|
||||
return this.$t('CONVERSATION.VOICE_CALL.CALL_ENDED');
|
||||
}
|
||||
} else {
|
||||
if (status === 'ringing') {
|
||||
return this.$t('CONVERSATION.VOICE_CALL.OUTGOING_CALL');
|
||||
}
|
||||
|
||||
if (status === 'no-answer') {
|
||||
return this.$t('CONVERSATION.VOICE_CALL.NO_ANSWER');
|
||||
}
|
||||
|
||||
if (status === 'ended') {
|
||||
return this.$t('CONVERSATION.VOICE_CALL.CALL_ENDED');
|
||||
}
|
||||
}
|
||||
|
||||
// Default fallback based on direction
|
||||
return isIncoming
|
||||
? this.$t('CONVERSATION.VOICE_CALL.INCOMING_CALL')
|
||||
: this.$t('CONVERSATION.VOICE_CALL.OUTGOING_CALL');
|
||||
}
|
||||
|
||||
// Default behavior for non-voice calls
|
||||
const { content_attributes: contentAttributes } = this.message;
|
||||
const { email: { subject } = {} } = contentAttributes || {};
|
||||
return this.getPlainText(subject || this.message.content);
|
||||
@@ -69,6 +193,34 @@ export default {
|
||||
class="-mt-0.5 align-middle text-slate-600 dark:text-slate-300 inline-block"
|
||||
icon="lock-closed"
|
||||
/>
|
||||
|
||||
<!-- Voice calls with phosphor icons (non-filled variants) -->
|
||||
<span
|
||||
v-else-if="isVoiceCall"
|
||||
class="-mt-0.5 align-middle inline-block mr-1"
|
||||
:class="{
|
||||
'text-red-600 dark:text-red-400': callStatus === 'missed' || callStatus === 'no-answer',
|
||||
'text-green-600 dark:text-green-400': callStatus === 'active' || callStatus === 'ringing',
|
||||
'text-slate-600 dark:text-slate-300': callStatus === 'ended'
|
||||
}"
|
||||
>
|
||||
<!-- Missed call icon -->
|
||||
<i v-if="callStatus === 'missed' || callStatus === 'no-answer'"
|
||||
class="i-ph-phone-x text-base"></i>
|
||||
|
||||
<!-- Active call icon -->
|
||||
<i v-else-if="callStatus === 'active'"
|
||||
class="i-ph-phone-call text-base"></i>
|
||||
|
||||
<!-- Incoming call icon -->
|
||||
<i v-else-if="(callStatus === 'ended' && isIncomingCall) || (isIncomingCall)"
|
||||
class="i-ph-phone-incoming text-base"></i>
|
||||
|
||||
<!-- Outgoing call icon -->
|
||||
<i v-else
|
||||
class="i-ph-phone-outgoing text-base"></i>
|
||||
</span>
|
||||
|
||||
<fluent-icon
|
||||
v-else-if="messageByAgent"
|
||||
size="16"
|
||||
@@ -90,7 +242,7 @@ export default {
|
||||
/>
|
||||
{{ $t('CHAT_LIST.ATTACHMENTS.image.CONTENT') }}
|
||||
</span>
|
||||
<span v-else-if="message.content">
|
||||
<span v-else-if="message.content || isVoiceCall">
|
||||
{{ parsedLastMessage }}
|
||||
</span>
|
||||
<span v-else-if="message.attachments">
|
||||
|
||||
Reference in New Issue
Block a user