Skip to content

Commit 53ef70b

Browse files
committed
feat: support copy path mode
1 parent 2c983c2 commit 53ef70b

File tree

2 files changed

+160
-21
lines changed

2 files changed

+160
-21
lines changed

packages/core/src/client/index.ts

Lines changed: 154 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import { LitElement, TemplateResult, css, html } from 'lit';
22
import { property, query, state } from 'lit/decorators.js';
33
import { styleMap } from 'lit/directives/style-map.js';
44
import { PathName, DefaultPort } from '../shared';
5-
import { formatOpenPath } from 'launch-ide';
65

76
const styleId = '__code-inspector-unique-id';
87
const AstroFile = 'data-astro-source-file';
@@ -154,6 +153,12 @@ export class CodeInspectorComponent extends LitElement {
154153
sendType: 'xhr' | 'img' = 'xhr';
155154
@state()
156155
activeNode: ActiveNode = {};
156+
@state()
157+
actionMode: 'ide' | 'copy' = 'ide'; // 模式:ide-在IDE中打开,copy-复制路径
158+
@state()
159+
showModeToast = false; // 显示模式切换提示
160+
@state()
161+
modeToastTimer: number | null = null; // 模式切换提示定时器
157162

158163
@query('#inspector-switch')
159164
inspectorSwitchRef!: HTMLDivElement;
@@ -530,30 +535,53 @@ export class CodeInspectorComponent extends LitElement {
530535
return targetUrl;
531536
};
532537

538+
// 切换模式
539+
toggleMode = () => {
540+
this.actionMode = this.actionMode === 'ide' ? 'copy' : 'ide';
541+
this.showModeToastNotification();
542+
};
543+
544+
// 显示模式切换提示
545+
showModeToastNotification = () => {
546+
// 清除之前的定时器
547+
if (this.modeToastTimer !== null) {
548+
window.clearTimeout(this.modeToastTimer);
549+
}
550+
551+
this.showModeToast = true;
552+
553+
// 2秒后自动隐藏
554+
this.modeToastTimer = window.setTimeout(() => {
555+
this.showModeToast = false;
556+
this.modeToastTimer = null;
557+
}, 2000);
558+
};
559+
533560
// 触发功能的处理
534561
trackCode = () => {
535-
if (this.locate) {
536-
// 请求本地服务端,打开vscode
537-
if (this.sendType === 'xhr') {
538-
this.sendXHR();
539-
} else {
540-
this.sendImg();
562+
// 根据当前模式执行对应操作
563+
if (this.actionMode === 'ide') {
564+
// IDE模式:打开编辑器
565+
if (this.locate) {
566+
// 请求本地服务端,打开vscode
567+
if (this.sendType === 'xhr') {
568+
this.sendXHR();
569+
} else {
570+
this.sendImg();
571+
}
541572
}
573+
if (this.target) {
574+
window.open(this.buildTargetUrl(), '_blank');
575+
}
576+
} else if (this.actionMode === 'copy') {
577+
// 复制模式:复制路径
578+
// 直接复制文件路径,格式:/path/to/file.tsx:line:column
579+
const pathToCopy = `${this.element.path}:${this.element.line}:${this.element.column}`;
580+
this.copyToClipboard(pathToCopy);
542581
}
543-
if (this.copy) {
544-
const path = formatOpenPath(
545-
this.element.path,
546-
String(this.element.line),
547-
String(this.element.column),
548-
this.copy
549-
);
550-
this.copyToClipboard(path[0]);
551-
}
552-
if (this.target) {
553-
window.open(this.buildTargetUrl(), '_blank');
554-
}
582+
555583
window.dispatchEvent(new CustomEvent('code-inspector:trackCode', {
556-
detail: this.element,
584+
detail: { ...this.element, mode: this.actionMode },
557585
}));
558586
};
559587

@@ -743,6 +771,23 @@ export class CodeInspectorComponent extends LitElement {
743771
}
744772
};
745773

774+
// 监听键盘按下,处理模式切换
775+
handleKeyDown = (e: KeyboardEvent) => {
776+
// Shift+Alt+C 切换模式
777+
// 检查 key, code, 和 keyCode 以确保在不同系统上都能工作
778+
const isC =
779+
e.key === 'c' ||
780+
e.key === 'C' ||
781+
e.code === 'KeyC' ||
782+
e.keyCode === 67;
783+
784+
if (e.shiftKey && e.altKey && isC && !e.ctrlKey && !e.metaKey) {
785+
e.preventDefault();
786+
e.stopPropagation();
787+
this.toggleMode();
788+
}
789+
};
790+
746791
// 监听键盘抬起,清除遮罩层
747792
handleKeyUp = (e: KeyboardEvent) => {
748793
if (!this.isTracking(e) && !this.open) {
@@ -882,6 +927,7 @@ export class CodeInspectorComponent extends LitElement {
882927
window.addEventListener('touchmove', this.handleDrag, true);
883928
window.addEventListener('click', this.handleMouseClick, true);
884929
window.addEventListener('pointerdown', this.handlePointerDown, true);
930+
window.addEventListener('keydown', this.handleKeyDown, true);
885931
window.addEventListener('keyup', this.handleKeyUp, true);
886932
window.addEventListener('mouseleave', this.removeCover, true);
887933
window.addEventListener('mouseup', this.handleMouseUp, true);
@@ -896,6 +942,7 @@ export class CodeInspectorComponent extends LitElement {
896942
window.removeEventListener('touchmove', this.handleDrag, true);
897943
window.removeEventListener('click', this.handleMouseClick, true);
898944
window.removeEventListener('pointerdown', this.handlePointerDown, true);
945+
window.removeEventListener('keydown', this.handleKeyDown, true);
899946
window.removeEventListener('keyup', this.handleKeyUp, true);
900947
window.removeEventListener('mouseleave', this.removeCover, true);
901948
window.removeEventListener('mouseup', this.handleMouseUp, true);
@@ -995,12 +1042,20 @@ export class CodeInspectorComponent extends LitElement {
9951042
<div class="name-line">
9961043
<div class="element-name">
9971044
<span class="element-title">&lt;${this.element.name}&gt;</span>
998-
<span class="element-tip">click to open editor</span>
1045+
<span class="element-tip">${
1046+
this.actionMode === 'ide'
1047+
? 'click to open editor'
1048+
: 'click to copy path'
1049+
}</span>
9991050
</div>
10001051
</div>
10011052
<div class="path-line">
10021053
${this.element.path}:${this.element.line}:${this.element.column}
10031054
</div>
1055+
<div class="mode-indicator">
1056+
Mode: ${this.actionMode === 'ide' ? '📝 IDE' : '📋 Copy'}
1057+
<span class="mode-hint">(Shift+Alt+C to toggle)</span>
1058+
</div>
10041059
</div>
10051060
</div>
10061061
</div>
@@ -1149,6 +1204,26 @@ export class CodeInspectorComponent extends LitElement {
11491204
>
11501205
${this.activeNode.content}
11511206
</div>
1207+
<div
1208+
id="mode-toast"
1209+
class="mode-toast ${this.showModeToast ? 'show' : ''}"
1210+
>
1211+
<div class="mode-toast-content">
1212+
${
1213+
this.actionMode === 'ide'
1214+
? html`<div class="mode-toast-icon">📝</div>
1215+
<div class="mode-toast-text">
1216+
<div class="mode-toast-title">IDE Mode</div>
1217+
<div class="mode-toast-desc">Click to open in editor</div>
1218+
</div>`
1219+
: html`<div class="mode-toast-icon">📋</div>
1220+
<div class="mode-toast-text">
1221+
<div class="mode-toast-title">Copy Mode</div>
1222+
<div class="mode-toast-desc">Click to copy path</div>
1223+
</div>`
1224+
}
1225+
</div>
1226+
</div>
11521227
`;
11531228
}
11541229

@@ -1234,6 +1309,21 @@ export class CodeInspectorComponent extends LitElement {
12341309
line-height: 12px;
12351310
margin-top: 4px;
12361311
}
1312+
.mode-indicator {
1313+
color: #006aff;
1314+
font-size: 11px;
1315+
margin-top: 6px;
1316+
padding-top: 4px;
1317+
border-top: 1px solid #eee;
1318+
display: flex;
1319+
align-items: center;
1320+
gap: 4px;
1321+
}
1322+
.mode-hint {
1323+
color: #999;
1324+
font-size: 10px;
1325+
margin-left: 4px;
1326+
}
12371327
.inspector-switch {
12381328
position: fixed;
12391329
z-index: 9999999999999;
@@ -1336,6 +1426,49 @@ export class CodeInspectorComponent extends LitElement {
13361426
.close-icon {
13371427
cursor: pointer;
13381428
}
1429+
.mode-toast {
1430+
position: fixed;
1431+
top: 20px;
1432+
left: 50%;
1433+
transform: translateX(-50%) translateY(-100px);
1434+
z-index: 99999999999999;
1435+
background: rgba(0, 0, 0, 0.85);
1436+
color: white;
1437+
padding: 12px 20px;
1438+
border-radius: 8px;
1439+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
1440+
opacity: 0;
1441+
transition: all 0.3s ease-in-out;
1442+
pointer-events: none;
1443+
font-family: 'PingFang SC', -apple-system, BlinkMacSystemFont, 'Segoe UI',
1444+
sans-serif;
1445+
}
1446+
.mode-toast.show {
1447+
transform: translateX(-50%) translateY(0);
1448+
opacity: 1;
1449+
}
1450+
.mode-toast-content {
1451+
display: flex;
1452+
align-items: center;
1453+
gap: 12px;
1454+
}
1455+
.mode-toast-icon {
1456+
font-size: 24px;
1457+
line-height: 1;
1458+
}
1459+
.mode-toast-text {
1460+
display: flex;
1461+
flex-direction: column;
1462+
gap: 2px;
1463+
}
1464+
.mode-toast-title {
1465+
font-size: 14px;
1466+
font-weight: bold;
1467+
}
1468+
.mode-toast-desc {
1469+
font-size: 12px;
1470+
opacity: 0.8;
1471+
}
13391472
`;
13401473
}
13411474

packages/core/types/client/index.d.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,9 @@ export declare class CodeInspectorComponent extends LitElement {
9494
preUserSelect: string;
9595
sendType: 'xhr' | 'img';
9696
activeNode: ActiveNode;
97+
actionMode: 'ide' | 'copy';
98+
showModeToast: boolean;
99+
modeToastTimer: number | null;
97100
inspectorSwitchRef: HTMLDivElement;
98101
codeInspectorContainerRef: HTMLDivElement;
99102
elementInfoRef: HTMLDivElement;
@@ -133,6 +136,8 @@ export declare class CodeInspectorComponent extends LitElement {
133136
sendXHR: () => void;
134137
sendImg: () => void;
135138
buildTargetUrl: () => string;
139+
toggleMode: () => void;
140+
showModeToastNotification: () => void;
136141
trackCode: () => void;
137142
copyToClipboard(text: string): void;
138143
handleDrag: (e: MouseEvent | TouchEvent) => void;
@@ -142,6 +147,7 @@ export declare class CodeInspectorComponent extends LitElement {
142147
handleContextMenu: (e: MouseEvent) => void;
143148
generateNodeTree: (nodePath: HTMLElement[]) => TreeNode;
144149
handlePointerDown: (e: PointerEvent) => void;
150+
handleKeyDown: (e: KeyboardEvent) => void;
145151
handleKeyUp: (e: KeyboardEvent) => void;
146152
printTip: () => void;
147153
getMousePosition: (e: MouseEvent | TouchEvent) => {

0 commit comments

Comments
 (0)