@trtc/calls-uikit-vue 4.4.2 → 4.4.5

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 (57) hide show
  1. package/package.json +2 -2
  2. package/src/Components/TUICallKit.vue +1 -1
  3. package/src/Components/assets/aiAssistant/desktop/subtitleSettings.svg +4 -0
  4. package/src/Components/assets/aiAssistant/mobile/close-aiAssistant.svg +7 -0
  5. package/src/Components/assets/aiAssistant/mobile/open-aiAssistant.svg +7 -0
  6. package/src/Components/assets/aiAssistant/mobile/subtitleSettings.svg +3 -0
  7. package/src/Components/components/base/CustomSelect/CustomSelect.ts +45 -0
  8. package/src/Components/components/base/CustomSelect/CustomSelect.vue +199 -0
  9. package/src/Components/components/common/AIAssistant/AISubtitle.vue +155 -37
  10. package/src/Components/components/common/AIAssistant/components/AITranscriberSwitchH5.vue +35 -0
  11. package/src/Components/components/common/AIAssistant/components/AITranscriberSwitchPC.vue +89 -0
  12. package/src/Components/components/common/AIAssistant/components/SubtitleContent.vue +234 -0
  13. package/src/Components/components/common/AIAssistant/components/SubtitleSettingsH5.vue +534 -0
  14. package/src/Components/components/common/AIAssistant/components/SubtitleSettingsPC.vue +294 -0
  15. package/src/Components/components/common/TopBar/TopBar.vue +41 -15
  16. package/src/Components/hooks/index.ts +1 -0
  17. package/src/Components/hooks/useAIAssistant.ts +142 -0
  18. package/src/Components/hooks/useGetVolumeMap.ts +2 -2
  19. package/src/TUICallService/CallService/AIAssistant.ts +285 -39
  20. package/src/TUICallService/CallService/UIKitModal.ts +14 -6
  21. package/src/TUICallService/CallService/bellContext.ts +25 -2
  22. package/src/TUICallService/CallService/engineEventHandler.ts +6 -1
  23. package/src/TUICallService/CallService/index.ts +72 -39
  24. package/src/TUICallService/CallService/miniProgram.ts +0 -12
  25. package/src/TUICallService/TUIStore/callStore.ts +6 -1
  26. package/src/TUICallService/UIKitModal/UIKitModal.ts +117 -0
  27. package/src/TUICallService/UIKitModal/index.ts +2 -0
  28. package/src/TUICallService/UIKitModal/type.ts +15 -0
  29. package/src/TUICallService/const/index.ts +4 -0
  30. package/src/TUICallService/interface/ICallStore.ts +5 -0
  31. package/src/TUICallService/locales/en.ts +15 -0
  32. package/src/TUICallService/locales/ja_JP.ts +15 -0
  33. package/src/TUICallService/locales/zh-cn.ts +15 -0
  34. package/src/TUICallService/utils/common-utils.ts +1 -1
  35. package/src/index.ts +1 -1
  36. package/stats.html +1 -1
  37. package/tuicall-uikit-vue.es.js +4199 -3474
  38. package/tuicall-uikit-vue.umd.js +2 -2
  39. package/types/Components/components/base/CustomSelect/CustomSelect.d.ts +41 -0
  40. package/types/Components/hooks/index.d.ts +1 -0
  41. package/types/Components/hooks/useAIAssistant.d.ts +19 -0
  42. package/types/TUICallService/CallService/AIAssistant.d.ts +72 -15
  43. package/types/TUICallService/CallService/bellContext.d.ts +3 -0
  44. package/types/TUICallService/CallService/index.d.ts +4 -3
  45. package/types/TUICallService/CallService/miniProgram.d.ts +0 -1
  46. package/types/TUICallService/UIKitModal/UIKitModal.d.ts +4 -0
  47. package/types/TUICallService/UIKitModal/index.d.ts +2 -0
  48. package/types/TUICallService/UIKitModal/type.d.ts +13 -0
  49. package/types/TUICallService/interface/ICallStore.d.ts +4 -0
  50. package/types/TUICallService/locales/en.d.ts +14 -0
  51. package/types/TUICallService/locales/ja_JP.d.ts +14 -0
  52. package/types/TUICallService/locales/zh-cn.d.ts +14 -0
  53. package/types/tsconfig.tsbuildinfo +1 -1
  54. package/src/Components/components/common/AIAssistant/AIAssistant.ts +0 -130
  55. package/src/Components/components/common/AIAssistant/index.ts +0 -11
  56. package/types/Components/components/common/AIAssistant/AIAssistant.d.ts +0 -40
  57. package/types/Components/components/common/AIAssistant/index.d.ts +0 -4
@@ -0,0 +1,234 @@
1
+ <template>
2
+ <div
3
+ v-if="isAITranscriberRunning && subtitleInfoList.length > 0"
4
+ ref="subtitleContainer"
5
+ :class="['subtitle-content', { 'subtitle-content--h5': isH5 }]"
6
+ @mouseenter="!isH5 && (showSettingsIcon = true)"
7
+ @mouseleave="!isH5 && (showSettingsIcon = false)"
8
+ >
9
+ <div
10
+ v-show="isH5 || showSettingsIcon"
11
+ :class="['subtitle-content__settings-btn', { 'subtitle-content__settings-btn--h5': isH5 }]"
12
+ @click="handleSettingsClick"
13
+ >
14
+ <TKImage
15
+ :src="settingsIcon"
16
+ :width="iconSize"
17
+ :height="iconSize"
18
+ />
19
+ </div>
20
+
21
+ <div v-for="(subtitleInfo, index) in (Array.isArray(subtitleInfoList) ? subtitleInfoList : [])" :key="subtitleInfo.roundId">
22
+ <div v-if="index !== 0" style="height: 16px;"> </div>
23
+ <div class="sender-name">{{ `${subtitleInfo?.nick || subtitleInfo?.sender}:` }}</div>
24
+ <div>{{ subtitleInfo?.text }}</div>
25
+ <div v-for="tranlationContent in (Array.isArray(subtitleInfo?.translation) ? subtitleInfo.translation : [])" :key="tranlationContent?.language">
26
+ <span>{{ formatTranslationContent(tranlationContent?.text) }}</span>
27
+ </div>
28
+ </div>
29
+ </div>
30
+ </template>
31
+
32
+ <script lang="ts" setup>
33
+ import { ref, computed, watch, nextTick } from '../../../../../adapter-vue';
34
+ import { TUIGlobal } from '../../../../../TUICallService/index';
35
+ import { useAIAssistant } from '../../../../hooks/useAIAssistant';
36
+ import TKImage from '../../../base/TKImage/TKImage.vue';
37
+ import subtitleSettingsDeskTopIcon from '../../../../assets/aiAssistant/desktop/subtitleSettings.svg';
38
+ import subtitleSettingsH5Icon from '../../../../assets/aiAssistant/mobile/subtitleSettings.svg';
39
+
40
+ // Internal state management
41
+ const showSettingsIcon = ref(false);
42
+ const subtitleContainer = ref<HTMLElement | null>(null);
43
+
44
+ // Use AI Assistant hook (combines both status and subtitle data)
45
+ const { subtitleInfoList, isAITranscriberRunning } = useAIAssistant();
46
+
47
+ // Device type detection
48
+ const isH5 = TUIGlobal.isH5;
49
+
50
+ // Dynamic icon selection based on device type
51
+ const settingsIcon = computed(() => {
52
+ return isH5 ? subtitleSettingsH5Icon : subtitleSettingsDeskTopIcon;
53
+ });
54
+
55
+ // Icon size is consistent across all devices
56
+ const iconSize = '16px';
57
+
58
+ // Events
59
+ const emit = defineEmits(['open-settings']);
60
+
61
+ // Handle settings button click
62
+ const handleSettingsClick = () => {
63
+ emit('open-settings');
64
+ };
65
+
66
+ // Auto scroll to bottom when new messages arrive
67
+ const scrollToBottom = () => {
68
+ if (subtitleContainer.value) {
69
+ nextTick(() => {
70
+ subtitleContainer.value!.scrollTop = subtitleContainer.value!.scrollHeight;
71
+ });
72
+ }
73
+ };
74
+
75
+ // Watch for changes in subtitle list and auto scroll
76
+ watch(
77
+ () => subtitleInfoList.value,
78
+ (newList, oldList) => {
79
+ // Only scroll if new messages are added
80
+ if (newList && oldList && newList.length > oldList.length) {
81
+ scrollToBottom();
82
+ }
83
+ },
84
+ { deep: true }
85
+ );
86
+
87
+ // Also scroll when the component first shows subtitles
88
+ watch(
89
+ () => isAITranscriberRunning.value && subtitleInfoList.value.length > 0,
90
+ (shouldShow) => {
91
+ if (shouldShow) {
92
+ scrollToBottom();
93
+ }
94
+ }
95
+ );
96
+
97
+ // Parse translation data to extract language and text
98
+ const parseTranslationData = (content: any) => {
99
+ if (content === null || content === undefined) {
100
+ return { language: 'Unknown', text: '' };
101
+ }
102
+
103
+ // If content is already a string, check if it's a JSON string
104
+ if (typeof content === 'string') {
105
+ try {
106
+ // Try to parse as JSON in case it's a nested JSON string
107
+ const parsed = JSON.parse(content);
108
+ if (parsed && typeof parsed === 'object') {
109
+ return {
110
+ language: parsed.language || 'Unknown',
111
+ text: parsed.text || content
112
+ };
113
+ }
114
+ return { language: 'Unknown', text: content };
115
+ } catch {
116
+ // If parsing fails, return the original string
117
+ return { language: 'Unknown', text: content };
118
+ }
119
+ }
120
+
121
+ return { language: 'Unknown', text: String(content) };
122
+ };
123
+
124
+ // Format translation content to prevent [object Object] display
125
+ const formatTranslationContent = (content: any): string => {
126
+ return parseTranslationData(content).text;
127
+ };
128
+
129
+ // Get language display name from translation content
130
+ const getLanguageDisplayFromContent = (content: any): string => {
131
+ const { language } = parseTranslationData(content);
132
+ return getLanguageDisplay(language);
133
+ };
134
+
135
+ // Get language display name
136
+ const getLanguageDisplay = (languageCode: string): string => {
137
+ if (!languageCode || languageCode === 'Unknown') return 'Translation';
138
+
139
+ // Handle numeric language codes
140
+ if (languageCode === '0' || languageCode === '1' || languageCode === '2') {
141
+ return 'Translation';
142
+ }
143
+
144
+ // Map common language codes with bilingual format: English (中文)
145
+ const languageMap: Record<string, string> = {
146
+ 'en': 'English (英语)',
147
+ 'zh': 'Chinese (中文)',
148
+ 'ja': 'Japanese (日语)',
149
+ 'ko': 'Korean (韩语)',
150
+ 'es': 'Spanish (西班牙语)',
151
+ 'fr': 'French (法语)',
152
+ 'de': 'German (德语)',
153
+ 'vi': 'Vietnamese (越南语)',
154
+ 'id': 'Indonesian (印尼语)',
155
+ 'th': 'Thai (泰语)',
156
+ 'pt': 'Portuguese (葡萄牙语)',
157
+ 'ar': 'Arabic (阿拉伯语)',
158
+ 'ms': 'Malay (马来语)',
159
+ 'it': 'Italian (意大利语)',
160
+ 'ru': 'Russian (俄语)'
161
+ };
162
+
163
+ return languageMap[languageCode] || languageCode;
164
+ };
165
+ </script>
166
+
167
+ <style lang="scss" scoped>
168
+ // Common styles for both PC and H5
169
+ .subtitle-content {
170
+ position: relative;
171
+ padding: 10px 12px;
172
+ color: #fff;
173
+ background-color: #000000B8;
174
+ opacity: 0.72;
175
+ border-radius: 8px;
176
+ overflow-y: auto;
177
+ overflow-x: hidden;
178
+ font-size: 12px;
179
+
180
+ /* Hide scrollbar for webkit browsers */
181
+ &::-webkit-scrollbar {
182
+ width: 0;
183
+ background: transparent;
184
+ }
185
+
186
+ /* Hide scrollbar for Firefox */
187
+ scrollbar-width: none;
188
+ }
189
+
190
+ // PC specific styles
191
+ .subtitle-content:not(.subtitle-content--h5) {
192
+ width: 640px;
193
+ min-width: 640px;
194
+ height: 180px;
195
+ max-height: 180px;
196
+
197
+ .subtitle-content__settings-btn {
198
+ position: fixed;
199
+ top: 8px;
200
+ right: 8px;
201
+ cursor: pointer;
202
+ z-index: 999;
203
+ }
204
+ }
205
+
206
+ // H5 specific styles
207
+ .subtitle-content--h5 {
208
+ position: relative;
209
+ width: 350px;
210
+ min-width: 350px;
211
+ height: 116px;
212
+ max-height: 116px;
213
+
214
+ .subtitle-content__settings-btn {
215
+ position: fixed;
216
+ top: 50%;
217
+ right: 4px;
218
+ cursor: pointer;
219
+ z-index: 999;
220
+ transform: translateY(-50%);
221
+ }
222
+ }
223
+
224
+ .sender-name {
225
+ font-family: PingFang SC;
226
+ font-weight: 400;
227
+ font-style: Regular;
228
+ font-size: 12px;
229
+ leading-trim: NONE;
230
+ line-height: 16px;
231
+ letter-spacing: 0px;
232
+ color: #FFFFFFBF;
233
+ }
234
+ </style>