From 4ce12ea6e3274931cf430be99da33b5667c8640c Mon Sep 17 00:00:00 2001
From: CalciumIon <1808837298@qq.com>
Date: Wed, 19 Feb 2025 23:25:42 +0800
Subject: [PATCH] feat: Improve mobile text truncation and sidebar visibility
---
web/src/components/SiderBar.js | 12 ++---
web/src/helpers/render.js | 69 +++++++++++++++++++++++++-
web/src/pages/Playground/Playground.js | 7 +--
3 files changed, 78 insertions(+), 10 deletions(-)
diff --git a/web/src/components/SiderBar.js b/web/src/components/SiderBar.js
index 503dc81a..46d728da 100644
--- a/web/src/components/SiderBar.js
+++ b/web/src/components/SiderBar.js
@@ -80,7 +80,7 @@ const SiderBar = () => {
itemKey: 'channel',
to: '/channel',
icon: ,
- className: isAdmin() ? 'semi-navigation-item-normal' : 'tableHiddle',
+ className: isAdmin() ? '' : 'tableHiddle',
},
{
text: t('聊天'),
@@ -101,7 +101,7 @@ const SiderBar = () => {
icon: ,
className:
localStorage.getItem('enable_data_export') === 'true'
- ? 'semi-navigation-item-normal'
+ ? ''
: 'tableHiddle',
},
{
@@ -109,7 +109,7 @@ const SiderBar = () => {
itemKey: 'redemption',
to: '/redemption',
icon: ,
- className: isAdmin() ? 'semi-navigation-item-normal' : 'tableHiddle',
+ className: isAdmin() ? '' : 'tableHiddle',
},
{
text: t('钱包'),
@@ -122,7 +122,7 @@ const SiderBar = () => {
itemKey: 'user',
to: '/user',
icon: ,
- className: isAdmin() ? 'semi-navigation-item-normal' : 'tableHiddle',
+ className: isAdmin() ? '' : 'tableHiddle',
},
{
text: t('日志'),
@@ -137,7 +137,7 @@ const SiderBar = () => {
icon: ,
className:
localStorage.getItem('enable_drawing') === 'true'
- ? 'semi-navigation-item-normal'
+ ? ''
: 'tableHiddle',
},
{
@@ -147,7 +147,7 @@ const SiderBar = () => {
icon: ,
className:
localStorage.getItem('enable_task') === 'true'
- ? 'semi-navigation-item-normal'
+ ? ''
: 'tableHiddle',
},
{
diff --git a/web/src/helpers/render.js b/web/src/helpers/render.js
index 310fc3ea..5342d741 100644
--- a/web/src/helpers/render.js
+++ b/web/src/helpers/render.js
@@ -1,6 +1,6 @@
import i18next from 'i18next';
import { Modal, Tag, Typography } from '@douyinfe/semi-ui';
-import { copy, showSuccess } from './utils.js';
+import { copy, isMobile, showSuccess } from './utils.js';
export function renderText(text, limit) {
if (text.length > limit) {
@@ -67,6 +67,73 @@ export function renderRatio(ratio) {
return {ratio}x {i18next.t('倍率')};
}
+const measureTextWidth = (text, style = {
+ fontSize: '14px',
+ fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif'
+}, containerWidth) => {
+ const span = document.createElement('span');
+
+ span.style.visibility = 'hidden';
+ span.style.position = 'absolute';
+ span.style.whiteSpace = 'nowrap';
+ span.style.fontSize = style.fontSize;
+ span.style.fontFamily = style.fontFamily;
+
+ span.textContent = text;
+
+ document.body.appendChild(span);
+ const width = span.offsetWidth;
+
+ document.body.removeChild(span);
+
+ return width;
+};
+
+export function truncateText(text, maxWidth = 200) {
+ if (!isMobile()) {
+ return text;
+ }
+ if (!text) return text;
+
+ try {
+ // Handle percentage-based maxWidth
+ let actualMaxWidth = maxWidth;
+ if (typeof maxWidth === 'string' && maxWidth.endsWith('%')) {
+ const percentage = parseFloat(maxWidth) / 100;
+ // Use window width as fallback container width
+ actualMaxWidth = window.innerWidth * percentage;
+ }
+
+ const width = measureTextWidth(text);
+ if (width <= actualMaxWidth) return text;
+
+ let left = 0;
+ let right = text.length;
+ let result = text;
+
+ while (left <= right) {
+ const mid = Math.floor((left + right) / 2);
+ const truncated = text.slice(0, mid) + '...';
+ const currentWidth = measureTextWidth(truncated);
+
+ if (currentWidth <= actualMaxWidth) {
+ result = truncated;
+ left = mid + 1;
+ } else {
+ right = mid - 1;
+ }
+ }
+
+ return result;
+ } catch (error) {
+ console.warn('Text measurement failed, falling back to character count', error);
+ if (text.length > 20) {
+ return text.slice(0, 17) + '...';
+ }
+ return text;
+ }
+}
+
export const renderGroupOption = (item) => {
const {
disabled,
diff --git a/web/src/pages/Playground/Playground.js b/web/src/pages/Playground/Playground.js
index 3468d2b1..8579d1cc 100644
--- a/web/src/pages/Playground/Playground.js
+++ b/web/src/pages/Playground/Playground.js
@@ -7,7 +7,7 @@ import { SSE } from 'sse';
import { IconSetting } from '@douyinfe/semi-icons';
import { StyleContext } from '../../context/Style/index.js';
import { useTranslation } from 'react-i18next';
-import { renderGroupOption } from '../../helpers/render.js';
+import { renderGroupOption, truncateText } from '../../helpers/render.js';
const roleInfo = {
user: {
@@ -99,9 +99,10 @@ const Playground = () => {
const { success, message, data } = res.data;
if (success) {
let localGroupOptions = Object.entries(data).map(([group, info]) => ({
- label: info.desc,
+ label: truncateText(info.desc, "50%"),
value: group,
- ratio: info.ratio
+ ratio: info.ratio,
+ fullLabel: info.desc // 保存完整文本用于tooltip
}));
if (localGroupOptions.length === 0) {