@tencentcloud/roomkit-electron-vue3 2.7.0 → 2.7.1

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 (50) hide show
  1. package/es/components/AITools/AISubtitles.vue.mjs +1 -1
  2. package/es/components/AITools/AISubtitles.vue2.mjs +18 -19
  3. package/es/components/AITools/AITranscription.vue.mjs +1 -1
  4. package/es/components/AITools/AITranscription.vue2.mjs +65 -76
  5. package/es/components/ManageMember/MemberControl/index.vue.mjs +1 -1
  6. package/es/components/ManageMember/MemberControl/index.vue2.mjs +6 -4
  7. package/es/components/ManageMember/MemberItemCommon/MemberInfo.vue.mjs +1 -1
  8. package/es/components/RoomFooter/BasicBeauty.vue.mjs +1 -1
  9. package/es/components/RoomFooter/BasicBeauty.vue2.mjs +3 -1
  10. package/es/components/RoomFooter/ChatControl.vue.mjs +2 -0
  11. package/es/components/ScheduleConference/ScheduleConferencePanel/index.vue2.mjs +1 -1
  12. package/es/components/ScheduleConference/ScheduleRoomControl.vue2.mjs +1 -1
  13. package/es/components/ScheduleConference/ScheduleRoomList.vue2.mjs +1 -1
  14. package/es/index.mjs +118 -110
  15. package/es/services/function/aiTask.d.ts +13 -17
  16. package/es/services/function/aiTask.mjs +63 -100
  17. package/es/services/manager/dataReportManager.d.ts +4 -1
  18. package/es/services/manager/dataReportManager.mjs +3 -0
  19. package/es/utils/utils.d.ts +2 -0
  20. package/es/utils/utils.mjs +33 -0
  21. package/lib/components/AITools/AISubtitles.vue.js +1 -1
  22. package/lib/components/AITools/AISubtitles.vue2.js +17 -18
  23. package/lib/components/AITools/AITranscription.vue.js +1 -1
  24. package/lib/components/AITools/AITranscription.vue2.js +64 -75
  25. package/lib/components/ManageMember/MemberControl/index.vue.js +1 -1
  26. package/lib/components/ManageMember/MemberControl/index.vue2.js +5 -3
  27. package/lib/components/ManageMember/MemberItemCommon/MemberInfo.vue.js +1 -1
  28. package/lib/components/RoomFooter/BasicBeauty.vue.js +1 -1
  29. package/lib/components/RoomFooter/BasicBeauty.vue2.js +3 -1
  30. package/lib/components/RoomFooter/ChatControl.vue.js +2 -0
  31. package/lib/components/ScheduleConference/ScheduleConferencePanel/index.vue2.js +1 -1
  32. package/lib/components/ScheduleConference/ScheduleRoomControl.vue2.js +1 -1
  33. package/lib/components/ScheduleConference/ScheduleRoomList.vue2.js +1 -1
  34. package/lib/index.js +118 -110
  35. package/lib/services/function/aiTask.d.ts +13 -17
  36. package/lib/services/function/aiTask.js +63 -100
  37. package/lib/services/manager/dataReportManager.d.ts +4 -1
  38. package/lib/services/manager/dataReportManager.js +3 -0
  39. package/lib/utils/utils.d.ts +2 -0
  40. package/lib/utils/utils.js +33 -0
  41. package/package.json +2 -2
  42. package/src/TUIRoom/components/AITools/AISubtitles.vue +26 -23
  43. package/src/TUIRoom/components/AITools/AITranscription.vue +106 -101
  44. package/src/TUIRoom/components/ManageMember/MemberControl/index.vue +8 -3
  45. package/src/TUIRoom/components/ManageMember/MemberItemCommon/MemberInfo.vue +1 -1
  46. package/src/TUIRoom/components/RoomFooter/BasicBeauty.vue +2 -1
  47. package/src/TUIRoom/components/RoomFooter/ChatControl.vue +2 -1
  48. package/src/TUIRoom/services/function/aiTask.ts +79 -113
  49. package/src/TUIRoom/services/manager/dataReportManager.ts +3 -0
  50. package/src/TUIRoom/utils/utils.ts +47 -0
@@ -3,18 +3,20 @@ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { en
3
3
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
4
  import mitt from "mitt";
5
5
  import { isElectron, isMobile } from "../../utils/environment.mjs";
6
+ import { findLastIndex } from "../../utils/utils.mjs";
6
7
  var AI_TASK = /* @__PURE__ */ ((AI_TASK2) => {
7
8
  AI_TASK2["TRANSCRIPTION_TASK"] = "transcription";
8
9
  return AI_TASK2;
9
10
  })(AI_TASK || {});
11
+ const ASR_EVENT_CODE = 1e4;
10
12
  class AITask {
11
13
  constructor(service) {
12
14
  __publicField(this, "emitter", mitt());
13
15
  __publicField(this, "trtc");
14
16
  __publicField(this, "service");
15
- __publicField(this, "subtitleMsg", []);
16
- __publicField(this, "subtitleText", { value: "" });
17
- __publicField(this, "transcriptionText", { value: "" });
17
+ __publicField(this, "subtitleMessages", {});
18
+ __publicField(this, "transcribedMessageList", []);
19
+ __publicField(this, "subtitleTimeout", {});
18
20
  this.service = service;
19
21
  if (isElectron || isMobile) return;
20
22
  this.bindCtx();
@@ -43,126 +45,87 @@ class AITask {
43
45
  if (typeof ((_a = this.service.roomEngine.instance) == null ? void 0 : _a.getTRTCCloud) === "undefined" || typeof ((_c = (_b = this.service.roomEngine.instance) == null ? void 0 : _b.getTRTCCloud()) == null ? void 0 : _c._trtc) === "undefined") {
44
46
  return;
45
47
  }
46
- const trtc = (_d = this.service.roomEngine.instance) == null ? void 0 : _d.getTRTCCloud()._trtc;
47
- this.trtc = trtc;
48
- trtc.on("custom-message", this.handleAIMessage);
48
+ this.trtc = (_d = this.service.roomEngine.instance) == null ? void 0 : _d.getTRTCCloud()._trtc;
49
+ this.trtc.on("custom-message", this.handleAIMessage);
49
50
  }
50
51
  handleUnmount() {
51
52
  var _a;
52
- this.subtitleMsg = [];
53
- this.subtitleText.value = "";
54
- this.transcriptionText.value = "";
53
+ this.subtitleMessages = {};
54
+ this.transcribedMessageList = [];
55
55
  (_a = this.trtc) == null ? void 0 : _a.off("custom-message", this.handleAIMessage);
56
56
  }
57
57
  bindEvent() {
58
58
  this.service.lifeCycleManager.on("mount", this.handleMount);
59
59
  this.service.lifeCycleManager.on("unmount", this.handleUnmount);
60
60
  }
61
- // todo trtc defines this type as any
61
+ resetSubtitleTimeout(id, fn) {
62
+ if (this.subtitleTimeout[id]) {
63
+ clearTimeout(this.subtitleTimeout[id]);
64
+ }
65
+ this.subtitleTimeout[id] = setTimeout(fn, 3e3);
66
+ }
62
67
  handleAIMessage(event) {
63
68
  if (event.cmdId !== 1) return;
64
69
  const data = new TextDecoder().decode(event.data);
65
70
  const jsonData = JSON.parse(data);
66
71
  this.handleMessage(jsonData);
67
72
  this.emit("transcription", {
68
- subtitleText: this.subtitleText,
69
- transcriptionText: this.transcriptionText,
70
- subtitleMsg: this.subtitleMsg
73
+ subtitleMessages: this.subtitleMessages,
74
+ transcribedMessageList: this.transcribedMessageList
71
75
  });
72
76
  }
73
77
  handleMessage(data) {
74
- const refreshSubtitle = () => {
75
- let displayText = "";
76
- for (let i = 0; i < this.subtitleMsg.length; i++) {
77
- displayText += `${this.service.roomStore.getDisplayName(this.subtitleMsg[i].userid)}: ${this.subtitleMsg[i].text}
78
- `;
79
- if (this.subtitleMsg[i].translation_text !== "") {
80
- displayText += `${this.service.roomStore.getDisplayName(this.subtitleMsg[i].userid)}: ${this.subtitleMsg[i].translation_text}
81
- `;
82
- }
83
- }
84
- this.subtitleText.value = displayText;
78
+ if (data.type !== ASR_EVENT_CODE) return;
79
+ const { sender, payload } = data;
80
+ const { end } = payload;
81
+ const createSubtitleMsg = () => {
82
+ return {
83
+ sender,
84
+ text: payload.text,
85
+ translationText: payload.translation_text,
86
+ startMsTs: data.start_ms_ts,
87
+ end
88
+ };
85
89
  };
86
- if (data.type === 1e4 && data.payload.end === false) {
87
- let exist = false;
88
- for (let i = 0; i < this.subtitleMsg.length; i++) {
89
- if (data.sender === this.subtitleMsg[i].userid) {
90
- this.subtitleMsg[i].text = data.payload.text;
91
- this.subtitleMsg[i].translation_text = data.payload.translation_text;
92
- exist = true;
93
- break;
94
- }
95
- }
96
- if (!exist) {
97
- this.subtitleMsg.push({
98
- userid: data.sender,
99
- text: data.payload.text,
100
- translation_text: data.payload.translation_text
101
- });
102
- }
103
- refreshSubtitle();
104
- } else if (data.type === 1e4 && data.payload.end === true) {
105
- for (let i = 0; i < this.subtitleMsg.length; i++) {
106
- if (data.sender === this.subtitleMsg[i].userid) {
107
- this.subtitleMsg[i].text = data.payload.text;
108
- this.subtitleMsg[i].translation_text = data.payload.translation_text;
109
- break;
110
- }
111
- }
112
- refreshSubtitle();
113
- let content = `${data.payload.start_time}->${data.payload.end_time} ${data.sender}: ${data.payload.text}
114
- `;
115
- if (data.payload.translation_text !== "") {
116
- content += `${data.payload.start_time}->${data.payload.end_time} ${data.sender}: ${data.payload.translation_text}
117
- `;
90
+ const updateMsg = (msg) => {
91
+ msg.text = payload.text;
92
+ msg.translationText = payload.translation_text;
93
+ msg.end = end;
94
+ };
95
+ const appendMsg = (msg, target) => {
96
+ if (Array.isArray(target)) {
97
+ target.push(msg);
98
+ } else if (typeof target === "object") {
99
+ const recordTarget = target;
100
+ recordTarget[msg.sender] = msg;
101
+ } else {
102
+ throw new Error("Invalid target type");
118
103
  }
119
- this.transcriptionText.value += content;
104
+ };
105
+ const existingSubtitle = this.subtitleMessages[sender];
106
+ if (existingSubtitle) {
107
+ updateMsg(existingSubtitle);
108
+ } else {
109
+ appendMsg(createSubtitleMsg(), this.subtitleMessages);
120
110
  }
121
- if (data.type === "subtitle") {
122
- let exist = false;
123
- for (let i = 0; i < this.subtitleMsg.length; i++) {
124
- if (data.userid === this.subtitleMsg[i].userid) {
125
- this.subtitleMsg[i].text = data.text;
126
- this.subtitleMsg[i].translation_text = data.translation_text;
127
- exist = true;
128
- break;
129
- }
130
- }
131
- if (!exist) {
132
- this.subtitleMsg.push({
133
- userid: data.userid,
134
- text: data.text,
135
- translation_text: data.translation_text
136
- });
137
- }
138
- refreshSubtitle();
139
- } else if (data.type === "transcription") {
140
- for (let i = 0; i < this.subtitleMsg.length; i++) {
141
- if (data.userid === this.subtitleMsg[i].userid) {
142
- this.subtitleMsg[i].text = data.text;
143
- this.subtitleMsg[i].translation_text = data.translation_text;
144
- break;
145
- }
146
- }
147
- refreshSubtitle();
148
- let content = `${formatTimestampToTime(data.start_ms_ts)}->${formatTimestampToTime(data.end_ms_ts)} ${this.service.roomStore.getDisplayName(data.userid)}: ${data.text}
149
- `;
150
- if (data.translation_text !== "") {
151
- content += `${formatTimestampToTime(data.start_ms_ts)}->${formatTimestampToTime(data.end_ms_ts)} ${this.service.roomStore.getDisplayName(data.userid)}: ${data.translation_text}
152
- `;
153
- }
154
- this.transcriptionText.value += content;
111
+ const transcriptionIndex = findLastIndex(
112
+ this.transcribedMessageList,
113
+ (msg) => msg.sender === sender && !msg.end
114
+ );
115
+ if (transcriptionIndex !== -1) {
116
+ updateMsg(this.transcribedMessageList[transcriptionIndex]);
117
+ } else {
118
+ appendMsg(createSubtitleMsg(), this.transcribedMessageList);
155
119
  }
120
+ this.resetSubtitleTimeout(sender, () => {
121
+ if (!end) return;
122
+ delete this.subtitleMessages[sender];
123
+ this.emit("transcription", {
124
+ subtitleMessages: this.subtitleMessages,
125
+ transcribedMessageList: this.transcribedMessageList
126
+ });
127
+ });
156
128
  }
157
- StartAITranscription() {
158
- }
159
- }
160
- function formatTimestampToTime(timestamp) {
161
- const date = new Date(timestamp);
162
- const hours = date.getHours().toString().padStart(2, "0");
163
- const minutes = date.getMinutes().toString().padStart(2, "0");
164
- const seconds = date.getSeconds().toString().padStart(2, "0");
165
- return `${hours}:${minutes}:${seconds}`;
166
129
  }
167
130
  export {
168
131
  AITask,
@@ -10,7 +10,10 @@ export declare enum MetricsKey {
10
10
  disableScreenSharing = 106053,
11
11
  enableWatermark = 106054,
12
12
  enableVirtualBackground = 106055,
13
- hideFeatureButton = 106056
13
+ hideFeatureButton = 106056,
14
+ openChat = 106057,
15
+ setBasicBeauty = 106058,
16
+ aiTask = 106059
14
17
  }
15
18
  export declare class DataReportManager {
16
19
  private taskQueue;
@@ -16,6 +16,9 @@ var MetricsKey = /* @__PURE__ */ ((MetricsKey2) => {
16
16
  MetricsKey2[MetricsKey2["enableWatermark"] = 106054] = "enableWatermark";
17
17
  MetricsKey2[MetricsKey2["enableVirtualBackground"] = 106055] = "enableVirtualBackground";
18
18
  MetricsKey2[MetricsKey2["hideFeatureButton"] = 106056] = "hideFeatureButton";
19
+ MetricsKey2[MetricsKey2["openChat"] = 106057] = "openChat";
20
+ MetricsKey2[MetricsKey2["setBasicBeauty"] = 106058] = "setBasicBeauty";
21
+ MetricsKey2[MetricsKey2["aiTask"] = 106059] = "aiTask";
19
22
  return MetricsKey2;
20
23
  })(MetricsKey || {});
21
24
  class DataReportManager {
@@ -60,3 +60,5 @@ export declare function convertSecondsToHMS(seconds: number): {
60
60
  seconds: number;
61
61
  };
62
62
  export declare function getNanoId(size?: number): string;
63
+ export declare function findLastIndex<T>(array: T[], predicate: (value: T, index: number, obj: T[]) => boolean, thisArg?: any): number;
64
+ export declare function formatTimestampToTime(timestamp: number, format?: string): string;
@@ -145,6 +145,37 @@ function getNanoId(size = 21) {
145
145
  }
146
146
  return id;
147
147
  }
148
+ function findLastIndex(array, predicate, thisArg) {
149
+ const len = array.length >>> 0;
150
+ let k = len - 1;
151
+ while (k >= 0) {
152
+ const kValue = array[k];
153
+ if (predicate.call(thisArg, kValue, k, array)) {
154
+ return k;
155
+ }
156
+ k = k - 1;
157
+ }
158
+ return -1;
159
+ }
160
+ function formatTimestampToTime(timestamp, format = "MM-DD HH:mm") {
161
+ const date = new Date(timestamp);
162
+ const padStart = (value, length = 2) => value.toString().padStart(length, "0");
163
+ const replacements = {
164
+ YYYY: date.getFullYear().toString(),
165
+ YY: (date.getFullYear() % 100).toString().padStart(2, "0"),
166
+ MM: padStart(date.getMonth() + 1),
167
+ DD: padStart(date.getDate()),
168
+ HH: padStart(date.getHours()),
169
+ hh: padStart(date.getHours() % 12),
170
+ mm: padStart(date.getMinutes()),
171
+ ss: padStart(date.getSeconds()),
172
+ A: date.getHours() >= 12 ? "PM" : "AM"
173
+ };
174
+ return format.replace(
175
+ /YYYY|YY|MM|DD|HH|hh|mm|ss|A/g,
176
+ (match) => replacements[match]
177
+ );
178
+ }
148
179
  export {
149
180
  addSuffix,
150
181
  calculateByteLength,
@@ -152,6 +183,8 @@ export {
152
183
  debounce,
153
184
  deepClone,
154
185
  exitFullScreen,
186
+ findLastIndex,
187
+ formatTimestampToTime,
155
188
  getNanoId,
156
189
  getUrlParam,
157
190
  getUrlWithRoomId,
@@ -3,5 +3,5 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
3
3
  const AISubtitles_vue_vue_type_script_setup_true_lang = require("./AISubtitles.vue2.js");
4
4
  ;/* empty css */
5
5
  const _pluginVue_exportHelper = require("../../_virtual/_plugin-vue_export-helper.js");
6
- const AISubtitlesOverlay = /* @__PURE__ */ _pluginVue_exportHelper.default(AISubtitles_vue_vue_type_script_setup_true_lang.default, [["__scopeId", "data-v-720279c8"]]);
6
+ const AISubtitlesOverlay = /* @__PURE__ */ _pluginVue_exportHelper.default(AISubtitles_vue_vue_type_script_setup_true_lang.default, [["__scopeId", "data-v-c187363f"]]);
7
7
  exports.default = AISubtitlesOverlay;
@@ -8,6 +8,7 @@ require("@tencentcloud/tuiroom-engine-electron");
8
8
  require("mitt");
9
9
  require("../../services/manager/roomActionManager.js");
10
10
  require("@tencentcloud/tui-core");
11
+ const dataReportManager = require("../../services/manager/dataReportManager.js");
11
12
  const aiTask = require("../../services/function/aiTask.js");
12
13
  const _hoisted_1 = {
13
14
  key: 0,
@@ -16,32 +17,30 @@ const _hoisted_1 = {
16
17
  const _sfc_main = /* @__PURE__ */ Vue.defineComponent({
17
18
  __name: "AISubtitles",
18
19
  setup(__props) {
19
- const rawSubtitleText = Vue.ref("");
20
- const subtitleLines = Vue.computed(
21
- () => rawSubtitleText.value.split("\n").filter((item) => item)
22
- );
23
- let subtitleTimeout = null;
24
- const resetSubtitleTimeout = () => {
25
- if (subtitleTimeout) {
26
- clearTimeout(subtitleTimeout);
27
- }
28
- subtitleTimeout = setTimeout(() => {
29
- rawSubtitleText.value = "";
30
- }, 3e3);
31
- };
20
+ const subtitleMessages = Vue.ref({});
21
+ const subtitleLines = Vue.computed(() => {
22
+ const arr = Object.keys(subtitleMessages.value).map((userId) => {
23
+ return subtitleMessages.value[userId];
24
+ });
25
+ return arr.sort((a, b) => a.startMsTs - b.startMsTs);
26
+ });
32
27
  const handleAISubtitles = (data) => {
33
28
  if (!data) return;
34
- rawSubtitleText.value = data.subtitleText.value;
35
- resetSubtitleTimeout();
29
+ subtitleMessages.value = Object.assign({}, data.subtitleMessages);
36
30
  };
37
- roomService.roomService.aiTask.on(aiTask.AI_TASK.TRANSCRIPTION_TASK, handleAISubtitles);
31
+ Vue.onMounted(() => {
32
+ roomService.roomService.dataReportManager.reportCount(dataReportManager.MetricsKey.AITask);
33
+ roomService.roomService.aiTask.on(aiTask.AI_TASK.TRANSCRIPTION_TASK, handleAISubtitles);
34
+ });
38
35
  Vue.onUnmounted(() => {
39
36
  roomService.roomService.aiTask.off(aiTask.AI_TASK.TRANSCRIPTION_TASK, handleAISubtitles);
40
37
  });
41
38
  return (_ctx, _cache) => {
42
39
  return subtitleLines.value.length ? (Vue.openBlock(), Vue.createElementBlock("div", _hoisted_1, [
43
- (Vue.openBlock(true), Vue.createElementBlock(Vue.Fragment, null, Vue.renderList(subtitleLines.value, (line, index) => {
44
- return Vue.openBlock(), Vue.createElementBlock("div", { key: index }, Vue.toDisplayString(line), 1);
40
+ (Vue.openBlock(true), Vue.createElementBlock(Vue.Fragment, null, Vue.renderList(subtitleLines.value, (line) => {
41
+ return Vue.openBlock(), Vue.createElementBlock("div", {
42
+ key: line.sender
43
+ }, Vue.toDisplayString(`${Vue.unref(roomService.roomService).roomStore.getDisplayName(line.sender)}: ${line == null ? void 0 : line.text}`), 1);
45
44
  }), 128))
46
45
  ])) : Vue.createCommentVNode("", true);
47
46
  };
@@ -3,5 +3,5 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
3
3
  const AITranscription_vue_vue_type_script_setup_true_lang = require("./AITranscription.vue2.js");
4
4
  ;/* empty css */
5
5
  const _pluginVue_exportHelper = require("../../_virtual/_plugin-vue_export-helper.js");
6
- const AITranscription = /* @__PURE__ */ _pluginVue_exportHelper.default(AITranscription_vue_vue_type_script_setup_true_lang.default, [["__scopeId", "data-v-ef9f284c"]]);
6
+ const AITranscription = /* @__PURE__ */ _pluginVue_exportHelper.default(AITranscription_vue_vue_type_script_setup_true_lang.default, [["__scopeId", "data-v-631b02ec"]]);
7
7
  exports.default = AITranscription;
@@ -8,108 +8,97 @@ require("@tencentcloud/tuiroom-engine-electron");
8
8
  require("mitt");
9
9
  require("../../services/manager/roomActionManager.js");
10
10
  require("@tencentcloud/tui-core");
11
+ const dataReportManager = require("../../services/manager/dataReportManager.js");
11
12
  const aiTask = require("../../services/function/aiTask.js");
13
+ const utils = require("../../utils/utils.js");
12
14
  const _hoisted_1 = { class: "title" };
13
15
  const _hoisted_2 = { class: "speaker" };
14
16
  const _hoisted_3 = { class: "timestamp" };
15
- const _hoisted_4 = { class: "content" };
17
+ const timeInterval = 60 * 1e3;
16
18
  const _sfc_main = /* @__PURE__ */ Vue.defineComponent({
17
19
  __name: "AITranscription",
18
20
  setup(__props) {
19
- const conversationContainer = Vue.ref(null);
20
- Vue.onMounted(() => scrollToBottom());
21
- const processedConversations = Vue.ref(processConversation(roomService.roomService.aiTask.transcriptionText.value));
21
+ const conversationContainerRef = Vue.ref();
22
+ const isUserScrolling = Vue.ref(false);
23
+ const rawTranscribedMessageList = Vue.ref(
24
+ roomService.roomService.aiTask.transcribedMessageList
25
+ );
26
+ Vue.onMounted(() => {
27
+ scrollToBottom();
28
+ });
22
29
  const scrollToBottom = async () => {
23
- if (conversationContainer.value) {
30
+ if (conversationContainerRef.value && !isUserScrolling.value) {
24
31
  await Vue.nextTick();
25
- conversationContainer.value.scrollIntoView({ block: "end" });
32
+ conversationContainerRef.value.scrollTop = conversationContainerRef.value.scrollHeight;
33
+ }
34
+ };
35
+ const handleScroll = () => {
36
+ if (conversationContainerRef.value) {
37
+ const isAtBottom = conversationContainerRef.value.scrollTop + conversationContainerRef.value.clientHeight >= conversationContainerRef.value.scrollHeight - 5;
38
+ if (isAtBottom) {
39
+ isUserScrolling.value = false;
40
+ scrollToBottom();
41
+ } else {
42
+ isUserScrolling.value = true;
43
+ }
26
44
  }
27
45
  };
28
- const conversations = Vue.computed(() => {
29
- const result = [];
30
- let currentSpeaker = null;
31
- let currentTimestamp = null;
32
- let currentMessages = [];
33
- processedConversations.value.forEach((item) => {
34
- const [start, end] = item.timestamp.split("->");
35
- const timestampMinute = start.slice(0, 5);
36
- if (item.speaker === currentSpeaker && timestampMinute === currentTimestamp) {
37
- currentMessages.push(item.content);
46
+ const transcribedMessageList = Vue.computed(() => {
47
+ const aggregatedMessageList = [];
48
+ let currentAggregatedMessage = null;
49
+ for (const message of rawTranscribedMessageList.value) {
50
+ if (!currentAggregatedMessage || message.sender !== currentAggregatedMessage.sender || message.startMsTs - currentAggregatedMessage.startMsTs > timeInterval) {
51
+ currentAggregatedMessage = {
52
+ messages: [message],
53
+ sender: message.sender,
54
+ startMsTs: message.startMsTs
55
+ };
56
+ aggregatedMessageList.push(currentAggregatedMessage);
38
57
  } else {
39
- if (currentSpeaker !== null) {
40
- result.push({
41
- timestamp: currentTimestamp,
42
- speaker: currentSpeaker,
43
- messages: currentMessages
44
- });
45
- }
46
- currentSpeaker = item.speaker;
47
- currentTimestamp = timestampMinute;
48
- currentMessages = [item.content];
58
+ currentAggregatedMessage.messages.push(message);
49
59
  }
50
- });
51
- if (currentSpeaker !== null) {
52
- result.push({
53
- timestamp: currentTimestamp,
54
- speaker: currentSpeaker,
55
- messages: currentMessages
56
- });
57
60
  }
58
- return result;
61
+ return aggregatedMessageList;
59
62
  });
60
- roomService.roomService.aiTask.on(aiTask.AI_TASK.TRANSCRIPTION_TASK, (data) => {
63
+ Vue.watch(rawTranscribedMessageList, () => {
64
+ scrollToBottom();
65
+ });
66
+ const handleAITranscriptionTask = async (data) => {
61
67
  if (!data) return;
62
- processedConversations.value = processConversation(
63
- data.transcriptionText.value
64
- );
68
+ rawTranscribedMessageList.value = [...data.transcribedMessageList];
69
+ };
70
+ Vue.onMounted(() => {
71
+ roomService.roomService.dataReportManager.reportCount(dataReportManager.MetricsKey.AITask);
72
+ roomService.roomService.aiTask.on(aiTask.AI_TASK.TRANSCRIPTION_TASK, handleAITranscriptionTask);
73
+ });
74
+ Vue.onUnmounted(() => {
75
+ roomService.roomService.aiTask.off(aiTask.AI_TASK.TRANSCRIPTION_TASK, handleAITranscriptionTask);
65
76
  });
66
- function processConversation(data) {
67
- const pattern = /(\d{2}:\d{2}:\d{2}->\d{2}:\d{2}:\d{2})\s+([\u4e00-\u9fa5\w]+):\s*(.*)/;
68
- const conversations2 = [];
69
- const lines = data.split("\n");
70
- lines.forEach((line) => {
71
- const match = pattern.exec(line);
72
- if (match) {
73
- const timestamp = match[1];
74
- const speaker = match[2];
75
- const content = match[3];
76
- conversations2.push({
77
- timestamp,
78
- speaker,
79
- content
80
- });
81
- }
82
- });
83
- conversations2.sort((a, b) => {
84
- const timeA = a.timestamp.split("->")[0];
85
- const timeB = b.timestamp.split("->")[0];
86
- return timeA.localeCompare(timeB);
87
- });
88
- return conversations2;
89
- }
90
77
  return (_ctx, _cache) => {
91
78
  return Vue.openBlock(), Vue.createElementBlock("div", {
92
79
  class: "conversation",
93
- ref_key: "conversationContainer",
94
- ref: conversationContainer
80
+ ref_key: "conversationContainerRef",
81
+ ref: conversationContainerRef,
82
+ onScroll: handleScroll
95
83
  }, [
96
- (Vue.openBlock(true), Vue.createElementBlock(Vue.Fragment, null, Vue.renderList(conversations.value, (item, index) => {
84
+ (Vue.openBlock(true), Vue.createElementBlock(Vue.Fragment, null, Vue.renderList(transcribedMessageList.value, (group) => {
97
85
  return Vue.openBlock(), Vue.createElementBlock("div", {
98
- key: index,
99
- class: "conversation-item"
86
+ key: group.startMsTs,
87
+ class: "conversation-group"
100
88
  }, [
101
89
  Vue.createElementVNode("div", _hoisted_1, [
102
- Vue.createElementVNode("span", _hoisted_2, Vue.toDisplayString(item.speaker), 1),
103
- Vue.createElementVNode("span", _hoisted_3, Vue.toDisplayString(item.timestamp), 1)
90
+ Vue.createElementVNode("span", _hoisted_2, Vue.toDisplayString(Vue.unref(roomService.roomService).roomStore.getDisplayName(group.sender)), 1),
91
+ Vue.createElementVNode("span", _hoisted_3, Vue.toDisplayString(Vue.unref(utils.formatTimestampToTime)(group.startMsTs)), 1)
104
92
  ]),
105
- Vue.createElementVNode("div", _hoisted_4, [
106
- (Vue.openBlock(true), Vue.createElementBlock(Vue.Fragment, null, Vue.renderList(item.messages, (msg, msgIndex) => {
107
- return Vue.openBlock(), Vue.createElementBlock("div", { key: msgIndex }, Vue.toDisplayString(msg), 1);
108
- }), 128))
109
- ])
93
+ (Vue.openBlock(true), Vue.createElementBlock(Vue.Fragment, null, Vue.renderList(group.messages, (message, messageIndex) => {
94
+ return Vue.openBlock(), Vue.createElementBlock("div", {
95
+ key: messageIndex,
96
+ class: "content"
97
+ }, Vue.toDisplayString(message.text), 1);
98
+ }), 128))
110
99
  ]);
111
100
  }), 128))
112
- ], 512);
101
+ ], 544);
113
102
  };
114
103
  }
115
104
  });
@@ -3,5 +3,5 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
3
3
  const index_vue_vue_type_script_setup_true_lang = ;/* empty css */
4
4
  ;/* empty css */
5
5
  const _pluginVue_exportHelper = require("../../../_virtual/_plugin-vue_export-helper.js");
6
- const MemberControl = /* @__PURE__ */ _pluginVue_exportHelper.default(index_vue_vue_type_script_setup_true_lang.default, [["__scopeId", "data-v-6cb30e2c"]]);
6
+ const MemberControl = /* @__PURE__ */ _pluginVue_exportHelper.default(index_vue_vue_type_script_setup_true_lang.default, [["__scopeId", "data-v-7b4cb2fa"]]);
7
7
  exports.default = MemberControl;
@@ -31,9 +31,11 @@ const _sfc_main = /* @__PURE__ */ Vue.defineComponent({
31
31
  tempUserName
32
32
  } = useMemberControlHooks.default(props);
33
33
  const { isCanOperateMySelf } = useMemberItemHooks.default(props.userInfo);
34
- const singleControl = Vue.computed(() => controlList.value[0]);
34
+ const singleControl = Vue.computed(() => {
35
+ return isCanOperateMySelf.value ? null : controlList.value[0];
36
+ });
35
37
  const moreControlList = Vue.computed(() => {
36
- return isCanOperateMySelf ? controlList.value : controlList.value.slice(1);
38
+ return isCanOperateMySelf.value ? controlList.value : controlList.value.slice(1);
37
39
  });
38
40
  const dropdownClass = Vue.ref("down");
39
41
  const moreBtnRef = Vue.ref();
@@ -82,7 +84,7 @@ const _sfc_main = /* @__PURE__ */ Vue.defineComponent({
82
84
  }
83
85
  return (_ctx, _cache) => {
84
86
  return Vue.openBlock(), Vue.createElementBlock("div", _hoisted_1, [
85
- !Vue.unref(isCanOperateMySelf) ? (Vue.openBlock(), Vue.createBlock(Button.default, {
87
+ singleControl.value ? (Vue.openBlock(), Vue.createBlock(Button.default, {
86
88
  key: 0,
87
89
  class: "button",
88
90
  size: "default",
@@ -3,5 +3,5 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
3
3
  const MemberInfo_vue_vue_type_script_setup_true_lang = require("./MemberInfo.vue2.js");
4
4
  ;/* empty css */
5
5
  const _pluginVue_exportHelper = require("../../../_virtual/_plugin-vue_export-helper.js");
6
- const MemberInfo = /* @__PURE__ */ _pluginVue_exportHelper.default(MemberInfo_vue_vue_type_script_setup_true_lang.default, [["__scopeId", "data-v-cba7feb3"]]);
6
+ const MemberInfo = /* @__PURE__ */ _pluginVue_exportHelper.default(MemberInfo_vue_vue_type_script_setup_true_lang.default, [["__scopeId", "data-v-8d1bfc30"]]);
7
7
  exports.default = MemberInfo;
@@ -3,5 +3,5 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
3
3
  const BasicBeauty_vue_vue_type_script_setup_true_lang = require("./BasicBeauty.vue2.js");
4
4
  ;/* empty css */
5
5
  const _pluginVue_exportHelper = require("../../_virtual/_plugin-vue_export-helper.js");
6
- const BasicBeauty = /* @__PURE__ */ _pluginVue_exportHelper.default(BasicBeauty_vue_vue_type_script_setup_true_lang.default, [["__scopeId", "data-v-211cd54c"]]);
6
+ const BasicBeauty = /* @__PURE__ */ _pluginVue_exportHelper.default(BasicBeauty_vue_vue_type_script_setup_true_lang.default, [["__scopeId", "data-v-2e9e258c"]]);
7
7
  exports.default = BasicBeauty;
@@ -12,7 +12,9 @@ const TUIRoomEngine = require("@tencentcloud/tuiroom-engine-electron");
12
12
  require("mitt");
13
13
  require("../../services/manager/roomActionManager.js");
14
14
  require("@tencentcloud/tui-core");
15
+ const dataReportManager = require("../../services/manager/dataReportManager.js");
15
16
  const environment = require("../../utils/environment.js");
17
+ const utils = require("../../utils/utils.js");
16
18
  const index$1 = require("../common/base/Dialog/index.vue.js");
17
19
  const Button = require("../common/base/Button.vue.js");
18
20
  const Slider = require("../common/base/Slider.vue.js");
@@ -25,7 +27,6 @@ const CompareIcon = require("../common/icons/CompareIcon.vue.js");
25
27
  const useRoomEngine = require("../../hooks/useRoomEngine.js");
26
28
  const basic = require("../../stores/basic.js");
27
29
  const room = require("../../constants/room.js");
28
- const utils = require("../../utils/utils.js");
29
30
  const _hoisted_1 = {
30
31
  key: 0,
31
32
  class: "basicBeauty-control-container"
@@ -116,6 +117,7 @@ const _sfc_main = /* @__PURE__ */ Vue.defineComponent({
116
117
  view: "test-preview"
117
118
  }));
118
119
  isLoading.value = false;
120
+ roomService.roomService.dataReportManager.reportCount(dataReportManager.MetricsKey.setBasicBeauty);
119
121
  };
120
122
  const closeBeautySettingPanel = async () => {
121
123
  var _a;
@@ -14,6 +14,7 @@ require("@tencentcloud/tuiroom-engine-electron");
14
14
  require("mitt");
15
15
  require("../../services/manager/roomActionManager.js");
16
16
  require("@tencentcloud/tui-core");
17
+ const dataReportManager = require("../../services/manager/dataReportManager.js");
17
18
  require("../../utils/environment.js");
18
19
  const _hoisted_1 = {
19
20
  key: 0,
@@ -36,6 +37,7 @@ const _sfc_main = /* @__PURE__ */ Vue.defineComponent({
36
37
  basicStore.setSidebarOpenStatus(true);
37
38
  basicStore.setSidebarName("chat");
38
39
  chatStore.updateUnReadCount(0);
40
+ roomService.roomService.dataReportManager.reportCount(dataReportManager.MetricsKey.openChat);
39
41
  }
40
42
  return (_ctx, _cache) => {
41
43
  return Vue.unref(chatControlConfig).visible ? (Vue.openBlock(), Vue.createElementBlock("div", _hoisted_1, [
@@ -27,8 +27,8 @@ require("mitt");
27
27
  require("../../../services/manager/roomActionManager.js");
28
28
  require("@tencentcloud/tui-core");
29
29
  require("../../../utils/environment.js");
30
- const room = require("../../../constants/room.js");
31
30
  const utils = require("../../../utils/utils.js");
31
+ const room = require("../../../constants/room.js");
32
32
  const common = require("../../../utils/common.js");
33
33
  const scheduleUtils = require("../scheduleUtils.js");
34
34
  const SvgIcon = require("../../common/base/SvgIcon.vue.js");