gitmaps 1.1.21 → 1.1.23
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 +0 -0
- package/app/lib/card-context-menu.tsx +18 -18
- package/app/lib/context.ts +1 -1
- package/app/lib/file-preview.ts +1 -1
- package/app/lib/settings-modal.tsx +5 -16
- package/app/lib/viewport-culling.ts +20 -1
- package/package.json +1 -1
package/app/analytics.db
CHANGED
|
Binary file
|
|
@@ -50,32 +50,32 @@ function ContextMenu({ onAction, onActionLayer, onSelectFolder, isInActiveLayer,
|
|
|
50
50
|
|
|
51
51
|
return (
|
|
52
52
|
<>
|
|
53
|
-
<button className="ctx-item" onClick={() => onAction('copy-path')}>📋 Copy path</button>
|
|
54
|
-
<button className="ctx-item" onClick={() => onAction('select')}>☑️ Select</button>
|
|
53
|
+
<button type="button" className="ctx-item" onClick={() => onAction('copy-path')}>📋 Copy path</button>
|
|
54
|
+
<button type="button" className="ctx-item" onClick={() => onAction('select')}>☑️ Select</button>
|
|
55
55
|
{ancestors.length > 0 ? (
|
|
56
56
|
<div className="ctx-item ctx-dropdown">
|
|
57
57
|
<span>📁 Select from folder ▸</span>
|
|
58
58
|
<div className="ctx-dropdown-content">
|
|
59
59
|
{ancestors.map(dir => (
|
|
60
|
-
<button key={dir} className="ctx-item" onClick={() => onSelectFolder(dir)}>
|
|
60
|
+
<button type="button" key={dir} className="ctx-item" onClick={() => onSelectFolder(dir)}>
|
|
61
61
|
📂 {dir}
|
|
62
62
|
</button>
|
|
63
63
|
))}
|
|
64
64
|
</div>
|
|
65
65
|
</div>
|
|
66
66
|
) : (
|
|
67
|
-
<button className="ctx-item" onClick={() => onSelectFolder('')}>📁 Select all (root)</button>
|
|
67
|
+
<button type="button" className="ctx-item" onClick={() => onSelectFolder('')}>📁 Select all (root)</button>
|
|
68
68
|
)}
|
|
69
|
-
<button className="ctx-item" onClick={() => onAction('pin')}>{pinned ? '📌 Unpin card' : '📌 Pin card'}</button>
|
|
69
|
+
<button type="button" className="ctx-item" onClick={() => onAction('pin')}>{pinned ? '📌 Unpin card' : '📌 Pin card'}</button>
|
|
70
70
|
<div className="ctx-divider"></div>
|
|
71
|
-
<button className="ctx-item" onClick={() => onAction('expand')}>📖 Open in Editor</button>
|
|
72
|
-
<button className="ctx-item" onClick={() => onAction('edit')}>✏️ Edit file</button>
|
|
73
|
-
<button className="ctx-item" onClick={() => onAction('blame')}>👤 Git blame</button>
|
|
74
|
-
<button className="ctx-item" onClick={() => onAction('connect')}>🔗 Connect to...</button>
|
|
75
|
-
<button className="ctx-item" onClick={() => onAction('fit-content')}>📏 Fit content</button>
|
|
76
|
-
<button className="ctx-item" onClick={() => onAction('fit-screen')}>📺 Fit screen</button>
|
|
71
|
+
<button type="button" className="ctx-item" onClick={() => onAction('expand')}>📖 Open in Editor</button>
|
|
72
|
+
<button type="button" className="ctx-item" onClick={() => onAction('edit')}>✏️ Edit file</button>
|
|
73
|
+
<button type="button" className="ctx-item" onClick={() => onAction('blame')}>👤 Git blame</button>
|
|
74
|
+
<button type="button" className="ctx-item" onClick={() => onAction('connect')}>🔗 Connect to...</button>
|
|
75
|
+
<button type="button" className="ctx-item" onClick={() => onAction('fit-content')}>📏 Fit content</button>
|
|
76
|
+
<button type="button" className="ctx-item" onClick={() => onAction('fit-screen')}>📺 Fit screen</button>
|
|
77
77
|
<div className="ctx-divider"></div>
|
|
78
|
-
<button className="ctx-item" onClick={() => onAction('history')}>🕰️ File history</button>
|
|
78
|
+
<button type="button" className="ctx-item" onClick={() => onAction('history')}>🕰️ File history</button>
|
|
79
79
|
<div className="ctx-item ctx-dropdown">
|
|
80
80
|
<span>📦 Move to Layer ▸</span>
|
|
81
81
|
<div className="ctx-dropdown-content">
|
|
@@ -83,24 +83,24 @@ function ContextMenu({ onAction, onActionLayer, onSelectFolder, isInActiveLayer,
|
|
|
83
83
|
<div className="ctx-item" style="opacity: 0.5; pointer-events: none">No custom layers</div>
|
|
84
84
|
) : (
|
|
85
85
|
customLayers.map(l => (
|
|
86
|
-
<button key={l.id} className="ctx-item" onClick={() => onActionLayer(l.id)}>
|
|
86
|
+
<button type="button" key={l.id} className="ctx-item" onClick={() => onActionLayer(l.id)}>
|
|
87
87
|
+ {l.name}
|
|
88
88
|
</button>
|
|
89
89
|
))
|
|
90
90
|
)}
|
|
91
91
|
<div className="ctx-divider"></div>
|
|
92
|
-
<button className="ctx-item" onClick={() => onActionLayer('new')}>✨ Create New Layer</button>
|
|
92
|
+
<button type="button" className="ctx-item" onClick={() => onActionLayer('new')}>✨ Create New Layer</button>
|
|
93
93
|
</div>
|
|
94
94
|
</div>
|
|
95
95
|
{isInActiveLayer && (
|
|
96
|
-
<button className="ctx-item" onClick={() => onAction('remove-from-layer')} style="color: #60a5fa">
|
|
96
|
+
<button type="button" className="ctx-item" onClick={() => onAction('remove-from-layer')} style="color: #60a5fa">
|
|
97
97
|
↩ Move to Main
|
|
98
98
|
</button>
|
|
99
99
|
)}
|
|
100
100
|
<div className="ctx-divider"></div>
|
|
101
|
-
<button className="ctx-item" onClick={() => onAction('hide')} style="color: #f59e0b">🙈 Hide file</button>
|
|
102
|
-
<button className="ctx-item" onClick={() => onAction('rename')}>✏️ Rename / Move</button>
|
|
103
|
-
<button className="ctx-item" onClick={() => onAction('delete')} style="color: #ef4444">🗑️ Delete file</button>
|
|
101
|
+
<button type="button" className="ctx-item" onClick={() => onAction('hide')} style="color: #f59e0b">🙈 Hide file</button>
|
|
102
|
+
<button type="button" className="ctx-item" onClick={() => onAction('rename')}>✏️ Rename / Move</button>
|
|
103
|
+
<button type="button" className="ctx-item" onClick={() => onAction('delete')} style="color: #ef4444">🗑️ Delete file</button>
|
|
104
104
|
</>
|
|
105
105
|
);
|
|
106
106
|
}
|
package/app/lib/context.ts
CHANGED
|
@@ -94,7 +94,7 @@ export function createCanvasContext(actor: any): CanvasContext {
|
|
|
94
94
|
allFilesData: null,
|
|
95
95
|
commitFilesData: null,
|
|
96
96
|
deferredCards: new Map(),
|
|
97
|
-
controlMode: (localStorage.getItem('gitcanvas:controlMode') as any) || '
|
|
97
|
+
controlMode: (localStorage.getItem('gitcanvas:controlMode') as any) || 'simple',
|
|
98
98
|
};
|
|
99
99
|
|
|
100
100
|
currentCanvasContext = ctx;
|
package/app/lib/file-preview.ts
CHANGED
|
@@ -35,7 +35,7 @@ let currentCardPath: string | null = null;
|
|
|
35
35
|
let isInitialized = false;
|
|
36
36
|
let _ctx: CanvasContext | null = null;
|
|
37
37
|
let isPreviewEnabled =
|
|
38
|
-
localStorage.getItem("gitmaps:previewEnabled")
|
|
38
|
+
localStorage.getItem("gitmaps:previewEnabled") === "true"; // disabled by default
|
|
39
39
|
let _isHoveringPopup = false;
|
|
40
40
|
|
|
41
41
|
// ─── Popup container ─────────────────────────────────────
|
|
@@ -98,14 +98,10 @@ function SettingsPanel({ settings }: { settings: GitCanvasSettings }) {
|
|
|
98
98
|
<ToggleGroup id="settingRenderMode" value={settings.renderMode}
|
|
99
99
|
options={[{ value: 'canvas', label: 'Canvas' }, { value: 'dom', label: 'DOM' }]} />
|
|
100
100
|
</SettingsRow>
|
|
101
|
-
<SettingsRow label="Font Size" desc="Code font size in
|
|
101
|
+
<SettingsRow label="Font Size" desc="Code font size in full cards and editor views">
|
|
102
102
|
<Slider id="settingFontSize" valueId="fontSizeValue"
|
|
103
103
|
min={10} max={18} step={1} value={settings.fontSize} suffix="px" />
|
|
104
104
|
</SettingsRow>
|
|
105
|
-
<SettingsRow label="Popup Font Size" desc="Font size for hover popup previews">
|
|
106
|
-
<Slider id="settingPopupFontSize" valueId="popupFontSizeValue"
|
|
107
|
-
min={10} max={24} step={1} value={settings.popupFontSize} suffix="px" />
|
|
108
|
-
</SettingsRow>
|
|
109
105
|
<SettingsRow label="Card Width" desc="Character columns per card (like editors)">
|
|
110
106
|
<Slider id="settingCardWidth" valueId="cardWidthValue"
|
|
111
107
|
min={40} max={120} step={5} value={cardCols} suffix=" cols" />
|
|
@@ -146,19 +142,19 @@ function SettingsPanel({ settings }: { settings: GitCanvasSettings }) {
|
|
|
146
142
|
|
|
147
143
|
{/* Preview Mode Section */}
|
|
148
144
|
<SettingsSection title="Preview Mode">
|
|
149
|
-
<SettingsRow label="
|
|
145
|
+
<SettingsRow label="Zoomed-out title" desc="Filename size at the farthest preview zoom">
|
|
150
146
|
<Slider id="settingPreviewFarTitlePx" valueId="previewFarTitlePxValue"
|
|
151
147
|
min={6} max={14} step={1} value={settings.previewFarTitlePx} suffix="px" />
|
|
152
148
|
</SettingsRow>
|
|
153
|
-
<SettingsRow label="
|
|
149
|
+
<SettingsRow label="Zoomed-in title" desc="Filename size at the closest preview zoom">
|
|
154
150
|
<Slider id="settingPreviewNearTitlePx" valueId="previewNearTitlePxValue"
|
|
155
151
|
min={10} max={24} step={1} value={settings.previewNearTitlePx} suffix="px" />
|
|
156
152
|
</SettingsRow>
|
|
157
|
-
<SettingsRow label="
|
|
153
|
+
<SettingsRow label="Zoomed-out lines" desc="Minimum content lines shown at the farthest preview zoom">
|
|
158
154
|
<Slider id="settingPreviewFarLines" valueId="previewFarLinesValue"
|
|
159
155
|
min={1} max={8} step={1} value={settings.previewFarLines} suffix="" />
|
|
160
156
|
</SettingsRow>
|
|
161
|
-
<SettingsRow label="
|
|
157
|
+
<SettingsRow label="Zoomed-in lines" desc="Target content lines shown at the closest preview zoom">
|
|
162
158
|
<Slider id="settingPreviewNearLines" valueId="previewNearLinesValue"
|
|
163
159
|
min={8} max={40} step={1} value={settings.previewNearLines} suffix="" />
|
|
164
160
|
</SettingsRow>
|
|
@@ -257,13 +253,6 @@ export function openSettingsModal(ctx?: any) {
|
|
|
257
253
|
applyFontSize(parseInt(fontSlider.value));
|
|
258
254
|
});
|
|
259
255
|
|
|
260
|
-
const popupFontSlider = _modal.querySelector('#settingPopupFontSize') as HTMLInputElement;
|
|
261
|
-
const popupFontValue = _modal.querySelector('#popupFontSizeValue')!;
|
|
262
|
-
popupFontSlider?.addEventListener('input', () => {
|
|
263
|
-
popupFontValue.textContent = `${popupFontSlider.value}px`;
|
|
264
|
-
updateSettings({ popupFontSize: parseInt(popupFontSlider.value) });
|
|
265
|
-
});
|
|
266
|
-
|
|
267
256
|
const cardWidthSlider = _modal.querySelector('#settingCardWidth') as HTMLInputElement;
|
|
268
257
|
const cardWidthValue = _modal.querySelector('#cardWidthValue')!;
|
|
269
258
|
cardWidthSlider?.addEventListener('input', () => {
|
|
@@ -826,6 +826,25 @@ export function setupPillInteraction(ctx: CanvasContext) {
|
|
|
826
826
|
window.addEventListener('mouseup', onPillUp);
|
|
827
827
|
});
|
|
828
828
|
|
|
829
|
+
ctx.canvas.addEventListener('contextmenu', (e: MouseEvent) => {
|
|
830
|
+
const pill = (e.target as HTMLElement).closest('.file-pill') as HTMLElement;
|
|
831
|
+
if (!pill) return;
|
|
832
|
+
e.preventDefault();
|
|
833
|
+
e.stopPropagation();
|
|
834
|
+
|
|
835
|
+
const pillPath = pill.dataset.path || '';
|
|
836
|
+
if (pillPath) {
|
|
837
|
+
const selected = ctx.snap().context.selectedCards || [];
|
|
838
|
+
if (!selected.includes(pillPath)) {
|
|
839
|
+
ctx.actor.send({ type: 'SELECT_CARD', path: pillPath, shift: false });
|
|
840
|
+
updatePillSelectionHighlights(ctx);
|
|
841
|
+
}
|
|
842
|
+
import('./cards').then(({ showCardContextMenu }) => {
|
|
843
|
+
showCardContextMenu(ctx, pill, e.clientX, e.clientY);
|
|
844
|
+
});
|
|
845
|
+
}
|
|
846
|
+
});
|
|
847
|
+
|
|
829
848
|
// Native dblclick to open editor modal (consistent with card dblclick)
|
|
830
849
|
ctx.canvas.addEventListener('dblclick', (e: MouseEvent) => {
|
|
831
850
|
const pill = (e.target as HTMLElement).closest('.file-pill') as HTMLElement;
|
|
@@ -834,7 +853,7 @@ export function setupPillInteraction(ctx: CanvasContext) {
|
|
|
834
853
|
e.preventDefault();
|
|
835
854
|
const pillPath = pill.dataset.path || '';
|
|
836
855
|
if (pillPath) {
|
|
837
|
-
const file = ctx
|
|
856
|
+
const file = resolvePreviewFile(ctx, pillPath) ||
|
|
838
857
|
{ path: pillPath, name: pillPath.split('/').pop(), lines: 0 };
|
|
839
858
|
import('./file-modal').then(({ openFileModal }) => openFileModal(ctx, file));
|
|
840
859
|
}
|