@yesdgq/claude-buddy 1.1.1018 → 1.1.2000
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/assets/config.html +55 -32
- package/assets/config.js +203 -14
- package/assets/libs/style.css +155 -12
- package/dist/index.js +1 -1
- package/package.json +1 -1
package/assets/config.html
CHANGED
|
@@ -147,16 +147,18 @@
|
|
|
147
147
|
|
|
148
148
|
|
|
149
149
|
<!-- AUTH 配置列表 -->
|
|
150
|
-
<div v-if="!loading">
|
|
151
|
-
<div v-for="(auth, index) in config.AUTH" :key="index"
|
|
152
|
-
:class="['auth-card', { 'auth-card-current': index === config.activeIndex, 'auth-card-dragging': draggingIndex === index, 'auth-card-drag-over': dragOverIndex === index }]"
|
|
153
|
-
|
|
154
|
-
@
|
|
155
|
-
@
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
@
|
|
150
|
+
<div v-if="!loading" :class="{ 'auth-list-ready': authListReady }">
|
|
151
|
+
<div v-for="(auth, index) in config.AUTH" :key="authKeys[index] || index"
|
|
152
|
+
:class="['auth-card', getDragShiftClass(index), { 'auth-card-current': index === config.activeIndex, 'auth-card-dragging': draggingIndex === index, 'auth-card-drag-over': dragOverIndex === index }]"
|
|
153
|
+
:style="getDragShiftStyle(index)"
|
|
154
|
+
@dragover="handleDragOver(index, $event)"
|
|
155
|
+
@dragleave="handleDragLeave($event)"
|
|
156
|
+
@drop="handleDrop(index, $event)">
|
|
157
|
+
<div class="drag-handle"
|
|
158
|
+
draggable="true"
|
|
159
|
+
@dragstart="handleDragStart(index, $event)"
|
|
160
|
+
@drag="handleDrag($event)"
|
|
161
|
+
@dragend="handleDragEnd($event)">
|
|
160
162
|
<i class="fa fa-ellipsis-v"></i>
|
|
161
163
|
</div>
|
|
162
164
|
<div class="auth-header">
|
|
@@ -240,11 +242,32 @@
|
|
|
240
242
|
</button>
|
|
241
243
|
</div>
|
|
242
244
|
</div>
|
|
243
|
-
</div>
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
245
|
+
</div>
|
|
246
|
+
|
|
247
|
+
<div v-if="currentCli === 'Codex'" class="codex-env-section">
|
|
248
|
+
<div class="default-model-header">
|
|
249
|
+
<label>
|
|
250
|
+
<i class="fa fa-cubes"></i>
|
|
251
|
+
{{ t.envVariables }}
|
|
252
|
+
</label>
|
|
253
|
+
</div>
|
|
254
|
+
<div class="default-model-row">
|
|
255
|
+
<label class="default-model-inline-label">
|
|
256
|
+
{{ t.defaultModelTitle }}
|
|
257
|
+
</label>
|
|
258
|
+
<div class="default-model-input-wrap">
|
|
259
|
+
<input
|
|
260
|
+
v-model="auth.DEFAULT_MODEL"
|
|
261
|
+
type="text"
|
|
262
|
+
:placeholder="t.defaultModelPlaceholder"
|
|
263
|
+
>
|
|
264
|
+
</div>
|
|
265
|
+
</div>
|
|
266
|
+
</div>
|
|
267
|
+
|
|
268
|
+
<!-- 模型管理 -->
|
|
269
|
+
<div v-if="currentCli !== 'Codex'" class="models-section" :class="{ 'is-expanded': showModelSections[index] }">
|
|
270
|
+
<div class="models-header">
|
|
248
271
|
<label>
|
|
249
272
|
<i class="fa fa-cogs"></i>
|
|
250
273
|
{{ t.modelManagement }}
|
|
@@ -290,7 +313,7 @@
|
|
|
290
313
|
</div>
|
|
291
314
|
|
|
292
315
|
<!-- 环境变量配置 -->
|
|
293
|
-
<div class="env-section" :class="{ 'is-expanded': showEnvSections[index] }">
|
|
316
|
+
<div v-if="currentCli !== 'Codex'" class="env-section" :class="{ 'is-expanded': showEnvSections[index] }">
|
|
294
317
|
<div class="env-header">
|
|
295
318
|
<label>
|
|
296
319
|
<i class="fa fa-cogs"></i>
|
|
@@ -338,17 +361,8 @@
|
|
|
338
361
|
</div>
|
|
339
362
|
</div>
|
|
340
363
|
|
|
341
|
-
<!--
|
|
342
|
-
<
|
|
343
|
-
@click="addAuth"
|
|
344
|
-
class="btn btn-primary"
|
|
345
|
-
>
|
|
346
|
-
<i class="fa fa-plus-circle"></i>
|
|
347
|
-
{{ t.addNewConfig }}
|
|
348
|
-
</button>
|
|
349
|
-
|
|
350
|
-
<!-- 保存按钮 -->
|
|
351
|
-
<div class="btn-group">
|
|
364
|
+
<!-- 保存按钮 -->
|
|
365
|
+
<div class="btn-group">
|
|
352
366
|
<button
|
|
353
367
|
@click="saveConfig"
|
|
354
368
|
:disabled="saving"
|
|
@@ -369,11 +383,20 @@
|
|
|
369
383
|
</div>
|
|
370
384
|
</div>
|
|
371
385
|
|
|
372
|
-
<!-- Toast 容器 -->
|
|
373
|
-
<div id="toast-container"></div>
|
|
374
|
-
|
|
375
|
-
<!--
|
|
376
|
-
<button
|
|
386
|
+
<!-- Toast 容器 -->
|
|
387
|
+
<div id="toast-container"></div>
|
|
388
|
+
|
|
389
|
+
<!-- 右下角悬浮添加配置按钮 -->
|
|
390
|
+
<button
|
|
391
|
+
@click="addAuth"
|
|
392
|
+
class="fab-add"
|
|
393
|
+
:title="t.addNewConfig"
|
|
394
|
+
>
|
|
395
|
+
<i class="fa fa-plus"></i>
|
|
396
|
+
</button>
|
|
397
|
+
|
|
398
|
+
<!-- 右下角悬浮保存按钮 -->
|
|
399
|
+
<button
|
|
377
400
|
@click="saveConfig"
|
|
378
401
|
:disabled="saving"
|
|
379
402
|
class="fab-save"
|
package/assets/config.js
CHANGED
|
@@ -11,6 +11,8 @@ createApp({
|
|
|
11
11
|
showTokens: [],
|
|
12
12
|
showEnvSections: [],
|
|
13
13
|
showModelSections: [],
|
|
14
|
+
authKeys: [],
|
|
15
|
+
authListReady: false,
|
|
14
16
|
configPath: '',
|
|
15
17
|
showHelp: false,
|
|
16
18
|
currentCli: 'Claude',
|
|
@@ -44,6 +46,13 @@ createApp({
|
|
|
44
46
|
// 拖拽相关状态
|
|
45
47
|
draggingIndex: null,
|
|
46
48
|
dragOverIndex: null,
|
|
49
|
+
dropTargetIndex: null,
|
|
50
|
+
draggedCardHeight: 0,
|
|
51
|
+
draggedCardVisualHeight: 0,
|
|
52
|
+
dragCardRects: [],
|
|
53
|
+
dragStartY: 0,
|
|
54
|
+
dragCurrentY: 0,
|
|
55
|
+
isDropping: false,
|
|
47
56
|
// 版本更新信息
|
|
48
57
|
updateInfo: {
|
|
49
58
|
hasUpdate: false,
|
|
@@ -90,6 +99,8 @@ createApp({
|
|
|
90
99
|
deleteThisConfig: 'Delete this configuration',
|
|
91
100
|
emptyConfigCannotDelete: 'Empty configuration cannot be deleted',
|
|
92
101
|
modelManagement: 'Model Management',
|
|
102
|
+
defaultModelTitle: 'Default Model',
|
|
103
|
+
defaultModelPlaceholder: 'Enter default GPT model',
|
|
93
104
|
collapse: 'Collapse',
|
|
94
105
|
expand: 'Expand',
|
|
95
106
|
modelNamePlaceholder: 'Model name',
|
|
@@ -160,6 +171,8 @@ createApp({
|
|
|
160
171
|
deleteThisConfig: '删除此配置',
|
|
161
172
|
emptyConfigCannotDelete: '空配置不能删除',
|
|
162
173
|
modelManagement: '模型管理',
|
|
174
|
+
defaultModelTitle: '默认模型',
|
|
175
|
+
defaultModelPlaceholder: '输入默认gpt模型',
|
|
163
176
|
collapse: '收起',
|
|
164
177
|
expand: '展开',
|
|
165
178
|
modelNamePlaceholder: '模型名称',
|
|
@@ -430,6 +443,7 @@ createApp({
|
|
|
430
443
|
cliType = this.currentCli.toLowerCase();
|
|
431
444
|
}
|
|
432
445
|
this.loading = true;
|
|
446
|
+
this.authListReady = false;
|
|
433
447
|
this.error = null;
|
|
434
448
|
try {
|
|
435
449
|
const response = await axios.get('/api/config', {
|
|
@@ -458,6 +472,7 @@ createApp({
|
|
|
458
472
|
name: '',
|
|
459
473
|
BASE_URL: '',
|
|
460
474
|
TOKEN: '',
|
|
475
|
+
DEFAULT_MODEL: '',
|
|
461
476
|
MODELS: [],
|
|
462
477
|
ENV: []
|
|
463
478
|
}];
|
|
@@ -472,12 +487,16 @@ createApp({
|
|
|
472
487
|
if (!auth.MODELS) {
|
|
473
488
|
auth.MODELS = [];
|
|
474
489
|
}
|
|
490
|
+
if (cliType === 'codex' && typeof auth.DEFAULT_MODEL !== 'string') {
|
|
491
|
+
auth.DEFAULT_MODEL = '';
|
|
492
|
+
}
|
|
475
493
|
});
|
|
476
494
|
|
|
477
495
|
// 先设置辅助数组,再设置 config,确保 Vue 响应式正确更新
|
|
478
496
|
this.showTokens = new Array(config.AUTH.length).fill(false);
|
|
479
497
|
this.showEnvSections = new Array(config.AUTH.length).fill(false);
|
|
480
498
|
this.showModelSections = new Array(config.AUTH.length).fill(false);
|
|
499
|
+
this.authKeys = config.AUTH.map(() => this.createAuthKey());
|
|
481
500
|
|
|
482
501
|
// 最后更新 config
|
|
483
502
|
this.config = config;
|
|
@@ -489,6 +508,11 @@ createApp({
|
|
|
489
508
|
this.showToast(this.t.configLoadFailed + ': ' + (err.response?.data?.error || err.message), 'error');
|
|
490
509
|
} finally {
|
|
491
510
|
this.loading = false;
|
|
511
|
+
this.$nextTick(() => {
|
|
512
|
+
requestAnimationFrame(() => {
|
|
513
|
+
this.authListReady = true;
|
|
514
|
+
});
|
|
515
|
+
});
|
|
492
516
|
}
|
|
493
517
|
},
|
|
494
518
|
|
|
@@ -497,6 +521,7 @@ createApp({
|
|
|
497
521
|
this.error = null;
|
|
498
522
|
this.successMessage = null;
|
|
499
523
|
try {
|
|
524
|
+
this.normalizeCodexDefaults();
|
|
500
525
|
// 创建配置副本,过滤掉空配置项
|
|
501
526
|
const configToSave = {
|
|
502
527
|
...this.config,
|
|
@@ -525,17 +550,28 @@ createApp({
|
|
|
525
550
|
}
|
|
526
551
|
},
|
|
527
552
|
|
|
553
|
+
normalizeCodexDefaults() {
|
|
554
|
+
if (this.currentCli !== 'Codex') {
|
|
555
|
+
return;
|
|
556
|
+
}
|
|
557
|
+
this.config.AUTH.forEach(auth => {
|
|
558
|
+
auth.DEFAULT_MODEL = (auth.DEFAULT_MODEL || '').trim();
|
|
559
|
+
});
|
|
560
|
+
},
|
|
561
|
+
|
|
528
562
|
addAuth() {
|
|
529
563
|
this.config.AUTH.push({
|
|
530
564
|
name: '',
|
|
531
565
|
BASE_URL: '',
|
|
532
566
|
TOKEN: '',
|
|
567
|
+
DEFAULT_MODEL: '',
|
|
533
568
|
MODELS: [],
|
|
534
569
|
ENV: []
|
|
535
570
|
});
|
|
536
571
|
this.showTokens.push(false);
|
|
537
572
|
this.showEnvSections.push(false);
|
|
538
573
|
this.showModelSections.push(false);
|
|
574
|
+
this.authKeys.push(this.createAuthKey());
|
|
539
575
|
// 重置服务器倒计时
|
|
540
576
|
this.resetTimer();
|
|
541
577
|
},
|
|
@@ -559,6 +595,7 @@ createApp({
|
|
|
559
595
|
const deletedTokenState = this.showTokens[index];
|
|
560
596
|
const deletedEnvState = this.showEnvSections[index];
|
|
561
597
|
const deletedModelState = this.showModelSections[index];
|
|
598
|
+
const deletedAuthKey = this.authKeys[index];
|
|
562
599
|
const oldActiveIndex = this.config.activeIndex;
|
|
563
600
|
|
|
564
601
|
// 从列表中删除
|
|
@@ -566,6 +603,7 @@ createApp({
|
|
|
566
603
|
this.showTokens.splice(index, 1);
|
|
567
604
|
this.showEnvSections.splice(index, 1);
|
|
568
605
|
this.showModelSections.splice(index, 1);
|
|
606
|
+
this.authKeys.splice(index, 1);
|
|
569
607
|
|
|
570
608
|
// 调整 activeIndex:如果删除的是当前使用的配置,或者删除的配置在当前使用配置之前
|
|
571
609
|
if (index === this.config.activeIndex) {
|
|
@@ -583,17 +621,20 @@ createApp({
|
|
|
583
621
|
name: '',
|
|
584
622
|
BASE_URL: '',
|
|
585
623
|
TOKEN: '',
|
|
624
|
+
DEFAULT_MODEL: '',
|
|
586
625
|
MODELS: [],
|
|
587
626
|
ENV: []
|
|
588
627
|
});
|
|
589
628
|
this.showTokens.push(false);
|
|
590
629
|
this.showEnvSections.push(false);
|
|
591
630
|
this.showModelSections.push(false);
|
|
631
|
+
this.authKeys.push(this.createAuthKey());
|
|
592
632
|
this.config.activeIndex = 0;
|
|
593
633
|
}
|
|
594
634
|
|
|
595
635
|
// 立即保存配置,过滤掉空配置项(但保留至少一个配置)
|
|
596
636
|
try {
|
|
637
|
+
this.normalizeCodexDefaults();
|
|
597
638
|
const filteredAuth = this.config.AUTH.filter(auth => !this.isEmptyConfig(auth));
|
|
598
639
|
const configToSave = {
|
|
599
640
|
...this.config,
|
|
@@ -614,6 +655,7 @@ createApp({
|
|
|
614
655
|
this.showTokens.splice(index, 0, deletedTokenState);
|
|
615
656
|
this.showEnvSections.splice(index, 0, deletedEnvState);
|
|
616
657
|
this.showModelSections.splice(index, 0, deletedModelState);
|
|
658
|
+
this.authKeys.splice(index, 0, deletedAuthKey);
|
|
617
659
|
this.config.activeIndex = oldActiveIndex;
|
|
618
660
|
}
|
|
619
661
|
});
|
|
@@ -630,6 +672,7 @@ createApp({
|
|
|
630
672
|
|
|
631
673
|
// 立即保存配置
|
|
632
674
|
try {
|
|
675
|
+
this.normalizeCodexDefaults();
|
|
633
676
|
const configToSave = {
|
|
634
677
|
...this.config,
|
|
635
678
|
AUTH: this.config.AUTH.filter(auth => !this.isEmptyConfig(auth))
|
|
@@ -692,7 +735,12 @@ createApp({
|
|
|
692
735
|
|
|
693
736
|
// 判断是否为空配置
|
|
694
737
|
isEmptyConfig(auth) {
|
|
695
|
-
|
|
738
|
+
const hasDefaultModel = this.currentCli === 'Codex' && auth.DEFAULT_MODEL && auth.DEFAULT_MODEL.trim();
|
|
739
|
+
return !auth.name && !auth.BASE_URL && !auth.TOKEN && !hasDefaultModel && (!auth.ENV || auth.ENV.length === 0) && (!auth.MODELS || auth.MODELS.length === 0);
|
|
740
|
+
},
|
|
741
|
+
|
|
742
|
+
createAuthKey() {
|
|
743
|
+
return `auth-${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
696
744
|
},
|
|
697
745
|
|
|
698
746
|
// 切换使用说明显示/隐藏
|
|
@@ -700,9 +748,44 @@ createApp({
|
|
|
700
748
|
this.showHelp = !this.showHelp;
|
|
701
749
|
},
|
|
702
750
|
|
|
751
|
+
getDragShiftClass(index) {
|
|
752
|
+
if (this.draggingIndex === null || this.dropTargetIndex === null || this.isDropping || index === this.draggingIndex) {
|
|
753
|
+
return '';
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
if (this.draggingIndex < this.dropTargetIndex && index > this.draggingIndex && index <= this.dropTargetIndex) {
|
|
757
|
+
return 'auth-card-shift-up';
|
|
758
|
+
}
|
|
759
|
+
|
|
760
|
+
if (this.draggingIndex > this.dropTargetIndex && index >= this.dropTargetIndex && index < this.draggingIndex) {
|
|
761
|
+
return 'auth-card-shift-down';
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
return '';
|
|
765
|
+
},
|
|
766
|
+
|
|
767
|
+
getDragShiftStyle(index) {
|
|
768
|
+
if (index === this.draggingIndex) {
|
|
769
|
+
const offset = this.dragCurrentY - this.dragStartY;
|
|
770
|
+
return {
|
|
771
|
+
'--drag-follow-offset': `${offset}px`
|
|
772
|
+
};
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
const shiftClass = this.getDragShiftClass(index);
|
|
776
|
+
if (!shiftClass || !this.draggedCardHeight) {
|
|
777
|
+
return {};
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
const offset = shiftClass === 'auth-card-shift-up' ? -this.draggedCardHeight : this.draggedCardHeight;
|
|
781
|
+
return {
|
|
782
|
+
'--drag-shift-offset': `${offset}px`
|
|
783
|
+
};
|
|
784
|
+
},
|
|
785
|
+
|
|
703
786
|
// 选择 CLI 类型
|
|
704
787
|
async selectCli(cliName) {
|
|
705
|
-
if (cliName === 'Gemini'
|
|
788
|
+
if (cliName === 'Gemini') {
|
|
706
789
|
this.showToast(this.t.notAvailableYet, 'error');
|
|
707
790
|
this.resetTimer();
|
|
708
791
|
return;
|
|
@@ -714,25 +797,105 @@ createApp({
|
|
|
714
797
|
// 拖拽开始
|
|
715
798
|
handleDragStart(index, event) {
|
|
716
799
|
this.draggingIndex = index;
|
|
800
|
+
this.dragOverIndex = null;
|
|
801
|
+
this.dropTargetIndex = null;
|
|
802
|
+
this.isDropping = false;
|
|
803
|
+
const card = event.currentTarget.closest('.auth-card');
|
|
804
|
+
const cardStyle = window.getComputedStyle(card);
|
|
805
|
+
this.draggedCardHeight = card.offsetHeight + parseFloat(cardStyle.marginBottom || 0);
|
|
806
|
+
this.draggedCardVisualHeight = card.offsetHeight;
|
|
807
|
+
this.dragCardRects = Array.from(document.querySelectorAll('.auth-card')).map(cardEl => {
|
|
808
|
+
const rect = cardEl.getBoundingClientRect();
|
|
809
|
+
return {
|
|
810
|
+
top: rect.top,
|
|
811
|
+
bottom: rect.bottom,
|
|
812
|
+
height: rect.height
|
|
813
|
+
};
|
|
814
|
+
});
|
|
815
|
+
this.dragStartY = event.clientY;
|
|
816
|
+
this.dragCurrentY = event.clientY;
|
|
717
817
|
event.dataTransfer.effectAllowed = 'move';
|
|
718
818
|
// 设置拖拽时的透明度
|
|
719
819
|
event.target.style.opacity = '0.5';
|
|
720
820
|
},
|
|
721
821
|
|
|
822
|
+
handleDrag(event) {
|
|
823
|
+
if (this.draggingIndex === null || event.clientY === 0) {
|
|
824
|
+
return;
|
|
825
|
+
}
|
|
826
|
+
this.dragCurrentY = event.clientY;
|
|
827
|
+
this.updateDropTargetByY(event.clientY);
|
|
828
|
+
},
|
|
829
|
+
|
|
722
830
|
// 拖拽结束
|
|
723
831
|
handleDragEnd(event) {
|
|
832
|
+
if (this.isDropping) {
|
|
833
|
+
event.target.style.opacity = '1';
|
|
834
|
+
return;
|
|
835
|
+
}
|
|
724
836
|
this.draggingIndex = null;
|
|
725
837
|
this.dragOverIndex = null;
|
|
838
|
+
this.dropTargetIndex = null;
|
|
839
|
+
this.draggedCardHeight = 0;
|
|
840
|
+
this.draggedCardVisualHeight = 0;
|
|
841
|
+
this.dragCardRects = [];
|
|
842
|
+
this.dragStartY = 0;
|
|
843
|
+
this.dragCurrentY = 0;
|
|
844
|
+
this.isDropping = false;
|
|
726
845
|
event.target.style.opacity = '1';
|
|
727
846
|
},
|
|
728
847
|
|
|
729
848
|
// 拖拽经过
|
|
730
849
|
handleDragOver(index, event) {
|
|
731
850
|
event.preventDefault();
|
|
732
|
-
if (this.draggingIndex === null
|
|
851
|
+
if (this.draggingIndex === null) {
|
|
733
852
|
return;
|
|
734
853
|
}
|
|
735
|
-
this.
|
|
854
|
+
if (this.draggingIndex === index) {
|
|
855
|
+
return;
|
|
856
|
+
}
|
|
857
|
+
if (event.clientY !== 0) {
|
|
858
|
+
this.dragCurrentY = event.clientY;
|
|
859
|
+
}
|
|
860
|
+
this.updateDropTargetByY(event.clientY);
|
|
861
|
+
if (this.dragOverIndex !== index) {
|
|
862
|
+
this.dragOverIndex = index;
|
|
863
|
+
}
|
|
864
|
+
},
|
|
865
|
+
|
|
866
|
+
updateDropTargetByY(clientY) {
|
|
867
|
+
if (this.draggingIndex === null || clientY === 0) {
|
|
868
|
+
return;
|
|
869
|
+
}
|
|
870
|
+
|
|
871
|
+
const dragOffset = clientY - this.dragStartY;
|
|
872
|
+
const draggedRect = this.dragCardRects[this.draggingIndex];
|
|
873
|
+
if (!draggedRect) {
|
|
874
|
+
return;
|
|
875
|
+
}
|
|
876
|
+
|
|
877
|
+
const draggedTop = draggedRect.top + dragOffset;
|
|
878
|
+
const draggedBottom = draggedTop + this.draggedCardVisualHeight;
|
|
879
|
+
|
|
880
|
+
const crossedIndexes = this.dragCardRects
|
|
881
|
+
.map((rect, index) => ({ rect, index }))
|
|
882
|
+
.filter(({ index }) => index !== this.draggingIndex)
|
|
883
|
+
.filter(({ rect, index }) => {
|
|
884
|
+
const targetMiddle = rect.top + rect.height / 2;
|
|
885
|
+
return this.draggingIndex < index
|
|
886
|
+
? draggedBottom > targetMiddle
|
|
887
|
+
: draggedTop < targetMiddle;
|
|
888
|
+
})
|
|
889
|
+
.map(({ index }) => index);
|
|
890
|
+
|
|
891
|
+
const nextTargetIndex = this.draggingIndex < (crossedIndexes[0] ?? this.draggingIndex)
|
|
892
|
+
? crossedIndexes[crossedIndexes.length - 1]
|
|
893
|
+
: crossedIndexes[0];
|
|
894
|
+
|
|
895
|
+
const normalizedTargetIndex = nextTargetIndex === undefined ? null : nextTargetIndex;
|
|
896
|
+
if (this.dropTargetIndex !== normalizedTargetIndex) {
|
|
897
|
+
this.dropTargetIndex = normalizedTargetIndex;
|
|
898
|
+
}
|
|
736
899
|
},
|
|
737
900
|
|
|
738
901
|
// 拖拽离开
|
|
@@ -743,10 +906,13 @@ createApp({
|
|
|
743
906
|
// 放下
|
|
744
907
|
async handleDrop(index, event) {
|
|
745
908
|
event.preventDefault();
|
|
746
|
-
|
|
909
|
+
const targetIndex = this.dropTargetIndex ?? index;
|
|
910
|
+
if (this.draggingIndex === null || this.draggingIndex === targetIndex) {
|
|
747
911
|
this.dragOverIndex = null;
|
|
912
|
+
this.dropTargetIndex = null;
|
|
748
913
|
return;
|
|
749
914
|
}
|
|
915
|
+
this.isDropping = true;
|
|
750
916
|
|
|
751
917
|
// 保存原始数据,以便失败时恢复
|
|
752
918
|
const oldAuth = [...this.config.AUTH];
|
|
@@ -754,41 +920,63 @@ createApp({
|
|
|
754
920
|
const oldShowTokens = [...this.showTokens];
|
|
755
921
|
const oldShowEnvSections = [...this.showEnvSections];
|
|
756
922
|
const oldShowModelSections = [...this.showModelSections];
|
|
923
|
+
const oldAuthKeys = [...this.authKeys];
|
|
757
924
|
|
|
758
925
|
// 移动配置项
|
|
759
926
|
const [movedAuth] = this.config.AUTH.splice(this.draggingIndex, 1);
|
|
760
|
-
this.config.AUTH.splice(
|
|
927
|
+
this.config.AUTH.splice(targetIndex, 0, movedAuth);
|
|
761
928
|
|
|
762
929
|
// 同步移动显示状态
|
|
763
930
|
const [movedToken] = this.showTokens.splice(this.draggingIndex, 1);
|
|
764
|
-
this.showTokens.splice(
|
|
931
|
+
this.showTokens.splice(targetIndex, 0, movedToken);
|
|
765
932
|
|
|
766
933
|
const [movedEnv] = this.showEnvSections.splice(this.draggingIndex, 1);
|
|
767
|
-
this.showEnvSections.splice(
|
|
934
|
+
this.showEnvSections.splice(targetIndex, 0, movedEnv);
|
|
768
935
|
|
|
769
936
|
const [movedModel] = this.showModelSections.splice(this.draggingIndex, 1);
|
|
770
|
-
this.showModelSections.splice(
|
|
937
|
+
this.showModelSections.splice(targetIndex, 0, movedModel);
|
|
938
|
+
|
|
939
|
+
const [movedAuthKey] = this.authKeys.splice(this.draggingIndex, 1);
|
|
940
|
+
this.authKeys.splice(targetIndex, 0, movedAuthKey);
|
|
771
941
|
|
|
772
942
|
// 调整 activeIndex
|
|
773
943
|
if (this.draggingIndex === this.config.activeIndex) {
|
|
774
944
|
// 拖拽的是当前使用的配置,直接移动到目标位置
|
|
775
|
-
this.config.activeIndex =
|
|
776
|
-
} else if (this.draggingIndex < this.config.activeIndex &&
|
|
945
|
+
this.config.activeIndex = targetIndex;
|
|
946
|
+
} else if (this.draggingIndex < this.config.activeIndex && targetIndex >= this.config.activeIndex) {
|
|
777
947
|
// 从前向后拖拽,经过当前使用的配置
|
|
778
948
|
// activeIndex 位置的元素被向前移了一位,所以需要减 1
|
|
779
949
|
this.config.activeIndex--;
|
|
780
|
-
} else if (this.draggingIndex > this.config.activeIndex &&
|
|
950
|
+
} else if (this.draggingIndex > this.config.activeIndex && targetIndex <= this.config.activeIndex) {
|
|
781
951
|
// 从后向前拖拽,经过当前使用的配置
|
|
782
952
|
// activeIndex 位置的元素被向后移了一位,所以需要加 1
|
|
783
953
|
this.config.activeIndex++;
|
|
784
954
|
}
|
|
785
955
|
|
|
786
|
-
|
|
787
|
-
this.draggingIndex = null;
|
|
956
|
+
this.draggingIndex = targetIndex;
|
|
788
957
|
this.dragOverIndex = null;
|
|
958
|
+
this.dropTargetIndex = null;
|
|
959
|
+
this.dragCurrentY = this.dragStartY;
|
|
960
|
+
|
|
961
|
+
// 先完成 DOM 重排,下一帧再清理拖拽状态,避免松手时出现明显回弹刷新。
|
|
962
|
+
requestAnimationFrame(() => {
|
|
963
|
+
if (!this.isDropping || this.draggingIndex !== targetIndex) {
|
|
964
|
+
return;
|
|
965
|
+
}
|
|
966
|
+
this.draggingIndex = null;
|
|
967
|
+
this.dragOverIndex = null;
|
|
968
|
+
this.dropTargetIndex = null;
|
|
969
|
+
this.draggedCardHeight = 0;
|
|
970
|
+
this.draggedCardVisualHeight = 0;
|
|
971
|
+
this.dragCardRects = [];
|
|
972
|
+
this.dragStartY = 0;
|
|
973
|
+
this.dragCurrentY = 0;
|
|
974
|
+
this.isDropping = false;
|
|
975
|
+
});
|
|
789
976
|
|
|
790
977
|
// 保存配置
|
|
791
978
|
try {
|
|
979
|
+
this.normalizeCodexDefaults();
|
|
792
980
|
const configToSave = {
|
|
793
981
|
...this.config,
|
|
794
982
|
AUTH: this.config.AUTH.filter(auth => !this.isEmptyConfig(auth))
|
|
@@ -808,6 +996,7 @@ createApp({
|
|
|
808
996
|
this.showTokens = oldShowTokens;
|
|
809
997
|
this.showEnvSections = oldShowEnvSections;
|
|
810
998
|
this.showModelSections = oldShowModelSections;
|
|
999
|
+
this.authKeys = oldAuthKeys;
|
|
811
1000
|
}
|
|
812
1001
|
}
|
|
813
1002
|
},
|