[fix] table width + text selectiion + batch note naming
This commit is contained in:
@@ -214,7 +214,7 @@ function extractFpsMetrics(result: string): { avg: number | null; p1: number | n
|
|||||||
function NoteCell({ note, onEdit }: { note: string; onEdit: () => void }) {
|
function NoteCell({ note, onEdit }: { note: string; onEdit: () => void }) {
|
||||||
return (
|
return (
|
||||||
<div className="flex items-center min-w-0 gap-1">
|
<div className="flex items-center min-w-0 gap-1">
|
||||||
<span className="flex-1 min-w-0 truncate">
|
<span className="flex-1 min-w-0 truncate select-text">
|
||||||
{note || "无备注"}
|
{note || "无备注"}
|
||||||
</span>
|
</span>
|
||||||
<Button
|
<Button
|
||||||
@@ -278,6 +278,10 @@ export function FpsTest() {
|
|||||||
const testStartVideoSettingRef = useRef<typeof tool.state.videoSetting | null>(null)
|
const testStartVideoSettingRef = useRef<typeof tool.state.videoSetting | null>(null)
|
||||||
// 记录当前测试的分辨率信息(用于备注)
|
// 记录当前测试的分辨率信息(用于备注)
|
||||||
const currentTestResolutionRef = useRef<{ width: string; height: string; label: string } | null>(null)
|
const currentTestResolutionRef = useRef<{ width: string; height: string; label: string } | null>(null)
|
||||||
|
// 记录当前分辨率在分辨率组中的索引和总测试次数(用于批量测试备注)
|
||||||
|
const currentResolutionGroupInfoRef = useRef<{ resIndex: number; totalResolutions: number; totalTestCount: number; currentBatchIndex: number; batchCount: number } | null>(null)
|
||||||
|
// 记录最后一次测试的时间戳(用于平均值记录)
|
||||||
|
const lastTestTimestampRef = useRef<string | null>(null)
|
||||||
|
|
||||||
// 检测游戏是否运行
|
// 检测游戏是否运行
|
||||||
const checkGameRunning = useCallback(async () => {
|
const checkGameRunning = useCallback(async () => {
|
||||||
@@ -426,6 +430,8 @@ export function FpsTest() {
|
|||||||
|
|
||||||
setTestResult(parsed.data)
|
setTestResult(parsed.data)
|
||||||
setTestTimestamp(parsed.timestamp)
|
setTestTimestamp(parsed.timestamp)
|
||||||
|
// 保存最后一次测试的时间戳(用于平均值记录)
|
||||||
|
lastTestTimestampRef.current = parsed.timestamp
|
||||||
// 成功读取后,清除测试开始时间戳(测试已完成)
|
// 成功读取后,清除测试开始时间戳(测试已完成)
|
||||||
testStartTimestampRef.current = null
|
testStartTimestampRef.current = null
|
||||||
testStartTimeRef.current = null
|
testStartTimeRef.current = null
|
||||||
@@ -461,6 +467,7 @@ export function FpsTest() {
|
|||||||
// 如果是批量测试,保存结果到批量结果数组,否则直接保存
|
// 如果是批量测试,保存结果到批量结果数组,否则直接保存
|
||||||
const currentBatchProgress = batchTestProgress
|
const currentBatchProgress = batchTestProgress
|
||||||
const currentResolution = currentTestResolutionRef.current
|
const currentResolution = currentTestResolutionRef.current
|
||||||
|
const resolutionGroupInfo = currentResolutionGroupInfoRef.current
|
||||||
if (currentBatchProgress) {
|
if (currentBatchProgress) {
|
||||||
const result = { avg, p1 }
|
const result = { avg, p1 }
|
||||||
setBatchTestResults((prev) => [...prev, result])
|
setBatchTestResults((prev) => [...prev, result])
|
||||||
@@ -474,9 +481,18 @@ export function FpsTest() {
|
|||||||
if (testNote) {
|
if (testNote) {
|
||||||
batchNote = batchNote ? `${testNote} ${batchNote}` : testNote
|
batchNote = batchNote ? `${testNote} ${batchNote}` : testNote
|
||||||
}
|
}
|
||||||
batchNote = batchNote
|
|
||||||
? `${batchNote} [批量${currentBatchProgress.current}/${currentBatchProgress.total}]`
|
// 如果启用了分辨率组,使用新的备注格式:[分辨率] [批量当前测试/该分辨率批量总数]
|
||||||
: `[批量${currentBatchProgress.current}/${currentBatchProgress.total}]`
|
if (resolutionGroupInfo && isResolutionGroupEnabled) {
|
||||||
|
const { currentBatchIndex, batchCount } = resolutionGroupInfo
|
||||||
|
const batchInfo = `[批量${currentBatchIndex}/${batchCount}]`
|
||||||
|
batchNote = batchNote ? `${batchNote} ${batchInfo}` : batchInfo
|
||||||
|
} else {
|
||||||
|
// 普通批量测试,使用原来的格式
|
||||||
|
batchNote = batchNote
|
||||||
|
? `${batchNote} [批量${currentBatchProgress.current}/${currentBatchProgress.total}]`
|
||||||
|
: `[批量${currentBatchProgress.current}/${currentBatchProgress.total}]`
|
||||||
|
}
|
||||||
|
|
||||||
fpsTest.addResult({
|
fpsTest.addResult({
|
||||||
id: `${now.getTime()}-${Math.random().toString(36).slice(2, 11)}`,
|
id: `${now.getTime()}-${Math.random().toString(36).slice(2, 11)}`,
|
||||||
@@ -550,6 +566,8 @@ export function FpsTest() {
|
|||||||
// 清除保存的启动时视频设置和分辨率信息
|
// 清除保存的启动时视频设置和分辨率信息
|
||||||
testStartVideoSettingRef.current = null
|
testStartVideoSettingRef.current = null
|
||||||
currentTestResolutionRef.current = null
|
currentTestResolutionRef.current = null
|
||||||
|
currentResolutionGroupInfoRef.current = null
|
||||||
|
// 注意:不清除lastTestTimestampRef,因为平均值记录需要使用它
|
||||||
|
|
||||||
if (!silent) {
|
if (!silent) {
|
||||||
if (avg !== null || p1 !== null) {
|
if (avg !== null || p1 !== null) {
|
||||||
@@ -633,6 +651,7 @@ export function FpsTest() {
|
|||||||
testStartTimeRef.current = null
|
testStartTimeRef.current = null
|
||||||
testStartVideoSettingRef.current = null
|
testStartVideoSettingRef.current = null
|
||||||
currentTestResolutionRef.current = null
|
currentTestResolutionRef.current = null
|
||||||
|
currentResolutionGroupInfoRef.current = null
|
||||||
addToast({
|
addToast({
|
||||||
title: "测试超时(200秒),测试失败",
|
title: "测试超时(200秒),测试失败",
|
||||||
variant: "flat",
|
variant: "flat",
|
||||||
@@ -826,6 +845,7 @@ export function FpsTest() {
|
|||||||
testStartTimeRef.current = null
|
testStartTimeRef.current = null
|
||||||
testStartVideoSettingRef.current = null
|
testStartVideoSettingRef.current = null
|
||||||
currentTestResolutionRef.current = null
|
currentTestResolutionRef.current = null
|
||||||
|
currentResolutionGroupInfoRef.current = null
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -848,6 +868,17 @@ export function FpsTest() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 检查垂直同步设置,如果开启则提醒(但不阻止测试)
|
||||||
|
if (steam.state.steamDirValid && steam.currentUser()) {
|
||||||
|
await tool.getVideoConfig(steam.state.steamDir, steam.currentUser()?.steam_id32 || 0)
|
||||||
|
if (tool.state.videoSetting?.mat_vsync === "1") {
|
||||||
|
addToast({
|
||||||
|
title: "警告:垂直同步已开启,可能会影响测试结果准确性",
|
||||||
|
color: "warning",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const totalTests = batchTestCount
|
const totalTests = batchTestCount
|
||||||
batchTestAbortRef.current = false
|
batchTestAbortRef.current = false
|
||||||
setBatchTestResults([])
|
setBatchTestResults([])
|
||||||
@@ -879,6 +910,15 @@ export function FpsTest() {
|
|||||||
globalTestIndex++
|
globalTestIndex++
|
||||||
setBatchTestProgress({ current: globalTestIndex, total: totalTestCount })
|
setBatchTestProgress({ current: globalTestIndex, total: totalTestCount })
|
||||||
|
|
||||||
|
// 设置当前分辨率组信息(用于备注)
|
||||||
|
currentResolutionGroupInfoRef.current = {
|
||||||
|
resIndex,
|
||||||
|
totalResolutions,
|
||||||
|
totalTestCount,
|
||||||
|
currentBatchIndex: i,
|
||||||
|
batchCount: totalTests,
|
||||||
|
}
|
||||||
|
|
||||||
// 执行单次测试,第一次测试跳过5秒等待
|
// 执行单次测试,第一次测试跳过5秒等待
|
||||||
const isFirstTest = resIndex === 0 && i === 1
|
const isFirstTest = resIndex === 0 && i === 1
|
||||||
const success = await runSingleTest(i, totalTests, isFirstTest, currentResolution)
|
const success = await runSingleTest(i, totalTests, isFirstTest, currentResolution)
|
||||||
@@ -915,23 +955,50 @@ export function FpsTest() {
|
|||||||
validResults.reduce((sum, r) => sum + (r.avg || 0), 0) / validResults.length
|
validResults.reduce((sum, r) => sum + (r.avg || 0), 0) / validResults.length
|
||||||
const avgP1 = validResults.reduce((sum, r) => sum + (r.p1 || 0), 0) / validResults.length
|
const avgP1 = validResults.reduce((sum, r) => sum + (r.p1 || 0), 0) / validResults.length
|
||||||
|
|
||||||
const now = new Date()
|
// 使用最后一次测试的时间戳作为平均值记录的时间戳(更准确)
|
||||||
const testDate = now.toISOString()
|
// 如果最后一次测试时间戳存在,使用它;否则使用当前时间
|
||||||
const month = String(now.getMonth() + 1).padStart(2, "0")
|
let testTime: string
|
||||||
const day = String(now.getDate()).padStart(2, "0")
|
let testDate: string
|
||||||
const hour = String(now.getHours()).padStart(2, "0")
|
if (lastTestTimestampRef.current) {
|
||||||
const minute = String(now.getMinutes()).padStart(2, "0")
|
testTime = lastTestTimestampRef.current
|
||||||
const second = String(now.getSeconds()).padStart(2, "0")
|
// 将时间戳转换为ISO格式(用于排序)
|
||||||
const testTime = `${month}/${day} ${hour}:${minute}:${second}`
|
const now = new Date()
|
||||||
|
const [monthDay, time] = testTime.split(" ")
|
||||||
|
const [month, day] = monthDay.split("/")
|
||||||
|
const [hour, minute, second] = time.split(":")
|
||||||
|
const testDateTime = new Date(
|
||||||
|
now.getFullYear(),
|
||||||
|
parseInt(month) - 1,
|
||||||
|
parseInt(day),
|
||||||
|
parseInt(hour),
|
||||||
|
parseInt(minute),
|
||||||
|
parseInt(second)
|
||||||
|
)
|
||||||
|
testDate = testDateTime.toISOString()
|
||||||
|
} else {
|
||||||
|
const now = new Date()
|
||||||
|
testDate = now.toISOString()
|
||||||
|
const month = String(now.getMonth() + 1).padStart(2, "0")
|
||||||
|
const day = String(now.getDate()).padStart(2, "0")
|
||||||
|
const hour = String(now.getHours()).padStart(2, "0")
|
||||||
|
const minute = String(now.getMinutes()).padStart(2, "0")
|
||||||
|
const second = String(now.getSeconds()).padStart(2, "0")
|
||||||
|
testTime = `${month}/${day} ${hour}:${minute}:${second}`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 修改备注格式:[分辨率] [批量N次平均]
|
||||||
let averageNote = `[${currentResolution.label}]`
|
let averageNote = `[${currentResolution.label}]`
|
||||||
if (testNote) {
|
if (testNote) {
|
||||||
averageNote = `${testNote} ${averageNote}`
|
averageNote = `${testNote} ${averageNote}`
|
||||||
}
|
}
|
||||||
averageNote = `${averageNote} [批量${totalTests}次平均]`
|
averageNote = `${averageNote} [批量${totalTests}次平均]`
|
||||||
|
|
||||||
|
// 生成唯一ID
|
||||||
|
const idTime = lastTestTimestampRef.current
|
||||||
|
? new Date(testDate).getTime()
|
||||||
|
: Date.now()
|
||||||
fpsTest.addResult({
|
fpsTest.addResult({
|
||||||
id: `${now.getTime()}-${Math.random().toString(36).slice(2, 11)}`,
|
id: `${idTime}-${Math.random().toString(36).slice(2, 11)}`,
|
||||||
testTime,
|
testTime,
|
||||||
testDate,
|
testDate,
|
||||||
mapName: mapConfig?.name || "unknown",
|
mapName: mapConfig?.name || "unknown",
|
||||||
@@ -1016,21 +1083,46 @@ export function FpsTest() {
|
|||||||
validResults.reduce((sum, r) => sum + (r.avg || 0), 0) / validResults.length
|
validResults.reduce((sum, r) => sum + (r.avg || 0), 0) / validResults.length
|
||||||
const avgP1 = validResults.reduce((sum, r) => sum + (r.p1 || 0), 0) / validResults.length
|
const avgP1 = validResults.reduce((sum, r) => sum + (r.p1 || 0), 0) / validResults.length
|
||||||
|
|
||||||
const now = new Date()
|
// 使用最后一次测试的时间戳作为平均值记录的时间戳(更准确)
|
||||||
const testDate = now.toISOString()
|
let testTime: string
|
||||||
const month = String(now.getMonth() + 1).padStart(2, "0")
|
let testDate: string
|
||||||
const day = String(now.getDate()).padStart(2, "0")
|
if (lastTestTimestampRef.current) {
|
||||||
const hour = String(now.getHours()).padStart(2, "0")
|
testTime = lastTestTimestampRef.current
|
||||||
const minute = String(now.getMinutes()).padStart(2, "0")
|
// 将时间戳转换为ISO格式(用于排序)
|
||||||
const second = String(now.getSeconds()).padStart(2, "0")
|
const now = new Date()
|
||||||
const testTime = `${month}/${day} ${hour}:${minute}:${second}`
|
const [monthDay, time] = testTime.split(" ")
|
||||||
|
const [month, day] = monthDay.split("/")
|
||||||
|
const [hour, minute, second] = time.split(":")
|
||||||
|
const testDateTime = new Date(
|
||||||
|
now.getFullYear(),
|
||||||
|
parseInt(month) - 1,
|
||||||
|
parseInt(day),
|
||||||
|
parseInt(hour),
|
||||||
|
parseInt(minute),
|
||||||
|
parseInt(second)
|
||||||
|
)
|
||||||
|
testDate = testDateTime.toISOString()
|
||||||
|
} else {
|
||||||
|
const now = new Date()
|
||||||
|
testDate = now.toISOString()
|
||||||
|
const month = String(now.getMonth() + 1).padStart(2, "0")
|
||||||
|
const day = String(now.getDate()).padStart(2, "0")
|
||||||
|
const hour = String(now.getHours()).padStart(2, "0")
|
||||||
|
const minute = String(now.getMinutes()).padStart(2, "0")
|
||||||
|
const second = String(now.getSeconds()).padStart(2, "0")
|
||||||
|
testTime = `${month}/${day} ${hour}:${minute}:${second}`
|
||||||
|
}
|
||||||
|
|
||||||
const averageNote = testNote
|
const averageNote = testNote
|
||||||
? `${testNote} [批量${totalTests}次平均]`
|
? `${testNote} [批量${totalTests}次平均]`
|
||||||
: `[批量${totalTests}次平均]`
|
: `[批量${totalTests}次平均]`
|
||||||
|
|
||||||
|
// 生成唯一ID
|
||||||
|
const idTime = lastTestTimestampRef.current
|
||||||
|
? new Date(testDate).getTime()
|
||||||
|
: Date.now()
|
||||||
fpsTest.addResult({
|
fpsTest.addResult({
|
||||||
id: `${now.getTime()}-${Math.random().toString(36).slice(2, 11)}`,
|
id: `${idTime}-${Math.random().toString(36).slice(2, 11)}`,
|
||||||
testTime,
|
testTime,
|
||||||
testDate,
|
testDate,
|
||||||
mapName: mapConfig?.name || "unknown",
|
mapName: mapConfig?.name || "unknown",
|
||||||
@@ -1183,6 +1275,84 @@ export function FpsTest() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 仅导出平均结果CSV
|
||||||
|
const handleExportAverageCSV = async () => {
|
||||||
|
// 过滤备注中包含"平均"的结果
|
||||||
|
const averageResults = fpsTest.state.results.filter(
|
||||||
|
(result) => result.note && result.note.includes("平均")
|
||||||
|
)
|
||||||
|
|
||||||
|
if (averageResults.length === 0) {
|
||||||
|
addToast({ title: "没有平均结果数据可导出", color: "warning" })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 构建CSV内容
|
||||||
|
const headers = [
|
||||||
|
"测试时间",
|
||||||
|
"测试地图",
|
||||||
|
"平均帧",
|
||||||
|
"P1低帧",
|
||||||
|
"CPU",
|
||||||
|
"系统版本",
|
||||||
|
"GPU",
|
||||||
|
"内存(GB)",
|
||||||
|
"分辨率",
|
||||||
|
"视频设置",
|
||||||
|
"备注",
|
||||||
|
]
|
||||||
|
|
||||||
|
const csvRows = [headers.join(",")]
|
||||||
|
|
||||||
|
for (const result of averageResults) {
|
||||||
|
const row = [
|
||||||
|
`"${result.testTime}"`,
|
||||||
|
`"${result.mapLabel}"`,
|
||||||
|
result.avg !== null ? result.avg.toFixed(1) : "N/A",
|
||||||
|
result.p1 !== null ? result.p1.toFixed(1) : "N/A",
|
||||||
|
`"${result.hardwareInfo?.cpu || "N/A"}"`,
|
||||||
|
`"${result.hardwareInfo?.os || "N/A"}"`,
|
||||||
|
`"${result.hardwareInfo?.gpu || "N/A"}"`,
|
||||||
|
result.hardwareInfo?.memory ? result.hardwareInfo.memory.toString() : "N/A",
|
||||||
|
result.videoSetting
|
||||||
|
? `${result.videoSetting.defaultres}x${result.videoSetting.defaultresheight}`
|
||||||
|
: "N/A",
|
||||||
|
`"${formatVideoSettingSummary(result.videoSetting)}"`,
|
||||||
|
`"${result.note || ""}"`,
|
||||||
|
]
|
||||||
|
csvRows.push(row.join(","))
|
||||||
|
}
|
||||||
|
|
||||||
|
const csvContent = csvRows.join("\n")
|
||||||
|
|
||||||
|
// 添加UTF-8 BOM以确保Excel等软件正确识别编码
|
||||||
|
const csvContentWithBOM = "\uFEFF" + csvContent
|
||||||
|
|
||||||
|
// 使用文件保存对话框
|
||||||
|
const filePath = await save({
|
||||||
|
filters: [
|
||||||
|
{
|
||||||
|
name: "CSV",
|
||||||
|
extensions: ["csv"],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
defaultPath: `fps_test_average_results_${new Date().toISOString().split("T")[0]}.csv`,
|
||||||
|
})
|
||||||
|
|
||||||
|
if (filePath) {
|
||||||
|
await writeTextFile(filePath, csvContentWithBOM)
|
||||||
|
addToast({ title: "导出成功", color: "success" })
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("导出CSV失败:", error)
|
||||||
|
addToast({
|
||||||
|
title: `导出失败: ${error instanceof Error ? error.message : String(error)}`,
|
||||||
|
color: "danger",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 应用预设分辨率
|
// 应用预设分辨率
|
||||||
const handlePresetResolution = (preset: { width: string; height: string; label: string }) => {
|
const handlePresetResolution = (preset: { width: string; height: string; label: string }) => {
|
||||||
fpsTest.setResolution(preset.width, preset.height)
|
fpsTest.setResolution(preset.width, preset.height)
|
||||||
@@ -1228,10 +1398,16 @@ export function FpsTest() {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{showResultsTable && (
|
{showResultsTable && (
|
||||||
<Button size="sm" variant="flat" onPress={handleExportCSV} className="font-medium">
|
<>
|
||||||
<DownloadOne size={14} />
|
<Button size="sm" variant="flat" onPress={handleExportAverageCSV} className="font-medium">
|
||||||
导出CSV
|
<DownloadOne size={14} />
|
||||||
</Button>
|
仅导出平均结果
|
||||||
|
</Button>
|
||||||
|
<Button size="sm" variant="flat" onPress={handleExportCSV} className="font-medium">
|
||||||
|
<DownloadOne size={14} />
|
||||||
|
导出CSV
|
||||||
|
</Button>
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
<Button
|
<Button
|
||||||
size="sm"
|
size="sm"
|
||||||
@@ -1291,7 +1467,7 @@ export function FpsTest() {
|
|||||||
<TableColumn width={80}>测试地图</TableColumn>
|
<TableColumn width={80}>测试地图</TableColumn>
|
||||||
<TableColumn width={80}>平均帧</TableColumn>
|
<TableColumn width={80}>平均帧</TableColumn>
|
||||||
<TableColumn width={80}>P1低帧</TableColumn>
|
<TableColumn width={80}>P1低帧</TableColumn>
|
||||||
<TableColumn width={150}>CPU</TableColumn>
|
<TableColumn width={100}>CPU</TableColumn>
|
||||||
<TableColumn minWidth={80}>系统版本</TableColumn>
|
<TableColumn minWidth={80}>系统版本</TableColumn>
|
||||||
<TableColumn minWidth={100}>GPU</TableColumn>
|
<TableColumn minWidth={100}>GPU</TableColumn>
|
||||||
<TableColumn width={80}>内存</TableColumn>
|
<TableColumn width={80}>内存</TableColumn>
|
||||||
@@ -1314,10 +1490,16 @@ export function FpsTest() {
|
|||||||
<TableCell className="text-xs">
|
<TableCell className="text-xs">
|
||||||
{result.p1 !== null ? `${result.p1.toFixed(1)}` : "N/A"}
|
{result.p1 !== null ? `${result.p1.toFixed(1)}` : "N/A"}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell className="text-xs max-w-[150px]">
|
<TableCell className="text-xs max-w-[175px]">
|
||||||
<div className="truncate">
|
<Tooltip
|
||||||
{result.hardwareInfo?.cpu || "N/A"}
|
content={result.hardwareInfo?.cpu || "N/A"}
|
||||||
</div>
|
delay={500}
|
||||||
|
placement="top"
|
||||||
|
>
|
||||||
|
<div className="truncate cursor-help">
|
||||||
|
{result.hardwareInfo?.cpu || "N/A"}
|
||||||
|
</div>
|
||||||
|
</Tooltip>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell className="text-xs">
|
<TableCell className="text-xs">
|
||||||
<div className="truncate">
|
<div className="truncate">
|
||||||
@@ -1474,9 +1656,9 @@ export function FpsTest() {
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
isDisabled={isMonitoring}
|
isDisabled={isMonitoring}
|
||||||
className="h-5 min-w-[40px] px-1.5 text-xs font-medium"
|
className="h-5 gap-1 flex px-1.5 min-w-fit text-xs font-medium"
|
||||||
>
|
>
|
||||||
<List size={14} />
|
<List size={12} />
|
||||||
多组
|
多组
|
||||||
</Button>
|
</Button>
|
||||||
{!isResolutionGroupEnabled && (
|
{!isResolutionGroupEnabled && (
|
||||||
|
|||||||
Reference in New Issue
Block a user