- {{ currentLive?.liveName || liveParams.liveName }}
+ {{ currentLive?.liveName || liveParams.liveName }}
{
align-items: center;
gap: 8px;
+ .live-name {
+ max-width: 280px;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ }
+
.copy-icon {
cursor: pointer;
diff --git a/Web/web-vite-vue3/src/TUILiveKit/component/LivePlayer/LivePlayerPC.vue b/Web/web-vite-vue3/src/TUILiveKit/component/LivePlayer/LivePlayerPC.vue
index 7b1e9105..72008b4c 100644
--- a/Web/web-vite-vue3/src/TUILiveKit/component/LivePlayer/LivePlayerPC.vue
+++ b/Web/web-vite-vue3/src/TUILiveKit/component/LivePlayer/LivePlayerPC.vue
@@ -16,7 +16,7 @@
:src="currentLive?.liveOwner.avatarUrl" :size="32"
:style="{ border: '1px solid var(--uikit-color-white-7)' }"
/>
- {{ currentLive?.liveOwner.userName || currentLive?.liveOwner.userId }}
+
@@ -303,9 +303,14 @@ async function handleJoinLive() {
color: $text-color1;
overflow: hidden;
text-overflow: ellipsis;
+ white-space: nowrap;
@include text-size-16;
}
+ .header-name {
+ max-width: 180px;
+ }
+
.icon-back {
max-width: 180px;
&:hover {
diff --git a/Web/web-vite-vue3/src/TUILiveKit/component/LiveSettingButton.vue b/Web/web-vite-vue3/src/TUILiveKit/component/LiveSettingButton.vue
index 3e1b2e90..43fb9ccf 100644
--- a/Web/web-vite-vue3/src/TUILiveKit/component/LiveSettingButton.vue
+++ b/Web/web-vite-vue3/src/TUILiveKit/component/LiveSettingButton.vue
@@ -19,7 +19,7 @@
diff --git a/Web/web-vite-vue3/src/TUILiveKit/i18n/en-US/index.ts b/Web/web-vite-vue3/src/TUILiveKit/i18n/en-US/index.ts
index 25ea0a22..0cfee437 100644
--- a/Web/web-vite-vue3/src/TUILiveKit/i18n/en-US/index.ts
+++ b/Web/web-vite-vue3/src/TUILiveKit/i18n/en-US/index.ts
@@ -69,6 +69,7 @@ export const resource = {
Cancel: 'Cancel',
'Failed to create live': 'Failed to create live',
'Failed to update live settings': 'Failed to update live settings',
+ 'The live name failed the security check. Please modify it and try again.': 'The live name failed the security check. Please modify it and try again.',
'No device detected': 'No device detected',
'No system permission': 'No system permission',
'Not support capture': 'Not support capture',
diff --git a/Web/web-vite-vue3/src/TUILiveKit/i18n/zh-CN/index.ts b/Web/web-vite-vue3/src/TUILiveKit/i18n/zh-CN/index.ts
index c3a0bb4b..aead1f46 100644
--- a/Web/web-vite-vue3/src/TUILiveKit/i18n/zh-CN/index.ts
+++ b/Web/web-vite-vue3/src/TUILiveKit/i18n/zh-CN/index.ts
@@ -69,6 +69,7 @@ export const resource = {
Cancel: '取消',
'Failed to create live': '创建直播间失败',
'Failed to update live settings': '更新直播设置失败',
+ 'The live name failed the security check. Please modify it and try again.': '直播间名称未通过安全检查,请修改后重试',
'No device detected': '未检测到设备',
'No system permission': '无系统权限',
'Not support capture': '不支持采集',
diff --git a/Web/web-vite-vue3/src/TUILiveKit/types/error.ts b/Web/web-vite-vue3/src/TUILiveKit/types/error.ts
index b48551e2..6a8329e5 100644
--- a/Web/web-vite-vue3/src/TUILiveKit/types/error.ts
+++ b/Web/web-vite-vue3/src/TUILiveKit/types/error.ts
@@ -42,6 +42,9 @@ export enum LiveErrorCode {
// 101011 sub-errors (payment limits)
ROOM_MEMBER_COUNT_LIMIT = 40030,
ROOM_COUNT_LIMIT = 40031,
+
+ // Content security
+ NAME_SECURITY_CHECK_FAILED = 40040,
}
/**
@@ -64,6 +67,9 @@ export enum OriginalErrorCode {
// Payment limits
PAYMENT_LIMIT = 101011,
+
+ // Content security
+ GROUP_INFO_SECURE_CHECK_FAIL = 100026,
}
/**
@@ -152,4 +158,16 @@ export const ERROR_CODE_MAP: Record
= {
code: LiveErrorCode.ROOM_ID_NOT_EXIST,
message: 'Room is not existed.',
},
+ [OriginalErrorCode.GROUP_INFO_SECURE_CHECK_FAIL]: {
+ code: LiveErrorCode.NAME_SECURITY_CHECK_FAILED,
+ message: 'The live name failed the security check. Please modify it and try again.',
+ },
};
+
+/**
+ * Keys in this file's `message` fields double as i18n keys — the caller
+ * wraps them with `t(message)` before display. The i18n resource files
+ * (i18n/zh-CN, i18n/en-US) must contain matching entries. When a key
+ * is not found, `t()` falls back to the key itself (the English string),
+ * which is why every message is written in English here.
+ */
diff --git a/Web/web-vite-vue3/src/TUILiveKit/utils/errorHandler.ts b/Web/web-vite-vue3/src/TUILiveKit/utils/errorHandler.ts
index 29a49857..294df0d0 100644
--- a/Web/web-vite-vue3/src/TUILiveKit/utils/errorHandler.ts
+++ b/Web/web-vite-vue3/src/TUILiveKit/utils/errorHandler.ts
@@ -29,6 +29,30 @@ class ErrorHandler {
parseError(error: unknown): ErrorParseResult {
const raw = normalizeRawError(error);
+ // Some IM errors embed the code inside the message string
+ // (e.g. "error_code:100026, error_message:group info secure check fail!").
+ // Extract it so parseByKnownCode can match against ERROR_CODE_MAP.
+ // Use matchAll to collect every occurrence — a message may contain
+ // multiple error_code segments, and we want the first one that
+ // resolves to a known mapping rather than blindly taking the first.
+ if (raw.code === null || raw.code === undefined) {
+ const matches = typeof raw.message === 'string'
+ ? [...raw.message.matchAll(/error_code:(\d+)/g)]
+ : [];
+ for (const match of matches) {
+ const code = Number(match[1]);
+ if (code in ERROR_CODE_MAP) {
+ raw.code = code;
+ break;
+ }
+ }
+ // Fall back to the first match if none mapped to a known code,
+ // so parseByKnownCode still gets a chance to report it.
+ if ((raw.code === null || raw.code === undefined) && matches.length > 0) {
+ raw.code = Number(matches[0][1]);
+ }
+ }
+
if (raw.code !== null && raw.code !== undefined) {
switch (raw.code) {
case OriginalErrorCode.PARAM_ILLEGAL:
diff --git a/Web/web-vite-vue3/src/main.ts b/Web/web-vite-vue3/src/main.ts
index 7d164f2e..394f7227 100644
--- a/Web/web-vite-vue3/src/main.ts
+++ b/Web/web-vite-vue3/src/main.ts
@@ -1,5 +1,5 @@
import { createApp } from 'vue';
-import 'tuikit-atomicx-vue3/live';
+import 'tuikit-atomicx-vue3';
import App from '@/App.vue';
import router from './router/index';