zen-gitsync 2.0.5 → 2.0.6

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.
@@ -1,8 +1,8 @@
1
1
  <script setup lang="ts">
2
- import { ref, onMounted, computed } from 'vue'
2
+ import { ref, onMounted, computed, watch } from 'vue'
3
3
  import { ElMessage, ElMessageBox } from 'element-plus'
4
4
  // import { io } from 'socket.io-client'
5
- import { Refresh, ArrowLeft, ArrowRight, Folder, Document, ArrowUp, RefreshRight } from '@element-plus/icons-vue'
5
+ import { Refresh, ArrowLeft, ArrowRight, Folder, Document, ArrowUp, RefreshRight, Check, Close } from '@element-plus/icons-vue'
6
6
  import { useGitLogStore } from '../stores/gitLogStore'
7
7
  import { useGitStore } from '../stores/gitStore'
8
8
 
@@ -303,15 +303,14 @@ function handleFileClick(file: {path: string, type: string}) {
303
303
  getFileDiff(file.path)
304
304
  }
305
305
 
306
- // 文件类型标签显示
307
- function fileTypeLabel(type: string) {
308
- switch (type) {
309
- case 'added': return '新增';
310
- case 'modified': return '修改';
311
- case 'deleted': return '删除';
312
- case 'untracked': return '未跟踪';
313
- default: return '其他';
314
- }
306
+ // 暂存单个文件
307
+ async function stageFile(filePath: string) {
308
+ await gitLogStore.addFileToStage(filePath)
309
+ }
310
+
311
+ // 取消暂存单个文件
312
+ async function unstageFile(filePath: string) {
313
+ await gitLogStore.unstageFile(filePath)
315
314
  }
316
315
 
317
316
  // 刷新Git状态的方法
@@ -349,26 +348,57 @@ async function revertFileChanges(filePath: string) {
349
348
  // 刷新Git状态
350
349
  await loadStatus()
351
350
  } else {
352
- ElMessage.error(result.error || '撤回文件修改失败')
351
+ // 使用自定义错误信息,避免显示undefined
352
+ ElMessage.error(result.error ? `撤回失败: ${result.error}` : '撤回文件修改失败,请重试')
353
353
  }
354
354
  } catch (error) {
355
- // 用户取消或发生错误
356
- if ((error as Error).message !== 'cancel') {
357
- ElMessage.error(`撤回文件修改失败: ${(error as Error).message}`)
355
+ // 用户取消操作不显示错误
356
+ if ((error as any) === 'cancel' || (error as Error).message === 'cancel') {
357
+ // 用户取消操作,不做任何处理,也不显示错误
358
+ return
359
+ }
360
+
361
+ // 其他错误情况才显示错误消息
362
+ // 避免显示undefined错误信息
363
+ const errorMessage = (error as Error).message || '未知错误';
364
+ if (errorMessage !== 'undefined') {
365
+ ElMessage.error(`撤回文件修改失败: ${errorMessage}`)
366
+ } else {
367
+ ElMessage.error('撤回文件修改失败,请重试')
358
368
  }
359
369
  }
360
370
  }
361
371
 
372
+ // 提取文件名和目录
373
+ function getFileName(path: string): string {
374
+ const parts = path.split('/')
375
+ return parts[parts.length - 1]
376
+ }
377
+
378
+ function getFileDirectory(path: string): string {
379
+ const parts = path.split('/')
380
+ if (parts.length <= 1) return ''
381
+
382
+ // 保留所有除最后一个部分的路径
383
+ return parts.slice(0, -1).join('/')
384
+ }
385
+
362
386
  onMounted(() => {
363
387
  // App.vue已经加载了Git相关数据,此时只需加载状态
364
388
  // 如果已有初始目录,则只需加载状态
365
389
  loadStatus()
366
390
  })
367
391
 
392
+ // 监听autoUpdateEnabled的变化,手动调用toggleAutoUpdate
393
+ watch(() => gitLogStore.autoUpdateEnabled, (newValue, oldValue) => {
394
+ console.log(`自动更新状态变更: ${oldValue} -> ${newValue}`)
395
+ // 调用store中的方法来实现服务器通信功能
396
+ gitLogStore.toggleAutoUpdate()
397
+ }, { immediate: false })
398
+
368
399
  // onUnmounted(() => {
369
400
  // socket.disconnect()
370
401
  // })
371
-
372
402
  // 暴露刷新方法给父组件
373
403
  defineExpose({
374
404
  refreshStatus
@@ -377,49 +407,165 @@ defineExpose({
377
407
 
378
408
  <template>
379
409
  <div class="card">
380
- <div class="current-directory">
381
- <el-icon><Folder /></el-icon>
382
- <span>{{ currentDirectory }}</span>
383
- <el-button type="primary" size="small" @click="openDirectoryDialog" plain>
384
- 切换目录
385
- </el-button>
386
- </div>
387
410
  <div class="status-header">
388
- <h2>Git 状态(git status)</h2>
389
- <el-button
390
- type="primary"
391
- :icon="Refresh"
392
- circle
393
- size="small"
394
- @click="refreshStatus"
395
- :loading="isRefreshing"
396
- />
397
- </div>
398
- <div class="status-box">
399
- {{ !gitStore.isGitRepo ? '当前目录不是一个Git仓库' : gitLogStore.statusText || '加载中...' }}
411
+ <h2>Git 状态</h2>
412
+ <div class="header-actions">
413
+ <el-tooltip
414
+ :content="gitLogStore.autoUpdateEnabled ? '禁用自动更新文件状态' : '启用自动更新文件状态'"
415
+ placement="top"
416
+ :hide-after="1000"
417
+ >
418
+ <el-switch
419
+ v-model="gitLogStore.autoUpdateEnabled"
420
+ style="--el-switch-on-color: #67C23A; --el-switch-off-color: #909399; margin-right: 10px;"
421
+ inline-prompt
422
+ :active-icon="Check"
423
+ :inactive-icon="Close"
424
+ class="auto-update-switch"
425
+ />
426
+ </el-tooltip>
427
+ <el-tooltip content="刷新状态" placement="top" :hide-after="1000">
428
+ <el-button
429
+ type="primary"
430
+ :icon="Refresh"
431
+ circle
432
+ size="small"
433
+ @click="refreshStatus"
434
+ :loading="isRefreshing"
435
+ />
436
+ </el-tooltip>
437
+ </div>
400
438
  </div>
401
- <!-- 颜色区分不同类型文件 -->
402
- <div v-if="gitLogStore.fileList.length" class="file-list">
403
- <div
404
- v-for="file in gitLogStore.fileList"
405
- :key="file.path"
406
- :class="['file-item', file.type]"
407
- >
408
- <div class="file-info" @click="handleFileClick(file)">
409
- <span class="file-type">{{ fileTypeLabel(file.type) }}</span>
410
- <span class="file-path">{{ file.path }}</span>
439
+
440
+ <div class="card-content">
441
+ <div class="current-directory">
442
+ <el-icon><Folder /></el-icon>
443
+ <span>{{ currentDirectory }}</span>
444
+ <el-button type="primary" size="small" @click="openDirectoryDialog" plain>
445
+ 切换目录
446
+ </el-button>
447
+ </div>
448
+
449
+ <div v-if="!gitStore.isGitRepo" class="status-box">
450
+ 当前目录不是一个Git仓库
451
+ </div>
452
+
453
+ <!-- 现代化、简洁的文件列表 -->
454
+ <div v-if="gitLogStore.fileList.length" class="file-list-container">
455
+ <!-- 分组显示文件 -->
456
+ <div v-if="gitLogStore.fileList.some(f => f.type === 'added')" class="file-group">
457
+ <div class="file-group-header">已暂存的更改</div>
458
+ <div class="file-list">
459
+ <div
460
+ v-for="file in gitLogStore.fileList.filter(f => f.type === 'added')"
461
+ :key="file.path"
462
+ class="file-item"
463
+ @click="handleFileClick(file)"
464
+ >
465
+ <div class="file-info">
466
+ <div class="file-path-container">
467
+ <span class="file-name">{{ getFileName(file.path) }}</span>
468
+ <span class="file-directory">{{ getFileDirectory(file.path) }}</span>
469
+ </div>
470
+ </div>
471
+ <div class="file-actions">
472
+ <el-tooltip content="取消暂存" placement="top" :hide-after="1000">
473
+ <el-button
474
+ type="warning"
475
+ size="small"
476
+ circle
477
+ @click.stop="unstageFile(file.path)"
478
+ >-</el-button>
479
+ </el-tooltip>
480
+ </div>
481
+ </div>
482
+ </div>
483
+ </div>
484
+
485
+ <div v-if="gitLogStore.fileList.some(f => f.type === 'modified' || f.type === 'deleted')" class="file-group">
486
+ <div class="file-group-header">未暂存的更改</div>
487
+ <div class="file-list">
488
+ <div
489
+ v-for="file in gitLogStore.fileList.filter(f => f.type === 'modified' || f.type === 'deleted')"
490
+ :key="file.path"
491
+ class="file-item"
492
+ @click="handleFileClick(file)"
493
+ >
494
+ <div class="file-info">
495
+ <div class="file-status-indicator" :class="file.type"></div>
496
+ <div class="file-path-container">
497
+ <span class="file-name">{{ getFileName(file.path) }}</span>
498
+ <span class="file-directory">{{ getFileDirectory(file.path) }}</span>
499
+ </div>
500
+ </div>
501
+ <div class="file-actions">
502
+ <el-tooltip content="添加到暂存区" placement="top" :hide-after="1000">
503
+ <el-button
504
+ type="success"
505
+ size="small"
506
+ circle
507
+ @click.stop="stageFile(file.path)"
508
+ >+</el-button>
509
+ </el-tooltip>
510
+ <el-tooltip content="撤回修改" placement="top" :hide-after="1000">
511
+ <el-button
512
+ type="danger"
513
+ size="small"
514
+ :icon="RefreshRight"
515
+ circle
516
+ @click.stop="revertFileChanges(file.path)"
517
+ />
518
+ </el-tooltip>
519
+ </div>
520
+ </div>
521
+ </div>
522
+ </div>
523
+
524
+ <div v-if="gitLogStore.fileList.some(f => f.type === 'untracked')" class="file-group">
525
+ <div class="file-group-header">未跟踪的文件</div>
526
+ <div class="file-list">
527
+ <div
528
+ v-for="file in gitLogStore.fileList.filter(f => f.type === 'untracked')"
529
+ :key="file.path"
530
+ class="file-item"
531
+ @click="handleFileClick(file)"
532
+ >
533
+ <div class="file-info">
534
+ <div class="file-status-indicator untracked"></div>
535
+ <div class="file-path-container">
536
+ <span class="file-name">{{ getFileName(file.path) }}</span>
537
+ <span class="file-directory">{{ getFileDirectory(file.path) }}</span>
538
+ </div>
539
+ </div>
540
+ <div class="file-actions">
541
+ <el-tooltip content="添加到暂存区" placement="top" :hide-after="1000">
542
+ <el-button
543
+ type="success"
544
+ size="small"
545
+ circle
546
+ @click.stop="stageFile(file.path)"
547
+ >+</el-button>
548
+ </el-tooltip>
549
+ <el-tooltip content="删除文件" placement="top" :hide-after="1000">
550
+ <el-button
551
+ type="danger"
552
+ size="small"
553
+ :icon="Close"
554
+ circle
555
+ @click.stop="revertFileChanges(file.path)"
556
+ />
557
+ </el-tooltip>
558
+ </div>
559
+ </div>
560
+ </div>
411
561
  </div>
412
- <div class="file-actions">
413
- <el-tooltip content="撤回修改" placement="top" :hide-after="1000">
414
- <el-button
415
- type="danger"
416
- size="small"
417
- :icon="RefreshRight"
418
- circle
419
- @click.stop="revertFileChanges(file.path)"
420
- />
421
- </el-tooltip>
562
+ </div>
563
+
564
+ <div v-else-if="gitStore.isGitRepo" class="empty-status">
565
+ <div class="empty-icon">
566
+ <el-icon><Document /></el-icon>
422
567
  </div>
568
+ <div class="empty-text">没有检测到任何更改</div>
423
569
  </div>
424
570
  </div>
425
571
 
@@ -505,6 +651,7 @@ defineExpose({
505
651
  :title="`文件差异: ${selectedFile}`"
506
652
  width="80%"
507
653
  destroy-on-close
654
+ class="diff-dialog"
508
655
  >
509
656
  <div v-loading="isLoadingDiff" class="diff-content">
510
657
  <div v-if="diffContent" v-html="formatDiff(diffContent)" class="diff-formatted"></div>
@@ -535,226 +682,418 @@ defineExpose({
535
682
  .card {
536
683
  background-color: #fff;
537
684
  border-radius: 8px;
538
- box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
539
- padding: 20px;
540
- margin-bottom: 20px;
685
+ box-shadow: 0 2px 10px rgba(0, 0, 0, 0.03);
686
+ border: 1px solid rgba(0, 0, 0, 0.03);
687
+ height: 100%;
688
+ width: 100%;
689
+ display: flex;
690
+ flex-direction: column;
691
+ overflow: hidden;
541
692
  }
542
693
 
543
694
  .status-header {
544
695
  display: flex;
545
696
  justify-content: space-between;
546
697
  align-items: center;
547
- margin-bottom: 10px;
698
+ padding: 8px 16px;
699
+ border-bottom: 1px solid #f0f0f0;
700
+ height: 36px;
548
701
  }
549
702
 
550
703
  .status-header h2 {
551
704
  margin: 0;
705
+ font-size: 16px;
706
+ font-weight: 500;
707
+ color: #303133;
708
+ }
709
+
710
+ .header-actions {
711
+ display: flex;
712
+ align-items: center;
713
+ }
714
+
715
+ .card-content {
716
+ padding: 15px;
717
+ overflow-y: auto;
718
+ flex: 1;
719
+ display: flex;
720
+ flex-direction: column;
721
+ }
722
+
723
+ .current-directory {
724
+ display: flex;
725
+ align-items: center;
726
+ margin-bottom: 16px;
727
+ padding: 10px;
728
+ background-color: #f8f9fa;
729
+ border-radius: 6px;
730
+ font-family: monospace;
731
+ border: 1px solid #f0f0f0;
732
+ }
733
+
734
+ .current-directory .el-icon {
735
+ margin-right: 8px;
736
+ color: #409eff;
737
+ }
738
+
739
+ .current-directory span {
740
+ flex-grow: 1;
741
+ word-break: break-all;
742
+ margin-right: 10px;
552
743
  }
553
744
 
554
745
  .status-box {
555
746
  white-space: pre-wrap;
556
747
  font-family: monospace;
557
- background-color: #f5f7fa;
558
- padding: 15px;
559
- border-radius: 4px;
560
- margin-bottom: 15px;
561
- max-height: 300px;
748
+ background-color: #f8f9fa;
749
+ padding: 16px;
750
+ border-radius: 6px;
751
+ margin-bottom: 20px;
752
+ max-height: 200px;
562
753
  overflow-y: auto;
754
+ border: 1px solid #f0f0f0;
755
+ font-size: 14px;
756
+ line-height: 1.5;
757
+ }
758
+
759
+ /* 现代化的文件列表容器 */
760
+ .file-list-container {
761
+ flex: 1;
762
+ overflow: hidden;
763
+ display: flex;
764
+ flex-direction: column;
765
+ margin-bottom: 0;
766
+ gap: 12px;
767
+ height: calc(100% - 70px); /* 给底部留出些空间 */
768
+ }
769
+
770
+ .file-group {
771
+ background-color: #f8f9fa;
772
+ border-radius: 6px;
773
+ overflow: hidden;
774
+ border: 1px solid #ebeef5;
775
+ margin-bottom: 12px;
776
+ display: flex;
777
+ flex-direction: column;
778
+ }
779
+
780
+ /* 让每个文件组根据内容自动增长 */
781
+ .file-group {
782
+ flex: 0 1 auto; /* 不主动增长,但允许缩小,基于内容大小 */
783
+ }
784
+
785
+ /* 最后一个分组可以吸收剩余空间 */
786
+ .file-group:last-child {
787
+ margin-bottom: 0;
788
+ flex: 1 1 auto; /* 可以增长占用剩余空间 */
789
+ }
790
+
791
+ .file-group-header {
792
+ font-size: 14px;
793
+ font-weight: bold;
794
+ padding: 8px 12px;
795
+ background-color: #f0f2f5;
796
+ color: #606266;
797
+ border-bottom: 1px solid #ebeef5;
798
+ flex-shrink: 0; /* 防止header被压缩 */
563
799
  }
564
800
 
565
801
  .file-list {
566
- max-height: 300px;
567
802
  overflow-y: auto;
803
+ min-height: 40px; /* 最小高度 */
804
+ flex-grow: 1; /* 允许文件列表在文件组内扩展 */
805
+ padding: 0;
806
+ margin: 0;
807
+ scrollbar-width: thin; /* Firefox */
808
+ scrollbar-color: rgba(144, 147, 153, 0.3) transparent; /* Firefox */
809
+ }
810
+
811
+ /* Webkit浏览器的滚动条样式 */
812
+ .file-list::-webkit-scrollbar {
813
+ width: 6px;
814
+ height: 6px;
815
+ }
816
+
817
+ .file-list::-webkit-scrollbar-thumb {
818
+ background-color: rgba(144, 147, 153, 0.3);
819
+ border-radius: 4px;
820
+ }
821
+
822
+ .file-list::-webkit-scrollbar-thumb:hover {
823
+ background-color: rgba(144, 147, 153, 0.5);
824
+ }
825
+
826
+ .file-list::-webkit-scrollbar-track {
827
+ background-color: transparent;
828
+ }
829
+
830
+ /* 让每个文件列表自适应高度,使其在容器中更好地分配空间 */
831
+ .file-list:empty {
832
+ display: none; /* 如果列表为空,不显示 */
833
+ }
834
+
835
+ /* 当没有足够的项目填充列表时,禁用滚动 */
836
+ .file-list:has(.empty-file-group) {
837
+ overflow-y: hidden;
838
+ }
839
+
840
+ /* 替换为更兼容的选择器 */
841
+ /* 改用直接为empty-file-group父容器添加样式 */
842
+ .empty-file-container {
843
+ overflow-y: hidden !important; /* 强制禁用滚动 */
844
+ display: flex;
845
+ flex-direction: column;
846
+ align-items: stretch;
847
+ flex: 1;
848
+ }
849
+
850
+ .empty-file-group {
851
+ padding: 16px;
852
+ text-align: center;
853
+ color: #909399;
854
+ font-size: 13px;
855
+ font-style: italic;
856
+ display: flex;
857
+ align-items: center;
858
+ justify-content: center;
859
+ min-height: 50px; /* 增加最小高度 */
860
+ background-color: #f8f9fa;
861
+ border-radius: 4px;
862
+ margin: 8px;
863
+ }
864
+
865
+ /* 自定义每个分组的展开逻辑 */
866
+ /* 已暂存文件分组 - 保持小巧 */
867
+ .file-group:nth-child(1) {
868
+ flex: 0 1 auto;
869
+ }
870
+
871
+ /* 未暂存更改分组 - 稍微大一些 */
872
+ .file-group:nth-child(2) {
873
+ flex: 0 1 auto;
874
+ }
875
+
876
+ /* 未跟踪文件分组 - 可以占据剩余空间 */
877
+ .file-group:nth-child(3) {
878
+ flex: 1 1 auto;
568
879
  }
569
880
 
570
881
  .file-item {
571
882
  padding: 8px 12px;
572
- margin-bottom: 5px;
573
- border-radius: 4px;
574
- cursor: pointer;
575
883
  display: flex;
576
884
  align-items: center;
577
885
  justify-content: space-between;
886
+ border-bottom: 1px solid #ebeef5;
887
+ cursor: pointer;
888
+ transition: background-color 0.2s;
889
+ }
890
+
891
+ .file-item:last-child {
892
+ border-bottom: none;
578
893
  }
579
894
 
580
895
  .file-item:hover {
581
- background-color: #f5f7fa;
896
+ background-color: #ecf5ff;
582
897
  }
583
898
 
584
899
  .file-info {
585
900
  display: flex;
586
901
  align-items: center;
587
902
  flex-grow: 1;
903
+ overflow: hidden;
904
+ white-space: nowrap;
905
+ gap: 8px;
588
906
  }
589
907
 
590
- .file-actions {
591
- margin-left: 10px;
592
- opacity: 0.5;
593
- transition: opacity 0.2s;
908
+ .file-status-indicator {
909
+ width: 6px;
910
+ height: 6px;
911
+ border-radius: 50%;
912
+ background-color: #409eff;
913
+ flex-shrink: 0;
594
914
  }
595
915
 
596
- .file-item:hover .file-actions {
597
- opacity: 1;
916
+ .file-status-indicator.added {
917
+ background-color: #67c23a;
598
918
  }
599
919
 
600
- .file-type {
601
- font-size: 12px;
602
- padding: 2px 6px;
603
- border-radius: 10px;
604
- margin-right: 10px;
605
- flex-shrink: 0;
920
+ .file-status-indicator.modified {
921
+ background-color: #409eff;
606
922
  }
607
923
 
608
- .added .file-type {
609
- background-color: #e1f3d8;
610
- color: #67c23a;
924
+ .file-status-indicator.deleted {
925
+ background-color: #f56c6c;
611
926
  }
612
927
 
613
- .modified .file-type {
614
- background-color: #e6f1fc;
615
- color: #409eff;
928
+ .file-status-indicator.untracked {
929
+ background-color: #e6a23c;
616
930
  }
617
931
 
618
- .deleted .file-type {
619
- background-color: #fef0f0;
620
- color: #f56c6c;
932
+ .file-path-container {
933
+ display: flex;
934
+ flex-direction: column;
935
+ overflow: hidden;
621
936
  }
622
937
 
623
- .untracked .file-type {
624
- background-color: #fdf6ec;
625
- color: #e6a23c;
938
+ .file-name {
939
+ font-weight: 500;
940
+ color: #303133;
941
+ overflow: hidden;
942
+ text-overflow: ellipsis;
943
+ line-height: 1.2;
626
944
  }
627
945
 
628
- .file-path {
629
- font-family: monospace;
630
- word-break: break-all;
946
+ .file-directory {
947
+ font-size: 12px;
948
+ color: #909399;
949
+ overflow: hidden;
950
+ text-overflow: ellipsis;
951
+ line-height: 1.2;
631
952
  }
632
953
 
633
- .diff-content {
634
- font-family: monospace;
635
- white-space: pre-wrap;
636
- max-height: 60vh;
637
- overflow-y: auto;
638
- padding: 10px;
639
- background-color: #f5f7fa;
640
- border-radius: 4px;
954
+ .file-actions {
955
+ display: flex;
956
+ gap: 5px;
957
+ opacity: 0;
958
+ transition: opacity 0.2s;
641
959
  }
642
960
 
643
- .diff-formatted {
644
- font-size: 14px;
645
- line-height: 1.5;
961
+ .file-item:hover .file-actions {
962
+ opacity: 1;
646
963
  }
647
964
 
648
- .file-navigation {
965
+ .empty-status {
649
966
  display: flex;
650
- justify-content: center;
967
+ flex-direction: column;
651
968
  align-items: center;
969
+ justify-content: center;
970
+ height: calc(100% - 70px);
971
+ background-color: #f8f9fa;
972
+ border-radius: 6px;
973
+ border: 1px solid #ebeef5;
652
974
  margin-top: 15px;
653
975
  }
654
976
 
655
- .file-counter {
656
- margin: 0 15px;
977
+ .empty-icon {
978
+ font-size: 32px;
979
+ color: #c0c4cc;
980
+ margin-bottom: 10px;
981
+ }
982
+
983
+ .empty-text {
984
+ color: #909399;
657
985
  font-size: 14px;
658
- color: #606266;
659
986
  }
660
987
 
661
- .current-directory {
988
+ /* 添加针对空内容区域的样式 */
989
+ .card-content:empty {
662
990
  display: flex;
663
991
  align-items: center;
664
- margin-bottom: 15px;
665
- padding: 8px 12px;
666
- background-color: #f5f7fa;
667
- border-radius: 4px;
668
- font-family: monospace;
669
- }
670
-
671
- .current-directory .el-icon {
672
- margin-right: 8px;
673
- color: #409eff;
992
+ justify-content: center;
993
+ background-color: #f8f9fa;
994
+ border-radius: 6px;
995
+ border: 1px dashed #dcdfe6;
996
+ color: #909399;
997
+ height: 100%;
674
998
  }
675
999
 
676
- .current-directory span {
677
- flex-grow: 1;
678
- word-break: break-all;
679
- margin-right: 10px;
1000
+ .card-content:empty::after {
1001
+ content: '没有Git状态信息可显示';
1002
+ font-size: 14px;
680
1003
  }
681
1004
 
1005
+ /* 添加目录浏览相关样式 */
682
1006
  .browser-current-path {
683
- margin-bottom: 10px;
684
- font-size: 14px;
685
- color: #606266;
686
- background-color: #f5f7fa;
687
- padding: 8px 12px;
688
- border-radius: 4px;
689
1007
  font-family: monospace;
690
- word-break: break-all;
1008
+ margin-bottom: 15px;
1009
+ padding: 10px;
1010
+ background-color: #f5f7fa;
1011
+ border-radius: 6px;
1012
+ overflow-x: auto;
1013
+ white-space: nowrap;
1014
+ border: 1px solid #ebeef5;
691
1015
  }
692
1016
 
693
1017
  .browser-error {
694
- margin-bottom: 10px;
695
1018
  color: #f56c6c;
696
- padding: 8px 12px;
1019
+ margin: 10px 0;
1020
+ padding: 10px;
697
1021
  background-color: #fef0f0;
698
1022
  border-radius: 4px;
1023
+ border-left: 3px solid #f56c6c;
699
1024
  }
700
1025
 
701
- .directory-browser {
702
- padding: 10px;
703
- height: 400px;
1026
+ .browser-nav {
704
1027
  display: flex;
705
- flex-direction: column;
1028
+ gap: 10px;
1029
+ margin-bottom: 10px;
706
1030
  }
707
1031
 
708
- .browser-nav {
709
- margin-bottom: 10px;
1032
+ .no-padding-left {
1033
+ padding-left: 12px;
1034
+ }
1035
+
1036
+ .directory-browser {
1037
+ height: 400px;
1038
+ border: 1px solid #ebeef5;
1039
+ border-radius: 6px;
1040
+ overflow: hidden;
710
1041
  display: flex;
711
- justify-content: space-between;
712
- position: sticky;
713
- top: 0;
714
- background-color: #fff;
715
- z-index: 1;
716
- padding: 10px 0;
1042
+ flex-direction: column;
717
1043
  }
718
1044
 
719
1045
  .directory-items-container {
720
1046
  flex: 1;
721
1047
  overflow-y: auto;
1048
+ background-color: #f8f9fa;
1049
+ padding: 10px;
722
1050
  }
723
1051
 
724
1052
  .directory-items {
725
1053
  list-style: none;
726
1054
  padding: 0;
727
1055
  margin: 0;
1056
+ display: grid;
1057
+ grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
1058
+ gap: 10px;
728
1059
  }
729
1060
 
730
1061
  .directory-item {
731
- padding: 8px 12px;
732
- margin-bottom: 5px;
733
- border-radius: 4px;
734
- cursor: pointer;
735
1062
  display: flex;
736
1063
  align-items: center;
1064
+ padding: 8px;
1065
+ cursor: pointer;
1066
+ border-radius: 4px;
1067
+ background-color: white;
1068
+ border: 1px solid #ebeef5;
1069
+ transition: all 0.2s;
1070
+ overflow: hidden;
1071
+ white-space: nowrap;
1072
+ text-overflow: ellipsis;
1073
+ gap: 5px;
737
1074
  }
738
1075
 
739
1076
  .directory-item:hover {
740
- background-color: #f5f7fa;
1077
+ background-color: #ecf5ff;
1078
+ border-color: #c6e2ff;
741
1079
  }
742
1080
 
743
1081
  .directory-item.directory {
1082
+ background-color: #f0f7ff;
744
1083
  color: #409eff;
745
1084
  }
746
1085
 
747
- .directory-item.file {
748
- color: #606266;
1086
+ .directory-item .el-icon {
1087
+ margin-right: 5px;
1088
+ flex-shrink: 0;
749
1089
  }
750
1090
 
751
- .directory-item .el-icon {
752
- margin-right: 10px;
1091
+ .directory-item.directory .el-icon {
1092
+ color: #409eff;
753
1093
  }
754
1094
 
755
- .directory-item span {
756
- font-family: monospace;
757
- word-break: break-all;
1095
+ .directory-item.file .el-icon {
1096
+ color: #909399;
758
1097
  }
759
1098
 
760
1099
  .directory-buttons {
@@ -762,41 +1101,87 @@ defineExpose({
762
1101
  gap: 10px;
763
1102
  margin-top: 10px;
764
1103
  }
765
-
766
- /* 移除按钮左侧的内边距 */
767
- .no-padding-left {
768
- padding-left: 8px !important;
769
- }
770
1104
  </style>
771
1105
 
772
- <!-- 添加非scoped样式,使diff格式化样式对动态内容生效 -->
1106
+ <!-- scoped样式,使diff格式化样式对动态内容生效 -->
773
1107
  <style>
774
1108
  .diff-header {
775
1109
  font-weight: bold;
776
1110
  background-color: #e6f1fc;
777
- padding: 3px;
778
- margin: 5px 0;
1111
+ padding: 5px;
1112
+ margin: 8px 0;
1113
+ border-radius: 4px;
1114
+ color: #0366d6;
1115
+ border-bottom: 1px solid #c8e1ff;
779
1116
  }
780
1117
 
781
1118
  .diff-old-file, .diff-new-file {
782
- color: #888;
1119
+ color: #586069;
1120
+ padding: 2px 5px;
1121
+ font-family: monospace;
1122
+ }
1123
+
1124
+ .diff-old-file {
1125
+ color: #cb2431;
1126
+ }
1127
+
1128
+ .diff-new-file {
1129
+ color: #22863a;
783
1130
  }
784
1131
 
785
1132
  .diff-hunk-header {
786
1133
  color: #6f42c1;
1134
+ background-color: #f1f8ff;
1135
+ padding: 2px 5px;
1136
+ margin: 5px 0;
1137
+ border-radius: 3px;
1138
+ font-family: monospace;
787
1139
  }
788
1140
 
789
1141
  .diff-added {
790
1142
  background-color: #e6ffed;
791
- color: #28a745;
1143
+ color: #22863a;
1144
+ padding: 0 5px;
1145
+ border-left: 4px solid #22863a;
1146
+ font-family: monospace;
1147
+ display: block;
1148
+ margin: 2px 0;
792
1149
  }
793
1150
 
794
1151
  .diff-removed {
795
1152
  background-color: #ffeef0;
796
- color: #d73a49;
1153
+ color: #cb2431;
1154
+ padding: 0 5px;
1155
+ border-left: 4px solid #cb2431;
1156
+ font-family: monospace;
1157
+ display: block;
1158
+ margin: 2px 0;
797
1159
  }
798
1160
 
799
1161
  .diff-context {
800
1162
  color: #444;
1163
+ padding: 0 5px;
1164
+ font-family: monospace;
1165
+ display: block;
1166
+ margin: 2px 0;
1167
+ background-color: #fafbfc;
1168
+ }
1169
+
1170
+ /* 增加自动更新开关的样式 */
1171
+ .auto-update-switch .el-switch__core {
1172
+ transition: all 0.3s ease-in-out;
1173
+ box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
1174
+ }
1175
+
1176
+ .auto-update-switch .el-switch__core:hover {
1177
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
1178
+ }
1179
+
1180
+ .auto-update-switch.is-checked .el-switch__core {
1181
+ box-shadow: 0 2px 5px rgba(103, 194, 58, 0.3);
1182
+ }
1183
+
1184
+ .auto-update-switch.is-checked .el-switch__core:hover {
1185
+ box-shadow: 0 2px 8px rgba(103, 194, 58, 0.5);
801
1186
  }
802
1187
  </style>