gitmaps 1.1.14 → 1.1.16
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/app/analytics.db
CHANGED
|
Binary file
|
|
@@ -69,6 +69,13 @@ describe('low zoom preview helpers', () => {
|
|
|
69
69
|
expect(markers.some((m) => m.color === '#ef4444')).toBe(true);
|
|
70
70
|
});
|
|
71
71
|
|
|
72
|
+
test('whole-file added/deleted states create full-height rail markers', () => {
|
|
73
|
+
const added = collectPreviewDiffMarkers({ status: 'added' }, 20);
|
|
74
|
+
const deleted = collectPreviewDiffMarkers({ status: 'deleted' }, 20);
|
|
75
|
+
expect(added[0]?.height).toBe(1);
|
|
76
|
+
expect(deleted[0]?.height).toBe(1);
|
|
77
|
+
});
|
|
78
|
+
|
|
72
79
|
test('title typography is larger than body typography for readability', () => {
|
|
73
80
|
const scale = getLowZoomScale(0.18);
|
|
74
81
|
expect(scale.titleFont).toBeGreaterThan(scale.bodyFont);
|
|
@@ -135,11 +135,20 @@ export function getPreviewScrollMetrics(file: any, height: number, zoom: number,
|
|
|
135
135
|
}
|
|
136
136
|
|
|
137
137
|
export function collectPreviewDiffMarkers(file: any, totalLines: number) {
|
|
138
|
-
const markers: Array<{ ratio: number; color: string }> = [];
|
|
138
|
+
const markers: Array<{ ratio: number; color: string; height?: number }> = [];
|
|
139
139
|
const safeTotal = Math.max(1, totalLines);
|
|
140
140
|
const added = file?.addedLines instanceof Set ? Array.from(file.addedLines) : [];
|
|
141
141
|
const deletedBefore = file?.deletedBeforeLine instanceof Map ? Array.from(file.deletedBeforeLine.keys()) : [];
|
|
142
142
|
|
|
143
|
+
if (file?.status === 'added') {
|
|
144
|
+
markers.push({ ratio: 0, color: '#22c55e', height: 1 });
|
|
145
|
+
return markers;
|
|
146
|
+
}
|
|
147
|
+
if (file?.status === 'deleted') {
|
|
148
|
+
markers.push({ ratio: 0, color: '#ef4444', height: 1 });
|
|
149
|
+
return markers;
|
|
150
|
+
}
|
|
151
|
+
|
|
143
152
|
for (const line of added) {
|
|
144
153
|
markers.push({ ratio: Math.max(0, Math.min(1, (line - 1) / safeTotal)), color: '#22c55e' });
|
|
145
154
|
}
|
|
@@ -185,9 +194,9 @@ export function renderLowZoomPreviewCanvas(
|
|
|
185
194
|
ctx.fill();
|
|
186
195
|
|
|
187
196
|
const accentWidth = Math.max(6, width * 0.012);
|
|
188
|
-
const scrollbarWidth =
|
|
189
|
-
const markerLaneWidth =
|
|
190
|
-
const rightRailWidth = scrollbarWidth + markerLaneWidth +
|
|
197
|
+
const scrollbarWidth = 7;
|
|
198
|
+
const markerLaneWidth = 8;
|
|
199
|
+
const rightRailWidth = scrollbarWidth + markerLaneWidth + 12;
|
|
191
200
|
ctx.fillStyle = accentColor;
|
|
192
201
|
ctx.fillRect(0, 0, accentWidth, height);
|
|
193
202
|
|
|
@@ -238,23 +247,29 @@ export function renderLowZoomPreviewCanvas(
|
|
|
238
247
|
ctx.fillText(line, leftInset, y);
|
|
239
248
|
});
|
|
240
249
|
|
|
241
|
-
const trackX = width - scrollbarWidth -
|
|
242
|
-
const markerX = trackX - markerLaneWidth -
|
|
250
|
+
const trackX = width - scrollbarWidth - 5;
|
|
251
|
+
const markerX = trackX - markerLaneWidth - 4;
|
|
243
252
|
const trackY = scrollMetrics.trackPadding;
|
|
244
253
|
const trackHeight = scrollMetrics.trackHeight;
|
|
245
254
|
|
|
246
255
|
ctx.fillStyle = 'rgba(255,255,255,0.08)';
|
|
256
|
+
roundRect(ctx, markerX, trackY, markerLaneWidth, trackHeight, 3);
|
|
257
|
+
ctx.fill();
|
|
258
|
+
|
|
259
|
+
ctx.fillStyle = 'rgba(255,255,255,0.12)';
|
|
247
260
|
roundRect(ctx, trackX, trackY, scrollbarWidth, trackHeight, scrollbarWidth / 2);
|
|
248
261
|
ctx.fill();
|
|
249
262
|
|
|
250
263
|
const markers = collectPreviewDiffMarkers(file, scrollMetrics.totalLines);
|
|
251
264
|
for (const marker of markers) {
|
|
252
|
-
const
|
|
265
|
+
const markerHeight = marker.height === 1 ? trackHeight : 5;
|
|
266
|
+
const y = marker.height === 1 ? trackY : trackY + marker.ratio * Math.max(0, trackHeight - markerHeight);
|
|
253
267
|
ctx.fillStyle = marker.color;
|
|
254
|
-
ctx
|
|
268
|
+
roundRect(ctx, markerX, Math.max(trackY, y), markerLaneWidth, markerHeight, 2);
|
|
269
|
+
ctx.fill();
|
|
255
270
|
}
|
|
256
271
|
|
|
257
|
-
ctx.fillStyle = 'rgba(196,181,253,0.
|
|
272
|
+
ctx.fillStyle = 'rgba(196,181,253,0.96)';
|
|
258
273
|
roundRect(ctx, trackX, scrollMetrics.thumbY, scrollbarWidth, scrollMetrics.thumbHeight, scrollbarWidth / 2);
|
|
259
274
|
ctx.fill();
|
|
260
275
|
}
|
|
@@ -37,6 +37,7 @@ const VIEWPORT_MARGIN = 500;
|
|
|
37
37
|
// LOD threshold: below this zoom level, use lightweight pill placeholders
|
|
38
38
|
const LOD_ZOOM_THRESHOLD = 0.25;
|
|
39
39
|
const LOW_ZOOM_MODE_STORAGE_KEY = 'gitmaps:detailMode';
|
|
40
|
+
const PREVIEW_HINT_SHOWN_KEY = 'gitmaps:previewModeHintShown';
|
|
40
41
|
|
|
41
42
|
// Maximum deferred cards to materialize per animation frame
|
|
42
43
|
// Prevents frame drops when zooming out then back in on huge repos
|
|
@@ -120,6 +121,21 @@ export function isPreviewModeForced() {
|
|
|
120
121
|
return _detailMode === 'preview';
|
|
121
122
|
}
|
|
122
123
|
|
|
124
|
+
function maybeShowPreviewModeHint() {
|
|
125
|
+
if (_detailMode !== 'preview') return;
|
|
126
|
+
try {
|
|
127
|
+
if (localStorage.getItem(PREVIEW_HINT_SHOWN_KEY) === 'true') return;
|
|
128
|
+
localStorage.setItem(PREVIEW_HINT_SHOWN_KEY, 'true');
|
|
129
|
+
} catch { }
|
|
130
|
+
|
|
131
|
+
setTimeout(() => {
|
|
132
|
+
try {
|
|
133
|
+
const { showToast } = require('./utils');
|
|
134
|
+
showToast('Preview mode: wheel scrolls card content · right rail shows scroll + diff markers · top-right switch returns to Classic', 'info');
|
|
135
|
+
} catch { }
|
|
136
|
+
}, 120);
|
|
137
|
+
}
|
|
138
|
+
|
|
123
139
|
// ── Status colors for low-zoom cards
|
|
124
140
|
const PILL_COLORS: Record<string, string> = {
|
|
125
141
|
'ts': '#3178c6',
|
|
@@ -441,6 +457,7 @@ export function performViewportCulling(ctx: CanvasContext) {
|
|
|
441
457
|
if (isChanged) pill.dataset.changed = 'true';
|
|
442
458
|
ctx.canvas.appendChild(pill);
|
|
443
459
|
pillCards.set(path, pill);
|
|
460
|
+
maybeShowPreviewModeHint();
|
|
444
461
|
} else if (inView && pillCards.has(path)) {
|
|
445
462
|
updatePillCardLayout(ctx, pillCards.get(path)!, zoom, !!isChanged);
|
|
446
463
|
} else if (!inView && pillCards.has(path)) {
|
|
@@ -470,6 +487,7 @@ export function performViewportCulling(ctx: CanvasContext) {
|
|
|
470
487
|
if (isChanged) pill.dataset.changed = 'true';
|
|
471
488
|
ctx.canvas.appendChild(pill);
|
|
472
489
|
pillCards.set(path, pill);
|
|
490
|
+
maybeShowPreviewModeHint();
|
|
473
491
|
}
|
|
474
492
|
} else {
|
|
475
493
|
updatePillCardLayout(ctx, pillCards.get(path)!, zoom, card.dataset.changed === 'true');
|