Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
phsl
/
new-api
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
1f6cb4bd
authored
Feb 19, 2025
by
CalciumIon
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: Improve mobile text truncation and sidebar visibility
parent
5ef44f68
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
78 additions
and
10 deletions
+78
-10
web/src/components/SiderBar.js
+6
-6
web/src/helpers/render.js
+68
-1
web/src/pages/Playground/Playground.js
+4
-3
No files found.
web/src/components/SiderBar.js
View file @
1f6cb4bd
...
@@ -80,7 +80,7 @@ const SiderBar = () => {
...
@@ -80,7 +80,7 @@ const SiderBar = () => {
itemKey
:
'channel'
,
itemKey
:
'channel'
,
to
:
'/channel'
,
to
:
'/channel'
,
icon
:
<
IconLayers
/>
,
icon
:
<
IconLayers
/>
,
className
:
isAdmin
()
?
'
semi-navigation-item-normal
'
:
'tableHiddle'
,
className
:
isAdmin
()
?
''
:
'tableHiddle'
,
},
},
{
{
text
:
t
(
'聊天'
),
text
:
t
(
'聊天'
),
...
@@ -101,7 +101,7 @@ const SiderBar = () => {
...
@@ -101,7 +101,7 @@ const SiderBar = () => {
icon
:
<
IconCalendarClock
/>
,
icon
:
<
IconCalendarClock
/>
,
className
:
className
:
localStorage
.
getItem
(
'enable_data_export'
)
===
'true'
localStorage
.
getItem
(
'enable_data_export'
)
===
'true'
?
'
semi-navigation-item-normal
'
?
''
:
'tableHiddle'
,
:
'tableHiddle'
,
},
},
{
{
...
@@ -109,7 +109,7 @@ const SiderBar = () => {
...
@@ -109,7 +109,7 @@ const SiderBar = () => {
itemKey
:
'redemption'
,
itemKey
:
'redemption'
,
to
:
'/redemption'
,
to
:
'/redemption'
,
icon
:
<
IconGift
/>
,
icon
:
<
IconGift
/>
,
className
:
isAdmin
()
?
'
semi-navigation-item-normal
'
:
'tableHiddle'
,
className
:
isAdmin
()
?
''
:
'tableHiddle'
,
},
},
{
{
text
:
t
(
'钱包'
),
text
:
t
(
'钱包'
),
...
@@ -122,7 +122,7 @@ const SiderBar = () => {
...
@@ -122,7 +122,7 @@ const SiderBar = () => {
itemKey
:
'user'
,
itemKey
:
'user'
,
to
:
'/user'
,
to
:
'/user'
,
icon
:
<
IconUser
/>
,
icon
:
<
IconUser
/>
,
className
:
isAdmin
()
?
'
semi-navigation-item-normal
'
:
'tableHiddle'
,
className
:
isAdmin
()
?
''
:
'tableHiddle'
,
},
},
{
{
text
:
t
(
'日志'
),
text
:
t
(
'日志'
),
...
@@ -137,7 +137,7 @@ const SiderBar = () => {
...
@@ -137,7 +137,7 @@ const SiderBar = () => {
icon
:
<
IconImage
/>
,
icon
:
<
IconImage
/>
,
className
:
className
:
localStorage
.
getItem
(
'enable_drawing'
)
===
'true'
localStorage
.
getItem
(
'enable_drawing'
)
===
'true'
?
'
semi-navigation-item-normal
'
?
''
:
'tableHiddle'
,
:
'tableHiddle'
,
},
},
{
{
...
@@ -147,7 +147,7 @@ const SiderBar = () => {
...
@@ -147,7 +147,7 @@ const SiderBar = () => {
icon
:
<
IconChecklistStroked
/>
,
icon
:
<
IconChecklistStroked
/>
,
className
:
className
:
localStorage
.
getItem
(
'enable_task'
)
===
'true'
localStorage
.
getItem
(
'enable_task'
)
===
'true'
?
'
semi-navigation-item-normal
'
?
''
:
'tableHiddle'
,
:
'tableHiddle'
,
},
},
{
{
...
...
web/src/helpers/render.js
View file @
1f6cb4bd
import
i18next
from
'i18next'
;
import
i18next
from
'i18next'
;
import
{
Modal
,
Tag
,
Typography
}
from
'@douyinfe/semi-ui'
;
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
)
{
export
function
renderText
(
text
,
limit
)
{
if
(
text
.
length
>
limit
)
{
if
(
text
.
length
>
limit
)
{
...
@@ -67,6 +67,73 @@ export function renderRatio(ratio) {
...
@@ -67,6 +67,73 @@ export function renderRatio(ratio) {
return
<
Tag
color
=
{
color
}
>
{
ratio
}
x
{
i18next
.
t
(
'倍率'
)}
<
/Tag>
;
return
<
Tag
color
=
{
color
}
>
{
ratio
}
x
{
i18next
.
t
(
'倍率'
)}
<
/Tag>
;
}
}
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
)
=>
{
export
const
renderGroupOption
=
(
item
)
=>
{
const
{
const
{
disabled
,
disabled
,
...
...
web/src/pages/Playground/Playground.js
View file @
1f6cb4bd
...
@@ -7,7 +7,7 @@ import { SSE } from 'sse';
...
@@ -7,7 +7,7 @@ import { SSE } from 'sse';
import
{
IconSetting
}
from
'@douyinfe/semi-icons'
;
import
{
IconSetting
}
from
'@douyinfe/semi-icons'
;
import
{
StyleContext
}
from
'../../context/Style/index.js'
;
import
{
StyleContext
}
from
'../../context/Style/index.js'
;
import
{
useTranslation
}
from
'react-i18next'
;
import
{
useTranslation
}
from
'react-i18next'
;
import
{
renderGroupOption
}
from
'../../helpers/render.js'
;
import
{
renderGroupOption
,
truncateText
}
from
'../../helpers/render.js'
;
const
roleInfo
=
{
const
roleInfo
=
{
user
:
{
user
:
{
...
@@ -99,9 +99,10 @@ const Playground = () => {
...
@@ -99,9 +99,10 @@ const Playground = () => {
const
{
success
,
message
,
data
}
=
res
.
data
;
const
{
success
,
message
,
data
}
=
res
.
data
;
if
(
success
)
{
if
(
success
)
{
let
localGroupOptions
=
Object
.
entries
(
data
).
map
(([
group
,
info
])
=>
({
let
localGroupOptions
=
Object
.
entries
(
data
).
map
(([
group
,
info
])
=>
({
label
:
info
.
desc
,
label
:
truncateText
(
info
.
desc
,
"50%"
)
,
value
:
group
,
value
:
group
,
ratio
:
info
.
ratio
ratio
:
info
.
ratio
,
fullLabel
:
info
.
desc
// 保存完整文本用于tooltip
}));
}));
if
(
localGroupOptions
.
length
===
0
)
{
if
(
localGroupOptions
.
length
===
0
)
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment