@trtc/calls-uikit-vue2 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.
- package/README-zh_CN.md +6 -0
- package/README.md +6 -0
- package/package.json +2 -2
- package/src/Components/TUICallKit.vue +1 -1
- package/src/Components/assets/aiAssistant/desktop/subtitleSettings.svg +4 -0
- package/src/Components/assets/aiAssistant/mobile/close-aiAssistant.svg +7 -0
- package/src/Components/assets/aiAssistant/mobile/open-aiAssistant.svg +7 -0
- package/src/Components/assets/aiAssistant/mobile/subtitleSettings.svg +3 -0
- package/src/Components/components/base/CustomSelect/CustomSelect.ts +45 -0
- package/src/Components/components/base/CustomSelect/CustomSelect.vue +199 -0
- package/src/Components/components/common/AIAssistant/AISubtitle.vue +155 -37
- package/src/Components/components/common/AIAssistant/components/AITranscriberSwitchH5.vue +35 -0
- package/src/Components/components/common/AIAssistant/components/AITranscriberSwitchPC.vue +89 -0
- package/src/Components/components/common/AIAssistant/components/SubtitleContent.vue +234 -0
- package/src/Components/components/common/AIAssistant/components/SubtitleSettingsH5.vue +534 -0
- package/src/Components/components/common/AIAssistant/components/SubtitleSettingsPC.vue +294 -0
- package/src/Components/components/common/TopBar/TopBar.vue +41 -15
- package/src/Components/hooks/index.ts +1 -0
- package/src/Components/hooks/useAIAssistant.ts +142 -0
- package/src/Components/hooks/useGetVolumeMap.ts +2 -2
- package/src/TUICallService/CallService/AIAssistant.ts +285 -39
- package/src/TUICallService/CallService/UIKitModal.ts +67 -6
- package/src/TUICallService/CallService/bellContext.ts +25 -2
- package/src/TUICallService/CallService/engineEventHandler.ts +6 -1
- package/src/TUICallService/CallService/index.ts +72 -39
- package/src/TUICallService/CallService/miniProgram.ts +0 -12
- package/src/TUICallService/TUIStore/callStore.ts +6 -1
- package/src/TUICallService/UIKitModal/UIKitModal.ts +117 -0
- package/src/TUICallService/UIKitModal/index.ts +2 -0
- package/src/TUICallService/UIKitModal/type.ts +15 -0
- package/src/TUICallService/const/index.ts +4 -0
- package/src/TUICallService/interface/ICallStore.ts +5 -0
- package/src/TUICallService/locales/en.ts +15 -0
- package/src/TUICallService/locales/ja_JP.ts +15 -0
- package/src/TUICallService/locales/zh-cn.ts +15 -0
- package/src/TUICallService/utils/common-utils.ts +1 -1
- package/src/index.ts +1 -1
- package/tuicall-uikit-vue2.es.js +3363 -2692
- package/tuicall-uikit-vue2.umd.js +3 -2
- package/types/Components/components/base/CustomSelect/CustomSelect.d.ts +41 -0
- package/types/Components/hooks/index.d.ts +1 -0
- package/types/Components/hooks/useAIAssistant.d.ts +19 -0
- package/types/TUICallService/CallService/AIAssistant.d.ts +72 -15
- package/types/TUICallService/CallService/bellContext.d.ts +3 -0
- package/types/TUICallService/CallService/index.d.ts +4 -3
- package/types/TUICallService/CallService/miniProgram.d.ts +0 -1
- package/types/TUICallService/UIKitModal/UIKitModal.d.ts +4 -0
- package/types/TUICallService/UIKitModal/index.d.ts +2 -0
- package/types/TUICallService/UIKitModal/type.d.ts +13 -0
- package/types/TUICallService/interface/ICallStore.d.ts +4 -0
- package/types/TUICallService/locales/en.d.ts +14 -0
- package/types/TUICallService/locales/ja_JP.d.ts +14 -0
- package/types/TUICallService/locales/zh-cn.d.ts +14 -0
- package/types/tsconfig.tsbuildinfo +1 -1
- package/src/Components/components/common/AIAssistant/AIAssistant.ts +0 -130
- package/src/Components/components/common/AIAssistant/index.ts +0 -11
- package/types/Components/components/common/AIAssistant/AIAssistant.d.ts +0 -40
- package/types/Components/components/common/AIAssistant/index.d.ts +0 -4
package/README-zh_CN.md
CHANGED
|
@@ -39,6 +39,12 @@ TUICallKit 支持市面上主流浏览器,详情参考:[浏览器支持情
|
|
|
39
39
|
| 56+ | 80+ | 56+ | 11+ | 11+ | 46+ |
|
|
40
40
|
|
|
41
41
|
|
|
42
|
+
## 推荐使用更高效的 AI 集成助手
|
|
43
|
+
我们为您提供了全新的 AI 集成方式,如果您不需要完整的 Demo 工程, 只想快速开始集成,推荐您使用更高效的 AI 集成助手,只需要简单描述您的需求,即可自动生成集成代码,大幅提升开发效率。
|
|
44
|
+
|
|
45
|
+
点击这里,立即体验 [AI 集成](https://cloud.tencent.com/document/product/647/125504)。
|
|
46
|
+
|
|
47
|
+
|
|
42
48
|
## 安装
|
|
43
49
|
使用 npm:
|
|
44
50
|
```
|
package/README.md
CHANGED
|
@@ -41,6 +41,12 @@ Please be sure to use HTTPS protocol or localhost to deploy your Web App, otherw
|
|
|
41
41
|
| 56+ | 80+ | 56+ | 11+ | 11+ | 46+ |
|
|
42
42
|
|
|
43
43
|
|
|
44
|
+
## Recommend Using the More Efficient AI Integration Assistant
|
|
45
|
+
|
|
46
|
+
We offer you a brand new method for AI integration. If you don't need the complete demo project and just want to get started with integration quickly, we recommend using the more efficient AI Integration Assistant. Simply describe your requirements, and it will automatically generate the integration code, significantly boosting development efficiency.
|
|
47
|
+
|
|
48
|
+
Click here to experience [AI integration]((https://cloud.tencent.com/document/product/647/125504)) now!
|
|
49
|
+
|
|
44
50
|
|
|
45
51
|
## Install
|
|
46
52
|
npm:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@trtc/calls-uikit-vue2",
|
|
3
|
-
"version": "4.4.
|
|
3
|
+
"version": "4.4.5",
|
|
4
4
|
"main": "./tuicall-uikit-vue2.umd.js",
|
|
5
5
|
"module": "./tuicall-uikit-vue2.es.js",
|
|
6
6
|
"types": "./types/index.d.ts",
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
},
|
|
15
15
|
"dependencies": {
|
|
16
16
|
"@tencentcloud/tui-core-lite": "1.0.0",
|
|
17
|
-
"@trtc/call-engine-lite-js": "~3.5.
|
|
17
|
+
"@trtc/call-engine-lite-js": "~3.5.5",
|
|
18
18
|
"@tencentcloud/lite-chat": "^1.6.3",
|
|
19
19
|
"@trtc/call-engine-lite-wx": "~3.4.7"
|
|
20
20
|
},
|
|
@@ -14,7 +14,7 @@ import SingleCall from './components/SingleCall/SingleCall.vue';
|
|
|
14
14
|
import GroupCall from './components/GroupCall/GroupCall.vue';
|
|
15
15
|
import { PermitTip } from './components/common/PermitTip/PermitTip';
|
|
16
16
|
import { Toast } from './components/common/Toast';
|
|
17
|
-
import
|
|
17
|
+
import AISubtitle from './components/common/AIAssistant/AISubtitle.vue';
|
|
18
18
|
import { UIKitModal } from './components/common/UIKitModal';
|
|
19
19
|
import { TUIGlobal, TUIStore, StoreName, TUICallKitAPI, NAME, CallStatus, CallMediaType, VideoDisplayMode, VideoResolution } from '../TUICallService/index';
|
|
20
20
|
import {
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
<svg width="13" height="14" viewBox="0 0 13 14" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path d="M9.06218 6.75C9.06218 8.40685 7.71903 9.75 6.06218 9.75C4.40532 9.75 3.06218 8.40685 3.06218 6.75C3.06218 5.09315 4.40532 3.75 6.06218 3.75C7.71903 3.75 9.06218 5.09315 9.06218 6.75ZM8.06218 6.75C8.06218 5.64543 7.16675 4.75 6.06218 4.75C4.95761 4.75 4.06218 5.64543 4.06218 6.75C4.06218 7.85457 4.95761 8.75 6.06218 8.75C7.16675 8.75 8.06218 7.85457 8.06218 6.75Z" fill="white" fill-opacity="0.75"/>
|
|
3
|
+
<path d="M6.06218 0L12.1244 3.375V10.125L6.06218 13.5L0 10.125V3.375L6.06218 0ZM1 3.9628V9.5372L6.06218 12.3555L11.1244 9.5372V3.9628L6.06218 1.14453L1 3.9628Z" fill="white" fill-opacity="0.75"/>
|
|
4
|
+
</svg>
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path d="M19 12.1182H17.333V3.66699H2.66699V16.333H8.18945V18H1V2H19V12.1182Z" fill="white" fill-opacity="0.9"/>
|
|
3
|
+
<path d="M15.6667 8.02202C15.6667 8.02202 14.9677 7.72533 13.7849 7.77478C13.086 7.82422 12.5484 7.97257 12.172 8.36815C11.7419 8.81319 11.5269 9.35711 11.5269 10.0494C11.5269 10.7417 11.7419 11.2361 12.1183 11.6317C12.4946 11.9779 12.9785 12.1262 13.6237 12.1757C14.4301 12.2745 15.6667 11.9779 15.6667 11.9779V13.2635C15.6667 13.2635 14.7527 13.4613 13.5161 13.4613C12.4946 13.4613 11.6882 13.1152 11.043 12.5218C10.4516 11.879 10.129 11.0878 10.129 10.0988C10.129 9.06043 10.4516 8.17036 11.1505 7.52754C11.8495 6.88471 12.7097 6.53857 13.7849 6.53857C14.7527 6.53857 15.6667 6.73637 15.6667 6.73637V8.02202Z" fill="white" fill-opacity="0.9"/>
|
|
4
|
+
<path d="M9.53763 8.02202C9.53763 8.02202 8.83871 7.72533 7.65592 7.77478C6.95699 7.82422 6.41936 7.97257 6.04301 8.36815C5.6129 8.81319 5.39785 9.35711 5.39785 10.0494C5.39785 10.7417 5.6129 11.2361 5.98925 11.6317C6.36559 11.9779 6.84946 12.1262 7.49462 12.1757C8.30108 12.2745 9.53763 11.9779 9.53763 11.9779V13.2635C9.53763 13.2635 8.62366 13.4613 7.3871 13.4613C6.36559 13.4613 5.55914 13.1152 4.91398 12.5218C4.32258 11.879 4 11.0878 4 10.0988C4 9.06043 4.32258 8.17036 5.02151 7.52754C5.72043 6.88471 6.58065 6.53857 7.65592 6.53857C8.62366 6.53857 9.53763 6.73637 9.53763 6.73637V8.02202Z" fill="white" fill-opacity="0.9"/>
|
|
5
|
+
<rect x="10" y="14.5916" width="10" height="5" rx="2.5" fill="#676A70"/>
|
|
6
|
+
<rect x="10.4997" y="15.0916" width="4" height="4" rx="2" fill="white"/>
|
|
7
|
+
</svg>
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path d="M19 12.1182H17.333V3.66699H2.66699V16.333H8.18945V18H1V2H19V12.1182Z" fill="white" fill-opacity="0.9"/>
|
|
3
|
+
<path d="M15.6667 8.02202C15.6667 8.02202 14.9677 7.72533 13.7849 7.77478C13.086 7.82422 12.5484 7.97257 12.172 8.36815C11.7419 8.81319 11.5269 9.35711 11.5269 10.0494C11.5269 10.7417 11.7419 11.2361 12.1183 11.6317C12.4946 11.9779 12.9785 12.1262 13.6237 12.1757C14.4301 12.2745 15.6667 11.9779 15.6667 11.9779V13.2635C15.6667 13.2635 14.7527 13.4613 13.5161 13.4613C12.4946 13.4613 11.6882 13.1152 11.043 12.5218C10.4516 11.879 10.129 11.0878 10.129 10.0988C10.129 9.06043 10.4516 8.17036 11.1505 7.52754C11.8495 6.88471 12.7097 6.53857 13.7849 6.53857C14.7527 6.53857 15.6667 6.73637 15.6667 6.73637V8.02202Z" fill="white" fill-opacity="0.9"/>
|
|
4
|
+
<path d="M9.53763 8.02202C9.53763 8.02202 8.83871 7.72533 7.65592 7.77478C6.95699 7.82422 6.41936 7.97257 6.04301 8.36815C5.6129 8.81319 5.39785 9.35711 5.39785 10.0494C5.39785 10.7417 5.6129 11.2361 5.98925 11.6317C6.36559 11.9779 6.84946 12.1262 7.49462 12.1757C8.30108 12.2745 9.53763 11.9779 9.53763 11.9779V13.2635C9.53763 13.2635 8.62366 13.4613 7.3871 13.4613C6.36559 13.4613 5.55914 13.1152 4.91398 12.5218C4.32258 11.879 4 11.0878 4 10.0988C4 9.06043 4.32258 8.17036 5.02151 7.52754C5.72043 6.88471 6.58065 6.53857 7.65592 6.53857C8.62366 6.53857 9.53763 6.73637 9.53763 6.73637V8.02202Z" fill="white" fill-opacity="0.9"/>
|
|
5
|
+
<path d="M10 17.0916C10 15.7108 11.1193 14.5916 12.5 14.5916H17.5C18.8807 14.5916 20 15.7108 20 17.0916C20 18.4723 18.8807 19.5916 17.5 19.5916H12.5C11.1193 19.5916 10 18.4723 10 17.0916Z" fill="#4588F5"/>
|
|
6
|
+
<rect x="15.5042" y="15.0916" width="4" height="4" rx="2" fill="white"/>
|
|
7
|
+
</svg>
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
export interface SelectOption {
|
|
2
|
+
value: string | number;
|
|
3
|
+
label: string;
|
|
4
|
+
disabled?: boolean;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export const CustomSelectProps = {
|
|
8
|
+
// Vue2 compatible: use 'value' instead of 'modelValue'
|
|
9
|
+
value: {
|
|
10
|
+
type: [String, Number],
|
|
11
|
+
default: '',
|
|
12
|
+
},
|
|
13
|
+
options: {
|
|
14
|
+
type: Array as () => SelectOption[],
|
|
15
|
+
default: () => [],
|
|
16
|
+
},
|
|
17
|
+
placeholder: {
|
|
18
|
+
type: String,
|
|
19
|
+
default: 'Please select',
|
|
20
|
+
},
|
|
21
|
+
disabled: {
|
|
22
|
+
type: Boolean,
|
|
23
|
+
default: false,
|
|
24
|
+
},
|
|
25
|
+
clearable: {
|
|
26
|
+
type: Boolean,
|
|
27
|
+
default: false,
|
|
28
|
+
},
|
|
29
|
+
size: {
|
|
30
|
+
type: String,
|
|
31
|
+
values: ['small', 'medium', 'large'],
|
|
32
|
+
default: 'medium',
|
|
33
|
+
},
|
|
34
|
+
width: {
|
|
35
|
+
type: String,
|
|
36
|
+
default: '100%',
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export const CustomSelectEmits = {
|
|
41
|
+
// Vue2 compatible: use 'input' instead of 'update:modelValue'
|
|
42
|
+
'input': (value: string | number) => true,
|
|
43
|
+
'change': (value: string | number) => true,
|
|
44
|
+
'clear': () => true,
|
|
45
|
+
};
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="custom-select-wrapper" ref="wrapperRef">
|
|
3
|
+
<div
|
|
4
|
+
class="custom-select"
|
|
5
|
+
:class="{ 'is-open': isOpen, 'is-disabled': disabled }"
|
|
6
|
+
@click.stop="toggleDropdown"
|
|
7
|
+
>
|
|
8
|
+
<span class="select-text">{{ displayText }}</span>
|
|
9
|
+
<svg
|
|
10
|
+
class="select-arrow"
|
|
11
|
+
:class="{ 'is-open': isOpen }"
|
|
12
|
+
width="12"
|
|
13
|
+
height="8"
|
|
14
|
+
viewBox="0 0 12 8"
|
|
15
|
+
fill="none"
|
|
16
|
+
>
|
|
17
|
+
<path
|
|
18
|
+
d="M1 1L6 6L11 1"
|
|
19
|
+
stroke="#C0C4CC"
|
|
20
|
+
stroke-width="1.5"
|
|
21
|
+
stroke-linecap="round"
|
|
22
|
+
stroke-linejoin="round"
|
|
23
|
+
/>
|
|
24
|
+
</svg>
|
|
25
|
+
</div>
|
|
26
|
+
<div class="custom-options" v-show="isOpen">
|
|
27
|
+
<div
|
|
28
|
+
v-for="option in options"
|
|
29
|
+
:key="option.value"
|
|
30
|
+
class="custom-option"
|
|
31
|
+
:class="{ 'is-selected': value === option.value }"
|
|
32
|
+
@click.stop="selectOption(option.value)"
|
|
33
|
+
>
|
|
34
|
+
{{ option.label }}
|
|
35
|
+
</div>
|
|
36
|
+
</div>
|
|
37
|
+
</div>
|
|
38
|
+
</template>
|
|
39
|
+
|
|
40
|
+
<script setup lang="ts">
|
|
41
|
+
import { ref, computed, onMounted, onUnmounted } from '../../../../adapter-vue';
|
|
42
|
+
import { CustomSelectProps, CustomSelectEmits, type SelectOption } from './CustomSelect';
|
|
43
|
+
|
|
44
|
+
const props = defineProps(CustomSelectProps);
|
|
45
|
+
const emit = defineEmits(CustomSelectEmits);
|
|
46
|
+
|
|
47
|
+
const isOpen = ref(false);
|
|
48
|
+
const wrapperRef = ref<HTMLElement | null>(null);
|
|
49
|
+
|
|
50
|
+
const displayText = computed(() => {
|
|
51
|
+
const selectedOption = props.options.find(option => option.value === props.value);
|
|
52
|
+
return selectedOption ? selectedOption.label : props.placeholder;
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
const toggleDropdown = () => {
|
|
56
|
+
if (props.disabled) return;
|
|
57
|
+
isOpen.value = !isOpen.value;
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const selectOption = (value: string | number) => {
|
|
61
|
+
// Vue2 compatible: emit 'input' event for v-model
|
|
62
|
+
emit('input', value);
|
|
63
|
+
emit('change', value);
|
|
64
|
+
isOpen.value = false;
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
// Close dropdown when clicking outside
|
|
68
|
+
const handleClickOutside = (event: MouseEvent) => {
|
|
69
|
+
if (!wrapperRef.value) return;
|
|
70
|
+
|
|
71
|
+
const target = event.target as HTMLElement;
|
|
72
|
+
// Check if click is outside the wrapper element
|
|
73
|
+
if (!wrapperRef.value.contains(target)) {
|
|
74
|
+
isOpen.value = false;
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
onMounted(() => {
|
|
79
|
+
document.addEventListener('click', handleClickOutside);
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
onUnmounted(() => {
|
|
83
|
+
document.removeEventListener('click', handleClickOutside);
|
|
84
|
+
});
|
|
85
|
+
</script>
|
|
86
|
+
|
|
87
|
+
<style lang="scss" scoped>
|
|
88
|
+
.custom-select-wrapper {
|
|
89
|
+
position: relative;
|
|
90
|
+
width: 100%;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
.custom-select {
|
|
94
|
+
height: 36px;
|
|
95
|
+
padding: 0 32px 0 12px;
|
|
96
|
+
border: 1px solid #DCDFE6;
|
|
97
|
+
border-radius: 4px;
|
|
98
|
+
font-size: 14px;
|
|
99
|
+
color: #606266;
|
|
100
|
+
background: #FFFFFF;
|
|
101
|
+
cursor: pointer;
|
|
102
|
+
display: flex;
|
|
103
|
+
align-items: center;
|
|
104
|
+
transition: all 0.3s;
|
|
105
|
+
|
|
106
|
+
&:hover:not(.is-disabled) {
|
|
107
|
+
border-color: #C0C4CC;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
&.is-open {
|
|
111
|
+
border-color: #409EFF;
|
|
112
|
+
box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.2);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
&.is-disabled {
|
|
116
|
+
background: #F5F7FA;
|
|
117
|
+
color: #C0C4CC;
|
|
118
|
+
cursor: not-allowed;
|
|
119
|
+
border-color: #E4E7ED;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
.select-text {
|
|
124
|
+
overflow: hidden;
|
|
125
|
+
text-overflow: ellipsis;
|
|
126
|
+
white-space: nowrap;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
.select-arrow {
|
|
130
|
+
position: absolute;
|
|
131
|
+
right: 12px;
|
|
132
|
+
top: 50%;
|
|
133
|
+
transform: translateY(-50%);
|
|
134
|
+
pointer-events: none;
|
|
135
|
+
transition: transform 0.3s;
|
|
136
|
+
|
|
137
|
+
&.is-open {
|
|
138
|
+
transform: translateY(-50%) rotate(180deg);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
.custom-options {
|
|
143
|
+
position: absolute;
|
|
144
|
+
top: 100%;
|
|
145
|
+
left: 0;
|
|
146
|
+
right: 0;
|
|
147
|
+
background: #FFFFFF;
|
|
148
|
+
border: 1px solid #DCDFE6;
|
|
149
|
+
border-radius: 4px;
|
|
150
|
+
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
|
|
151
|
+
z-index: 1000;
|
|
152
|
+
margin-top: 4px;
|
|
153
|
+
overflow: hidden;
|
|
154
|
+
max-height: 200px;
|
|
155
|
+
overflow-y: auto;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
.custom-option {
|
|
159
|
+
padding: 8px 12px;
|
|
160
|
+
font-size: 14px;
|
|
161
|
+
color: #606266;
|
|
162
|
+
cursor: pointer;
|
|
163
|
+
transition: all 0.2s;
|
|
164
|
+
|
|
165
|
+
&:hover {
|
|
166
|
+
background: #F5F7FA;
|
|
167
|
+
color: #409EFF;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
&.is-selected {
|
|
171
|
+
color: #409EFF;
|
|
172
|
+
font-weight: 500;
|
|
173
|
+
|
|
174
|
+
&:hover {
|
|
175
|
+
background: #F5F7FA;
|
|
176
|
+
color: #409EFF;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// Scrollbar styling for options
|
|
182
|
+
.custom-options::-webkit-scrollbar {
|
|
183
|
+
width: 6px;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
.custom-options::-webkit-scrollbar-track {
|
|
187
|
+
background: #F1F1F1;
|
|
188
|
+
border-radius: 3px;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
.custom-options::-webkit-scrollbar-thumb {
|
|
192
|
+
background: #C0C4CC;
|
|
193
|
+
border-radius: 3px;
|
|
194
|
+
|
|
195
|
+
&:hover {
|
|
196
|
+
background: #A8ABB2;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
</style>
|
|
@@ -1,17 +1,40 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div
|
|
3
|
-
v-
|
|
4
|
-
:class="[
|
|
3
|
+
v-if="isAITranscriberEnabled"
|
|
4
|
+
:class="[
|
|
5
|
+
isPC ? 'ai-subtitle-pc' : 'ai-subtitle-h5',
|
|
6
|
+
customClass,
|
|
7
|
+
{
|
|
8
|
+
'ai-subtitle-pc--expanded': showSettingsModal && isPC,
|
|
9
|
+
'ai-subtitle-h5--expanded': showSettingsModal && !isPC
|
|
10
|
+
}
|
|
11
|
+
]"
|
|
5
12
|
:style="[customStyle]"
|
|
6
13
|
>
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
14
|
+
<!-- Subtitle Content Component -->
|
|
15
|
+
<SubtitleContent
|
|
16
|
+
v-show="!showSettingsModal"
|
|
17
|
+
@open-settings="openSettingsModal"
|
|
18
|
+
:class="isPC ? 'ai-subtitle-pc__content' : 'ai-subtitle-h5__content'"
|
|
19
|
+
/>
|
|
20
|
+
|
|
21
|
+
<!-- Settings Modal Component (Same Level) -->
|
|
22
|
+
<SubtitleSettingsPC
|
|
23
|
+
v-if="isPC"
|
|
24
|
+
:visible="showSettingsModal"
|
|
25
|
+
@update:visible="showSettingsModal = $event"
|
|
26
|
+
@confirm="handleSettingsConfirm"
|
|
27
|
+
class="ai-subtitle-pc__settings"
|
|
28
|
+
/>
|
|
29
|
+
|
|
30
|
+
<!-- Settings Modal Component (H5) -->
|
|
31
|
+
<SubtitleSettingsH5
|
|
32
|
+
v-else
|
|
33
|
+
:visible="showSettingsModal"
|
|
34
|
+
@update:visible="showSettingsModal = $event"
|
|
35
|
+
@confirm="handleSettingsConfirm"
|
|
36
|
+
class="ai-subtitle-h5__settings"
|
|
37
|
+
/>
|
|
15
38
|
</div>
|
|
16
39
|
</template>
|
|
17
40
|
|
|
@@ -24,8 +47,17 @@ export default {
|
|
|
24
47
|
</script>
|
|
25
48
|
|
|
26
49
|
<script lang="ts" setup>
|
|
27
|
-
import {
|
|
28
|
-
import
|
|
50
|
+
import { ref, onMounted } from '../../../../adapter-vue';
|
|
51
|
+
import SubtitleContent from './components/SubtitleContent.vue';
|
|
52
|
+
import SubtitleSettingsPC from './components/SubtitleSettingsPC.vue';
|
|
53
|
+
import SubtitleSettingsH5 from './components/SubtitleSettingsH5.vue';
|
|
54
|
+
import { TUIGlobal } from '../../../../TUICallService/index';
|
|
55
|
+
import { useAIAssistant } from '../../../hooks/useAIAssistant';
|
|
56
|
+
|
|
57
|
+
const isPC = TUIGlobal.isPC;
|
|
58
|
+
|
|
59
|
+
// Use AI Assistant hook (now includes both status and data)
|
|
60
|
+
const { isAITranscriberEnabled } = useAIAssistant();
|
|
29
61
|
|
|
30
62
|
defineProps({
|
|
31
63
|
customClass: {
|
|
@@ -36,40 +68,126 @@ defineProps({
|
|
|
36
68
|
},
|
|
37
69
|
})
|
|
38
70
|
|
|
39
|
-
const
|
|
71
|
+
const showSettingsModal = ref(false);
|
|
40
72
|
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
subtitleInfoList.value = JSON.parse(JSON.stringify(data.subtitleInfoList));
|
|
73
|
+
const openSettingsModal = () => {
|
|
74
|
+
showSettingsModal.value = true;
|
|
45
75
|
};
|
|
46
76
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
onUnmounted(() => {
|
|
52
|
-
aiAssistant.off(ASREvent.TRANSCRIPTION, handleAISubtitle);
|
|
53
|
-
})
|
|
77
|
+
const handleSettingsConfirm = (settings: any) => {
|
|
78
|
+
// Handle settings save logic here
|
|
79
|
+
showSettingsModal.value = false;
|
|
80
|
+
};
|
|
54
81
|
</script>
|
|
55
82
|
|
|
56
83
|
<style lang="scss" scoped>
|
|
57
|
-
|
|
84
|
+
// PC端样式
|
|
85
|
+
.ai-subtitle-pc {
|
|
58
86
|
position: absolute;
|
|
59
|
-
z-index:
|
|
60
|
-
bottom: 110px;
|
|
87
|
+
z-index: 1;
|
|
61
88
|
left: 50%;
|
|
62
|
-
padding: 10px 12px;
|
|
63
|
-
color: #fff;
|
|
64
|
-
background-color: rgba(79, 88, 107, 0.7);
|
|
65
|
-
border-radius: 8px;
|
|
66
89
|
transform: translateX(-50%);
|
|
67
|
-
width:
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
90
|
+
width: auto;
|
|
91
|
+
height: auto;
|
|
92
|
+
bottom: 110px;
|
|
93
|
+
|
|
94
|
+
// PC端展开状态
|
|
95
|
+
&--expanded {
|
|
96
|
+
position: absolute !important;
|
|
97
|
+
top: 0 !important;
|
|
98
|
+
left: 0 !important;
|
|
99
|
+
right: 0 !important;
|
|
100
|
+
bottom: 0 !important;
|
|
101
|
+
width: 100% !important;
|
|
102
|
+
height: 100% !important;
|
|
103
|
+
background-color: transparent;
|
|
104
|
+
transform: none !important;
|
|
105
|
+
z-index: 1000;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
&__content {
|
|
109
|
+
// PC端内容定位
|
|
110
|
+
.ai-subtitle-pc:not(.ai-subtitle-pc--expanded) & {
|
|
111
|
+
position: relative;
|
|
112
|
+
width: auto;
|
|
113
|
+
height: auto;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// PC端展开时隐藏内容
|
|
117
|
+
.ai-subtitle-pc--expanded & {
|
|
118
|
+
display: none;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
&__settings {
|
|
123
|
+
// PC端设置面板定位
|
|
124
|
+
.ai-subtitle-pc--expanded & {
|
|
125
|
+
position: absolute;
|
|
126
|
+
top: 50%;
|
|
127
|
+
left: 50%;
|
|
128
|
+
transform: translate(-50%, -50%);
|
|
129
|
+
z-index: 1001;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// PC端未展开时隐藏设置
|
|
133
|
+
.ai-subtitle-pc:not(.ai-subtitle-pc--expanded) & {
|
|
134
|
+
display: none;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
71
137
|
}
|
|
72
|
-
|
|
73
|
-
|
|
138
|
+
|
|
139
|
+
// H5端样式
|
|
140
|
+
.ai-subtitle-h5 {
|
|
141
|
+
position: absolute;
|
|
142
|
+
z-index: 100;
|
|
143
|
+
left: 50%;
|
|
144
|
+
transform: translateX(-50%);
|
|
145
|
+
width: auto;
|
|
146
|
+
height: auto;
|
|
147
|
+
bottom: 26%;
|
|
148
|
+
|
|
149
|
+
// H5端展开状态
|
|
150
|
+
&--expanded {
|
|
151
|
+
position: absolute !important;
|
|
152
|
+
top: 0 !important;
|
|
153
|
+
left: 0 !important;
|
|
154
|
+
right: 0 !important;
|
|
155
|
+
bottom: 0 !important;
|
|
156
|
+
width: 100% !important;
|
|
157
|
+
height: 100% !important;
|
|
158
|
+
background-color: transparent;
|
|
159
|
+
transform: none !important;
|
|
160
|
+
z-index: 1000;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
&__content {
|
|
164
|
+
// H5端内容定位
|
|
165
|
+
.ai-subtitle-h5:not(.ai-subtitle-h5--expanded) & {
|
|
166
|
+
position: relative;
|
|
167
|
+
width: auto;
|
|
168
|
+
height: auto;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// H5端展开时隐藏内容
|
|
172
|
+
.ai-subtitle-h5--expanded & {
|
|
173
|
+
display: none;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
&__settings {
|
|
178
|
+
// H5端设置面板定位
|
|
179
|
+
.ai-subtitle-h5--expanded & {
|
|
180
|
+
position: absolute;
|
|
181
|
+
top: 50%;
|
|
182
|
+
left: 50%;
|
|
183
|
+
transform: translate(-50%, -50%);
|
|
184
|
+
z-index: 1001;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// H5端未展开时隐藏设置
|
|
188
|
+
.ai-subtitle-h5:not(.ai-subtitle-h5--expanded) & {
|
|
189
|
+
display: none;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
74
192
|
}
|
|
75
193
|
</style>
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div @click="handleToggle">
|
|
3
|
+
<TKImage v-if="isAITranscriberRunning" :src="openAiAssistantIcon" width="24px" height="24px" />
|
|
4
|
+
<TKImage v-else :src="closeAiAssistantIcon" width="24px" height="24px" />
|
|
5
|
+
</div>
|
|
6
|
+
</template>
|
|
7
|
+
|
|
8
|
+
<script setup lang="ts">
|
|
9
|
+
import { TUICallKitAPI } from "../../../../../TUICallService/index";
|
|
10
|
+
import { useAIAssistant } from '../../../../hooks/useAIAssistant';
|
|
11
|
+
import TKImage from '../../../base/TKImage/TKImage.vue';
|
|
12
|
+
import openAiAssistantIcon from '../../../../assets/aiAssistant/mobile/open-aiAssistant.svg';
|
|
13
|
+
import closeAiAssistantIcon from '../../../../assets/aiAssistant/mobile/close-aiAssistant.svg';
|
|
14
|
+
|
|
15
|
+
// Use AI Transcriber status hook
|
|
16
|
+
const { isAITranscriberRunning } = useAIAssistant();
|
|
17
|
+
|
|
18
|
+
// Toggle AI transcriber
|
|
19
|
+
const handleToggle = async () => {
|
|
20
|
+
try {
|
|
21
|
+
if (isAITranscriberRunning.value) {
|
|
22
|
+
await TUICallKitAPI._aiAssistant.stopRealtimeTranscriber();
|
|
23
|
+
} else {
|
|
24
|
+
await TUICallKitAPI._aiAssistant.startRealtimeTranscriber({
|
|
25
|
+
sourceLanguage: 'zh',
|
|
26
|
+
translationLanguages: ['en']
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
} catch (error) {
|
|
30
|
+
console.error('Failed to toggle AI transcriber:', error);
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
</script>
|
|
34
|
+
|
|
35
|
+
<style lang="scss" scoped></style>
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="ai-transcriber-switch">
|
|
3
|
+
<span class="ai-transcriber-switch__label">{{ t('ai-subtitle') }}</span>
|
|
4
|
+
<div
|
|
5
|
+
class="ai-transcriber-switch__toggle"
|
|
6
|
+
:class="{ 'ai-transcriber-switch__toggle--active': isAITranscriberRunning }"
|
|
7
|
+
@click="handleToggle"
|
|
8
|
+
>
|
|
9
|
+
<div class="ai-transcriber-switch__slider"></div>
|
|
10
|
+
</div>
|
|
11
|
+
</div>
|
|
12
|
+
</template>
|
|
13
|
+
|
|
14
|
+
<script setup lang="ts">
|
|
15
|
+
import { TUICallKitAPI } from "../../../../../TUICallService/index";
|
|
16
|
+
import { useAIAssistant } from '../../../../hooks/useAIAssistant';
|
|
17
|
+
import { useTranslate } from '../../../../hooks/useTranslate';
|
|
18
|
+
|
|
19
|
+
// Use i18n translation
|
|
20
|
+
const t = useTranslate();
|
|
21
|
+
|
|
22
|
+
// Use AI Transcriber status hook
|
|
23
|
+
const { isAITranscriberRunning } = useAIAssistant();
|
|
24
|
+
|
|
25
|
+
// Toggle AI transcriber
|
|
26
|
+
const handleToggle = async () => {
|
|
27
|
+
try {
|
|
28
|
+
if (isAITranscriberRunning.value) {
|
|
29
|
+
await TUICallKitAPI._aiAssistant.stopRealtimeTranscriber();
|
|
30
|
+
} else {
|
|
31
|
+
await TUICallKitAPI._aiAssistant.startRealtimeTranscriber({
|
|
32
|
+
sourceLanguage: 'zh',
|
|
33
|
+
translationLanguages: ['en']
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
} catch (error) {
|
|
37
|
+
console.error('Failed to toggle AI transcriber:', error);
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
</script>
|
|
41
|
+
|
|
42
|
+
<style lang="scss" scoped>
|
|
43
|
+
.ai-transcriber-switch {
|
|
44
|
+
display: flex;
|
|
45
|
+
align-items: center;
|
|
46
|
+
gap: 8px;
|
|
47
|
+
padding: 8px 12px;
|
|
48
|
+
border-radius: 20px;
|
|
49
|
+
color: white;
|
|
50
|
+
font-size: 14px;
|
|
51
|
+
font-weight: 400;
|
|
52
|
+
font-family: PingFang SC;
|
|
53
|
+
cursor: pointer;
|
|
54
|
+
|
|
55
|
+
&__label {
|
|
56
|
+
white-space: nowrap;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
&__toggle {
|
|
60
|
+
position: relative;
|
|
61
|
+
width: 32px;
|
|
62
|
+
height: 20px;
|
|
63
|
+
background: #FFFFFF4D;
|
|
64
|
+
border-radius: 10px;
|
|
65
|
+
transition: background-color 0.3s ease;
|
|
66
|
+
cursor: pointer;
|
|
67
|
+
|
|
68
|
+
&--active {
|
|
69
|
+
background: #1C66E5;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
&__slider {
|
|
74
|
+
position: absolute;
|
|
75
|
+
top: 3px;
|
|
76
|
+
left: 2px;
|
|
77
|
+
width: 14px;
|
|
78
|
+
height: 14px;
|
|
79
|
+
border-radius: 50%;
|
|
80
|
+
background: white;
|
|
81
|
+
transition: transform 0.3s ease;
|
|
82
|
+
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
|
|
83
|
+
|
|
84
|
+
.ai-transcriber-switch__toggle--active & {
|
|
85
|
+
transform: translateX(14px);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
</style>
|