Skip to content

Commit 67eb0f6

Browse files
committed
WIP
WIP fix: detect file modifications using hashes fix: surface diff fetch failures fix: handle file-directory transitions in compare WIP
1 parent ad6a5f6 commit 67eb0f6

5 files changed

Lines changed: 532 additions & 35 deletions

File tree

app/components/diff/ViewerPanel.vue

Lines changed: 88 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<script setup lang="ts">
22
import type { FileDiffResponse, FileChange } from '#shared/types'
33
import { createDiff, insertSkipBlocks, countDiffStats } from '#shared/utils/diff'
4+
// @ts-expect-error: (tasky): idk why this is type-erroring even if it has types? /shrug
45
import { motion } from 'motion-v'
56
67
const props = defineProps<{
@@ -14,7 +15,7 @@ const mergeModifiedLines = ref(true)
1415
const maxChangeRatio = ref(0.45)
1516
const maxDiffDistance = ref(30)
1617
const inlineMaxCharEdits = ref(2)
17-
const wordWrap = ref(true)
18+
const wordWrap = ref(false)
1819
const showOptions = ref(false)
1920
const loading = ref(true)
2021
const loadError = ref<Error | null>(null)
@@ -276,11 +277,11 @@ function getCodeUrl(version: string): string {
276277
<!-- Dropdown menu -->
277278
<motion.div
278279
v-if="showOptions"
279-
class="absolute right-0 top-full mt-2 z-20 p-4 bg-bg-elevated border border-border shadow-2xl overflow-hidden"
280-
:initial="{ width: 220, height: 100, borderRadius: 20 }"
280+
class="absolute right-0 top-full mt-2 z-20 p-4 bg-bg-elevated/40 backdrop-blur-sm border border-border shadow-2xl overflow-hidden"
281+
:initial="{ width: 220, height: 110, borderRadius: 20 }"
281282
:animate="{
282283
width: mergeModifiedLines ? 400 : 220,
283-
height: mergeModifiedLines ? 220 : 100,
284+
height: mergeModifiedLines ? 260 : 110,
284285
borderRadius: mergeModifiedLines ? 14 : 20,
285286
}"
286287
:transition="{
@@ -292,11 +293,37 @@ function getCodeUrl(version: string): string {
292293
}"
293294
>
294295
<div class="flex flex-col gap-2">
295-
<!-- Merge modified lines toggle -->
296-
<Toggle label="Merge modified lines" v-model="mergeModifiedLines" />
297-
298-
<!-- Word wrap toggle -->
299-
<Toggle label="Word wrap" v-model="wordWrap" />
296+
<!-- Merge modified lines checkbox -->
297+
<div class="flex items-center gap-2">
298+
<input
299+
id="merge-modified-lines"
300+
v-model="mergeModifiedLines"
301+
type="checkbox"
302+
class="w-4 h-4 rounded border-border bg-bg text-blue-500 focus:ring-2 focus:ring-blue-500/50 cursor-pointer"
303+
/>
304+
<label
305+
for="merge-modified-lines"
306+
class="text-sm cursor-pointer select-none whitespace-nowrap w-full"
307+
>
308+
Merge modified lines
309+
</label>
310+
</div>
311+
312+
<!-- Word wrap checkbox -->
313+
<div class="flex items-center gap-2">
314+
<input
315+
id="word-wrap"
316+
v-model="wordWrap"
317+
type="checkbox"
318+
class="w-4 h-4 rounded border-border bg-bg text-blue-500 focus:ring-2 focus:ring-blue-500/50 cursor-pointer"
319+
/>
320+
<label
321+
for="word-wrap"
322+
class="text-sm cursor-pointer select-none whitespace-nowrap w-full"
323+
>
324+
Word wrap
325+
</label>
326+
</div>
300327

301328
<!-- Sliders -->
302329
<motion.div
@@ -320,7 +347,7 @@ function getCodeUrl(version: string): string {
320347
v-for="mark in changeRatioMarks"
321348
:key="`cr-${mark}`"
322349
class="slider-mark"
323-
:style="{ left: `calc(${mark}% - 1.5px)` }"
350+
:style="{ left: `calc(${mark}% - 11px)` }"
324351
/>
325352
<div class="slider-range" :style="{ width: `${changeRatioPercent}%` }" />
326353
</div>
@@ -353,7 +380,7 @@ function getCodeUrl(version: string): string {
353380
v-for="mark in diffDistanceMarks"
354381
:key="`dd-${mark}`"
355382
class="slider-mark"
356-
:style="{ left: `calc(${mark}% - 1.5px)` }"
383+
:style="{ left: `calc(${mark}% - 11px)` }"
357384
/>
358385
<div class="slider-range" :style="{ width: `${diffDistancePercent}%` }" />
359386
</div>
@@ -386,7 +413,7 @@ function getCodeUrl(version: string): string {
386413
v-for="mark in charEditMarks"
387414
:key="`ce-${mark}`"
388415
class="slider-mark"
389-
:style="{ left: `calc(${mark}% - 1.5px)` }"
416+
:style="{ left: `calc(${mark}% - 11px)` }"
390417
/>
391418
<div class="slider-range" :style="{ width: `${charEditPercent}%` }" />
392419
</div>
@@ -481,17 +508,21 @@ function getCodeUrl(version: string): string {
481508
position: relative;
482509
display: flex;
483510
align-items: center;
484-
height: 36px;
511+
height: 48px;
485512
width: 100%;
486513
border: 1px solid var(--border);
487514
background: var(--bg-subtle);
488-
border-radius: 6px;
515+
border-radius: 12px;
489516
overflow: hidden;
490517
cursor: grab;
491-
transition: border-color 200ms ease;
518+
transition:
519+
background-color 150ms ease,
520+
border-color 150ms ease,
521+
opacity 150ms ease;
492522
}
493523
494524
.slider-shell:hover {
525+
background: var(--bg-muted);
495526
border-color: var(--border-hover);
496527
}
497528
@@ -510,32 +541,36 @@ function getCodeUrl(version: string): string {
510541
display: flex;
511542
align-items: center;
512543
justify-content: space-between;
513-
padding: 0 12px;
544+
padding: 0 16px;
514545
pointer-events: none;
515546
z-index: 3;
516547
}
517548
518549
.slider-label {
519-
font-size: 0.75rem;
550+
font-size: 0.875rem;
520551
font-weight: 400;
521-
color: var(--fg);
552+
color: color-mix(in srgb, var(--fg) 30%, transparent);
522553
letter-spacing: -0.01em;
523-
transition: color 200ms ease;
554+
transition: color 150ms ease;
555+
}
556+
557+
.slider-shell:hover .slider-label {
558+
color: var(--fg);
524559
}
525560
526561
.slider-value {
527-
min-width: 24px;
562+
min-width: 32px;
528563
text-align: right;
529-
font-size: 0.75rem;
564+
font-size: 0.875rem;
530565
font-weight: 500;
531566
color: var(--fg);
532567
}
533568
534569
.slider-track {
535570
position: absolute;
536571
inset: 0;
537-
background: var(--bg-subtle);
538-
border-radius: 5px;
572+
background: var(--bg-muted);
573+
border-radius: 10px;
539574
overflow: hidden;
540575
z-index: 1;
541576
pointer-events: none;
@@ -544,25 +579,44 @@ function getCodeUrl(version: string): string {
544579
.slider-mark {
545580
position: absolute;
546581
top: 50%;
547-
width: 3px;
548-
height: 3px;
582+
width: 6px;
583+
height: 6px;
549584
border-radius: 50%;
550-
background: var(--border);
585+
background: color-mix(in srgb, var(--fg) 20%, transparent);
551586
transform: translateY(-50%);
552587
pointer-events: none;
553-
opacity: 0.6;
588+
opacity: 0.9;
554589
}
555590
556591
.slider-range {
557592
position: absolute;
558593
inset: 0 auto 0 0;
559-
background: var(--bg-muted);
560-
border-radius: 5px;
561-
transition: width 150ms ease-out;
594+
background: var(--bg-subtle);
595+
border-radius: 10px;
596+
transition:
597+
width 150ms ease-out,
598+
background-color 150ms ease-out;
562599
z-index: 2;
563600
pointer-events: none;
564601
}
565602
603+
.slider-range::after {
604+
content: '';
605+
position: absolute;
606+
right: 8px;
607+
top: 50%;
608+
width: 2px;
609+
height: 28px;
610+
border-radius: 12px;
611+
background: color-mix(in srgb, var(--fg) 20%, transparent);
612+
transform: translateY(-50%);
613+
transition: background-color 150ms ease;
614+
}
615+
616+
.slider-shell:hover .slider-range::after {
617+
background: color-mix(in srgb, var(--fg) 50%, transparent);
618+
}
619+
566620
.slider-input {
567621
position: absolute;
568622
inset: 0;
@@ -579,13 +633,13 @@ function getCodeUrl(version: string): string {
579633
580634
.slider-input::-webkit-slider-thumb {
581635
-webkit-appearance: none;
582-
height: 24px;
583-
width: 12px;
636+
height: 32px;
637+
width: 16px;
584638
}
585639
586640
.slider-input::-moz-range-thumb {
587-
height: 24px;
588-
width: 12px;
641+
height: 32px;
642+
width: 16px;
589643
border: none;
590644
background: transparent;
591645
}

0 commit comments

Comments
 (0)