@webitel/ui-chats 0.1.52 → 0.1.53
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -2
- package/src/config/config.ts +10 -6
- package/src/declaration.d.ts +7 -0
- package/src/ui/chat-footer/modules/user-input/components/chat-input-actions-bar.vue +2 -2
- package/src/ui/chat-footer/modules/user-input/components/chat-text-field.vue +4 -4
- package/src/ui/chat-footer/modules/user-input/enums/ChatAction.enum.ts +5 -0
- package/src/ui/messaging/composables/useChatScroll.ts +1 -1
- package/src/ui/messaging/composables/useObserveHeightUntilStable.ts +1 -1
- package/src/ui/messaging/modules/message/components/chat-message.vue +2 -2
- package/src/ui/messaging/modules/message/components/details/chat-message-document.vue +3 -2
- package/src/ui/messaging/modules/message/components/details/chat-message-player.vue +6 -5
- package/src/ui/messaging/modules/message/composables/useChatMessage.ts +2 -2
- package/src/ui/messaging/modules/message/composables/useChatMessageFile.ts +11 -11
- package/src/ui/the-chat-container.vue +2 -2
- package/src/ui/utils/ResultCallbacks.types.ts +7 -1
- package/types/.tsbuildinfo +1 -1
- package/types/config/config.d.ts +7 -2
- package/types/ui/chat-footer/modules/user-input/components/actions/attach-files-action.vue.d.ts +1 -1
- package/types/ui/chat-footer/modules/user-input/components/actions/send-message-action.vue.d.ts +1 -1
- package/types/ui/chat-footer/modules/user-input/components/chat-input-actions-bar.vue.d.ts +4 -4
- package/types/ui/chat-footer/modules/user-input/components/chat-text-field.vue.d.ts +4 -5
- package/types/ui/chat-footer/modules/user-input/enums/ChatAction.enum.d.ts +4 -0
- package/types/ui/image-viewer/image-viewer.vue.d.ts +1 -1
- package/types/ui/messaging/components/chat-observer.vue.d.ts +2 -2
- package/types/ui/messaging/components/scroll-to-bottom-btn.vue.d.ts +2 -2
- package/types/ui/messaging/components/the-messages-container.vue.d.ts +1 -1
- package/types/ui/messaging/modules/message/components/chat-message.vue.d.ts +2 -2
- package/types/ui/messaging/modules/message/components/details/chat-message-image.vue.d.ts +1 -1
- package/types/ui/messaging/modules/message/components/details/chat-message-player.vue.d.ts +3 -3
- package/types/ui/messaging/modules/message/components/details/chat-message-size-exceeded-error.vue.d.ts +1 -1
- package/types/ui/messaging/modules/message/components/details/chat-message-time.vue.d.ts +1 -1
- package/types/ui/messaging/modules/message/composables/useChatMessageFile.d.ts +4 -20
- package/types/ui/the-chat-container.vue.d.ts +3 -3
- package/types/ui/utils/ResultCallbacks.types.d.ts +5 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webitel/ui-chats",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.53",
|
|
4
4
|
"description": "Reusable Webitel Frontend Code for Chats UI",
|
|
5
5
|
"workspaces": [
|
|
6
6
|
"../../",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"@webitel/api-services": "^0.1.0",
|
|
42
42
|
"@webitel/chat-web-sdk": "^0.0.19",
|
|
43
43
|
"@webitel/styleguide": "~26.2",
|
|
44
|
-
"@webitel/ui-sdk": "~26.
|
|
44
|
+
"@webitel/ui-sdk": "~26.8",
|
|
45
45
|
"mitt": "^3",
|
|
46
46
|
"vue": "^3.5"
|
|
47
47
|
},
|
package/src/config/config.ts
CHANGED
|
@@ -1,14 +1,18 @@
|
|
|
1
|
-
import type { I18n } from 'vue-i18n';
|
|
2
1
|
import { messages } from '../locale';
|
|
3
2
|
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
/** Minimal i18n surface ui-chats needs — avoids vue-i18n schema variance issues. */
|
|
4
|
+
export type UiChatsI18n = {
|
|
5
|
+
global: {
|
|
6
|
+
mergeLocaleMessage: (locale: string, message: unknown) => void;
|
|
7
|
+
};
|
|
6
8
|
};
|
|
7
9
|
|
|
8
|
-
export
|
|
9
|
-
i18n
|
|
10
|
+
export type UiChatsConfig = {
|
|
11
|
+
i18n?: UiChatsI18n;
|
|
10
12
|
};
|
|
11
13
|
|
|
14
|
+
export const defaultConfig: UiChatsConfig = {};
|
|
15
|
+
|
|
12
16
|
export const setConfig = (conf: UiChatsConfig) => {
|
|
13
17
|
Object.assign(defaultConfig, conf);
|
|
14
18
|
|
|
@@ -17,6 +21,6 @@ export const setConfig = (conf: UiChatsConfig) => {
|
|
|
17
21
|
}
|
|
18
22
|
|
|
19
23
|
Object.entries(messages).forEach(([locale, localeMessages]) => {
|
|
20
|
-
conf.i18n
|
|
24
|
+
conf.i18n!.global.mergeLocaleMessage(locale, localeMessages);
|
|
21
25
|
});
|
|
22
26
|
};
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
import { ComponentSize } from '@webitel/ui-sdk/enums';
|
|
21
21
|
import { computed, inject } from 'vue';
|
|
22
22
|
|
|
23
|
-
import { ChatAction, type
|
|
23
|
+
import { ChatAction, type ChatActionSlots } from '../enums/ChatAction.enum';
|
|
24
24
|
import AttachFilesAction from './actions/attach-files-action.vue';
|
|
25
25
|
import EmojiPickerAction from './actions/emoji-picker-action.vue';
|
|
26
26
|
import SendMessageAction from './actions/send-message-action.vue';
|
|
@@ -36,7 +36,7 @@ const emit = defineEmits<{
|
|
|
36
36
|
(e: typeof ChatAction.AttachFiles, files: File[]): void;
|
|
37
37
|
}>();
|
|
38
38
|
|
|
39
|
-
|
|
39
|
+
defineSlots<ChatActionSlots>();
|
|
40
40
|
|
|
41
41
|
const ShownActionComponentsList = computed(() => {
|
|
42
42
|
/**
|
|
@@ -16,14 +16,14 @@ import { WtTextarea } from '@webitel/ui-sdk/components';
|
|
|
16
16
|
import { ComponentSize } from '@webitel/ui-sdk/enums';
|
|
17
17
|
import insertTextAtCursor from 'insert-text-at-cursor';
|
|
18
18
|
import type { Emitter } from 'mitt';
|
|
19
|
-
import { computed, inject,
|
|
19
|
+
import { computed, inject, useTemplateRef } from 'vue';
|
|
20
20
|
import { useI18n } from 'vue-i18n';
|
|
21
21
|
|
|
22
22
|
import type { UiChatsEmitterEvents } from '../../../../utils/emitter';
|
|
23
23
|
|
|
24
24
|
const { t } = useI18n();
|
|
25
25
|
|
|
26
|
-
const textModel = defineModel<
|
|
26
|
+
const textModel = defineModel<string>('text', {
|
|
27
27
|
required: true,
|
|
28
28
|
});
|
|
29
29
|
|
|
@@ -46,8 +46,8 @@ const textareaEl = computed(() =>
|
|
|
46
46
|
chatTextFieldInputRef.value?.$el.querySelector('textarea'),
|
|
47
47
|
);
|
|
48
48
|
|
|
49
|
-
function send(text
|
|
50
|
-
textModel.value = text;
|
|
49
|
+
function send(text?: string) {
|
|
50
|
+
textModel.value = text ?? '';
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
function focus() {
|
|
@@ -11,3 +11,8 @@ export type ChatAction = (typeof ChatAction)[keyof typeof ChatAction];
|
|
|
11
11
|
export type SharedActionSlots = {
|
|
12
12
|
[key in `action:${ChatAction}`]?: () => unknown;
|
|
13
13
|
};
|
|
14
|
+
|
|
15
|
+
/** slots `chat-input-actions-bar` itself exposes, keyed by the bare action name */
|
|
16
|
+
export type ChatActionSlots = {
|
|
17
|
+
[key in ChatAction]?: (props: Record<string, unknown>) => unknown;
|
|
18
|
+
};
|
|
@@ -136,14 +136,14 @@ const isTransferAgent = computed(
|
|
|
136
136
|
|
|
137
137
|
const isBot = computed<boolean>(() => props.message.member?.type === 'bot');
|
|
138
138
|
|
|
139
|
-
const getClientUsername = computed<string>(() => {
|
|
139
|
+
const getClientUsername = computed<string | undefined>(() => {
|
|
140
140
|
if (isTransferAgent.value) return props.message.member?.name;
|
|
141
141
|
if (isSelfSide.value) return props?.agentName;
|
|
142
142
|
|
|
143
143
|
return props.username || props.message.member?.name;
|
|
144
144
|
});
|
|
145
145
|
|
|
146
|
-
function handlePlayerInitialize(player) {
|
|
146
|
+
function handlePlayerInitialize(player: object) {
|
|
147
147
|
emit(MessageAction.InitializedPlayer, {
|
|
148
148
|
player,
|
|
149
149
|
});
|
|
@@ -38,11 +38,12 @@ const documentSize = computed(() => {
|
|
|
38
38
|
});
|
|
39
39
|
|
|
40
40
|
function downloadDocument() {
|
|
41
|
-
if (!props.file) return;
|
|
41
|
+
if (!props.file?.url) return;
|
|
42
42
|
const a = document.createElement('a');
|
|
43
43
|
a.href = props.file.url;
|
|
44
44
|
a.target = '_blank';
|
|
45
|
-
|
|
45
|
+
// empty `download` lets the browser derive the filename from the URL
|
|
46
|
+
a.download = props.file.name ?? '';
|
|
46
47
|
a.click();
|
|
47
48
|
}
|
|
48
49
|
</script>
|
|
@@ -35,7 +35,7 @@ import type { ChatMessageFile } from '../../../../types/ChatMessage.types';
|
|
|
35
35
|
|
|
36
36
|
const props = defineProps<{
|
|
37
37
|
file: ChatMessageFile;
|
|
38
|
-
type
|
|
38
|
+
type?: string;
|
|
39
39
|
}>();
|
|
40
40
|
|
|
41
41
|
const emit = defineEmits<{
|
|
@@ -52,13 +52,14 @@ const isVideo = computed(() => {
|
|
|
52
52
|
});
|
|
53
53
|
const mediaSrc = computed(() => {
|
|
54
54
|
return {
|
|
55
|
-
src: props.file.streamUrl || props.file.url,
|
|
56
|
-
type: props.type,
|
|
55
|
+
src: props.file.streamUrl || props.file.url || '',
|
|
56
|
+
type: props.type ?? '',
|
|
57
57
|
};
|
|
58
58
|
});
|
|
59
59
|
|
|
60
|
-
|
|
61
|
-
|
|
60
|
+
// `initialized` currently carries no payload, so the argument stays optional
|
|
61
|
+
function handlePlayerInitialize(player?: object) {
|
|
62
|
+
emit('initialized', player ?? {});
|
|
62
63
|
}
|
|
63
64
|
</script>
|
|
64
65
|
|
|
@@ -15,8 +15,8 @@ export const useChatMessages = (
|
|
|
15
15
|
) => {
|
|
16
16
|
function showChatDate(index: number): boolean {
|
|
17
17
|
const { prevMessage, message } = getMessage(index);
|
|
18
|
-
const prevDate =
|
|
19
|
-
const currentDate =
|
|
18
|
+
const prevDate = Number(prevMessage?.createdAt) || 0;
|
|
19
|
+
const currentDate = Number(message?.createdAt) || 0;
|
|
20
20
|
return (
|
|
21
21
|
!!prevMessage &&
|
|
22
22
|
formatDate(prevDate, FormatDateMode.DATE) !==
|
|
@@ -3,7 +3,7 @@ import { computed, type Ref, toRef } from 'vue';
|
|
|
3
3
|
import type { ChatMessageFile } from '../../../types/ChatMessage.types';
|
|
4
4
|
|
|
5
5
|
export function useChatMessageFile(
|
|
6
|
-
file: ChatMessageFile | Ref<ChatMessageFile
|
|
6
|
+
file: ChatMessageFile | Ref<ChatMessageFile | undefined> | undefined,
|
|
7
7
|
) {
|
|
8
8
|
const fileRef = toRef(file);
|
|
9
9
|
|
|
@@ -15,27 +15,27 @@ export function useChatMessageFile(
|
|
|
15
15
|
return fileRef.value?.streamUrl || fileRef.value?.url;
|
|
16
16
|
});
|
|
17
17
|
|
|
18
|
+
const isMediaType = (value: string | undefined) => {
|
|
19
|
+
return !!(value?.includes('audio') || value?.includes('video'));
|
|
20
|
+
};
|
|
21
|
+
|
|
18
22
|
const image = computed(() => {
|
|
19
23
|
const isImage = fileType.value?.includes('image');
|
|
20
24
|
const isHEIC = fileType.value?.includes('heic');
|
|
21
25
|
|
|
22
26
|
if (isHEIC) return null;
|
|
23
27
|
|
|
24
|
-
return isImage
|
|
28
|
+
return isImage ? fileRef.value : null;
|
|
25
29
|
});
|
|
30
|
+
|
|
26
31
|
const media = computed(() => {
|
|
27
|
-
return (
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
);
|
|
32
|
+
return isMediaType(fileType.value) || isMediaType(fileSrc.value)
|
|
33
|
+
? fileRef.value
|
|
34
|
+
: null;
|
|
31
35
|
});
|
|
32
36
|
|
|
33
|
-
const isMediaType = (value: string) => {
|
|
34
|
-
return !!(value?.includes('audio') || value?.includes('video'));
|
|
35
|
-
};
|
|
36
|
-
|
|
37
37
|
const document = computed(() => {
|
|
38
|
-
return !media.value && !image.value
|
|
38
|
+
return !media.value && !image.value ? fileRef.value : null;
|
|
39
39
|
});
|
|
40
40
|
|
|
41
41
|
return {
|
|
@@ -143,10 +143,10 @@ function closeMedia() {
|
|
|
143
143
|
|
|
144
144
|
const draft = ref<string>('');
|
|
145
145
|
|
|
146
|
-
const slottedChatActions = computed(() => {
|
|
146
|
+
const slottedChatActions = computed<ChatAction[]>(() => {
|
|
147
147
|
return Object.keys(slots)
|
|
148
148
|
.filter((key) => key.startsWith('action:'))
|
|
149
|
-
.map((key) => key.replace('action:', ''));
|
|
149
|
+
.map((key) => key.replace('action:', '') as ChatAction);
|
|
150
150
|
});
|
|
151
151
|
const isDropzoneDisabled = computed(
|
|
152
152
|
() => !props.chatActions.includes(ChatAction.AttachFiles),
|
|
@@ -1 +1,7 @@
|
|
|
1
|
-
|
|
1
|
+
// Defined locally so consumers (and this package's .d.ts) do not depend on
|
|
2
|
+
// @webitel/ui-sdk/src/types package-export resolution.
|
|
3
|
+
export type ResultCallbacks = {
|
|
4
|
+
onSuccess?: () => void;
|
|
5
|
+
onError?: (error: Error) => void;
|
|
6
|
+
onComplete?: () => void;
|
|
7
|
+
};
|