Skip to content

Commit 1133846

Browse files
authored
[codex] restore route priority drag behavior (cita-777#376)
* fix: restore route priority drag behavior * fix: use theme rail highlight surface
1 parent 5fffcb6 commit 1133846

4 files changed

Lines changed: 26 additions & 83 deletions

File tree

src/web/pages/token-routes/RouteCard.tsx

Lines changed: 5 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { memo, useState, type ReactNode } from 'react';
22
import {
33
DndContext,
4-
DragOverlay,
54
KeyboardSensor,
65
PointerSensor,
76
closestCenter,
@@ -42,13 +41,12 @@ import {
4241
isExplicitGroupRoute,
4342
resolveRouteTitle,
4443
resolveRouteIcon,
45-
getPriorityTagStyle,
4644
} from './utils.js';
4745
import {
4846
buildPriorityBuckets,
4947
} from './priorityBuckets.js';
5048
import {
51-
buildPriorityDragPreviewStyle,
49+
buildPriorityRailNodeStyle,
5250
buildPriorityRailSections,
5351
createPriorityRailNewLayerId,
5452
isPriorityRailNewLayerId,
@@ -159,52 +157,6 @@ function PriorityRailNewLayerRow({
159157
);
160158
}
161159

162-
function PriorityDragPreview({
163-
channel,
164-
displayPriority,
165-
activeRowWidth,
166-
}: {
167-
channel: RouteChannel;
168-
displayPriority: number;
169-
activeRowWidth?: number | null;
170-
}) {
171-
return (
172-
<div
173-
style={{
174-
display: 'inline-flex',
175-
alignItems: 'center',
176-
justifyContent: 'space-between',
177-
gap: 8,
178-
padding: '8px 12px',
179-
borderRadius: 'var(--radius-md)',
180-
border: '1px solid var(--color-border)',
181-
background: 'var(--color-bg-card)',
182-
boxShadow: 'var(--shadow-sm)',
183-
color: 'var(--color-text-primary)',
184-
fontSize: 12,
185-
...buildPriorityDragPreviewStyle(activeRowWidth),
186-
}}
187-
>
188-
<span
189-
className="badge"
190-
style={{
191-
fontSize: 10,
192-
fontWeight: 700,
193-
letterSpacing: 0.1,
194-
}}
195-
>
196-
{`P${displayPriority}`}
197-
</span>
198-
<span style={{ fontWeight: 600 }}>
199-
{channel.account?.username || `account-${channel.accountId}`}
200-
</span>
201-
<span className="badge badge-muted" style={{ fontSize: 10 }}>
202-
{channel.site?.name || 'unknown'}
203-
</span>
204-
</div>
205-
);
206-
}
207-
208160
function RouteCardInner({
209161
route,
210162
brand,
@@ -281,14 +233,10 @@ function RouteCardInner({
281233
const priorityBuckets = buildPriorityBuckets(channels || []);
282234
const priorityRailSections = buildPriorityRailSections(channels || []);
283235
const [activeDragChannelId, setActiveDragChannelId] = useState<number | null>(null);
284-
const [activeDragRowWidth, setActiveDragRowWidth] = useState<number | null>(null);
285236
const [dragOverId, setDragOverId] = useState<string | number | null>(null);
286-
const activeDragChannel = activeDragChannelId == null
287-
? null
288-
: (channels || []).find((channel) => channel.id === activeDragChannelId) || null;
289-
const activeDragBucketIndex = activeDragChannel == null
237+
const activeDragBucketIndex = activeDragChannelId == null
290238
? -1
291-
: priorityBuckets.findIndex((bucket) => bucket.channels.some((channel) => channel.id === activeDragChannel.id));
239+
: priorityBuckets.findIndex((bucket) => bucket.channels.some((channel) => channel.id === activeDragChannelId));
292240
const hoveredBucketIndex = typeof dragOverId === 'number'
293241
? priorityBuckets.findIndex((bucket) => bucket.channels.some((channel) => channel.id === dragOverId))
294242
: -1;
@@ -298,14 +246,12 @@ function RouteCardInner({
298246

299247
const clearDragState = () => {
300248
setActiveDragChannelId(null);
301-
setActiveDragRowWidth(null);
302249
setDragOverId(null);
303250
};
304251

305252
const handleDragStart = (event: DragStartEvent) => {
306253
const nextId = Number(event.active.id);
307254
setActiveDragChannelId(Number.isFinite(nextId) ? nextId : null);
308-
setActiveDragRowWidth(event.active.rect.current.initial?.width ?? null);
309255
setDragOverId(event.active.id);
310256
};
311257

@@ -679,7 +625,7 @@ function RouteCardInner({
679625
const hoveredExistingLayer = activeDragChannelId != null && hoveredBucketIndex === bucketIndex;
680626
const hoveredCrossLayer = hoveredExistingLayer && activeDragBucketIndex !== bucketIndex;
681627
const hoveredNewLayer = activeDragChannelId != null && hoveredNewLayerBucketIndex === bucketIndex;
682-
const railTone = getPriorityTagStyle(bucketIndex);
628+
const railNodeStyle = buildPriorityRailNodeStyle(bucketIndex, hoveredExistingLayer);
683629

684630
return (
685631
<div
@@ -739,16 +685,12 @@ function RouteCardInner({
739685
minWidth: 72,
740686
padding: '6px 10px',
741687
borderRadius: 999,
742-
border: `1px solid ${hoveredExistingLayer ? 'var(--color-primary)' : 'color-mix(in srgb, currentColor 24%, transparent)'}`,
743-
background: hoveredExistingLayer
744-
? 'color-mix(in srgb, var(--color-primary) 10%, var(--color-bg))'
745-
: railTone.background,
746-
color: hoveredExistingLayer ? 'var(--color-primary)' : railTone.color,
747688
fontSize: 11,
748689
fontWeight: 600,
749690
textAlign: 'center',
750691
lineHeight: 1.2,
751692
transition: 'all 0.16s ease',
693+
...railNodeStyle,
752694
}}
753695
>
754696
{railSection ? `P${bucketIndex} · ${railSection.channelCount}` : railLabel}
@@ -806,15 +748,6 @@ function RouteCardInner({
806748
})}
807749
</div>
808750
</SortableContext>
809-
<DragOverlay>
810-
{activeDragChannel && !compact ? (
811-
<PriorityDragPreview
812-
channel={activeDragChannel}
813-
displayPriority={Math.max(0, activeDragBucketIndex)}
814-
activeRowWidth={activeDragRowWidth}
815-
/>
816-
) : null}
817-
</DragOverlay>
818751
</DndContext>
819752
</div>
820753
) : (

src/web/pages/token-routes/SortableChannelRow.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ export function SortableChannelRow({
5050
const rowStyle: CSSProperties = {
5151
transform: CSS.Transform.toString(transform),
5252
transition,
53-
opacity: isDragging ? (mobile ? 0.72 : 0) : channel.enabled === false ? 0.5 : 1,
53+
opacity: isDragging ? 0.72 : channel.enabled === false ? 0.5 : 1,
5454
zIndex: isDragging ? 10 : 1,
5555
display: 'grid',
5656
gridTemplateColumns: managementLocked || mobile ? 'minmax(0, 1fr)' : 'minmax(0, 1fr) auto auto auto',

src/web/pages/token-routes/priorityRail.test.ts

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { describe, expect, it } from 'vitest';
22
import {
33
applyPriorityRailDrop,
4-
buildPriorityDragPreviewStyle,
4+
buildPriorityRailNodeStyle,
55
buildPriorityRailDragTargets,
66
buildPriorityRailSections,
77
createPriorityRailNewLayerId,
@@ -76,10 +76,15 @@ describe('priorityRail helpers', () => {
7676
]);
7777
});
7878

79-
it('uses the active row width for drag preview alignment when available', () => {
80-
expect(buildPriorityDragPreviewStyle(640)).toMatchObject({
81-
width: 640,
82-
maxWidth: 'calc(100vw - 32px)',
83-
});
79+
it('keeps priority color hierarchy even when a rail node is highlighted', () => {
80+
const p0 = buildPriorityRailNodeStyle(0, false);
81+
const p0Highlighted = buildPriorityRailNodeStyle(0, true);
82+
const p1Highlighted = buildPriorityRailNodeStyle(1, true);
83+
84+
expect(p0.background).not.toBe('var(--color-bg)');
85+
expect(String(p0Highlighted.background)).toContain('var(--color-bg)');
86+
expect(String(p0Highlighted.background)).not.toContain('white');
87+
expect(p0Highlighted.color).toBe('var(--color-primary)');
88+
expect(p0Highlighted.background).not.toBe(p1Highlighted.background);
8489
});
8590
});

src/web/pages/token-routes/priorityRail.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import type { CSSProperties } from 'react';
22
import type { PriorityRailDragTarget, PriorityRailSection } from './types.js';
3+
import { getPriorityTagStyle } from './utils.js';
34

45
type PriorityRailChannelLike = {
56
id: number;
@@ -119,10 +120,14 @@ export function applyPriorityRailDrop<T extends PriorityRailChannelLike>(
119120
);
120121
}
121122

122-
export function buildPriorityDragPreviewStyle(activeRowWidth?: number | null): CSSProperties {
123-
const resolvedWidth = Number.isFinite(activeRowWidth ?? Number.NaN) ? activeRowWidth ?? undefined : undefined;
123+
export function buildPriorityRailNodeStyle(priority: number, highlighted: boolean): CSSProperties {
124+
const tone = getPriorityTagStyle(priority);
125+
124126
return {
125-
width: resolvedWidth,
126-
maxWidth: 'calc(100vw - 32px)',
127+
border: `1px solid ${highlighted ? 'var(--color-primary)' : 'color-mix(in srgb, currentColor 24%, transparent)'}`,
128+
background: highlighted
129+
? `color-mix(in srgb, ${tone.background} 78%, var(--color-bg))`
130+
: tone.background,
131+
color: highlighted ? 'var(--color-primary)' : tone.color,
127132
};
128133
}

0 commit comments

Comments
 (0)