Skip to content

Commit e27fc10

Browse files
committed
fix: 为兼容移动端,暂时删除了身份面板的resize
1 parent fa49345 commit e27fc10

1 file changed

Lines changed: 16 additions & 236 deletions

File tree

src/components/panels/IdentityPanel.vue

Lines changed: 16 additions & 236 deletions
Original file line numberDiff line numberDiff line change
@@ -15,30 +15,17 @@
1515
</div>
1616

1717
<div class="panel-block-list">
18-
<div class="list-header" :style="gridStyle">
18+
<div class="list-header">
1919
<span class="header-cell">名称/账号</span>
20-
<div
21-
class="col-resize-handle"
22-
@mousedown="startColResize(0, $event)"
23-
></div>
2420
<span class="header-cell">发言</span>
25-
<div
26-
class="col-resize-handle"
27-
@mousedown="startColResize(1, $event)"
28-
></div>
2921
<span class="header-cell">身份</span>
30-
<div
31-
class="col-resize-handle"
32-
@mousedown="startColResize(2, $event)"
33-
></div>
3422
<span class="header-cell">染色</span>
3523
</div>
3624

3725
<div
3826
v-for="item in identityList"
3927
:key="item.id"
4028
class="identity-item"
41-
:style="gridStyle"
4229
>
4330
<div class="col-name" @dblclick="startEdit(item.id)">
4431
<input
@@ -53,11 +40,9 @@
5340
<span class="text">{{ item.id }}</span>
5441
</div>
5542
</div>
56-
<div class="col-divider"></div>
5743
<div class="col-count">
5844
<span class="count">{{ item.msgCount }}</span>
5945
</div>
60-
<div class="col-divider"></div>
6146

6247
<div class="col-role">
6348
<select
@@ -76,7 +61,6 @@
7661
<option value="unknown">其他</option>
7762
</select>
7863
</div>
79-
<div class="col-divider"></div>
8064

8165
<div class="col-color">
8266
<div
@@ -106,11 +90,10 @@
10690
</template>
10791

10892
<script setup lang="ts">
109-
import { ref, reactive, computed, watch } from 'vue';
93+
import { ref, computed } from 'vue';
11094
import { IdCard, UserRound } from '@lucide/vue';
11195
import { useStyleStore } from '@/stores/styleStore';
11296
import { useLogStore } from '@/stores/logStore';
113-
import { useUiStore, PANEL_MAX_WIDTH } from '@/stores/uiStore';
11497
import { useHistoryStore } from '@/stores/historyStore';
11598
import { useLogEditorStore } from '@/stores/editorStore';
11699
import type { RoleType } from '@/types/log';
@@ -132,7 +115,6 @@ interface IdentityListItem {
132115
133116
const styleStore = useStyleStore();
134117
const logStore = useLogStore();
135-
const uiStore = useUiStore();
136118
const historyStore = useHistoryStore();
137119
const logEditorStore = useLogEditorStore();
138120
const windowStore = useWindowStore();
@@ -251,198 +233,20 @@ function getRoleFromSelectEvent(event: Event): RoleType {
251233
const vFocus = {
252234
mounted: (el: HTMLElement) => el.focus(),
253235
};
254-
255-
// --- 列宽拖拽 ---
256-
// 4 列总宽始终 = 面板可用宽度,拖手柄是相邻两列此消彼长
257-
// Grid 7 格: 名称 | handle | 发言 | handle | 身份 | handle | 染色
258-
259-
const MIN_COL_WIDTH = 30;
260-
const HANDLE_COUNT = 3;
261-
const HANDLE_WIDTH = 4; // 与 CSS .col-resize-handle / .col-divider 的 width 一致
262-
const ROW_PADDING_X = 8; // 与 CSS .list-header / .identity-item 的 padding 水平值一致
263-
const GRID_OVERHEAD = HANDLE_COUNT * HANDLE_WIDTH + ROW_PADDING_X * 2;
264-
265-
// 身份列的最小宽度:需容纳最宽选项 "主持人"(3 CJK + select padding/arrow)
266-
const MIN_ROLE_WIDTH = 65;
267-
// 染色列固定宽度(色块 20px + 余量)
268-
const COLOR_COL_WIDTH = 36;
269-
270-
/** 面板可用于 4 列的净宽度 */
271-
function availableColSpace(): number {
272-
return uiStore.leftPanelWidth - GRID_OVERHEAD;
273-
}
274-
275-
/** 列总宽 */
276-
function totalColWidth(): number {
277-
return colWidths.reduce((s, w) => s + w, 0);
278-
}
279-
280-
/** 列总宽 + 开销 = 面板所需最小宽度 */
281-
function requiredPanelWidth(): number {
282-
return totalColWidth() + GRID_OVERHEAD;
283-
}
284-
285-
/** 用隐藏 canvas 测量文本像素宽度 */
286-
const measureCanvas = document.createElement('canvas');
287-
function measureText(text: string, font: string): number {
288-
const ctx = measureCanvas.getContext('2d')!;
289-
ctx.font = font;
290-
return Math.ceil(ctx.measureText(text).width);
291-
}
292-
293-
/** 根据当前数据计算各列理想宽度 */
294-
function calcIdealColWidths(
295-
items: IdentityListItem[],
296-
): [number, number, number, number] {
297-
if (items.length === 0) {
298-
return [80, 40, MIN_ROLE_WIDTH, COLOR_COL_WIDTH];
299-
}
300-
301-
// 名称列:最长名称文字宽度 + 余量
302-
const nameFont = '13px sans-serif';
303-
const maxNameW = items.reduce(
304-
(max, item) => Math.max(max, measureText(item.id, nameFont)),
305-
0,
306-
);
307-
const nameCol = Math.max(MIN_COL_WIDTH, maxNameW + 8);
308-
309-
// 发言列:最大数字宽度 + badge padding
310-
const countFont = '10px sans-serif';
311-
const maxCountW = items.reduce(
312-
(max, item) =>
313-
Math.max(max, measureText(String(item.msgCount), countFont)),
314-
0,
315-
);
316-
const countCol = Math.max(MIN_COL_WIDTH, maxCountW + 16); // badge padding 2×6 + 余量
317-
318-
// 身份列:固定最小宽度(select 下拉框需要容纳最宽选项)
319-
const roleCol = MIN_ROLE_WIDTH;
320-
321-
return [nameCol, countCol, roleCol, COLOR_COL_WIDTH];
322-
}
323-
324-
// 初始化列宽
325-
const colWidths = reactive([80, 40, MIN_ROLE_WIDTH, COLOR_COL_WIDTH]);
326-
327-
// 数据变化时自动调整列宽和侧边栏
328-
watch(
329-
identityList,
330-
(items) => {
331-
const [nameW, countW, roleW, colorW] = calcIdealColWidths(items);
332-
const idealTotal = nameW + countW + roleW + colorW;
333-
const available = availableColSpace();
334-
335-
if (idealTotal <= available) {
336-
// 空间足够:各列用理想宽度,名称列吃掉剩余
337-
colWidths[1] = countW;
338-
colWidths[2] = roleW;
339-
colWidths[3] = colorW;
340-
colWidths[0] = available - countW - roleW - colorW;
341-
} else {
342-
// 空间不够:优先保持当前用户设定的侧边栏宽度
343-
colWidths[1] = countW;
344-
colWidths[2] = roleW;
345-
colWidths[3] = colorW;
346-
const remainingForName = available - (countW + roleW + colorW);
347-
348-
if (remainingForName >= MIN_COL_WIDTH) {
349-
// 只要还能满足最小宽度,就直接在内部压缩名称列,不推侧边栏
350-
colWidths[0] = remainingForName;
351-
} else {
352-
colWidths[0] = MIN_COL_WIDTH;
353-
const minimalNeeded =
354-
MIN_COL_WIDTH + countW + roleW + colorW + GRID_OVERHEAD;
355-
if (uiStore.leftPanelWidth < minimalNeeded) {
356-
uiStore.leftPanelWidth = Math.min(
357-
PANEL_MAX_WIDTH,
358-
minimalNeeded,
359-
);
360-
}
361-
}
362-
}
363-
},
364-
{ immediate: true },
365-
);
366-
367-
const gridStyle = computed(() => ({
368-
gridTemplateColumns: colWidths
369-
.map((w) => `${w}px`)
370-
.join(` ${HANDLE_WIDTH}px `),
371-
}));
372-
373-
/** 拖拽列手柄:左列和右列此消彼长,触底后推宽侧边栏 */
374-
function startColResize(colIndex: number, e: MouseEvent) {
375-
e.preventDefault();
376-
const startX = e.clientX;
377-
const startLeft = colWidths[colIndex];
378-
const startRight = colWidths[colIndex + 1];
379-
const startPanelWidth = uiStore.leftPanelWidth;
380-
381-
// 身份列(index 2)有更高的最小宽度
382-
const minLeft = MIN_COL_WIDTH;
383-
const minRight = colIndex + 1 === 2 ? MIN_ROLE_WIDTH : MIN_COL_WIDTH;
384-
385-
function onMouseMove(ev: MouseEvent) {
386-
const delta = ev.clientX - startX;
387-
const newLeft = Math.max(minLeft, startLeft + delta);
388-
const newRight = startRight - delta;
389-
390-
if (newRight >= minRight) {
391-
colWidths[colIndex] = newLeft;
392-
colWidths[colIndex + 1] = newRight;
393-
} else {
394-
// 右列触底,推宽侧边栏
395-
colWidths[colIndex] = newLeft;
396-
colWidths[colIndex + 1] = minRight;
397-
const needed = requiredPanelWidth();
398-
uiStore.leftPanelWidth = Math.min(
399-
PANEL_MAX_WIDTH,
400-
Math.max(startPanelWidth, needed),
401-
);
402-
}
403-
404-
// 反向拖时缩回侧边栏
405-
if (delta < 0 && uiStore.leftPanelWidth > startPanelWidth) {
406-
const needed = requiredPanelWidth();
407-
if (needed < uiStore.leftPanelWidth) {
408-
uiStore.leftPanelWidth = Math.max(startPanelWidth, needed);
409-
}
410-
}
411-
}
412-
413-
function onMouseUp() {
414-
document.removeEventListener('mousemove', onMouseMove);
415-
document.removeEventListener('mouseup', onMouseUp);
416-
document.body.style.cursor = '';
417-
document.body.style.userSelect = '';
418-
}
419-
420-
document.body.style.cursor = 'col-resize';
421-
document.body.style.userSelect = 'none';
422-
document.addEventListener('mousemove', onMouseMove);
423-
document.addEventListener('mouseup', onMouseUp);
424-
}
425-
426-
// 侧边栏宽度变化时,名称列(第一列)吸收差值
427-
watch(
428-
() => uiStore.leftPanelWidth,
429-
() => {
430-
const diff = availableColSpace() - totalColWidth();
431-
if (diff !== 0) {
432-
colWidths[0] = Math.max(MIN_COL_WIDTH, colWidths[0] + diff);
433-
}
434-
},
435-
);
436236
</script>
437237

438238
<style scoped>
439-
/* --- 共享 grid 布局 (7格: col handle col handle col handle col) --- */
440239
.list-header,
441240
.identity-item {
442241
display: grid;
443-
/* gridTemplateColumns 由 :style="gridStyle" 动态设置 */
242+
grid-template-columns:
243+
minmax(0, 1fr)
244+
clamp(36px, 14%, 56px)
245+
clamp(58px, 24%, 82px)
246+
clamp(34px, 12%, 44px);
444247
align-items: center;
445-
padding: 4px 8px;
248+
column-gap: 8px;
249+
padding: 4px 10px;
446250
}
447251
448252
.list-header {
@@ -470,37 +274,6 @@ watch(
470274
background-color: var(--hover-bg);
471275
}
472276
473-
/* --- 列拖拽手柄 (表头) --- */
474-
.col-resize-handle {
475-
width: 4px;
476-
height: 100%;
477-
cursor: col-resize;
478-
position: relative;
479-
}
480-
481-
.col-resize-handle::after {
482-
content: '';
483-
position: absolute;
484-
top: 25%;
485-
bottom: 25%;
486-
left: 1px;
487-
width: 1px;
488-
background-color: var(--border-color);
489-
transition: background-color 0.15s;
490-
}
491-
492-
.col-resize-handle:hover::after {
493-
left: 0;
494-
width: 4px;
495-
background-color: var(--active-accent);
496-
border-radius: 2px;
497-
}
498-
499-
/* --- 数据行列分隔 (纯视觉对齐, 不可拖) --- */
500-
.col-divider {
501-
width: 4px;
502-
}
503-
504277
/* --- 各列样式 --- */
505278
.col-name {
506279
display: flex;
@@ -514,15 +287,18 @@ watch(
514287
align-items: center;
515288
justify-content: center;
516289
overflow: hidden;
290+
min-width: 0;
517291
}
518292
519293
.col-role {
520294
overflow: hidden;
295+
min-width: 0;
521296
}
522297
523298
.col-color {
524299
display: flex;
525300
justify-content: center;
301+
min-width: 0;
526302
}
527303
528304
.name-display {
@@ -543,11 +319,15 @@ watch(
543319
544320
.count {
545321
font-size: 10px;
322+
min-width: 0;
323+
max-width: 100%;
546324
padding: 2px 6px;
547325
background: var(--bg-secondary);
548326
border-radius: 10px;
549327
color: var(--text-muted);
550328
white-space: nowrap;
329+
overflow: hidden;
330+
text-overflow: ellipsis;
551331
}
552332
553333
.name-input {

0 commit comments

Comments
 (0)