Skip to content

Commit 76ccded

Browse files
committed
perf: 手机端分屏模式优化
1 parent 01e40e0 commit 76ccded

2 files changed

Lines changed: 174 additions & 139 deletions

File tree

src/App.vue

Lines changed: 52 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1651,7 +1651,7 @@ onBeforeUnmount(() => {
16511651
:detail-view-collapsed="detailViewCollapsed"
16521652
:on-expand-detail-view="toggleDetailView"
16531653
:pending-scroll-node-id="pendingScrollNodeId"
1654-
:is-realtime-streaming="isRealtimeContext"
1654+
:is-realtime-streaming="isRealtimeContext"
16551655
@select-task="handleSelectTask"
16561656
@upload-file="handleFileUpload"
16571657
@upload-content="handleContentUpload"
@@ -1696,7 +1696,6 @@ onBeforeUnmount(() => {
16961696
</template>
16971697
</n-split>
16981698
</div>
1699-
17001699
<!-- 文本搜索模式(独立显示,占据整个屏幕) -->
17011700
<div v-show="viewMode === 'search'" data-tour="search-main" style="height: 100%">
17021701
<text-search-view :is-dark="isDark" :loaded-targets="textSearchLoadedTargets" :loaded-default-target-id="textSearchLoadedDefaultTargetId" style="height: 100%" />
@@ -1724,46 +1723,57 @@ onBeforeUnmount(() => {
17241723
<!-- 分屏模式 -->
17251724
<div v-show="viewMode === 'split'" data-tour="split-main" style="height: 100%">
17261725
<template v-if="isMobile">
1727-
<n-split
1728-
direction="vertical"
1729-
v-model:size="splitVerticalSize"
1730-
:min="0.25"
1731-
:max="0.75"
1732-
style="height: 100%"
1733-
>
1734-
<template #1>
1735-
<process-view
1736-
:tasks="filteredTasks"
1737-
:selected-task="selectedTask"
1738-
:loading="loading"
1739-
:parser="parser"
1740-
:is-mobile="true"
1741-
:pending-scroll-node-id="pendingScrollNodeId"
1742-
:is-realtime-streaming="isRealtimeContext"
1743-
@select-task="handleSelectTask"
1744-
@upload-file="handleFileUpload"
1745-
@upload-content="handleContentUpload"
1746-
@select-node="handleSelectNode"
1747-
@select-action="handleSelectAction"
1748-
@select-recognition="handleSelectRecognition"
1749-
@select-nested="handleSelectNested"
1750-
@select-nested-action="handleSelectNestedAction"
1751-
@file-loading-start="handleFileLoadingStart"
1752-
@file-loading-end="handleFileLoadingEnd"
1753-
@open-task-drawer="showTaskDrawer = true"
1754-
@scroll-done="pendingScrollNodeId = null"
1755-
/>
1756-
</template>
1757-
<template #2>
1758-
<text-search-view
1759-
v-if="viewMode === 'split'"
1760-
:is-dark="isDark"
1761-
:loaded-targets="textSearchLoadedTargets"
1762-
:loaded-default-target-id="textSearchLoadedDefaultTargetId"
1763-
style="height: 100%"
1764-
/>
1765-
</template>
1766-
</n-split>
1726+
<div style="height: 100%; display: flex; flex-direction: column; gap: 8px; padding: 8px; box-sizing: border-box;">
1727+
<n-flex align="center" justify="space-between" style="gap: 8px">
1728+
<n-text depth="3" style="font-size: 12px">分屏比例</n-text>
1729+
<n-flex align="center" style="gap: 6px">
1730+
<n-button size="tiny" @click="splitVerticalSize = 0.72">分析优先</n-button>
1731+
<n-button size="tiny" @click="splitVerticalSize = 0.5">均分</n-button>
1732+
<n-button size="tiny" @click="splitVerticalSize = 0.28">搜索优先</n-button>
1733+
</n-flex>
1734+
</n-flex>
1735+
1736+
<n-split
1737+
direction="vertical"
1738+
v-model:size="splitVerticalSize"
1739+
:min="0.15"
1740+
:max="0.85"
1741+
style="flex: 1; min-height: 0"
1742+
>
1743+
<template #1>
1744+
<process-view
1745+
:tasks="filteredTasks"
1746+
:selected-task="selectedTask"
1747+
:loading="loading"
1748+
:parser="parser"
1749+
:is-mobile="true"
1750+
:pending-scroll-node-id="pendingScrollNodeId"
1751+
:is-realtime-streaming="isRealtimeContext"
1752+
style="height: 100%"
1753+
@select-task="handleSelectTask"
1754+
@upload-file="handleFileUpload"
1755+
@upload-content="handleContentUpload"
1756+
@select-node="handleSelectNode"
1757+
@select-action="handleSelectAction"
1758+
@select-recognition="handleSelectRecognition"
1759+
@select-nested="handleSelectNested"
1760+
@select-nested-action="handleSelectNestedAction"
1761+
@file-loading-start="handleFileLoadingStart"
1762+
@file-loading-end="handleFileLoadingEnd"
1763+
@open-task-drawer="showTaskDrawer = true"
1764+
@scroll-done="pendingScrollNodeId = null"
1765+
/>
1766+
</template>
1767+
<template #2>
1768+
<text-search-view
1769+
:is-dark="isDark"
1770+
:loaded-targets="textSearchLoadedTargets"
1771+
:loaded-default-target-id="textSearchLoadedDefaultTargetId"
1772+
style="height: 100%"
1773+
/>
1774+
</template>
1775+
</n-split>
1776+
</div>
17671777

17681778
<!-- 左侧任务抽屉 -->
17691779
<n-drawer

src/views/TextSearchView.vue

Lines changed: 122 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,8 @@ const isSearching = ref(false)
104104
const isLoadingFile = ref(false) // 是否正在加载文件
105105
const selectedLine = ref<number | null>(null) // 当前选中的行
106106
const searchHistory = ref<string[]>([]) // 搜索历史
107+
const searchOptionExpandedNames = ref<Array<string | number>>(['search-options']) // 搜索选项折叠状态
108+
const mobileControlExpandedNames = ref<Array<string | number>>([]) // 手机端顶部控制折叠状态
107109
const showFileContent = ref(false) // 是否显示文件内容(默认关闭以节省内存)
108110
const contentKey = ref(0) // 用于强制重新渲染,释放内存
109111
const hideDebugInfo = ref(true) // 是否隐藏调试信息(如 [Px...][Tx...][...cpp]),默认隐藏
@@ -815,39 +817,74 @@ const loadContextLines = async (targetLine: number) => {
815817
<n-flex v-if="isMobile" vertical style="gap: 8px">
816818
<n-flex align="center" justify="space-between">
817819
<n-text strong style="font-size: 16px">文本搜索</n-text>
818-
<n-flex align="center" style="gap: 8px">
819-
<input
820-
id="text-search-file-input"
821-
ref="fileInputRef"
822-
type="file"
823-
accept=".txt,.log"
824-
@change="handleFileUpload"
825-
style="display: none"
826-
/>
827-
<n-button size="small" type="primary" @click="triggerFileSelect">
828-
<template #icon><file-text-outlined /></template>
829-
选择其它文件
830-
</n-button>
831-
<n-button v-if="fileName" size="small" @click="clearContent" secondary type="warning">
832-
<template #icon><n-icon><close-outlined /></n-icon></template>
833-
</n-button>
834-
</n-flex>
835-
</n-flex>
836-
<n-flex vertical style="gap: 8px">
837-
<n-select
838-
v-model:value="sourceMode"
839-
:options="sourceModeOptions"
840-
size="small"
841-
/>
842-
<n-select
843-
v-if="sourceMode === 'loaded'"
844-
v-model:value="selectedLoadedTargetId"
845-
:options="loadedTargetOptions"
846-
placeholder="选择已加载目标"
847-
size="small"
848-
:disabled="loadedTargetOptions.length === 0"
849-
/>
850820
</n-flex>
821+
<n-collapse v-model:expanded-names="mobileControlExpandedNames">
822+
<n-collapse-item title="已加载目标 / 选择文件 / 搜索选项" name="mobile-controls">
823+
<n-flex vertical style="gap: 8px">
824+
<input
825+
id="text-search-file-input"
826+
ref="fileInputRef"
827+
type="file"
828+
accept=".txt,.log"
829+
@change="handleFileUpload"
830+
style="display: none"
831+
/>
832+
<n-flex align="center" style="gap: 8px; flex-wrap: wrap">
833+
<n-button size="small" type="primary" @click="triggerFileSelect">
834+
<template #icon><file-text-outlined /></template>
835+
选择其它文件
836+
</n-button>
837+
<n-button v-if="fileName" size="small" @click="clearContent" secondary type="warning">
838+
<template #icon><n-icon><close-outlined /></n-icon></template>
839+
</n-button>
840+
</n-flex>
841+
<n-select
842+
v-model:value="sourceMode"
843+
:options="sourceModeOptions"
844+
size="small"
845+
/>
846+
<n-select
847+
v-if="sourceMode === 'loaded'"
848+
v-model:value="selectedLoadedTargetId"
849+
:options="loadedTargetOptions"
850+
placeholder="选择已加载目标"
851+
size="small"
852+
:disabled="loadedTargetOptions.length === 0"
853+
/>
854+
<n-flex align="center" style="gap: 8px; flex-wrap: wrap">
855+
<n-checkbox v-model:checked="caseSensitive" size="small">区分大小写</n-checkbox>
856+
<n-checkbox v-model:checked="useRegex" size="small">正则</n-checkbox>
857+
<n-checkbox v-model:checked="hideDebugInfo" size="small">隐藏调试</n-checkbox>
858+
</n-flex>
859+
<n-flex wrap style="gap: 6px">
860+
<n-button
861+
v-for="option in quickSearchOptions"
862+
:key="`m-quick-${option}`"
863+
size="tiny"
864+
secondary
865+
@click="useHistoryItem(option)"
866+
:type="searchText === option ? 'primary' : 'default'"
867+
>
868+
{{ option }}
869+
</n-button>
870+
</n-flex>
871+
<n-flex v-if="searchHistory.length > 0" wrap style="gap: 6px">
872+
<n-tag
873+
v-for="(item, idx) in searchHistory.slice(0, 8)"
874+
:key="`m-history-${idx}`"
875+
size="small"
876+
closable
877+
@close="removeFromHistory(item)"
878+
@click="useHistoryItem(item)"
879+
style="cursor: pointer"
880+
:type="searchText === item ? 'primary' : 'default'"
881+
>
882+
{{ item.length > 24 ? item.substring(0, 24) + '...' : item }}
883+
</n-tag>
884+
</n-flex>
885+
</n-flex>
886+
</n-collapse-item>
887+
</n-collapse>
851888
<n-flex v-if="fileName && !isLoadingFile" align="center" style="gap: 8px">
852889
<n-text depth="3" style="font-size: 12px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; flex: 1">
853890
{{ fileName }}
@@ -859,7 +896,6 @@ const loadContextLines = async (targetLine: number) => {
859896
</n-flex>
860897
<n-text v-if="isLoadingFile" type="info" style="font-size: 13px">正在加载文件...</n-text>
861898
</n-flex>
862-
863899
<!-- 桌面端工具栏 -->
864900
<n-flex v-else align="center" justify="space-between" style="gap: 12px">
865901
<n-flex align="center" style="gap: 12px">
@@ -958,23 +994,7 @@ const loadContextLines = async (targetLine: number) => {
958994
搜索
959995
</n-button>
960996
</n-input-group>
961-
<n-flex align="center" style="gap: 8px; flex-wrap: wrap">
962-
<n-checkbox v-model:checked="caseSensitive" size="small">区分大小写</n-checkbox>
963-
<n-checkbox v-model:checked="useRegex" size="small">正则</n-checkbox>
964-
<n-checkbox v-model:checked="hideDebugInfo" size="small">隐藏调试</n-checkbox>
965-
</n-flex>
966-
<n-flex wrap style="gap: 6px">
967-
<n-button
968-
v-for="option in quickSearchOptions"
969-
:key="option"
970-
size="tiny"
971-
secondary
972-
@click="useHistoryItem(option)"
973-
:type="searchText === option ? 'primary' : 'default'"
974-
>
975-
{{ option }}
976-
</n-button>
977-
</n-flex>
997+
978998
</n-flex>
979999
</n-card>
9801000

@@ -1065,53 +1085,58 @@ const loadContextLines = async (targetLine: number) => {
10651085
</n-input-group>
10661086

10671087
<!-- 搜索选项 -->
1068-
<n-flex align="center" style="gap: 12px; flex-wrap: wrap">
1069-
<n-checkbox v-model:checked="caseSensitive">
1070-
区分大小写
1071-
</n-checkbox>
1072-
<n-checkbox v-model:checked="useRegex">
1073-
正则表达式
1074-
</n-checkbox>
1075-
<n-checkbox v-model:checked="hideDebugInfo">
1076-
隐藏调试标签
1077-
</n-checkbox>
1078-
</n-flex>
1079-
1080-
<!-- 快捷搜索 -->
1081-
<div>
1082-
<n-text depth="3" style="font-size: 12px; margin-bottom: 6px; display: block">
1083-
快捷搜索:
1084-
</n-text>
1085-
<n-flex wrap style="gap: 6px">
1086-
<n-button
1087-
v-for="option in quickSearchOptions"
1088-
:key="option"
1089-
size="tiny"
1090-
secondary
1091-
@click="useHistoryItem(option)"
1092-
:type="searchText === option ? 'primary' : 'default'"
1093-
>
1094-
{{ option }}
1095-
</n-button>
1096-
</n-flex>
1097-
</div>
1098-
1099-
<!-- 搜索历史 -->
1100-
<n-collapse v-if="searchHistory.length > 0" style="margin-top: 8px">
1101-
<n-collapse-item title="📝 搜索历史" name="history">
1102-
<n-flex wrap style="gap: 6px">
1103-
<n-tag
1104-
v-for="(item, idx) in searchHistory.slice(0, 10)"
1105-
:key="idx"
1106-
size="small"
1107-
closable
1108-
@close="removeFromHistory(item)"
1109-
@click="useHistoryItem(item)"
1110-
style="cursor: pointer"
1111-
:type="searchText === item ? 'primary' : 'default'"
1112-
>
1113-
{{ item.length > 30 ? item.substring(0, 30) + '...' : item }}
1114-
</n-tag>
1088+
<n-collapse v-model:expanded-names="searchOptionExpandedNames">
1089+
<n-collapse-item title="搜索选项" name="search-options">
1090+
<n-flex vertical style="gap: 10px">
1091+
<n-flex align="center" style="gap: 12px; flex-wrap: wrap">
1092+
<n-checkbox v-model:checked="caseSensitive">
1093+
区分大小写
1094+
</n-checkbox>
1095+
<n-checkbox v-model:checked="useRegex">
1096+
正则表达式
1097+
</n-checkbox>
1098+
<n-checkbox v-model:checked="hideDebugInfo">
1099+
隐藏调试标签
1100+
</n-checkbox>
1101+
</n-flex>
1102+
1103+
<div>
1104+
<n-text depth="3" style="font-size: 12px; margin-bottom: 6px; display: block">
1105+
快捷搜索:
1106+
</n-text>
1107+
<n-flex wrap style="gap: 6px">
1108+
<n-button
1109+
v-for="option in quickSearchOptions"
1110+
:key="option"
1111+
size="tiny"
1112+
secondary
1113+
@click="useHistoryItem(option)"
1114+
:type="searchText === option ? 'primary' : 'default'"
1115+
>
1116+
{{ option }}
1117+
</n-button>
1118+
</n-flex>
1119+
</div>
1120+
1121+
<div v-if="searchHistory.length > 0">
1122+
<n-text depth="3" style="font-size: 12px; margin-bottom: 6px; display: block">
1123+
搜索历史:
1124+
</n-text>
1125+
<n-flex wrap style="gap: 6px">
1126+
<n-tag
1127+
v-for="(item, idx) in searchHistory.slice(0, 10)"
1128+
:key="idx"
1129+
size="small"
1130+
closable
1131+
@close="removeFromHistory(item)"
1132+
@click="useHistoryItem(item)"
1133+
style="cursor: pointer"
1134+
:type="searchText === item ? 'primary' : 'default'"
1135+
>
1136+
{{ item.length > 30 ? item.substring(0, 30) + '...' : item }}
1137+
</n-tag>
1138+
</n-flex>
1139+
</div>
11151140
</n-flex>
11161141
</n-collapse-item>
11171142
</n-collapse>

0 commit comments

Comments
 (0)