xtralab 0.11.1 → 0.12.1
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/README.md +38 -231
- package/lib/agentSessions.d.ts +6 -2
- package/lib/askAgent/editorSelection.d.ts +53 -0
- package/lib/askAgent/editorSelection.js +95 -0
- package/lib/askAgent/icons.d.ts +7 -0
- package/lib/askAgent/icons.js +15 -0
- package/lib/askAgent/index.d.ts +32 -0
- package/lib/askAgent/index.js +741 -0
- package/lib/askAgent/popup.d.ts +83 -0
- package/lib/askAgent/popup.js +221 -0
- package/lib/askAgent/prompt.d.ts +24 -0
- package/lib/askAgent/prompt.js +116 -0
- package/lib/askAgent/queue.d.ts +93 -0
- package/lib/askAgent/queue.js +207 -0
- package/lib/askAgent/queuePanel.d.ts +76 -0
- package/lib/askAgent/queuePanel.js +188 -0
- package/lib/askAgent/targetPicker.d.ts +58 -0
- package/lib/askAgent/targetPicker.js +74 -0
- package/lib/askAgent/tokens.d.ts +124 -0
- package/lib/askAgent/tokens.js +13 -0
- package/lib/commandBar/index.d.ts +12 -8
- package/lib/commandBar/index.js +58 -41
- package/lib/editorBreadcrumbs/index.js +9 -4
- package/lib/editorBreadcrumbs/widget.d.ts +7 -7
- package/lib/editorBreadcrumbs/widget.js +6 -8
- package/lib/fileBrowser/commands.d.ts +2 -8
- package/lib/fileBrowser/commands.js +39 -30
- package/lib/fileBrowser/contents.d.ts +8 -3
- package/lib/fileBrowser/fileBrowser.d.ts +2 -1
- package/lib/fileBrowser/widget.d.ts +5 -9
- package/lib/fileBrowser/widget.js +1 -1
- package/lib/fileTypeIcons/index.js +5 -2
- package/lib/git/api.d.ts +0 -26
- package/lib/git/api.js +2 -44
- package/lib/git/askRequest.d.ts +23 -0
- package/lib/git/askRequest.js +90 -0
- package/lib/git/commands.d.ts +14 -2
- package/lib/git/commands.js +16 -13
- package/lib/git/diffModel.d.ts +1 -9
- package/lib/git/diffModel.js +1 -1
- package/lib/git/diffProvider.js +8 -3
- package/lib/git/diffSurface.d.ts +19 -2
- package/lib/git/diffSurface.js +64 -18
- package/lib/git/diffTheme.d.ts +0 -4
- package/lib/git/diffTheme.js +1 -1
- package/lib/git/diffWidget.d.ts +9 -0
- package/lib/git/diffWidget.js +38 -10
- package/lib/git/imageDiff.d.ts +17 -4
- package/lib/git/imageDiff.js +90 -30
- package/lib/git/index.js +7 -2
- package/lib/git/notebookDiff.d.ts +10 -67
- package/lib/git/notebookDiff.js +62 -69
- package/lib/git/tokens.d.ts +5 -2
- package/lib/highlight/index.js +12 -8
- package/lib/index.js +2 -0
- package/lib/launcher/agents.js +3 -4
- package/lib/launcher/commands.d.ts +6 -2
- package/lib/launcher/dashboard.d.ts +8 -1
- package/lib/launcher/dashboard.js +39 -33
- package/lib/launcher/editorRegistry.js +5 -3
- package/lib/launcher/editors.d.ts +15 -5
- package/lib/launcher/icons.d.ts +0 -37
- package/lib/launcher/icons.js +11 -12
- package/lib/launcher/index.js +2 -1
- package/lib/launcher/invocation.d.ts +0 -15
- package/lib/launcher/invocation.js +1 -1
- package/lib/launcher/schemaDefaults.d.ts +3 -1
- package/lib/launcher/schemaDefaults.js +3 -1
- package/lib/mimeData.d.ts +7 -0
- package/lib/mimeData.js +16 -0
- package/lib/omnibox/index.d.ts +4 -0
- package/lib/omnibox/index.js +43 -2
- package/lib/omnibox/model.d.ts +43 -14
- package/lib/omnibox/model.js +117 -14
- package/lib/omnibox/recents.d.ts +65 -0
- package/lib/omnibox/recents.js +109 -0
- package/lib/omnibox/tokens.d.ts +6 -2
- package/lib/omnibox/widget.d.ts +23 -6
- package/lib/omnibox/widget.js +26 -7
- package/lib/showOutput/index.js +15 -18
- package/lib/terminals/agentTerminals.d.ts +63 -0
- package/lib/terminals/agentTerminals.js +157 -0
- package/lib/terminals/index.d.ts +7 -1
- package/lib/terminals/index.js +50 -30
- package/lib/terminals/model.d.ts +11 -2
- package/lib/terminals/model.js +27 -8
- package/lib/terminals/tokens.d.ts +66 -0
- package/lib/terminals/tokens.js +7 -0
- package/lib/terminals/widget.d.ts +3 -6
- package/lib/terminals/widget.js +1 -1
- package/lib/topBar/index.js +3 -3
- package/lib/walkthrough/index.js +14 -3
- package/lib/walkthrough/panel.d.ts +12 -4
- package/lib/walkthrough/panel.js +9 -3
- package/package.json +49 -51
- package/schema/command-bar.json +10 -0
- package/schema/omnibox.json +15 -0
- package/src/agentSessions.ts +6 -2
- package/src/askAgent/editorSelection.ts +138 -0
- package/src/askAgent/icons.ts +16 -0
- package/src/askAgent/index.ts +915 -0
- package/src/askAgent/popup.tsx +407 -0
- package/src/askAgent/prompt.ts +144 -0
- package/src/askAgent/queue.ts +269 -0
- package/src/askAgent/queuePanel.tsx +418 -0
- package/src/askAgent/targetPicker.tsx +209 -0
- package/src/askAgent/tokens.ts +139 -0
- package/src/commandBar/index.ts +75 -49
- package/src/editorBreadcrumbs/index.ts +14 -4
- package/src/editorBreadcrumbs/widget.ts +11 -9
- package/src/fileBrowser/commands.ts +45 -31
- package/src/fileBrowser/contents.ts +7 -3
- package/src/fileBrowser/fileBrowser.tsx +1 -1
- package/src/fileBrowser/widget.tsx +5 -3
- package/src/fileTypeIcons/index.ts +6 -3
- package/src/git/api.ts +2 -61
- package/src/git/askRequest.ts +113 -0
- package/src/git/commands.ts +41 -14
- package/src/git/diffModel.ts +1 -1
- package/src/git/diffProvider.tsx +11 -3
- package/src/git/diffSurface.tsx +114 -22
- package/src/git/diffTheme.ts +1 -1
- package/src/git/diffWidget.tsx +54 -7
- package/src/git/imageDiff.tsx +169 -58
- package/src/git/index.ts +10 -2
- package/src/git/notebookDiff.tsx +91 -57
- package/src/git/tokens.ts +4 -2
- package/src/highlight/index.ts +12 -8
- package/src/index.ts +2 -0
- package/src/launcher/agents.ts +3 -4
- package/src/launcher/commands.ts +6 -2
- package/src/launcher/dashboard.tsx +86 -38
- package/src/launcher/editorRegistry.ts +10 -4
- package/src/launcher/editors.ts +15 -5
- package/src/launcher/icons.ts +11 -12
- package/src/launcher/index.ts +2 -1
- package/src/launcher/invocation.ts +1 -1
- package/src/launcher/schemaDefaults.ts +3 -1
- package/src/mimeData.ts +20 -0
- package/src/omnibox/index.ts +48 -1
- package/src/omnibox/model.ts +173 -33
- package/src/omnibox/recents.ts +155 -0
- package/src/omnibox/tokens.ts +6 -2
- package/src/omnibox/widget.tsx +54 -13
- package/src/showOutput/index.ts +20 -23
- package/src/terminals/agentTerminals.ts +238 -0
- package/src/terminals/index.ts +54 -30
- package/src/terminals/model.ts +28 -7
- package/src/terminals/tokens.ts +77 -0
- package/src/terminals/widget.tsx +4 -2
- package/src/topBar/index.ts +12 -6
- package/src/walkthrough/index.ts +19 -4
- package/src/walkthrough/panel.ts +15 -5
- package/style/askAgent.css +544 -0
- package/style/commandBar.css +12 -33
- package/style/git.css +72 -31
- package/style/index.css +1 -0
- package/style/index.js +2 -0
- package/style/topBar.css +4 -4
package/src/git/imageDiff.tsx
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
|
|
3
|
+
import type { TranslationBundle } from '@jupyterlab/translation';
|
|
4
|
+
|
|
3
5
|
/**
|
|
4
6
|
* xtralab's image diff, registered in place of `@jupyterlab/git:image-diff`.
|
|
5
7
|
*
|
|
@@ -28,7 +30,9 @@ const IMAGE_DATA_TYPES: Record<string, string> = {
|
|
|
28
30
|
'.ico': 'x-icon'
|
|
29
31
|
};
|
|
30
32
|
|
|
31
|
-
/**
|
|
33
|
+
/**
|
|
34
|
+
* The file extensions registered as the xtralab image diff provider.
|
|
35
|
+
*/
|
|
32
36
|
export const IMAGE_DIFF_EXTENSIONS = Object.keys(IMAGE_DATA_TYPES);
|
|
33
37
|
|
|
34
38
|
/**
|
|
@@ -44,7 +48,9 @@ export function imageDataType(path: string): string | null {
|
|
|
44
48
|
return IMAGE_DATA_TYPES[lower.slice(dot)] ?? null;
|
|
45
49
|
}
|
|
46
50
|
|
|
47
|
-
/**
|
|
51
|
+
/**
|
|
52
|
+
* Comparison layouts, matching jupyterlab-git's image diff modes.
|
|
53
|
+
*/
|
|
48
54
|
type ImageDiffViewMode = '2-up' | 'swipe' | 'onion';
|
|
49
55
|
|
|
50
56
|
const IMAGE_DIFF_VIEW_MODE_STORAGE_KEY = 'xtralab:image-diff-view-mode';
|
|
@@ -80,7 +86,9 @@ function cleanBase64(value: string): string {
|
|
|
80
86
|
return value.replace(/\s+/g, '');
|
|
81
87
|
}
|
|
82
88
|
|
|
83
|
-
/**
|
|
89
|
+
/**
|
|
90
|
+
* Decoded byte length of a (whitespace-free) base64 string.
|
|
91
|
+
*/
|
|
84
92
|
function base64ByteLength(clean: string): number {
|
|
85
93
|
if (clean.length === 0) {
|
|
86
94
|
return 0;
|
|
@@ -104,7 +112,9 @@ function formatBytes(bytes: number): string {
|
|
|
104
112
|
}
|
|
105
113
|
|
|
106
114
|
interface IImageSide {
|
|
107
|
-
/**
|
|
115
|
+
/**
|
|
116
|
+
* Cleaned base64 payload; empty string means the side does not exist.
|
|
117
|
+
*/
|
|
108
118
|
data: string;
|
|
109
119
|
present: boolean;
|
|
110
120
|
uri: string | null;
|
|
@@ -123,12 +133,22 @@ function toSide(raw: string, fileType: string): IImageSide {
|
|
|
123
133
|
}
|
|
124
134
|
|
|
125
135
|
interface IImageDiffViewProps {
|
|
126
|
-
/**
|
|
136
|
+
/**
|
|
137
|
+
* Base64 of the reference (old) revision; empty when added.
|
|
138
|
+
*/
|
|
127
139
|
reference: string;
|
|
128
|
-
/**
|
|
140
|
+
/**
|
|
141
|
+
* Base64 of the challenger (new) revision; empty when deleted.
|
|
142
|
+
*/
|
|
129
143
|
challenger: string;
|
|
130
|
-
/**
|
|
144
|
+
/**
|
|
145
|
+
* MIME subtype from {@link imageDataType}.
|
|
146
|
+
*/
|
|
131
147
|
fileType: string;
|
|
148
|
+
/**
|
|
149
|
+
* Translation bundle for user-facing strings.
|
|
150
|
+
*/
|
|
151
|
+
trans: TranslationBundle;
|
|
132
152
|
}
|
|
133
153
|
|
|
134
154
|
/**
|
|
@@ -137,7 +157,7 @@ interface IImageDiffViewProps {
|
|
|
137
157
|
* plus the selected 2-up / swipe / onion-skin view.
|
|
138
158
|
*/
|
|
139
159
|
export function ImageDiffView(props: IImageDiffViewProps): React.ReactElement {
|
|
140
|
-
const { reference, challenger, fileType } = props;
|
|
160
|
+
const { reference, challenger, fileType, trans } = props;
|
|
141
161
|
const ref = React.useMemo(
|
|
142
162
|
() => toSide(reference, fileType),
|
|
143
163
|
[reference, fileType]
|
|
@@ -161,13 +181,13 @@ export function ImageDiffView(props: IImageDiffViewProps): React.ReactElement {
|
|
|
161
181
|
<div
|
|
162
182
|
className="jp-xtralab-DiffWidget-segmented"
|
|
163
183
|
role="tablist"
|
|
164
|
-
aria-label=
|
|
184
|
+
aria-label={trans.__('Image diff view mode')}
|
|
165
185
|
>
|
|
166
186
|
{(
|
|
167
187
|
[
|
|
168
|
-
['2-up', '2-up'],
|
|
169
|
-
['swipe', 'Swipe'],
|
|
170
|
-
['onion', 'Onion Skin']
|
|
188
|
+
['2-up', trans.__('2-up')],
|
|
189
|
+
['swipe', trans.__('Swipe')],
|
|
190
|
+
['onion', trans.__('Onion Skin')]
|
|
171
191
|
] as [ImageDiffViewMode, string][]
|
|
172
192
|
).map(([value, label]) => (
|
|
173
193
|
<button
|
|
@@ -186,11 +206,11 @@ export function ImageDiffView(props: IImageDiffViewProps): React.ReactElement {
|
|
|
186
206
|
</div>
|
|
187
207
|
<div className="jp-xtralab-ImageDiff-body">
|
|
188
208
|
{mode === '2-up' ? (
|
|
189
|
-
<TwoUp reference={ref} challenger={chall} />
|
|
209
|
+
<TwoUp reference={ref} challenger={chall} trans={trans} />
|
|
190
210
|
) : mode === 'swipe' ? (
|
|
191
|
-
<Swipe reference={ref} challenger={chall} />
|
|
211
|
+
<Swipe reference={ref} challenger={chall} trans={trans} />
|
|
192
212
|
) : (
|
|
193
|
-
<OnionSkin reference={ref} challenger={chall} />
|
|
213
|
+
<OnionSkin reference={ref} challenger={chall} trans={trans} />
|
|
194
214
|
)}
|
|
195
215
|
</div>
|
|
196
216
|
</div>
|
|
@@ -200,6 +220,7 @@ export function ImageDiffView(props: IImageDiffViewProps): React.ReactElement {
|
|
|
200
220
|
interface ISideViewProps {
|
|
201
221
|
reference: IImageSide;
|
|
202
222
|
challenger: IImageSide;
|
|
223
|
+
trans: TranslationBundle;
|
|
203
224
|
}
|
|
204
225
|
|
|
205
226
|
function useNaturalSize(): [
|
|
@@ -231,7 +252,11 @@ function caption(
|
|
|
231
252
|
return `${dims}${formatBytes(side.bytes)}`;
|
|
232
253
|
}
|
|
233
254
|
|
|
234
|
-
function TwoUp({
|
|
255
|
+
function TwoUp({
|
|
256
|
+
reference,
|
|
257
|
+
challenger,
|
|
258
|
+
trans
|
|
259
|
+
}: ISideViewProps): React.ReactElement {
|
|
235
260
|
const [refSize, onRefLoad] = useNaturalSize();
|
|
236
261
|
const [challSize, onChallLoad] = useNaturalSize();
|
|
237
262
|
return (
|
|
@@ -242,15 +267,17 @@ function TwoUp({ reference, challenger }: ISideViewProps): React.ReactElement {
|
|
|
242
267
|
<img
|
|
243
268
|
className="jp-xtralab-ImageDiff-img"
|
|
244
269
|
src={reference.uri}
|
|
245
|
-
alt=
|
|
270
|
+
alt={trans.__('Reference revision')}
|
|
246
271
|
onLoad={onRefLoad}
|
|
247
272
|
/>
|
|
248
273
|
) : (
|
|
249
|
-
<div className="jp-xtralab-ImageDiff-empty">
|
|
274
|
+
<div className="jp-xtralab-ImageDiff-empty">
|
|
275
|
+
{trans.__('No previous image')}
|
|
276
|
+
</div>
|
|
250
277
|
)}
|
|
251
278
|
</div>
|
|
252
279
|
<figcaption className="jp-xtralab-ImageDiff-caption">
|
|
253
|
-
{caption(reference, refSize, 'Added')}
|
|
280
|
+
{caption(reference, refSize, trans.__('Added'))}
|
|
254
281
|
</figcaption>
|
|
255
282
|
</figure>
|
|
256
283
|
<figure className="jp-xtralab-ImageDiff-col">
|
|
@@ -259,15 +286,17 @@ function TwoUp({ reference, challenger }: ISideViewProps): React.ReactElement {
|
|
|
259
286
|
<img
|
|
260
287
|
className="jp-xtralab-ImageDiff-img"
|
|
261
288
|
src={challenger.uri}
|
|
262
|
-
alt=
|
|
289
|
+
alt={trans.__('Challenger revision')}
|
|
263
290
|
onLoad={onChallLoad}
|
|
264
291
|
/>
|
|
265
292
|
) : (
|
|
266
|
-
<div className="jp-xtralab-ImageDiff-empty">
|
|
293
|
+
<div className="jp-xtralab-ImageDiff-empty">
|
|
294
|
+
{trans.__('Deleted')}
|
|
295
|
+
</div>
|
|
267
296
|
)}
|
|
268
297
|
</div>
|
|
269
298
|
<figcaption className="jp-xtralab-ImageDiff-caption">
|
|
270
|
-
{caption(challenger, challSize, 'Deleted')}
|
|
299
|
+
{caption(challenger, challSize, trans.__('Deleted'))}
|
|
271
300
|
</figcaption>
|
|
272
301
|
</figure>
|
|
273
302
|
</div>
|
|
@@ -299,11 +328,85 @@ function RangeSlider(props: {
|
|
|
299
328
|
);
|
|
300
329
|
}
|
|
301
330
|
|
|
302
|
-
|
|
331
|
+
/**
|
|
332
|
+
* Fit a `naturalWidth × naturalHeight` image inside an `areaWidth ×
|
|
333
|
+
* areaHeight` box without upscaling past its intrinsic size — the same
|
|
334
|
+
* "contain, never enlarge" rule the 2-up and onion views get for free from
|
|
335
|
+
* `max-width/height: 100%; width/height: auto`. Returns the displayed pixel
|
|
336
|
+
* box, or `null` until both the image and the area have been measured.
|
|
337
|
+
*/
|
|
338
|
+
function containBox(
|
|
339
|
+
naturalWidth: number,
|
|
340
|
+
naturalHeight: number,
|
|
341
|
+
areaWidth: number,
|
|
342
|
+
areaHeight: number
|
|
343
|
+
): { width: number; height: number } | null {
|
|
344
|
+
if (
|
|
345
|
+
naturalWidth <= 0 ||
|
|
346
|
+
naturalHeight <= 0 ||
|
|
347
|
+
areaWidth <= 0 ||
|
|
348
|
+
areaHeight <= 0
|
|
349
|
+
) {
|
|
350
|
+
return null;
|
|
351
|
+
}
|
|
352
|
+
const scale = Math.min(
|
|
353
|
+
areaWidth / naturalWidth,
|
|
354
|
+
areaHeight / naturalHeight,
|
|
355
|
+
1
|
|
356
|
+
);
|
|
357
|
+
return { width: naturalWidth * scale, height: naturalHeight * scale };
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
/**
|
|
361
|
+
* Track an element's content-box size, kept current across layout changes.
|
|
362
|
+
*/
|
|
363
|
+
function useElementSize(): readonly [
|
|
364
|
+
React.RefObject<HTMLDivElement>,
|
|
365
|
+
{ width: number; height: number }
|
|
366
|
+
] {
|
|
367
|
+
const ref = React.useRef<HTMLDivElement>(null);
|
|
368
|
+
const [size, setSize] = React.useState({ width: 0, height: 0 });
|
|
369
|
+
React.useEffect(() => {
|
|
370
|
+
const el = ref.current;
|
|
371
|
+
if (el === null) {
|
|
372
|
+
return;
|
|
373
|
+
}
|
|
374
|
+
const measure = () => {
|
|
375
|
+
setSize({ width: el.clientWidth, height: el.clientHeight });
|
|
376
|
+
};
|
|
377
|
+
measure();
|
|
378
|
+
const observer = new ResizeObserver(measure);
|
|
379
|
+
observer.observe(el);
|
|
380
|
+
return () => {
|
|
381
|
+
observer.disconnect();
|
|
382
|
+
};
|
|
383
|
+
}, []);
|
|
384
|
+
return [ref, size] as const;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
function Swipe({
|
|
388
|
+
reference,
|
|
389
|
+
challenger,
|
|
390
|
+
trans
|
|
391
|
+
}: ISideViewProps): React.ReactElement {
|
|
303
392
|
const [position, setPosition] = React.useState(50);
|
|
304
393
|
const [dragging, setDragging] = React.useState(false);
|
|
394
|
+
const [refSize, onRefLoad] = useNaturalSize();
|
|
395
|
+
const [challSize, onChallLoad] = useNaturalSize();
|
|
396
|
+
const [areaRef, area] = useElementSize();
|
|
305
397
|
const frameRef = React.useRef<HTMLDivElement>(null);
|
|
306
398
|
|
|
399
|
+
// Display both revisions in a single box — the union of their intrinsic
|
|
400
|
+
// sizes, scaled down to fit but never enlarged — and size the frame to
|
|
401
|
+
// exactly that box. The divider's `left: N%`, the pointer-to-percent
|
|
402
|
+
// mapping (below) and each image's `clip-path` inset then all resolve
|
|
403
|
+
// against the same width, so the white line sits precisely on the seam
|
|
404
|
+
// between the two revisions at every position. A full-width frame instead
|
|
405
|
+
// let the line drift off the seam by as much as half the letterbox.
|
|
406
|
+
const naturalWidth = Math.max(refSize?.[0] ?? 0, challSize?.[0] ?? 0);
|
|
407
|
+
const naturalHeight = Math.max(refSize?.[1] ?? 0, challSize?.[1] ?? 0);
|
|
408
|
+
const box = containBox(naturalWidth, naturalHeight, area.width, area.height);
|
|
409
|
+
|
|
307
410
|
const setFromClientX = React.useCallback((clientX: number) => {
|
|
308
411
|
const frame = frameRef.current;
|
|
309
412
|
if (frame === null) {
|
|
@@ -379,19 +482,25 @@ function Swipe({ reference, challenger }: ISideViewProps): React.ReactElement {
|
|
|
379
482
|
|
|
380
483
|
return (
|
|
381
484
|
<div className="jp-xtralab-ImageDiff-interactive">
|
|
382
|
-
<div
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
485
|
+
<div className="jp-xtralab-ImageDiff-swipeArea" ref={areaRef}>
|
|
486
|
+
<div
|
|
487
|
+
className="jp-xtralab-ImageDiff-swipeFrame"
|
|
488
|
+
ref={frameRef}
|
|
489
|
+
style={
|
|
490
|
+
box !== null
|
|
491
|
+
? { width: `${box.width}px`, height: `${box.height}px` }
|
|
492
|
+
: { width: 0, height: 0, visibility: 'hidden' }
|
|
493
|
+
}
|
|
494
|
+
onPointerDown={onPointerDown}
|
|
495
|
+
data-dragging={dragging ? 'true' : undefined}
|
|
496
|
+
>
|
|
389
497
|
{reference.uri !== null ? (
|
|
390
498
|
<img
|
|
391
|
-
className="jp-xtralab-ImageDiff-
|
|
499
|
+
className="jp-xtralab-ImageDiff-swipeImg"
|
|
392
500
|
src={reference.uri}
|
|
393
|
-
alt=
|
|
501
|
+
alt={trans.__('Reference revision')}
|
|
394
502
|
draggable={false}
|
|
503
|
+
onLoad={onRefLoad}
|
|
395
504
|
style={{
|
|
396
505
|
clipPath: `inset(0 ${100 - position}% 0 0)`
|
|
397
506
|
}}
|
|
@@ -399,35 +508,36 @@ function Swipe({ reference, challenger }: ISideViewProps): React.ReactElement {
|
|
|
399
508
|
) : null}
|
|
400
509
|
{challenger.uri !== null ? (
|
|
401
510
|
<img
|
|
402
|
-
className="jp-xtralab-ImageDiff-
|
|
511
|
+
className="jp-xtralab-ImageDiff-swipeImg"
|
|
403
512
|
src={challenger.uri}
|
|
404
|
-
alt=
|
|
513
|
+
alt={trans.__('Challenger revision')}
|
|
405
514
|
draggable={false}
|
|
515
|
+
onLoad={onChallLoad}
|
|
406
516
|
style={{
|
|
407
517
|
clipPath: `inset(0 0 0 ${position}%)`
|
|
408
518
|
}}
|
|
409
519
|
/>
|
|
410
520
|
) : null}
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
521
|
+
<div
|
|
522
|
+
className="jp-xtralab-ImageDiff-swipeDivider"
|
|
523
|
+
style={{ left: `${position}%` }}
|
|
524
|
+
role="slider"
|
|
525
|
+
aria-label={trans.__('Swipe between reference and challenger')}
|
|
526
|
+
aria-valuemin={0}
|
|
527
|
+
aria-valuemax={100}
|
|
528
|
+
aria-valuenow={Math.round(position)}
|
|
529
|
+
aria-orientation="vertical"
|
|
530
|
+
tabIndex={0}
|
|
531
|
+
onKeyDown={onKeyDown}
|
|
532
|
+
>
|
|
533
|
+
<div className="jp-xtralab-ImageDiff-swipeDividerHandle jp-mod-top">
|
|
534
|
+
<div className="jp-xtralab-ImageDiff-swipeDividerArrow jp-mod-left" />
|
|
535
|
+
<div className="jp-xtralab-ImageDiff-swipeDividerArrow jp-mod-right" />
|
|
536
|
+
</div>
|
|
537
|
+
<div className="jp-xtralab-ImageDiff-swipeDividerHandle jp-mod-bottom">
|
|
538
|
+
<div className="jp-xtralab-ImageDiff-swipeDividerArrow jp-mod-left" />
|
|
539
|
+
<div className="jp-xtralab-ImageDiff-swipeDividerArrow jp-mod-right" />
|
|
540
|
+
</div>
|
|
431
541
|
</div>
|
|
432
542
|
</div>
|
|
433
543
|
</div>
|
|
@@ -437,7 +547,8 @@ function Swipe({ reference, challenger }: ISideViewProps): React.ReactElement {
|
|
|
437
547
|
|
|
438
548
|
function OnionSkin({
|
|
439
549
|
reference,
|
|
440
|
-
challenger
|
|
550
|
+
challenger,
|
|
551
|
+
trans
|
|
441
552
|
}: ISideViewProps): React.ReactElement {
|
|
442
553
|
const [opacity, setOpacity] = React.useState(50);
|
|
443
554
|
return (
|
|
@@ -447,14 +558,14 @@ function OnionSkin({
|
|
|
447
558
|
<img
|
|
448
559
|
className="jp-xtralab-ImageDiff-stackImg"
|
|
449
560
|
src={reference.uri}
|
|
450
|
-
alt=
|
|
561
|
+
alt={trans.__('Reference revision')}
|
|
451
562
|
/>
|
|
452
563
|
) : null}
|
|
453
564
|
{challenger.uri !== null ? (
|
|
454
565
|
<img
|
|
455
566
|
className="jp-xtralab-ImageDiff-stackImg"
|
|
456
567
|
src={challenger.uri}
|
|
457
|
-
alt=
|
|
568
|
+
alt={trans.__('Challenger revision')}
|
|
458
569
|
style={{ opacity: opacity / 100 }}
|
|
459
570
|
/>
|
|
460
571
|
) : null}
|
|
@@ -462,7 +573,7 @@ function OnionSkin({
|
|
|
462
573
|
<RangeSlider
|
|
463
574
|
value={opacity}
|
|
464
575
|
onChange={setOpacity}
|
|
465
|
-
ariaLabel=
|
|
576
|
+
ariaLabel={trans.__('Fade between reference and challenger')}
|
|
466
577
|
/>
|
|
467
578
|
</div>
|
|
468
579
|
);
|
package/src/git/index.ts
CHANGED
|
@@ -4,6 +4,9 @@ import {
|
|
|
4
4
|
} from '@jupyterlab/application';
|
|
5
5
|
import { IThemeManager, WidgetTracker } from '@jupyterlab/apputils';
|
|
6
6
|
import { IRenderMimeRegistry } from '@jupyterlab/rendermime';
|
|
7
|
+
import { ITranslator, nullTranslator } from '@jupyterlab/translation';
|
|
8
|
+
|
|
9
|
+
import { IAskAgent } from '../askAgent/tokens';
|
|
7
10
|
|
|
8
11
|
import {
|
|
9
12
|
CommandArguments,
|
|
@@ -30,12 +33,15 @@ const diffCommandPlugin: JupyterFrontEndPlugin<void> = {
|
|
|
30
33
|
description:
|
|
31
34
|
"The launcher dashboard's side-by-side git diff command, powered by @pierre/diffs.",
|
|
32
35
|
autoStart: true,
|
|
33
|
-
optional: [IThemeManager, IRenderMimeRegistry],
|
|
36
|
+
optional: [IThemeManager, IRenderMimeRegistry, ITranslator, IAskAgent],
|
|
34
37
|
activate: (
|
|
35
38
|
app: JupyterFrontEnd,
|
|
36
39
|
themeManager: IThemeManager | null,
|
|
37
|
-
rendermime: IRenderMimeRegistry | null
|
|
40
|
+
rendermime: IRenderMimeRegistry | null,
|
|
41
|
+
translator: ITranslator | null,
|
|
42
|
+
askAgent: IAskAgent | null
|
|
38
43
|
): void => {
|
|
44
|
+
const trans = (translator ?? nullTranslator).load('jupyterlab');
|
|
39
45
|
// Track open diffs so repeated opens reveal the existing tab.
|
|
40
46
|
const tracker = new WidgetTracker<DiffMainAreaWidget>({
|
|
41
47
|
namespace: GIT_DIFF_TRACKER_NAMESPACE
|
|
@@ -57,6 +63,8 @@ const diffCommandPlugin: JupyterFrontEndPlugin<void> = {
|
|
|
57
63
|
themeManager,
|
|
58
64
|
contentsManager: app.serviceManager.contents,
|
|
59
65
|
rendermime,
|
|
66
|
+
askAgent,
|
|
67
|
+
trans,
|
|
60
68
|
trackDiff: widget => tracker.add(widget),
|
|
61
69
|
onPinned: current => {
|
|
62
70
|
const existing = findDiff(current.change, true);
|