gitmaps 1.1.8 → 1.1.10
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
|
|
@@ -18,11 +18,11 @@ describe('low zoom preview helpers', () => {
|
|
|
18
18
|
expect(getLowZoomPreviewText({ path: 'bin.dat', ext: 'dat', isBinary: true, content: 'abc' }, 0)).toBe('');
|
|
19
19
|
});
|
|
20
20
|
|
|
21
|
-
test('
|
|
22
|
-
const near = getLowZoomScale(0.25);
|
|
21
|
+
test('keeps zoomed-out on-screen text smaller than zoomed-in text', () => {
|
|
23
22
|
const far = getLowZoomScale(0.1);
|
|
24
|
-
|
|
25
|
-
expect(far.
|
|
23
|
+
const near = getLowZoomScale(1);
|
|
24
|
+
expect(far.titleFont * 0.1).toBeLessThan(near.titleFont * 1);
|
|
25
|
+
expect(far.bodyFont * 0.1).toBeLessThan(near.bodyFont * 1);
|
|
26
26
|
});
|
|
27
27
|
|
|
28
28
|
test('wraps preview text into bounded lines with ellipsis', () => {
|
|
@@ -34,7 +34,12 @@ describe('low zoom preview helpers', () => {
|
|
|
34
34
|
test('preview capacity estimates stay positive', () => {
|
|
35
35
|
expect(estimatePreviewCharsPerLine(580, 0.25)).toBeGreaterThan(8);
|
|
36
36
|
expect(estimateTitleCharsPerLine(580, 0.25)).toBeGreaterThan(8);
|
|
37
|
-
expect(estimatePreviewLineCapacity(700, 0.25)).toBeGreaterThanOrEqual(
|
|
37
|
+
expect(estimatePreviewLineCapacity(700, 0.25)).toBeGreaterThanOrEqual(3);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
test('higher zoom yields substantially more visible preview lines', () => {
|
|
41
|
+
expect(estimatePreviewLineCapacity(700, 1)).toBeGreaterThanOrEqual(20);
|
|
42
|
+
expect(estimatePreviewLineCapacity(700, 0.1)).toBeLessThan(estimatePreviewLineCapacity(700, 1));
|
|
38
43
|
});
|
|
39
44
|
|
|
40
45
|
test('title typography is larger than body typography for readability', () => {
|
|
@@ -3,17 +3,21 @@ const PREVIEWABLE_EXTS = new Set([
|
|
|
3
3
|
]);
|
|
4
4
|
|
|
5
5
|
export function getLowZoomScale(zoom: number) {
|
|
6
|
-
const clampedZoom = Math.max(0.08, Math.min(
|
|
7
|
-
const progress = (
|
|
8
|
-
|
|
9
|
-
const
|
|
6
|
+
const clampedZoom = Math.max(0.08, Math.min(1, zoom));
|
|
7
|
+
const progress = (clampedZoom - 0.08) / (1 - 0.08);
|
|
8
|
+
|
|
9
|
+
const desiredScreenTitle = 8 + progress * 8;
|
|
10
|
+
const desiredScreenBody = 5.5 + progress * 6.5;
|
|
11
|
+
const desiredScreenPadding = 6 + progress * 8;
|
|
12
|
+
const desiredScreenGap = 4 + progress * 4;
|
|
13
|
+
|
|
10
14
|
return {
|
|
11
15
|
titleFont: desiredScreenTitle / clampedZoom,
|
|
12
16
|
titleLineHeight: (desiredScreenTitle * 1.08) / clampedZoom,
|
|
13
17
|
bodyFont: desiredScreenBody / clampedZoom,
|
|
14
|
-
bodyLineHeight: (desiredScreenBody * 1.
|
|
15
|
-
padding:
|
|
16
|
-
gap:
|
|
18
|
+
bodyLineHeight: (desiredScreenBody * 1.35) / clampedZoom,
|
|
19
|
+
padding: desiredScreenPadding / clampedZoom,
|
|
20
|
+
gap: desiredScreenGap / clampedZoom,
|
|
17
21
|
radius: 10 / clampedZoom,
|
|
18
22
|
};
|
|
19
23
|
}
|
|
@@ -83,22 +87,26 @@ function ellipsizeWrappedLines(lines: string[], maxLines: number) {
|
|
|
83
87
|
|
|
84
88
|
export function estimatePreviewLineCapacity(height: number, zoom: number): number {
|
|
85
89
|
const scale = getLowZoomScale(zoom);
|
|
86
|
-
const
|
|
87
|
-
|
|
90
|
+
const titleLines = zoom >= 0.35 ? 2 : 1;
|
|
91
|
+
const available = Math.max(
|
|
92
|
+
scale.bodyLineHeight * 2,
|
|
93
|
+
height - scale.padding * 2 - scale.titleLineHeight * titleLines - scale.bodyFont - scale.gap * 3,
|
|
94
|
+
);
|
|
95
|
+
return Math.max(zoom >= 0.6 ? 20 : zoom >= 0.35 ? 12 : 3, Math.floor(available / scale.bodyLineHeight));
|
|
88
96
|
}
|
|
89
97
|
|
|
90
98
|
export function estimateTitleCharsPerLine(width: number, zoom: number): number {
|
|
91
99
|
const scale = getLowZoomScale(zoom);
|
|
92
|
-
const available = Math.max(
|
|
93
|
-
const avgCharWidth = Math.max(
|
|
94
|
-
return Math.max(
|
|
100
|
+
const available = Math.max(120, width - scale.padding * 2 - Math.max(12, width * 0.018));
|
|
101
|
+
const avgCharWidth = Math.max(5.5, scale.titleFont * 0.56);
|
|
102
|
+
return Math.max(12, Math.floor(available / avgCharWidth));
|
|
95
103
|
}
|
|
96
104
|
|
|
97
105
|
export function estimatePreviewCharsPerLine(width: number, zoom: number): number {
|
|
98
106
|
const scale = getLowZoomScale(zoom);
|
|
99
|
-
const available = Math.max(
|
|
100
|
-
const avgCharWidth = Math.max(
|
|
101
|
-
return Math.max(
|
|
107
|
+
const available = Math.max(100, width - scale.padding * 2 - Math.max(12, width * 0.018));
|
|
108
|
+
const avgCharWidth = Math.max(5, scale.bodyFont * 0.58);
|
|
109
|
+
return Math.max(10, Math.floor(available / avgCharWidth));
|
|
102
110
|
}
|
|
103
111
|
|
|
104
112
|
export function renderLowZoomPreviewCanvas(
|
|
@@ -135,10 +143,11 @@ export function renderLowZoomPreviewCanvas(
|
|
|
135
143
|
roundRect(ctx, 0, 0, width, height, Math.max(6, scale.radius));
|
|
136
144
|
ctx.fill();
|
|
137
145
|
|
|
146
|
+
const accentWidth = Math.max(6, width * 0.012);
|
|
138
147
|
ctx.fillStyle = accentColor;
|
|
139
|
-
ctx.fillRect(0, 0,
|
|
148
|
+
ctx.fillRect(0, 0, accentWidth, height);
|
|
140
149
|
|
|
141
|
-
const leftInset = scale.padding +
|
|
150
|
+
const leftInset = scale.padding + accentWidth + scale.gap * 0.8;
|
|
142
151
|
const topInset = scale.padding;
|
|
143
152
|
const maxTextWidth = Math.max(40, width - leftInset - scale.padding);
|
|
144
153
|
|
|
@@ -146,19 +155,21 @@ export function renderLowZoomPreviewCanvas(
|
|
|
146
155
|
ctx.font = `700 ${scale.titleFont}px "JetBrains Mono", monospace`;
|
|
147
156
|
ctx.fillStyle = '#f8fafc';
|
|
148
157
|
const title = path.split('/').pop() || path;
|
|
149
|
-
const
|
|
158
|
+
const maxTitleLines = zoom >= 0.35 ? 2 : 1;
|
|
159
|
+
const titleLines = wrapPreviewText(title, estimateTitleCharsPerLine(width, zoom), maxTitleLines);
|
|
150
160
|
titleLines.forEach((line, index) => {
|
|
151
161
|
ctx.fillText(trimToWidth(ctx, line, maxTextWidth), leftInset, topInset + index * scale.titleLineHeight);
|
|
152
162
|
});
|
|
153
163
|
|
|
154
|
-
const subtitleY = topInset + titleLines.length * scale.titleLineHeight + scale.gap * 0.
|
|
155
|
-
|
|
164
|
+
const subtitleY = topInset + titleLines.length * scale.titleLineHeight + scale.gap * 0.65;
|
|
165
|
+
const subtitleFont = Math.max(scale.bodyFont * 0.82, 6 / Math.max(zoom, 0.08));
|
|
166
|
+
ctx.font = `${subtitleFont}px "JetBrains Mono", monospace`;
|
|
156
167
|
ctx.fillStyle = 'rgba(226,232,240,0.72)';
|
|
157
168
|
const pathParts = path.split('/');
|
|
158
|
-
const subtitle = pathParts.length > 1 ? pathParts.slice(Math.max(0, pathParts.length -
|
|
169
|
+
const subtitle = pathParts.length > 1 ? pathParts.slice(Math.max(0, pathParts.length - 2), -1).join(' / ') : 'root';
|
|
159
170
|
ctx.fillText(trimToWidth(ctx, subtitle, maxTextWidth), leftInset, subtitleY);
|
|
160
171
|
|
|
161
|
-
const previewY = subtitleY +
|
|
172
|
+
const previewY = subtitleY + subtitleFont + scale.gap;
|
|
162
173
|
const rawPreview = getLowZoomPreviewText(file, scrollTop) || 'Preview unavailable';
|
|
163
174
|
const wrapped = wrapPreviewText(
|
|
164
175
|
rawPreview,
|
|
@@ -56,10 +56,9 @@ let _currentLodMode: 'full' | 'pill' = 'full';
|
|
|
56
56
|
let _detailMode: 'auto' | 'preview' = (() => {
|
|
57
57
|
try {
|
|
58
58
|
const stored = localStorage.getItem(LOW_ZOOM_MODE_STORAGE_KEY);
|
|
59
|
-
|
|
60
|
-
return 'preview';
|
|
59
|
+
return stored === 'preview' ? 'preview' : 'auto';
|
|
61
60
|
} catch {
|
|
62
|
-
return '
|
|
61
|
+
return 'auto';
|
|
63
62
|
}
|
|
64
63
|
})();
|
|
65
64
|
|