@webitel/ui-chats 26.8.2 → 26.8.4

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.
Files changed (106) hide show
  1. package/package.json +9 -2
  2. package/src/locale/en/en.ts +3 -0
  3. package/src/locale/es/es.ts +3 -0
  4. package/src/locale/kz/kz.ts +3 -0
  5. package/src/locale/pl/pl.ts +3 -0
  6. package/src/locale/ro/ro.ts +3 -0
  7. package/src/locale/ru/ru.ts +3 -0
  8. package/src/locale/uk/uk.ts +3 -0
  9. package/src/locale/uz/uz.ts +3 -0
  10. package/src/locale/vi/vi.ts +3 -0
  11. package/src/shared/composables/__tests__/useChatScroll.spec.ts +164 -0
  12. package/src/shared/composables/__tests__/useObserveHeightUntilStable.spec.ts +48 -0
  13. package/src/{ui/messaging → shared}/composables/useChatScroll.ts +37 -9
  14. package/src/{ui/messaging → shared}/composables/useObserveHeightUntilStable.ts +2 -0
  15. package/src/ui/chat-footer/modules/user-input/components/actions/send-message-action.vue +1 -0
  16. package/src/ui/index.ts +2 -2
  17. package/src/ui/messaging/components/the-messages-container.vue +2 -2
  18. package/src/v2/index.ts +4 -0
  19. package/src/v2/locale/en.ts +29 -0
  20. package/src/v2/locale/es.ts +28 -0
  21. package/src/v2/locale/kz.ts +28 -0
  22. package/src/v2/locale/pl.ts +28 -0
  23. package/src/v2/locale/ro.ts +28 -0
  24. package/src/v2/locale/ru.ts +27 -0
  25. package/src/v2/locale/uk.ts +27 -0
  26. package/src/v2/locale/useChatsV2I18n.ts +14 -0
  27. package/src/v2/locale/uz.ts +28 -0
  28. package/src/v2/locale/vi.ts +28 -0
  29. package/src/v2/scripts/__tests__/attachments.spec.ts +168 -0
  30. package/src/v2/scripts/__tests__/fixtures.ts +56 -0
  31. package/src/v2/scripts/__tests__/formatDate.spec.ts +96 -0
  32. package/src/v2/scripts/__tests__/getMessageStatus.spec.ts +214 -0
  33. package/src/v2/scripts/__tests__/isContactCentreSide.spec.ts +21 -0
  34. package/src/v2/scripts/__tests__/resolveSystemNotice.spec.ts +157 -0
  35. package/src/v2/scripts/__tests__/toHistoryItems.spec.ts +100 -0
  36. package/src/v2/scripts/attachments.ts +144 -0
  37. package/src/v2/scripts/formatDate.ts +74 -0
  38. package/src/v2/scripts/getMessageStatus.ts +58 -0
  39. package/src/v2/scripts/isContactCentreSide.ts +14 -0
  40. package/src/v2/scripts/resolveSystemNotice.ts +119 -0
  41. package/src/v2/scripts/toHistoryItems.ts +63 -0
  42. package/src/v2/scripts/toTimestamp.ts +21 -0
  43. package/src/v2/types/index.ts +74 -0
  44. package/src/v2/ui/__tests__/mountWithChats.ts +38 -0
  45. package/src/v2/ui/chat-composer/__tests__/chat-composer.spec.ts +221 -0
  46. package/src/v2/ui/chat-composer/chat-composer.vue +212 -0
  47. package/src/v2/ui/chat-history/__tests__/chat-history.spec.ts +235 -0
  48. package/src/v2/ui/chat-history/chat-history.vue +262 -0
  49. package/src/v2/ui/chat-history/components/chat-date-divider.vue +36 -0
  50. package/src/v2/ui/chat-history/components/chat-message.vue +148 -0
  51. package/src/v2/ui/chat-history/components/chat-system-notice.vue +100 -0
  52. package/src/v2/ui/chat-history/components/message-attachments.vue +162 -0
  53. package/src/v2/ui/chat-history/components/message-status.vue +31 -0
  54. package/src/v2/ui/chat-history/components/message-text.vue +37 -0
  55. package/src/v2/ui/chat-history/components/scroll-to-bottom-btn.vue +55 -0
  56. package/src/v2/ui/chat-history/gallery.ts +8 -0
  57. package/src/v2/ui/chat-thread/__tests__/chat-thread.spec.ts +122 -0
  58. package/src/v2/ui/chat-thread/chat-thread.vue +111 -0
  59. package/types/.tsbuildinfo +1 -1
  60. package/types/locale/en/en.d.ts +25 -0
  61. package/types/locale/es/es.d.ts +25 -0
  62. package/types/locale/index.d.ts +225 -0
  63. package/types/locale/kz/kz.d.ts +25 -0
  64. package/types/locale/pl/pl.d.ts +25 -0
  65. package/types/locale/ro/ro.d.ts +25 -0
  66. package/types/locale/ru/ru.d.ts +25 -0
  67. package/types/locale/uk/uk.d.ts +25 -0
  68. package/types/locale/uz/uz.d.ts +25 -0
  69. package/types/locale/vi/vi.d.ts +25 -0
  70. package/types/{ui/messaging → shared}/composables/useChatScroll.d.ts +14 -4
  71. package/types/ui/index.d.ts +2 -2
  72. package/types/v2/index.d.ts +4 -0
  73. package/types/v2/locale/en.d.ts +27 -0
  74. package/types/v2/locale/es.d.ts +26 -0
  75. package/types/v2/locale/kz.d.ts +26 -0
  76. package/types/v2/locale/pl.d.ts +26 -0
  77. package/types/v2/locale/ro.d.ts +26 -0
  78. package/types/v2/locale/ru.d.ts +26 -0
  79. package/types/v2/locale/uk.d.ts +26 -0
  80. package/types/v2/locale/useChatsV2I18n.d.ts +5 -0
  81. package/types/v2/locale/uz.d.ts +26 -0
  82. package/types/v2/locale/vi.d.ts +26 -0
  83. package/types/v2/scripts/__tests__/fixtures.d.ts +7 -0
  84. package/types/v2/scripts/attachments.d.ts +30 -0
  85. package/types/v2/scripts/formatDate.d.ts +17 -0
  86. package/types/v2/scripts/getMessageStatus.d.ts +8 -0
  87. package/types/v2/scripts/isContactCentreSide.d.ts +8 -0
  88. package/types/v2/scripts/resolveSystemNotice.d.ts +23 -0
  89. package/types/v2/scripts/toHistoryItems.d.ts +19 -0
  90. package/types/v2/scripts/toTimestamp.d.ts +7 -0
  91. package/types/v2/types/index.d.ts +54 -0
  92. package/types/v2/ui/__tests__/mountWithChats.d.ts +8 -0
  93. package/types/v2/ui/chat-composer/chat-composer.vue.d.ts +31 -0
  94. package/types/v2/ui/chat-history/chat-history.vue.d.ts +11 -0
  95. package/types/v2/ui/chat-history/components/chat-date-divider.vue.d.ts +6 -0
  96. package/types/v2/ui/chat-history/components/chat-message.vue.d.ts +10 -0
  97. package/types/v2/ui/chat-history/components/chat-system-notice.vue.d.ts +9 -0
  98. package/types/v2/ui/chat-history/components/message-attachments.vue.d.ts +7 -0
  99. package/types/v2/ui/chat-history/components/message-status.vue.d.ts +7 -0
  100. package/types/v2/ui/chat-history/components/message-text.vue.d.ts +6 -0
  101. package/types/v2/ui/chat-history/components/scroll-to-bottom-btn.vue.d.ts +12 -0
  102. package/types/v2/ui/chat-history/gallery.d.ts +6 -0
  103. package/types/v2/ui/chat-thread/chat-thread.vue.d.ts +26 -0
  104. /package/src/{ui/messaging → shared}/composables/useScrollToBottomBtn.ts +0 -0
  105. /package/types/{ui/messaging → shared}/composables/useObserveHeightUntilStable.d.ts +0 -0
  106. /package/types/{ui/messaging → shared}/composables/useScrollToBottomBtn.d.ts +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webitel/ui-chats",
3
- "version": "26.8.2",
3
+ "version": "26.8.4",
4
4
  "description": "Reusable Webitel Frontend Code for Chats UI",
5
5
  "workspaces": [
6
6
  "../../",
@@ -13,7 +13,7 @@
13
13
  "typecheck": "vue-tsc --noEmit -p ./tsconfig.typecheck.json",
14
14
  "lint:fix": "npx biome check --write ./src",
15
15
  "biome:ci:gh": "biome ci ./src --reporter=github",
16
- "test:unit": "node -e \"process.exit(0)\"",
16
+ "test:unit": "vitest run --root ../.. packages/ui-chats/src",
17
17
  "lint": "biome ci ./src",
18
18
  "test": "npm run test:unit",
19
19
  "ci:check": "npm run biome:ci:gh && npm run test:unit",
@@ -21,7 +21,10 @@
21
21
  "utils:publish": "npm publish --access public"
22
22
  },
23
23
  "dependencies": {
24
+ "@vueuse/core": "^14.0.0",
24
25
  "autolinker": "^4.1.5",
26
+ "date-fns": "^4.1.0",
27
+ "date-fns-tz": "^3.2.0",
25
28
  "insert-text-at-cursor": "^0.3.0"
26
29
  },
27
30
  "devDependencies": {
@@ -75,6 +78,10 @@
75
78
  "./adapters": {
76
79
  "types": "./types/adapters/index.d.ts",
77
80
  "import": "./src/adapters/index.ts"
81
+ },
82
+ "./v2": {
83
+ "types": "./types/v2/index.d.ts",
84
+ "import": "./src/v2/index.ts"
78
85
  }
79
86
  },
80
87
  "author": "webitel",
@@ -1,3 +1,5 @@
1
+ import v2 from '../../v2/locale/en';
2
+
1
3
  export default {
2
4
  '@webitel/ui-chats': {
3
5
  ui: {
@@ -7,5 +9,6 @@ export default {
7
9
  textAreaPlaceholder: 'Write a message...',
8
10
  },
9
11
  },
12
+ v2,
10
13
  },
11
14
  };
@@ -1,3 +1,5 @@
1
+ import v2 from '../../v2/locale/es';
2
+
1
3
  export default {
2
4
  '@webitel/ui-chats': {
3
5
  ui: {
@@ -7,5 +9,6 @@ export default {
7
9
  textAreaPlaceholder: 'Escribe un mensaje...',
8
10
  },
9
11
  },
12
+ v2,
10
13
  },
11
14
  };
@@ -1,3 +1,5 @@
1
+ import v2 from '../../v2/locale/kz';
2
+
1
3
  export default {
2
4
  '@webitel/ui-chats': {
3
5
  ui: {
@@ -7,5 +9,6 @@ export default {
7
9
  textAreaPlaceholder: 'Хабарлама жаз...',
8
10
  },
9
11
  },
12
+ v2,
10
13
  },
11
14
  };
@@ -1,3 +1,5 @@
1
+ import v2 from '../../v2/locale/pl';
2
+
1
3
  export default {
2
4
  '@webitel/ui-chats': {
3
5
  ui: {
@@ -7,5 +9,6 @@ export default {
7
9
  textAreaPlaceholder: 'Napisz wiadomość...',
8
10
  },
9
11
  },
12
+ v2,
10
13
  },
11
14
  };
@@ -1,3 +1,5 @@
1
+ import v2 from '../../v2/locale/ro';
2
+
1
3
  export default {
2
4
  '@webitel/ui-chats': {
3
5
  ui: {
@@ -7,5 +9,6 @@ export default {
7
9
  textAreaPlaceholder: 'Scrie un mesaj...',
8
10
  },
9
11
  },
12
+ v2,
10
13
  },
11
14
  };
@@ -1,3 +1,5 @@
1
+ import v2 from '../../v2/locale/ru';
2
+
1
3
  export default {
2
4
  '@webitel/ui-chats': {
3
5
  ui: {
@@ -7,5 +9,6 @@ export default {
7
9
  textAreaPlaceholder: 'Напишите сообщение...',
8
10
  },
9
11
  },
12
+ v2,
10
13
  },
11
14
  };
@@ -1,3 +1,5 @@
1
+ import v2 from '../../v2/locale/uk';
2
+
1
3
  export default {
2
4
  '@webitel/ui-chats': {
3
5
  ui: {
@@ -7,5 +9,6 @@ export default {
7
9
  textAreaPlaceholder: 'Напишіть повідомлення...',
8
10
  },
9
11
  },
12
+ v2,
10
13
  },
11
14
  };
@@ -1,3 +1,5 @@
1
+ import v2 from '../../v2/locale/uz';
2
+
1
3
  export default {
2
4
  '@webitel/ui-chats': {
3
5
  ui: {
@@ -7,5 +9,6 @@ export default {
7
9
  textAreaPlaceholder: 'Xabar yozing...',
8
10
  },
9
11
  },
12
+ v2,
10
13
  },
11
14
  };
@@ -1,3 +1,5 @@
1
+ import v2 from '../../v2/locale/vi';
2
+
1
3
  export default {
2
4
  '@webitel/ui-chats': {
3
5
  ui: {
@@ -7,5 +9,6 @@ export default {
7
9
  textAreaPlaceholder: 'Viết tin nhắn...',
8
10
  },
9
11
  },
12
+ v2,
10
13
  },
11
14
  };
@@ -0,0 +1,164 @@
1
+ import { mount } from '@vue/test-utils';
2
+ import { describe, expect, it, vi } from 'vitest';
3
+ import { computed, defineComponent, h, nextTick, ref } from 'vue';
4
+
5
+ import { useChatScroll } from '../useChatScroll';
6
+
7
+ const Host = defineComponent({
8
+ props: {
9
+ items: {
10
+ type: Array,
11
+ required: true,
12
+ },
13
+ },
14
+ setup(props) {
15
+ const container = ref<HTMLElement | null>(null);
16
+ const content = ref<HTMLElement | null>(null);
17
+ const api = useChatScroll<{
18
+ mine: boolean;
19
+ }>({
20
+ chatContainer: container,
21
+ chatContent: content,
22
+ messages: computed(
23
+ () =>
24
+ props.items as {
25
+ mine: boolean;
26
+ }[],
27
+ ),
28
+ isSelf: (item) => item.mine,
29
+ itemClass: 'row',
30
+ chatId: computed(() => 'c1'),
31
+ isChatClosed: computed(() => false),
32
+ });
33
+ return {
34
+ container,
35
+ content,
36
+ api,
37
+ };
38
+ },
39
+ render() {
40
+ return h(
41
+ 'div',
42
+ {
43
+ ref: 'container',
44
+ },
45
+ [
46
+ h('div', {
47
+ ref: 'content',
48
+ }),
49
+ ],
50
+ );
51
+ },
52
+ });
53
+
54
+ describe('useChatScroll (shared)', () => {
55
+ it('mounts with a custom isSelf / itemClass and exposes its API', () => {
56
+ const wrapper = mount(Host, {
57
+ props: {
58
+ items: [
59
+ {
60
+ mine: false,
61
+ },
62
+ ],
63
+ },
64
+ });
65
+ const { api } = wrapper.vm as unknown as {
66
+ api: ReturnType<typeof useChatScroll>;
67
+ };
68
+ expect(api.newUnseenMessagesCount.value).toBe(0);
69
+ expect(typeof api.scrollToBottom).toBe('function');
70
+ wrapper.unmount();
71
+ });
72
+
73
+ it('still accepts v1 items without isSelf', () => {
74
+ const V1Host = defineComponent({
75
+ setup() {
76
+ const container = ref<HTMLElement | null>(null);
77
+ useChatScroll({
78
+ chatContainer: container,
79
+ chatContent: ref(null),
80
+ messages: computed(() => [
81
+ {
82
+ member: {
83
+ self: true,
84
+ },
85
+ },
86
+ ]),
87
+ chatId: computed(() => 'c1'),
88
+ isChatClosed: computed(() => false),
89
+ });
90
+ return () =>
91
+ h('div', {
92
+ ref: container,
93
+ });
94
+ },
95
+ });
96
+ expect(() => mount(V1Host).unmount()).not.toThrow();
97
+ });
98
+ });
99
+
100
+ describe('useChatScroll — thread switch during a pending load', () => {
101
+ it('does not restore the old thread’s scroll anchor into the new thread', async () => {
102
+ const chatId = ref('a');
103
+ const isLoading = ref(false);
104
+ const container = ref<HTMLElement | null>(null);
105
+ const Host = defineComponent({
106
+ setup() {
107
+ const api = useChatScroll({
108
+ chatContainer: container,
109
+ chatContent: ref(null),
110
+ messages: computed(() => []),
111
+ chatId: computed(() => chatId.value),
112
+ isChatClosed: computed(() => false),
113
+ isLoading,
114
+ });
115
+ return {
116
+ api,
117
+ };
118
+ },
119
+ render() {
120
+ return h(
121
+ 'div',
122
+ {
123
+ ref: (el) => {
124
+ container.value = el as HTMLElement;
125
+ },
126
+ },
127
+ [
128
+ h('div', {
129
+ class: 'chat-message',
130
+ }),
131
+ ],
132
+ );
133
+ },
134
+ });
135
+ const wrapper = mount(Host);
136
+ await nextTick();
137
+ const scrollTo = vi.fn();
138
+ (container.value as HTMLElement).scrollTo = scrollTo;
139
+ const { api } = wrapper.vm as unknown as {
140
+ api: ReturnType<typeof useChatScroll>;
141
+ };
142
+
143
+ api.loadNextMessages(true, () => {
144
+ isLoading.value = true;
145
+ });
146
+ await nextTick();
147
+ chatId.value = 'b';
148
+ await nextTick();
149
+ await nextTick();
150
+ scrollTo.mockClear();
151
+
152
+ isLoading.value = false;
153
+ await nextTick();
154
+ await nextTick();
155
+
156
+ // 'auto' is the prepend restore; scrollToBottom uses 'instant'
157
+ expect(scrollTo).not.toHaveBeenCalledWith(
158
+ expect.objectContaining({
159
+ behavior: 'auto',
160
+ }),
161
+ );
162
+ wrapper.unmount();
163
+ });
164
+ });
@@ -0,0 +1,48 @@
1
+ import { mount } from '@vue/test-utils';
2
+ import { afterEach, describe, expect, it, vi } from 'vitest';
3
+ import { defineComponent, h, ref } from 'vue';
4
+
5
+ import { useObserveHeightUntilStable } from '../useObserveHeightUntilStable';
6
+
7
+ const observers: Array<{
8
+ disconnect: ReturnType<typeof vi.fn>;
9
+ }> = [];
10
+
11
+ class TrackedResizeObserver {
12
+ disconnect = vi.fn();
13
+ observe = vi.fn();
14
+ unobserve = vi.fn();
15
+ constructor() {
16
+ observers.push(this);
17
+ }
18
+ }
19
+
20
+ describe('useObserveHeightUntilStable', () => {
21
+ afterEach(() => {
22
+ observers.length = 0;
23
+ vi.unstubAllGlobals();
24
+ });
25
+
26
+ // a second start (thread switch) must not leave the first observer scrolling forever
27
+ it('stops the previous observer when started again', () => {
28
+ vi.stubGlobal('ResizeObserver', TrackedResizeObserver);
29
+ const target = ref<HTMLElement | null>(document.createElement('div'));
30
+ const Host = defineComponent({
31
+ setup() {
32
+ return useObserveHeightUntilStable(target, () => {}, 2000);
33
+ },
34
+ render: () => h('div'),
35
+ });
36
+ const wrapper = mount(Host);
37
+ const api = wrapper.vm as unknown as {
38
+ startObserve: () => void;
39
+ };
40
+
41
+ api.startObserve();
42
+ api.startObserve();
43
+
44
+ expect(observers).toHaveLength(2);
45
+ expect(observers[0].disconnect).toHaveBeenCalled();
46
+ wrapper.unmount();
47
+ });
48
+ });
@@ -9,14 +9,23 @@ import {
9
9
  watch,
10
10
  } from 'vue';
11
11
 
12
- import type { ChatMessageType } from '../types/ChatMessage.types';
13
-
14
12
  import { useScrollToBottomBtn } from './useScrollToBottomBtn';
15
13
 
16
- export interface UseChatScrollOptions {
14
+ export interface UseChatScrollOptions<TItem = unknown> {
17
15
  chatContainer: Ref<HTMLElement | null>;
18
16
  chatContent: Ref<HTMLElement | null>;
19
- messages: Ref<ChatMessageType[]> | ComputedRef<ChatMessageType[]>;
17
+ messages: Ref<readonly TItem[]> | ComputedRef<readonly TItem[]>;
18
+ /**
19
+ * Whether a history item was sent by the viewer. The viewer's own new
20
+ * message always scrolls the history to the bottom.
21
+ * Defaults to v1's `item.member.self`.
22
+ */
23
+ isSelf?: (item: TItem) => boolean;
24
+ /**
25
+ * Class carried by every history row. The topmost row anchors the scroll
26
+ * position while older items are prepended.
27
+ */
28
+ itemClass?: string;
20
29
  chatId: ComputedRef<string>;
21
30
  isChatClosed: ComputedRef<boolean>;
22
31
  isLoading?: Ref<boolean> | ComputedRef<boolean>;
@@ -31,10 +40,23 @@ export interface UseChatScrollOptions {
31
40
  onSeen?: () => void;
32
41
  }
33
42
 
34
- export const useChatScroll = ({
43
+ const isSelfByMember = (item: unknown): boolean =>
44
+ !!(
45
+ item as
46
+ | {
47
+ member?: {
48
+ self?: boolean;
49
+ };
50
+ }
51
+ | undefined
52
+ )?.member?.self;
53
+
54
+ export const useChatScroll = <TItem = unknown>({
35
55
  chatContainer,
36
56
  chatContent,
37
57
  messages,
58
+ isSelf = isSelfByMember,
59
+ itemClass = 'chat-message',
38
60
  chatId,
39
61
  isChatClosed,
40
62
  isLoading,
@@ -42,7 +64,7 @@ export const useChatScroll = ({
42
64
  options.scrollToBottom();
43
65
  },
44
66
  onSeen,
45
- }: UseChatScrollOptions) => {
67
+ }: UseChatScrollOptions<TItem>) => {
46
68
  const { arrivedState } = useScroll(chatContainer);
47
69
 
48
70
  const {
@@ -70,8 +92,10 @@ export const useChatScroll = ({
70
92
 
71
93
  const newUnseenMessagesCount = ref(0);
72
94
 
73
- const lastMessage = computed(() => messages.value?.at(-1));
74
- const isLastMessageMy = computed(() => !!lastMessage.value?.member?.self);
95
+ const isLastMessageMy = computed(() => {
96
+ const lastMessage = messages.value?.at(-1);
97
+ return lastMessage !== undefined && isSelf(lastMessage);
98
+ });
75
99
 
76
100
  const isViewingBottom = (el: HTMLElement) =>
77
101
  el.clientHeight > 0 &&
@@ -112,7 +136,7 @@ export const useChatScroll = ({
112
136
  if (!chatContainer.value?.children) return;
113
137
  lastVisibleMessageEl =
114
138
  (chatContainer.value?.getElementsByClassName(
115
- 'chat-message',
139
+ itemClass,
116
140
  )[0] as HTMLElement) ?? null;
117
141
  };
118
142
 
@@ -198,6 +222,10 @@ export const useChatScroll = ({
198
222
 
199
223
  const resetScrollState = () => {
200
224
  stopStickToBottomObserving();
225
+ // a page still loading for the previous chat must not restore its
226
+ // anchor into this one
227
+ isLoadingNextMessages = false;
228
+ lastVisibleMessageEl = null;
201
229
  prevScrollHeight = 0;
202
230
  newUnseenMessagesCount.value = 0;
203
231
  resetScrollToBottomBtn();
@@ -39,6 +39,8 @@ export const useObserveHeightUntilStable = (
39
39
  };
40
40
 
41
41
  const startObserve = () => {
42
+ // a restart (e.g. switching chats) must not leave the previous observer running
43
+ stopObserve();
42
44
  if (!target.value) return;
43
45
 
44
46
  observer = new ResizeObserver(() => {
@@ -6,6 +6,7 @@
6
6
  variant="outlined"
7
7
  rounded
8
8
  wide
9
+ @mousedown.prevent
9
10
  @click="emit(ChatAction.SendMessage)"
10
11
  />
11
12
  </template>
package/src/ui/index.ts CHANGED
@@ -1,6 +1,6 @@
1
+ export { useChatScroll } from '../shared/composables/useChatScroll';
2
+ export { useObserveHeightUntilStable } from '../shared/composables/useObserveHeightUntilStable';
1
3
  export { ChatAction } from './chat-footer/modules/user-input/enums/ChatAction.enum';
2
- export { useChatScroll } from './messaging/composables/useChatScroll';
3
- export { useObserveHeightUntilStable } from './messaging/composables/useObserveHeightUntilStable';
4
4
  export { useChatMessageFile } from './messaging/modules/message/composables/useChatMessageFile';
5
5
  export { MessageAction } from './messaging/modules/message/enums/MessageAction.enum';
6
6
  export type {
@@ -52,10 +52,10 @@
52
52
  import { WebitelContactsContact } from '@webitel/api-services/gen/models';
53
53
  import type { Emitter } from 'mitt';
54
54
  import { computed, inject, useTemplateRef } from 'vue';
55
+ import { useChatScroll } from '../../../shared/composables/useChatScroll';
56
+ import { useObserveHeightUntilStable } from '../../../shared/composables/useObserveHeightUntilStable';
55
57
  import { ChatAction } from '../../chat-footer/modules/user-input/enums/ChatAction.enum';
56
58
  import type { UiChatsEmitterEvents } from '../../utils/emitter';
57
- import { useChatScroll } from '../composables/useChatScroll';
58
- import { useObserveHeightUntilStable } from '../composables/useObserveHeightUntilStable';
59
59
  import ChatMessage from '../modules/message/components/chat-message.vue';
60
60
  import { useChatMessages } from '../modules/message/composables/useChatMessage';
61
61
  import { MessageAction } from '../modules/message/enums/MessageAction.enum';
@@ -0,0 +1,4 @@
1
+ export * from './types';
2
+ export { default as ChatComposer } from './ui/chat-composer/chat-composer.vue';
3
+ export { default as ChatHistory } from './ui/chat-history/chat-history.vue';
4
+ export { default as ChatThread } from './ui/chat-thread/chat-thread.vue';
@@ -0,0 +1,29 @@
1
+ const en = {
2
+ composer: {
3
+ placeholder: 'Write a message...',
4
+ attach: 'Attach files',
5
+ emoji: 'Emoji',
6
+ send: 'Send',
7
+ },
8
+ history: {
9
+ today: 'Today',
10
+ waitingForOperator: 'Waiting for operator to accept…',
11
+ deletedMessage: 'Message deleted',
12
+ unsupportedMessage: 'Unsupported message',
13
+ download: 'Download',
14
+ },
15
+ systemNotice: {
16
+ started: 'Chat started by {actor}',
17
+ joined: '{actor} joined the chat',
18
+ accepted: '{actor} accepted the chat',
19
+ transferred: '{actor} transferred the chat',
20
+ left: '{actor} left the chat',
21
+ ended: 'Chat ended by {actor}',
22
+ unknown: 'System event',
23
+ system: 'system',
24
+ },
25
+ };
26
+
27
+ export type ChatsV2Locale = typeof en;
28
+
29
+ export default en;
@@ -0,0 +1,28 @@
1
+ // DRAFT: needs native-speaker review (WS-50)
2
+ import type { ChatsV2Locale } from './en';
3
+
4
+ export default {
5
+ composer: {
6
+ placeholder: 'Escribe un mensaje...',
7
+ attach: 'Adjuntar archivos',
8
+ emoji: 'Emoji',
9
+ send: 'Enviar',
10
+ },
11
+ history: {
12
+ today: 'Hoy',
13
+ waitingForOperator: 'Esperando a que el operador acepte…',
14
+ deletedMessage: 'Mensaje eliminado',
15
+ unsupportedMessage: 'Tipo de mensaje no compatible',
16
+ download: 'Descargar',
17
+ },
18
+ systemNotice: {
19
+ started: 'Chat iniciado por {actor}',
20
+ joined: '{actor} se unió al chat',
21
+ accepted: '{actor} aceptó el chat',
22
+ transferred: '{actor} transfirió el chat',
23
+ left: '{actor} salió del chat',
24
+ ended: 'Chat finalizado por {actor}',
25
+ unknown: 'Evento del sistema',
26
+ system: 'el sistema',
27
+ },
28
+ } satisfies ChatsV2Locale;
@@ -0,0 +1,28 @@
1
+ // DRAFT: needs native-speaker review (WS-50)
2
+ import type { ChatsV2Locale } from './en';
3
+
4
+ export default {
5
+ composer: {
6
+ placeholder: 'Хабарлама жазыңыз...',
7
+ attach: 'Файлдарды тіркеу',
8
+ emoji: 'Эмодзи',
9
+ send: 'Жіберу',
10
+ },
11
+ history: {
12
+ today: 'Бүгін',
13
+ waitingForOperator: 'Оператордың қабылдауы күтілуде…',
14
+ deletedMessage: 'Хабарлама жойылды',
15
+ unsupportedMessage: 'Қолдау көрсетілмейтін хабарлама түрі',
16
+ download: 'Жүктеп алу',
17
+ },
18
+ systemNotice: {
19
+ started: 'Чат басталды: {actor}',
20
+ joined: 'Чатқа жаңа қатысушы: {actor}',
21
+ accepted: 'Чат қабылданды: {actor}',
22
+ transferred: 'Чат ауыстырылды: {actor}',
23
+ left: 'Қатысушы чаттан шықты: {actor}',
24
+ ended: 'Чат аяқталды: {actor}',
25
+ unknown: 'Жүйелік оқиға',
26
+ system: 'жүйе',
27
+ },
28
+ } satisfies ChatsV2Locale;
@@ -0,0 +1,28 @@
1
+ // DRAFT: needs native-speaker review (WS-50)
2
+ import type { ChatsV2Locale } from './en';
3
+
4
+ export default {
5
+ composer: {
6
+ placeholder: 'Napisz wiadomość...',
7
+ attach: 'Załącz pliki',
8
+ emoji: 'Emoji',
9
+ send: 'Wyślij',
10
+ },
11
+ history: {
12
+ today: 'Dzisiaj',
13
+ waitingForOperator: 'Oczekiwanie na przyjęcie przez operatora…',
14
+ deletedMessage: 'Wiadomość usunięta',
15
+ unsupportedMessage: 'Nieobsługiwany typ wiadomości',
16
+ download: 'Pobierz',
17
+ },
18
+ systemNotice: {
19
+ started: 'Czat rozpoczęty: {actor}',
20
+ joined: 'Nowy uczestnik czatu: {actor}',
21
+ accepted: 'Czat przyjęty: {actor}',
22
+ transferred: 'Czat przekazany: {actor}',
23
+ left: 'Uczestnik opuścił czat: {actor}',
24
+ ended: 'Czat zakończony: {actor}',
25
+ unknown: 'Zdarzenie systemowe',
26
+ system: 'system',
27
+ },
28
+ } satisfies ChatsV2Locale;
@@ -0,0 +1,28 @@
1
+ // DRAFT: needs native-speaker review (WS-50)
2
+ import type { ChatsV2Locale } from './en';
3
+
4
+ export default {
5
+ composer: {
6
+ placeholder: 'Scrie un mesaj...',
7
+ attach: 'Atașează fișiere',
8
+ emoji: 'Emoji',
9
+ send: 'Trimite',
10
+ },
11
+ history: {
12
+ today: 'Astăzi',
13
+ waitingForOperator: 'Se așteaptă acceptarea de către operator…',
14
+ deletedMessage: 'Mesaj șters',
15
+ unsupportedMessage: 'Tip de mesaj neacceptat',
16
+ download: 'Descarcă',
17
+ },
18
+ systemNotice: {
19
+ started: 'Chat început de {actor}',
20
+ joined: '{actor} s-a alăturat chatului',
21
+ accepted: '{actor} a acceptat chatul',
22
+ transferred: '{actor} a transferat chatul',
23
+ left: '{actor} a părăsit chatul',
24
+ ended: 'Chat încheiat de {actor}',
25
+ unknown: 'Eveniment de sistem',
26
+ system: 'sistem',
27
+ },
28
+ } satisfies ChatsV2Locale;