mock-service-cli 3.5.0 → 3.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/file-explorer.html +165 -11
- package/package.json +1 -1
package/lib/file-explorer.html
CHANGED
|
@@ -434,16 +434,55 @@
|
|
|
434
434
|
}
|
|
435
435
|
|
|
436
436
|
.text-preview {
|
|
437
|
-
background: #
|
|
438
|
-
|
|
437
|
+
background: #1e1e1e;
|
|
438
|
+
color: #d4d4d4;
|
|
439
|
+
padding: 20px;
|
|
439
440
|
border-radius: 8px;
|
|
440
|
-
|
|
441
|
+
max-height: 70vh;
|
|
442
|
+
overflow: auto;
|
|
443
|
+
font-family: 'Fira Code', 'Monaco', 'Consolas', monospace;
|
|
441
444
|
font-size: 13px;
|
|
442
445
|
line-height: 1.6;
|
|
443
446
|
white-space: pre-wrap;
|
|
444
|
-
word-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
+
word-wrap: break-word;
|
|
448
|
+
margin: 0;
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
.preview-container {
|
|
452
|
+
display: flex;
|
|
453
|
+
flex-direction: column;
|
|
454
|
+
height: 100%;
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
.preview-header {
|
|
458
|
+
display: flex;
|
|
459
|
+
justify-content: flex-end;
|
|
460
|
+
margin-bottom: 12px;
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
.preview-header .copy-btn {
|
|
464
|
+
padding: 8px 16px;
|
|
465
|
+
background: linear-gradient(135deg, #8b5cf6, #6366f1);
|
|
466
|
+
color: white;
|
|
467
|
+
border: none;
|
|
468
|
+
border-radius: 6px;
|
|
469
|
+
font-size: 14px;
|
|
470
|
+
cursor: pointer;
|
|
471
|
+
transition: all 0.2s;
|
|
472
|
+
display: flex;
|
|
473
|
+
align-items: center;
|
|
474
|
+
gap: 6px;
|
|
475
|
+
box-shadow: 0 2px 8px rgba(139, 92, 246, 0.3);
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
.preview-header .copy-btn:hover {
|
|
479
|
+
transform: translateY(-1px);
|
|
480
|
+
box-shadow: 0 4px 12px rgba(139, 92, 246, 0.4);
|
|
481
|
+
background: linear-gradient(135deg, #7c3aed, #4f46e5);
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
.preview-header .copy-btn:active {
|
|
485
|
+
transform: translateY(0);
|
|
447
486
|
}
|
|
448
487
|
|
|
449
488
|
.empty-state {
|
|
@@ -548,39 +587,69 @@
|
|
|
548
587
|
let sortBy = 'name';
|
|
549
588
|
let sortAscending = true;
|
|
550
589
|
let showHiddenFiles = true;
|
|
590
|
+
let currentPreviewContent = '';
|
|
551
591
|
|
|
552
592
|
document.addEventListener('DOMContentLoaded', () => {
|
|
553
593
|
loadDirectory('/');
|
|
554
594
|
});
|
|
555
595
|
|
|
556
596
|
async function loadDirectory(path) {
|
|
597
|
+
// console.log('Loading directory:', path);
|
|
557
598
|
const fileGrid = document.getElementById('fileGrid');
|
|
599
|
+
|
|
600
|
+
// 重置所有状态
|
|
601
|
+
currentPath = '/';
|
|
602
|
+
allFiles = [];
|
|
603
|
+
currentFiles = [];
|
|
604
|
+
|
|
605
|
+
// 显示加载状态
|
|
558
606
|
fileGrid.innerHTML = '<div class="loading"><div class="spinner"></div><p>加载中...</p></div>';
|
|
559
607
|
|
|
560
608
|
try {
|
|
561
609
|
const response = await fetch(`/__api/list?path=${encodeURIComponent(path)}`);
|
|
610
|
+
// console.log('Response status:', response.status);
|
|
611
|
+
|
|
562
612
|
const data = await response.json();
|
|
613
|
+
// console.log('API response data:', data);
|
|
563
614
|
|
|
564
615
|
if (data.error) {
|
|
565
616
|
throw new Error(data.error);
|
|
566
617
|
}
|
|
567
618
|
|
|
568
619
|
currentPath = data.currentPath;
|
|
569
|
-
allFiles = data.files;
|
|
620
|
+
allFiles = data.files || [];
|
|
621
|
+
|
|
622
|
+
// console.log('allFiles set to:', allFiles);
|
|
570
623
|
|
|
571
624
|
renderBreadcrumb(data.currentPath, data.parentPath);
|
|
572
|
-
|
|
625
|
+
|
|
626
|
+
// 确保在调用 processAndRenderFiles 之前 allFiles 已经设置好
|
|
627
|
+
setTimeout(() => {
|
|
628
|
+
processAndRenderFiles();
|
|
629
|
+
}, 10);
|
|
630
|
+
|
|
573
631
|
updateBackButton(data.parentPath);
|
|
574
632
|
|
|
575
633
|
// 清空搜索框
|
|
576
|
-
document.getElementById('searchInput')
|
|
634
|
+
if (document.getElementById('searchInput')) {
|
|
635
|
+
document.getElementById('searchInput').value = '';
|
|
636
|
+
}
|
|
577
637
|
searchQuery = '';
|
|
578
638
|
} catch (error) {
|
|
639
|
+
console.error('Error loading directory:', error);
|
|
579
640
|
fileGrid.innerHTML = `<div class="empty-state"><p>错误: ${error.message}</p></div>`;
|
|
580
641
|
}
|
|
581
642
|
}
|
|
582
643
|
|
|
583
644
|
function processAndRenderFiles() {
|
|
645
|
+
// console.log('processAndRenderFiles called, allFiles:', allFiles);
|
|
646
|
+
|
|
647
|
+
if (!allFiles) {
|
|
648
|
+
console.error('allFiles is null or undefined');
|
|
649
|
+
renderFiles([]);
|
|
650
|
+
return;
|
|
651
|
+
}
|
|
652
|
+
|
|
584
653
|
let files = [...allFiles];
|
|
585
654
|
|
|
586
655
|
// 隐藏文件过滤
|
|
@@ -619,6 +688,7 @@
|
|
|
619
688
|
});
|
|
620
689
|
|
|
621
690
|
currentFiles = files;
|
|
691
|
+
// console.log('Rendering', files.length, 'files');
|
|
622
692
|
renderFiles(files);
|
|
623
693
|
}
|
|
624
694
|
|
|
@@ -718,7 +788,14 @@
|
|
|
718
788
|
function renderFiles(files) {
|
|
719
789
|
const fileGrid = document.getElementById('fileGrid');
|
|
720
790
|
|
|
721
|
-
|
|
791
|
+
// 确保视图类名正确
|
|
792
|
+
if (currentView === 'list') {
|
|
793
|
+
fileGrid.classList.add('list-view');
|
|
794
|
+
} else {
|
|
795
|
+
fileGrid.classList.remove('list-view');
|
|
796
|
+
}
|
|
797
|
+
|
|
798
|
+
if (!files || files.length === 0) {
|
|
722
799
|
fileGrid.innerHTML = '<div class="empty-state"><p>该目录为空</p></div>';
|
|
723
800
|
return;
|
|
724
801
|
}
|
|
@@ -777,6 +854,7 @@
|
|
|
777
854
|
}
|
|
778
855
|
});
|
|
779
856
|
|
|
857
|
+
// 强制更新 DOM
|
|
780
858
|
fileGrid.innerHTML = html;
|
|
781
859
|
}
|
|
782
860
|
|
|
@@ -788,6 +866,74 @@
|
|
|
788
866
|
}
|
|
789
867
|
}
|
|
790
868
|
|
|
869
|
+
async function copyText(text) {
|
|
870
|
+
try {
|
|
871
|
+
if (navigator.clipboard && navigator.clipboard.writeText) {
|
|
872
|
+
await navigator.clipboard.writeText(text);
|
|
873
|
+
showToast('已复制到剪贴板');
|
|
874
|
+
} else {
|
|
875
|
+
const textarea = document.createElement('textarea');
|
|
876
|
+
textarea.value = text;
|
|
877
|
+
textarea.style.position = 'fixed';
|
|
878
|
+
textarea.style.top = '-9999px';
|
|
879
|
+
document.body.appendChild(textarea);
|
|
880
|
+
textarea.select();
|
|
881
|
+
document.execCommand('copy');
|
|
882
|
+
document.body.removeChild(textarea);
|
|
883
|
+
showToast('已复制到剪贴板');
|
|
884
|
+
}
|
|
885
|
+
} catch (error) {
|
|
886
|
+
console.error('复制失败:', error);
|
|
887
|
+
showToast('复制失败');
|
|
888
|
+
}
|
|
889
|
+
}
|
|
890
|
+
|
|
891
|
+
function copyPreviewContent() {
|
|
892
|
+
if (currentPreviewContent !== '') {
|
|
893
|
+
copyText(currentPreviewContent);
|
|
894
|
+
}
|
|
895
|
+
}
|
|
896
|
+
|
|
897
|
+
function showToast(message) {
|
|
898
|
+
const toast = document.createElement('div');
|
|
899
|
+
toast.className = 'toast';
|
|
900
|
+
toast.textContent = message;
|
|
901
|
+
toast.style.cssText = `
|
|
902
|
+
position: fixed;
|
|
903
|
+
top: 20px;
|
|
904
|
+
right: 20px;
|
|
905
|
+
background: rgba(139, 92, 246, 0.95);
|
|
906
|
+
color: white;
|
|
907
|
+
padding: 12px 24px;
|
|
908
|
+
border-radius: 8px;
|
|
909
|
+
font-size: 14px;
|
|
910
|
+
z-index: 10000;
|
|
911
|
+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
|
|
912
|
+
animation: fadeInOut 2s ease-in-out;
|
|
913
|
+
`;
|
|
914
|
+
document.body.appendChild(toast);
|
|
915
|
+
|
|
916
|
+
const style = document.createElement('style');
|
|
917
|
+
style.textContent = `
|
|
918
|
+
@keyframes fadeInOut {
|
|
919
|
+
0% { opacity: 0; transform: translateY(-20px); }
|
|
920
|
+
15% { opacity: 1; transform: translateY(0); }
|
|
921
|
+
85% { opacity: 1; transform: translateY(0); }
|
|
922
|
+
100% { opacity: 0; transform: translateY(-20px); }
|
|
923
|
+
}
|
|
924
|
+
`;
|
|
925
|
+
document.head.appendChild(style);
|
|
926
|
+
|
|
927
|
+
setTimeout(() => {
|
|
928
|
+
if (toast.parentNode) {
|
|
929
|
+
document.body.removeChild(toast);
|
|
930
|
+
}
|
|
931
|
+
if (style.parentNode) {
|
|
932
|
+
document.head.removeChild(style);
|
|
933
|
+
}
|
|
934
|
+
}, 2000);
|
|
935
|
+
}
|
|
936
|
+
|
|
791
937
|
async function previewFile(path) {
|
|
792
938
|
const modal = document.getElementById('previewModal');
|
|
793
939
|
const title = document.getElementById('previewTitle');
|
|
@@ -812,7 +958,15 @@
|
|
|
812
958
|
if (contentType && contentType.includes('application/json')) {
|
|
813
959
|
const data = await response.json();
|
|
814
960
|
if (data.type === 'text') {
|
|
815
|
-
|
|
961
|
+
currentPreviewContent = data.content;
|
|
962
|
+
body.innerHTML = `
|
|
963
|
+
<div class="preview-container">
|
|
964
|
+
<div class="preview-header">
|
|
965
|
+
<button class="copy-btn" onclick="copyPreviewContent()">📋 复制全部</button>
|
|
966
|
+
</div>
|
|
967
|
+
<pre class="text-preview">${escapeHtml(data.content)}</pre>
|
|
968
|
+
</div>
|
|
969
|
+
`;
|
|
816
970
|
} else {
|
|
817
971
|
body.innerHTML = `<div class="empty-state"><p>该文件类型暂不支持预览</p><p><a href="/__api/file?path=${encodeURIComponent(
|
|
818
972
|
path
|