@kubohiroya/turbowarp-plus-editor-git 0.10.0 → 0.12.0
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/dist/editor-block-locator.d.ts +27 -0
- package/dist/file-diff-view.d.ts +3 -1
- package/dist/index.d.ts +25 -0
- package/dist/index.js +126 -32
- package/dist/project-change-list.d.ts +3 -1
- package/dist/project-source-diff.d.ts +2 -0
- package/dist/project-source-diff.js +2 -2
- package/dist/project-source-review-model.d.ts +35 -0
- package/dist/project-source-review.d.ts +6 -1
- package/dist/pull-request-panel.d.ts +4 -1
- package/dist/review-words.d.ts +6 -0
- package/dist/{scratch-block-diff-renderer-DZR8ep-T.js → scratch-block-diff-renderer-e_drVlHE.js} +598 -263
- package/dist/style.css +16 -0
- package/package.json +1 -1
- package/src/editor-block-locator.ts +55 -0
- package/src/file-diff-view.tsx +4 -3
- package/src/index.tsx +74 -16
- package/src/project-change-list.tsx +4 -3
- package/src/project-source-diff.css +14 -0
- package/src/project-source-diff.tsx +2 -0
- package/src/project-source-review-model.ts +154 -8
- package/src/project-source-review.tsx +136 -24
- package/src/pull-request-panel.tsx +9 -4
- package/src/review-words.ts +66 -0
- package/src/style.css +2 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { ProjectBlockLocator, ScratchBlockLocationWorkspace } from './block-diff-location.js';
|
|
2
|
+
/** The parts of a Scratch VM the locator reads to find a stage or sprite. */
|
|
3
|
+
export interface LocatorVM {
|
|
4
|
+
runtime: {
|
|
5
|
+
targets: readonly {
|
|
6
|
+
id: string;
|
|
7
|
+
isOriginal?: boolean;
|
|
8
|
+
isStage: boolean;
|
|
9
|
+
getName(): string;
|
|
10
|
+
}[];
|
|
11
|
+
};
|
|
12
|
+
editingTarget?: {
|
|
13
|
+
id: string;
|
|
14
|
+
} | null;
|
|
15
|
+
}
|
|
16
|
+
export interface EditorBlockLocatorOptions {
|
|
17
|
+
vm: LocatorVM;
|
|
18
|
+
/** Opens the code of one stage or sprite in the Editor, as project search does. */
|
|
19
|
+
openTargetCode(targetId: string): void | Promise<void>;
|
|
20
|
+
/** The Editor's code workspace as it is now, or `null` while none is shown. */
|
|
21
|
+
getWorkspace(): ScratchBlockLocationWorkspace | null | Promise<ScratchBlockLocationWorkspace | null>;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Finds the stage or sprite of a compared version in the open project, opens its code and waits for the block,
|
|
25
|
+
* then centers and outlines it. The caller decides which version matches the open project.
|
|
26
|
+
*/
|
|
27
|
+
export declare function createEditorBlockLocator({ vm, openTargetCode, getWorkspace }: EditorBlockLocatorOptions): ProjectBlockLocator;
|
package/dist/file-diff-view.d.ts
CHANGED
|
@@ -3,16 +3,18 @@ import type { FileChange, FileDiff } from './repository.js';
|
|
|
3
3
|
import type { labelsFor } from './messages.js';
|
|
4
4
|
import type { ProjectBlockRenderer } from './scratch-block-diff-renderer.js';
|
|
5
5
|
import type { ProjectAssetLoader } from './project-assets.js';
|
|
6
|
+
import type { ProjectBlockLocator } from './block-diff-location.js';
|
|
6
7
|
/** Project sources are the files the panel opens as projects. */
|
|
7
8
|
export declare const isProjectSource: (path: string) => boolean;
|
|
8
9
|
/**
|
|
9
10
|
* Shows one changed file. Project sources are compared as blocks by default, with their text diff one switch away.
|
|
10
11
|
*/
|
|
11
|
-
export declare function FileDiffView({ change, diff, labels, locale, renderBlock, loadAsset }: {
|
|
12
|
+
export declare function FileDiffView({ change, diff, labels, locale, renderBlock, loadAsset, locateBlock }: {
|
|
12
13
|
change: FileChange;
|
|
13
14
|
diff: FileDiff | null;
|
|
14
15
|
labels: ReturnType<typeof labelsFor>;
|
|
15
16
|
locale: string;
|
|
16
17
|
renderBlock?: ProjectBlockRenderer;
|
|
17
18
|
loadAsset?: ProjectAssetLoader;
|
|
19
|
+
locateBlock?: ProjectBlockLocator;
|
|
18
20
|
}): React.JSX.Element;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import type { GitConnectionSettings } from './connection-settings.js';
|
|
2
2
|
import type { ProjectBlockRenderer } from './scratch-block-diff-renderer.js';
|
|
3
|
+
import type { ScratchBlockLocationWorkspace } from './block-diff-location.js';
|
|
4
|
+
export { createScratchBlocksDiffLocator } from './block-diff-location.js';
|
|
5
|
+
export { createEditorBlockLocator } from './editor-block-locator.js';
|
|
3
6
|
export { createScratchBlocksDiffRenderer } from './scratch-block-diff-renderer.js';
|
|
4
7
|
export type { ScratchBlockDiffRendererOptions, ScratchBlocksPort } from './scratch-block-diff-renderer.js';
|
|
5
8
|
export { openRepository, createReadOnlyFs, GitPanelError } from './repository.js';
|
|
@@ -11,6 +14,28 @@ export interface GitHost {
|
|
|
11
14
|
isProjectDirty(): boolean;
|
|
12
15
|
isProjectRunning?(): boolean;
|
|
13
16
|
subscribe?(listener: (event: 'loaded' | 'changed') => void): () => void;
|
|
17
|
+
/**
|
|
18
|
+
* Opens the panel as a tab of the host's layout, with the same shape as the layout package's DocumentPanelRequest.
|
|
19
|
+
* Returning `false` keeps the modal dialog.
|
|
20
|
+
*/
|
|
21
|
+
openPanel?(request: GitPanelRequest): boolean;
|
|
22
|
+
/** Opens the code of one stage or sprite, so a diff can point at its block. Without it, no block is located. */
|
|
23
|
+
openTargetCode?(targetId: string): void | Promise<void>;
|
|
24
|
+
/** The Editor's code workspace as it is now. */
|
|
25
|
+
getWorkspace?(): ScratchBlockLocationWorkspace | null | Promise<ScratchBlockLocationWorkspace | null>;
|
|
26
|
+
}
|
|
27
|
+
export interface GitPanelRequest {
|
|
28
|
+
reference: {
|
|
29
|
+
providerId: string;
|
|
30
|
+
documentId: string;
|
|
31
|
+
};
|
|
32
|
+
filename: string;
|
|
33
|
+
title?: string;
|
|
34
|
+
transient?: boolean;
|
|
35
|
+
mount(element: HTMLElement, close: () => void): {
|
|
36
|
+
requestClose(): void;
|
|
37
|
+
dispose(): void;
|
|
38
|
+
};
|
|
14
39
|
}
|
|
15
40
|
export declare function mountGitPanel({ vm, document, host }: {
|
|
16
41
|
vm: object;
|
package/dist/index.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { _ as useCostumeImage, a as gitHubRepositoryFromOrigin, b as parseProjectSource, g as useAssetImage, i as createGitHubPullRequests, l as organizeProjectChanges, n as createScratchBlocksDiffLocator, o as ProjectSourceComparison, r as PullRequestError, s as ProjectSourceReview, t as createScratchBlocksDiffRenderer, u as projectPropertyLabel } from "./scratch-block-diff-renderer-e_drVlHE.js";
|
|
2
2
|
import { n as init_objectSpread2, r as __commonJSMin, t as _objectSpread2$1 } from "./objectSpread2-Dkd68nJH.js";
|
|
3
3
|
import { i as createReadOnlyFs, r as GitPanelError, t as openRepository } from "./repository-CtvWYPQ8.js";
|
|
4
4
|
import * as m from "react";
|
|
5
5
|
import React, { createContext, memo, useCallback, useContext, useEffect, useMemo, useRef, useState } from "react";
|
|
6
|
-
import { render, unmountComponentAtNode } from "react-dom";
|
|
6
|
+
import { createPortal, render, unmountComponentAtNode } from "react-dom";
|
|
7
7
|
// builtin:esm-external-require-react
|
|
8
8
|
var require_builtin_esm_external_require_react = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
9
9
|
init_objectSpread2();
|
|
@@ -2684,7 +2684,7 @@ var isProjectSource = (path) => path.split("/").pop() === "project.source.json";
|
|
|
2684
2684
|
/**
|
|
2685
2685
|
* Shows one changed file. Project sources are compared as blocks by default, with their text diff one switch away.
|
|
2686
2686
|
*/
|
|
2687
|
-
function FileDiffView({ change, diff, labels, locale, renderBlock, loadAsset }) {
|
|
2687
|
+
function FileDiffView({ change, diff, labels, locale, renderBlock, loadAsset, locateBlock }) {
|
|
2688
2688
|
var _change$oldMode, _change$newMode;
|
|
2689
2689
|
const [view, setView] = useState("blocks");
|
|
2690
2690
|
const names = locale.startsWith("ja") ? ja$3 : en$3;
|
|
@@ -2713,6 +2713,7 @@ function FileDiffView({ change, diff, labels, locale, renderBlock, loadAsset })
|
|
|
2713
2713
|
locale,
|
|
2714
2714
|
fallback: text,
|
|
2715
2715
|
loadAsset,
|
|
2716
|
+
locateBlock,
|
|
2716
2717
|
before: change.before === null ? null : sources.before,
|
|
2717
2718
|
after: change.after === null ? null : sources.after
|
|
2718
2719
|
}) : text);
|
|
@@ -2965,7 +2966,7 @@ var show = (value) => {
|
|
|
2965
2966
|
return text.length > 400 ? text.slice(0, 400) + "…" : text;
|
|
2966
2967
|
};
|
|
2967
2968
|
/** The details of one selected row: its code, pictures or values in both versions, and the files behind it. */
|
|
2968
|
-
function ProjectElementView({ changes, selection, locale, renderBlock, onSelectFile }) {
|
|
2969
|
+
function ProjectElementView({ changes, selection, locale, renderBlock, onSelectFile, locateBlock }) {
|
|
2969
2970
|
var _element$properties2;
|
|
2970
2971
|
const labels = projectChangeLabels(locale);
|
|
2971
2972
|
const { element, target } = selection;
|
|
@@ -3000,7 +3001,8 @@ function ProjectElementView({ changes, selection, locale, renderBlock, onSelectF
|
|
|
3000
3001
|
target: {
|
|
3001
3002
|
isStage: target.isStage,
|
|
3002
3003
|
name: target.name
|
|
3003
|
-
}
|
|
3004
|
+
},
|
|
3005
|
+
locateBlock
|
|
3004
3006
|
}), element.kind === "costumes" && /* @__PURE__ */ React.createElement("div", { className: "twgit-element-pictures" }, ["before", "after"].map((version) => {
|
|
3005
3007
|
var _element$md5ext3, _element$version;
|
|
3006
3008
|
return /* @__PURE__ */ React.createElement(Picture, {
|
|
@@ -3299,6 +3301,7 @@ function ConnectionSettings({ settings, locale, readOrigin, runOperation }) {
|
|
|
3299
3301
|
}, labels[error]));
|
|
3300
3302
|
}
|
|
3301
3303
|
// src/pull-request-panel.tsx
|
|
3304
|
+
init_objectSpread2();
|
|
3302
3305
|
var en = {
|
|
3303
3306
|
title: "Pull requests",
|
|
3304
3307
|
number: "Pull request number",
|
|
@@ -3344,7 +3347,7 @@ var ja = {
|
|
|
3344
3347
|
function errorMessage(error, labels) {
|
|
3345
3348
|
return error instanceof PullRequestError ? labels[error.code] : labels.failed;
|
|
3346
3349
|
}
|
|
3347
|
-
function PullRequests({ name, labels, locale, renderBlock }) {
|
|
3350
|
+
function PullRequests({ name, labels, locale, renderBlock, locateFor }) {
|
|
3348
3351
|
const client = useMemo(() => createGitHubPullRequests(name), [name]);
|
|
3349
3352
|
const [page, setPage] = useState(1);
|
|
3350
3353
|
const [listing, setListing] = useState();
|
|
@@ -3432,12 +3435,12 @@ function PullRequests({ name, labels, locale, renderBlock }) {
|
|
|
3432
3435
|
}, labels.onGitHub)), /* @__PURE__ */ React.createElement(ProjectSourceReview, {
|
|
3433
3436
|
title: pr.title,
|
|
3434
3437
|
description: pr.description,
|
|
3435
|
-
files: pr.files,
|
|
3438
|
+
files: locateFor ? pr.files.map((file) => "patch" in file ? _objectSpread2$1(_objectSpread2$1({}, file), {}, { locateBlock: locateFor(file.path, pr.head.sha) }) : file) : pr.files,
|
|
3436
3439
|
renderBlock,
|
|
3437
3440
|
locale
|
|
3438
3441
|
}))));
|
|
3439
3442
|
}
|
|
3440
|
-
function PullRequestReviewPanel({ repository, locale, renderBlock }) {
|
|
3443
|
+
function PullRequestReviewPanel({ repository, locale, renderBlock, locateFor }) {
|
|
3441
3444
|
const labels = locale.startsWith("ja") ? ja : en;
|
|
3442
3445
|
const [origin, setOrigin] = useState();
|
|
3443
3446
|
useEffect(() => {
|
|
@@ -3471,7 +3474,44 @@ function PullRequestReviewPanel({ repository, locale, renderBlock }) {
|
|
|
3471
3474
|
name: origin.name,
|
|
3472
3475
|
labels,
|
|
3473
3476
|
locale,
|
|
3474
|
-
renderBlock
|
|
3477
|
+
renderBlock,
|
|
3478
|
+
locateFor
|
|
3479
|
+
});
|
|
3480
|
+
}
|
|
3481
|
+
// src/editor-block-locator.ts
|
|
3482
|
+
/**
|
|
3483
|
+
* Finds the stage or sprite of a compared version in the open project, opens its code and waits for the block,
|
|
3484
|
+
* then centers and outlines it. The caller decides which version matches the open project.
|
|
3485
|
+
*/
|
|
3486
|
+
function createEditorBlockLocator({ vm, openTargetCode, getWorkspace }) {
|
|
3487
|
+
return createScratchBlocksDiffLocator(async ({ target, id: blockId, signal }) => {
|
|
3488
|
+
const found = vm.runtime.targets.find((item) => target.isStage ? item.isStage : !item.isStage && item.isOriginal !== false && item.getName() === target.name);
|
|
3489
|
+
if (!found || signal.aborted) return null;
|
|
3490
|
+
await openTargetCode(found.id);
|
|
3491
|
+
const deadline = Date.now() + waitLimit;
|
|
3492
|
+
while (!signal.aborted) {
|
|
3493
|
+
var _vm$editingTarget;
|
|
3494
|
+
if (((_vm$editingTarget = vm.editingTarget) === null || _vm$editingTarget === void 0 ? void 0 : _vm$editingTarget.id) === found.id) {
|
|
3495
|
+
const workspace = await getWorkspace();
|
|
3496
|
+
if (signal.aborted) break;
|
|
3497
|
+
if (workspace === null || workspace === void 0 ? void 0 : workspace.getBlockById(blockId)) return workspace;
|
|
3498
|
+
}
|
|
3499
|
+
if (Date.now() >= deadline) break;
|
|
3500
|
+
await nextFrame(signal);
|
|
3501
|
+
}
|
|
3502
|
+
return null;
|
|
3503
|
+
});
|
|
3504
|
+
}
|
|
3505
|
+
var waitLimit = 2e3;
|
|
3506
|
+
function nextFrame(signal) {
|
|
3507
|
+
return new Promise((resolve) => {
|
|
3508
|
+
const done = () => {
|
|
3509
|
+
signal.removeEventListener("abort", done);
|
|
3510
|
+
resolve();
|
|
3511
|
+
};
|
|
3512
|
+
signal.addEventListener("abort", done, { once: true });
|
|
3513
|
+
if (typeof requestAnimationFrame === "function") requestAnimationFrame(done);
|
|
3514
|
+
else setTimeout(done, 16);
|
|
3475
3515
|
});
|
|
3476
3516
|
}
|
|
3477
3517
|
// src/index.tsx
|
|
@@ -3490,9 +3530,20 @@ var initial = {
|
|
|
3490
3530
|
};
|
|
3491
3531
|
var controllers = /* @__PURE__ */ new WeakMap();
|
|
3492
3532
|
var watchInterval = 2e3;
|
|
3493
|
-
function GitPanel({ document, host, controller }) {
|
|
3494
|
-
var _state$repository, _state$snapshot$head$, _state$snapshot$head, _state$
|
|
3533
|
+
function GitPanel({ vm, document, host, controller }) {
|
|
3534
|
+
var _state$repository, _state$snapshot$head$, _state$snapshot$head, _state$snapshot2;
|
|
3495
3535
|
const [visible, setVisible] = useState(false);
|
|
3536
|
+
const [slot, setSlot] = useState(null);
|
|
3537
|
+
const shown = visible || slot !== null;
|
|
3538
|
+
const locator = useMemo(() => slot && host.openTargetCode && host.getWorkspace ? createEditorBlockLocator({
|
|
3539
|
+
vm,
|
|
3540
|
+
openTargetCode: host.openTargetCode,
|
|
3541
|
+
getWorkspace: host.getWorkspace
|
|
3542
|
+
}) : void 0, [
|
|
3543
|
+
slot !== null,
|
|
3544
|
+
host,
|
|
3545
|
+
vm
|
|
3546
|
+
]);
|
|
3496
3547
|
const [review, setReview] = useState(false);
|
|
3497
3548
|
const [locale, setLocale] = useState(document.documentElement.lang || "en");
|
|
3498
3549
|
const [dirty, setDirty] = useState(host.isProjectDirty());
|
|
@@ -3550,8 +3601,34 @@ function GitPanel({ document, host, controller }) {
|
|
|
3550
3601
|
}
|
|
3551
3602
|
};
|
|
3552
3603
|
controller.open = (language) => {
|
|
3604
|
+
var _host$openPanel;
|
|
3553
3605
|
setLocale(language);
|
|
3554
|
-
|
|
3606
|
+
if (!((_host$openPanel = host.openPanel) === null || _host$openPanel === void 0 ? void 0 : _host$openPanel.call(host, {
|
|
3607
|
+
reference: {
|
|
3608
|
+
providerId: "turbowarp-plus-git",
|
|
3609
|
+
documentId: "local-git"
|
|
3610
|
+
},
|
|
3611
|
+
filename: "Git",
|
|
3612
|
+
title: labelsFor(language).title,
|
|
3613
|
+
transient: true,
|
|
3614
|
+
mount(element, close) {
|
|
3615
|
+
setVisible(false);
|
|
3616
|
+
setSlot({
|
|
3617
|
+
element,
|
|
3618
|
+
close
|
|
3619
|
+
});
|
|
3620
|
+
return {
|
|
3621
|
+
requestClose: close,
|
|
3622
|
+
dispose() {
|
|
3623
|
+
setSlot((previous) => (previous === null || previous === void 0 ? void 0 : previous.element) === element ? null : previous);
|
|
3624
|
+
}
|
|
3625
|
+
};
|
|
3626
|
+
}
|
|
3627
|
+
}))) setVisible(true);
|
|
3628
|
+
};
|
|
3629
|
+
const closePanel = () => {
|
|
3630
|
+
if (slot) slot.close();
|
|
3631
|
+
else setVisible(false);
|
|
3555
3632
|
};
|
|
3556
3633
|
controller.refresh = async (automatic = false) => {
|
|
3557
3634
|
if (!alive.current || !current.current.repository) return;
|
|
@@ -3600,7 +3677,7 @@ function GitPanel({ document, host, controller }) {
|
|
|
3600
3677
|
}, [host]);
|
|
3601
3678
|
useEffect(() => {
|
|
3602
3679
|
const repository = state.repository;
|
|
3603
|
-
if (!
|
|
3680
|
+
if (!shown || !repository) return;
|
|
3604
3681
|
const view = document.defaultView;
|
|
3605
3682
|
let stopped = false;
|
|
3606
3683
|
let checking = false;
|
|
@@ -3647,19 +3724,19 @@ function GitPanel({ document, host, controller }) {
|
|
|
3647
3724
|
observer === null || observer === void 0 || observer.disconnect();
|
|
3648
3725
|
};
|
|
3649
3726
|
}, [
|
|
3650
|
-
|
|
3727
|
+
shown,
|
|
3651
3728
|
state.repository,
|
|
3652
3729
|
locale
|
|
3653
3730
|
]);
|
|
3654
3731
|
useEffect(() => {
|
|
3655
3732
|
var _dialog$current;
|
|
3656
|
-
if (!visible) return;
|
|
3733
|
+
if (!visible || slot) return;
|
|
3657
3734
|
const previous = document.activeElement;
|
|
3658
3735
|
(_dialog$current = dialog.current) === null || _dialog$current === void 0 || _dialog$current.focus();
|
|
3659
3736
|
return () => {
|
|
3660
3737
|
if (previous === null || previous === void 0 ? void 0 : previous.isConnected) previous.focus();
|
|
3661
3738
|
};
|
|
3662
|
-
}, [visible]);
|
|
3739
|
+
}, [visible, slot]);
|
|
3663
3740
|
const chooseRoot = async () => {
|
|
3664
3741
|
const view = document.defaultView;
|
|
3665
3742
|
await run(async () => {
|
|
@@ -3696,6 +3773,7 @@ function GitPanel({ document, host, controller }) {
|
|
|
3696
3773
|
} finally {
|
|
3697
3774
|
opening.current = false;
|
|
3698
3775
|
}
|
|
3776
|
+
if (slot) controller.open(locale);
|
|
3699
3777
|
if (!alive.current) return {};
|
|
3700
3778
|
setDirty(host.isProjectDirty());
|
|
3701
3779
|
setState((previous) => _objectSpread2$1(_objectSpread2$1({}, previous), {}, {
|
|
@@ -3776,7 +3854,7 @@ function GitPanel({ document, host, controller }) {
|
|
|
3776
3854
|
const focusTrap = (event) => {
|
|
3777
3855
|
if (event.key === "Escape") {
|
|
3778
3856
|
event.stopPropagation();
|
|
3779
|
-
|
|
3857
|
+
closePanel();
|
|
3780
3858
|
return;
|
|
3781
3859
|
}
|
|
3782
3860
|
if (event.key !== "Tab") return;
|
|
@@ -3795,23 +3873,21 @@ function GitPanel({ document, host, controller }) {
|
|
|
3795
3873
|
state.snapshot,
|
|
3796
3874
|
state.selected
|
|
3797
3875
|
]);
|
|
3798
|
-
if (!
|
|
3876
|
+
if (!shown) return null;
|
|
3799
3877
|
const groups = state.commit ? ["commit"] : [
|
|
3800
3878
|
"staged",
|
|
3801
3879
|
"unstaged",
|
|
3802
3880
|
"untracked"
|
|
3803
3881
|
];
|
|
3804
3882
|
const projectList = typeof projectChanges === "object" ? projectChanges : null;
|
|
3883
|
+
const projectFile = state.project === null ? null : [state.project, "project.source.json"].filter(Boolean).join("/");
|
|
3884
|
+
const fileLocator = (change) => locator && change.path === projectFile && (change.group === "unstaged" || change.group === "untracked" || change.group === "staged" && !state.changes.some((item) => item.path === change.path && item.group === "unstaged")) ? locator : void 0;
|
|
3885
|
+
const reviewLocator = (path, headSha) => {
|
|
3886
|
+
var _state$snapshot;
|
|
3887
|
+
return locator && path === projectFile && ((_state$snapshot = state.snapshot) === null || _state$snapshot === void 0 ? void 0 : _state$snapshot.head) === headSha && !state.changes.length ? locator : void 0;
|
|
3888
|
+
};
|
|
3805
3889
|
const selection = projectList && !state.selected ? findElement(projectList.list, element) : null;
|
|
3806
|
-
|
|
3807
|
-
className: "twgit-panel",
|
|
3808
|
-
ref: dialog,
|
|
3809
|
-
tabIndex: -1,
|
|
3810
|
-
role: "dialog",
|
|
3811
|
-
"aria-modal": "true",
|
|
3812
|
-
"aria-label": labels.title,
|
|
3813
|
-
onKeyDown: focusTrap
|
|
3814
|
-
}, /* @__PURE__ */ React.createElement("header", null, /* @__PURE__ */ React.createElement("h2", null, labels.title), /* @__PURE__ */ React.createElement("button", {
|
|
3890
|
+
const content = /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("header", null, /* @__PURE__ */ React.createElement("h2", null, labels.title), /* @__PURE__ */ React.createElement("button", {
|
|
3815
3891
|
onClick: chooseRoot,
|
|
3816
3892
|
disabled: state.busy
|
|
3817
3893
|
}, labels.choose), !review && /* @__PURE__ */ React.createElement("button", {
|
|
@@ -3824,7 +3900,7 @@ function GitPanel({ document, host, controller }) {
|
|
|
3824
3900
|
type: "button",
|
|
3825
3901
|
disabled: state.busy,
|
|
3826
3902
|
onClick: () => setReview(!review)
|
|
3827
|
-
}, review ? labels.localChanges : labels.pullRequests), /* @__PURE__ */ React.createElement("button", { onClick:
|
|
3903
|
+
}, review ? labels.localChanges : labels.pullRequests), /* @__PURE__ */ React.createElement("button", { onClick: closePanel }, labels.close)), /* @__PURE__ */ React.createElement("div", { className: "twgit-context" }, /* @__PURE__ */ React.createElement("span", null, labels.repository, " · ", ((_state$repository = state.repository) === null || _state$repository === void 0 ? void 0 : _state$repository.root.name) || "—"), /* @__PURE__ */ React.createElement("span", null, labels.project, " · ", state.project === null ? labels.none : state.project || labels.root), /* @__PURE__ */ React.createElement("span", { "data-git-dirty": "" }, dirty ? labels.dirty : labels.saved), state.snapshot && /* @__PURE__ */ React.createElement("span", {
|
|
3828
3904
|
"data-git-upstream": state.snapshot.upstream.state,
|
|
3829
3905
|
title: labels.checkedAt
|
|
3830
3906
|
}, upstreamText(state.snapshot, labels)), !review && host.connectionSettings && /* @__PURE__ */ React.createElement(ConnectionSettings, {
|
|
@@ -3845,7 +3921,8 @@ function GitPanel({ document, host, controller }) {
|
|
|
3845
3921
|
}, state.notice), state.busy && /* @__PURE__ */ React.createElement("p", { role: "status" }, labels.loading), !state.repository && /* @__PURE__ */ React.createElement("p", null, labels.empty), review && state.repository && host.renderReviewBlock && /* @__PURE__ */ React.createElement(PullRequestReviewPanel, {
|
|
3846
3922
|
repository: state.repository,
|
|
3847
3923
|
locale,
|
|
3848
|
-
renderBlock: host.renderReviewBlock
|
|
3924
|
+
renderBlock: host.renderReviewBlock,
|
|
3925
|
+
locateFor: reviewLocator
|
|
3849
3926
|
}), !review && state.repository && /* @__PURE__ */ React.createElement("div", { className: "twgit-content" }, /* @__PURE__ */ React.createElement("aside", null, state.browser && /* @__PURE__ */ React.createElement("details", null, /* @__PURE__ */ React.createElement("summary", null, labels.browse), /* @__PURE__ */ React.createElement("p", null, /* @__PURE__ */ React.createElement("code", null, state.browser.path || "/")), /* @__PURE__ */ React.createElement("button", {
|
|
3850
3927
|
disabled: state.busy || !state.browser.path,
|
|
3851
3928
|
onClick: () => void browse(state.browser.path.split("/").slice(0, -1).join("/"))
|
|
@@ -3878,7 +3955,7 @@ function GitPanel({ document, host, controller }) {
|
|
|
3878
3955
|
fileListOpen,
|
|
3879
3956
|
setFileListOpen
|
|
3880
3957
|
}) : fileList;
|
|
3881
|
-
})(), !state.changes.length && /* @__PURE__ */ React.createElement("p", null, labels.clean), /* @__PURE__ */ React.createElement("h3", null, labels.history), /* @__PURE__ */ React.createElement("ol", { className: "twgit-history" }, (_state$
|
|
3958
|
+
})(), !state.changes.length && /* @__PURE__ */ React.createElement("p", null, labels.clean), /* @__PURE__ */ React.createElement("h3", null, labels.history), /* @__PURE__ */ React.createElement("ol", { className: "twgit-history" }, (_state$snapshot2 = state.snapshot) === null || _state$snapshot2 === void 0 ? void 0 : _state$snapshot2.commits.map((commit) => /* @__PURE__ */ React.createElement("li", { key: commit.oid }, /* @__PURE__ */ React.createElement("button", {
|
|
3882
3959
|
disabled: state.busy,
|
|
3883
3960
|
"aria-pressed": state.commit === commit.oid,
|
|
3884
3961
|
title: commit.oid,
|
|
@@ -3887,6 +3964,7 @@ function GitPanel({ document, host, controller }) {
|
|
|
3887
3964
|
changes: projectList,
|
|
3888
3965
|
selection,
|
|
3889
3966
|
locale,
|
|
3967
|
+
locateBlock: state.commit ? void 0 : locator,
|
|
3890
3968
|
renderBlock: host.renderReviewBlock,
|
|
3891
3969
|
onSelectFile: openFile
|
|
3892
3970
|
}) : state.selected ? /* @__PURE__ */ React.createElement(FileDiffView, {
|
|
@@ -3894,9 +3972,24 @@ function GitPanel({ document, host, controller }) {
|
|
|
3894
3972
|
diff: state.diff,
|
|
3895
3973
|
labels,
|
|
3896
3974
|
locale,
|
|
3975
|
+
locateBlock: fileLocator(state.selected),
|
|
3897
3976
|
renderBlock: host.renderReviewBlock,
|
|
3898
3977
|
loadAsset
|
|
3899
|
-
}) : /* @__PURE__ */ React.createElement("p", null, labels.select))))
|
|
3978
|
+
}) : /* @__PURE__ */ React.createElement("p", null, labels.select))));
|
|
3979
|
+
if (slot) return createPortal(/* @__PURE__ */ React.createElement("div", {
|
|
3980
|
+
className: "twgit-panel twgit-panel-tab",
|
|
3981
|
+
role: "region",
|
|
3982
|
+
"aria-label": labels.title
|
|
3983
|
+
}, content), slot.element);
|
|
3984
|
+
return /* @__PURE__ */ React.createElement("div", { className: "twgit-backdrop" }, /* @__PURE__ */ React.createElement("div", {
|
|
3985
|
+
className: "twgit-panel",
|
|
3986
|
+
ref: dialog,
|
|
3987
|
+
tabIndex: -1,
|
|
3988
|
+
role: "dialog",
|
|
3989
|
+
"aria-modal": "true",
|
|
3990
|
+
"aria-label": labels.title,
|
|
3991
|
+
onKeyDown: focusTrap
|
|
3992
|
+
}, content));
|
|
3900
3993
|
}
|
|
3901
3994
|
/** The GitHub relation in plain words, with the number of records where it helps. */
|
|
3902
3995
|
function upstreamText({ upstream }, labels) {
|
|
@@ -3919,6 +4012,7 @@ function mountGitPanel({ vm, document, host }) {
|
|
|
3919
4012
|
};
|
|
3920
4013
|
controllers.set(vm, controller);
|
|
3921
4014
|
render(/* @__PURE__ */ React.createElement(GitPanel, {
|
|
4015
|
+
vm,
|
|
3922
4016
|
document,
|
|
3923
4017
|
host,
|
|
3924
4018
|
controller
|
|
@@ -3945,4 +4039,4 @@ function renderGitMenu(createElement, { vm, locale = "en", MenuItem, MenuSection
|
|
|
3945
4039
|
}
|
|
3946
4040
|
}, labelsFor(locale).menu));
|
|
3947
4041
|
}
|
|
3948
|
-
export { GitPanelError, createReadOnlyFs, createScratchBlocksDiffRenderer, mountGitPanel, openRepository, renderGitMenu };
|
|
4042
|
+
export { GitPanelError, createEditorBlockLocator, createReadOnlyFs, createScratchBlocksDiffLocator, createScratchBlocksDiffRenderer, mountGitPanel, openRepository, renderGitMenu };
|
|
@@ -3,6 +3,7 @@ import type { ChangedFile, ProjectChangeList, ProjectElementChange, ProjectTarge
|
|
|
3
3
|
import type { ProjectAssetLoader } from './project-assets.js';
|
|
4
4
|
import type { ChangeGroup, FileChange, Repository, Snapshot } from './repository.js';
|
|
5
5
|
import type { ProjectBlockRenderer } from './scratch-block-diff-renderer.js';
|
|
6
|
+
import type { ProjectBlockLocator } from './block-diff-location.js';
|
|
6
7
|
declare const en: {
|
|
7
8
|
title: string;
|
|
8
9
|
stage: string;
|
|
@@ -68,7 +69,7 @@ export declare function findElement(list: ProjectChangeList, key: string | null)
|
|
|
68
69
|
target: null;
|
|
69
70
|
} | null;
|
|
70
71
|
/** The details of one selected row: its code, pictures or values in both versions, and the files behind it. */
|
|
71
|
-
export declare function ProjectElementView({ changes, selection, locale, renderBlock, onSelectFile }: {
|
|
72
|
+
export declare function ProjectElementView({ changes, selection, locale, renderBlock, onSelectFile, locateBlock }: {
|
|
72
73
|
changes: ProjectChanges;
|
|
73
74
|
selection: {
|
|
74
75
|
element: ProjectElementChange;
|
|
@@ -77,5 +78,6 @@ export declare function ProjectElementView({ changes, selection, locale, renderB
|
|
|
77
78
|
locale: string;
|
|
78
79
|
renderBlock?: ProjectBlockRenderer;
|
|
79
80
|
onSelectFile(file: ChangedFile): void;
|
|
81
|
+
locateBlock?: ProjectBlockLocator;
|
|
80
82
|
}): React.JSX.Element;
|
|
81
83
|
export {};
|
|
@@ -9,6 +9,8 @@ export { createScratchBlocksDiffLocator } from './block-diff-location.js';
|
|
|
9
9
|
export type { ProjectBlockLocation, ProjectBlockLocator, ScratchBlockLocationWorkspace } from './block-diff-location.js';
|
|
10
10
|
export type { BlockPart } from './project-source-patch.js';
|
|
11
11
|
export { createProjectSourceDiff } from './project-source-patch.js';
|
|
12
|
+
export { compareProjectForReview } from './project-source-review-model.js';
|
|
13
|
+
export type { ScriptChangeKind, ScriptReview, ScriptReviewSide, ScriptSummaryItem, TargetReview } from './project-source-review-model.js';
|
|
12
14
|
export { currentCostume } from './project-assets.js';
|
|
13
15
|
export { assetFileName, organizeProjectChanges, projectPropertyLabel } from './project-change-model.js';
|
|
14
16
|
export type { ChangedFile, OrganizeProjectChangesInput, ProjectChangeList, ProjectChangeStatus, ProjectElementChange, ProjectElementKind, ProjectTargetChanges } from './project-change-model.js';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { a as gitHubRepositoryFromOrigin, c as assetFileName, d as compareProjectForReview, f as BlockPreview, h as currentCostume, i as createGitHubPullRequests, l as organizeProjectChanges, m as usePreviewSync, n as createScratchBlocksDiffLocator, o as ProjectSourceComparison, p as createPreviewSync, s as ProjectSourceReview, t as createScratchBlocksDiffRenderer, u as projectPropertyLabel, v as compareProjectBlocks, x as readProjectSourceDiff, y as createProjectSourceDiff } from "./scratch-block-diff-renderer-e_drVlHE.js";
|
|
2
2
|
import { n as init_objectSpread2, t as _objectSpread2 } from "./objectSpread2-Dkd68nJH.js";
|
|
3
3
|
import React, { useEffect, useMemo, useRef, useState } from "react";
|
|
4
4
|
// src/project-source-diff.tsx
|
|
@@ -169,4 +169,4 @@ function ProjectSourceBlockDiff({ patch, beforeSource, renderBlock, locateBlock,
|
|
|
169
169
|
})
|
|
170
170
|
}, labels.more));
|
|
171
171
|
}
|
|
172
|
-
export { ProjectSourceBlockDiff, ProjectSourceComparison, ProjectSourceReview, assetFileName, createGitHubPullRequests, createPreviewSync, createProjectSourceDiff, createScratchBlocksDiffLocator, createScratchBlocksDiffRenderer, currentCostume, gitHubRepositoryFromOrigin, organizeProjectChanges, projectPropertyLabel };
|
|
172
|
+
export { ProjectSourceBlockDiff, ProjectSourceComparison, ProjectSourceReview, assetFileName, compareProjectForReview, createGitHubPullRequests, createPreviewSync, createProjectSourceDiff, createScratchBlocksDiffLocator, createScratchBlocksDiffRenderer, currentCostume, gitHubRepositoryFromOrigin, organizeProjectChanges, projectPropertyLabel };
|
|
@@ -3,14 +3,49 @@ import type { ScriptBlockMark } from './scratch-block-diff-renderer.js';
|
|
|
3
3
|
export interface ScriptReviewSide extends BlockSide {
|
|
4
4
|
marks: ScriptBlockMark[];
|
|
5
5
|
}
|
|
6
|
+
/**
|
|
7
|
+
* What happened to one script. `moved` means only positions changed, `reordered` only how blocks connect;
|
|
8
|
+
* neither changes what the script does.
|
|
9
|
+
*/
|
|
10
|
+
export type ScriptChangeKind = 'added' | 'removed' | 'updated' | 'reorganized' | 'moved' | 'reordered';
|
|
11
|
+
/** One phrase of a script's summary, in the order shown. The view words it in the reader's language. */
|
|
12
|
+
export type ScriptSummaryItem = {
|
|
13
|
+
kind: 'hatReplaced';
|
|
14
|
+
before: string;
|
|
15
|
+
after: string;
|
|
16
|
+
} | {
|
|
17
|
+
kind: 'wrapped';
|
|
18
|
+
opcode: string;
|
|
19
|
+
} | {
|
|
20
|
+
kind: 'branchAdded';
|
|
21
|
+
opcode: string;
|
|
22
|
+
} | {
|
|
23
|
+
kind: 'valueChanged';
|
|
24
|
+
opcode: string;
|
|
25
|
+
name: string;
|
|
26
|
+
} | {
|
|
27
|
+
kind: 'blocksAdded';
|
|
28
|
+
count: number;
|
|
29
|
+
} | {
|
|
30
|
+
kind: 'blocksRemoved';
|
|
31
|
+
count: number;
|
|
32
|
+
} | {
|
|
33
|
+
kind: 'reordered';
|
|
34
|
+
} | {
|
|
35
|
+
kind: 'moved';
|
|
36
|
+
};
|
|
6
37
|
export interface ScriptReview {
|
|
7
38
|
id: string;
|
|
8
39
|
before: ScriptReviewSide[];
|
|
9
40
|
after: ScriptReviewSide[];
|
|
41
|
+
kind: ScriptChangeKind;
|
|
42
|
+
summary: ScriptSummaryItem[];
|
|
10
43
|
}
|
|
11
44
|
export interface TargetReview {
|
|
12
45
|
name: string;
|
|
13
46
|
isStage: boolean;
|
|
47
|
+
/** Added or removed as a whole, or changed. Added and removed targets list no properties. */
|
|
48
|
+
status: 'added' | 'removed' | 'updated';
|
|
14
49
|
/** The stage or sprite in each version, absent where it does not exist. */
|
|
15
50
|
before?: ProjectTarget;
|
|
16
51
|
after?: ProjectTarget;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import type { ProjectBlockRenderer } from './scratch-block-diff-renderer.js';
|
|
3
|
+
import type { ProjectBlockLocator } from './block-diff-location.js';
|
|
3
4
|
import type { ProjectAssetLoader } from './project-assets.js';
|
|
4
5
|
export type ProjectSourceReviewFile = {
|
|
5
6
|
path: string;
|
|
@@ -10,6 +11,8 @@ export type ProjectSourceReviewFile = {
|
|
|
10
11
|
patch: string;
|
|
11
12
|
beforeSource?: string;
|
|
12
13
|
loadAsset?: ProjectAssetLoader;
|
|
14
|
+
/** Offers "Highlight in Editor" on this file's after version, which the caller has matched with the open project. */
|
|
15
|
+
locateBlock?: ProjectBlockLocator;
|
|
13
16
|
} | {
|
|
14
17
|
status: 'added' | 'removed' | 'updated';
|
|
15
18
|
});
|
|
@@ -32,6 +35,8 @@ export interface ProjectSourceComparisonProps {
|
|
|
32
35
|
fallback?: React.ReactNode;
|
|
33
36
|
/** Reads the images of both versions for thumbnails. Without it, stages and sprites are shown by name. */
|
|
34
37
|
loadAsset?: ProjectAssetLoader;
|
|
38
|
+
/** Offers "Highlight in Editor" on the after version, which the caller has matched with the open project. */
|
|
39
|
+
locateBlock?: ProjectBlockLocator;
|
|
35
40
|
/** Shows only the code of this stage or sprite, without the overview and the changes outside the code. */
|
|
36
41
|
target?: {
|
|
37
42
|
isStage: boolean;
|
|
@@ -39,5 +44,5 @@ export interface ProjectSourceComparisonProps {
|
|
|
39
44
|
};
|
|
40
45
|
}
|
|
41
46
|
/** Compares two versions of a project.source.json by stage, sprite and code, as the pull request review does. */
|
|
42
|
-
export declare function ProjectSourceComparison({ before, after, renderBlock, locale, fallback, loadAsset, target }: ProjectSourceComparisonProps): React.JSX.Element;
|
|
47
|
+
export declare function ProjectSourceComparison({ before, after, renderBlock, locale, fallback, loadAsset, locateBlock, target }: ProjectSourceComparisonProps): React.JSX.Element;
|
|
43
48
|
export declare function ProjectSourceReview({ title, description, verification, files, renderBlock, locale }: ProjectSourceReviewProps): React.JSX.Element;
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import type { ProjectBlockRenderer } from './scratch-block-diff-renderer.js';
|
|
3
3
|
import type { Repository } from './repository.js';
|
|
4
|
-
|
|
4
|
+
import type { ProjectBlockLocator } from './block-diff-location.js';
|
|
5
|
+
export declare function PullRequestReviewPanel({ repository, locale, renderBlock, locateFor }: {
|
|
5
6
|
repository: Repository;
|
|
6
7
|
locale: string;
|
|
7
8
|
renderBlock: ProjectBlockRenderer;
|
|
9
|
+
/** Returns a locator for a project file whose PR head matches the open project, or `undefined`. */
|
|
10
|
+
locateFor?(path: string, headSha: string): ProjectBlockLocator | undefined;
|
|
8
11
|
}): React.JSX.Element;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { ScriptSummaryItem } from './project-source-review-model.js';
|
|
2
|
+
export declare function hatName(opcode: string, locale: string): string | undefined;
|
|
3
|
+
/** One phrase per summary item, in the reader's language. */
|
|
4
|
+
export declare function summaryPhrase(item: ScriptSummaryItem, locale: string): string;
|
|
5
|
+
/** The colours of the previews, said once at the top of a review. */
|
|
6
|
+
export declare const legend: (locale: string) => readonly [readonly ["added", "緑の縁: 追加したブロック"], readonly ["removed", "赤の縁: 削除したブロック"], readonly ["updated", "紫の縁: 中身を変えたブロック"], readonly ["part", "オレンジの枠: 値を変えた欄"]] | readonly [readonly ["added", "Green outline: added block"], readonly ["removed", "Red outline: removed block"], readonly ["updated", "Purple outline: block with changed contents"], readonly ["part", "Orange frame: changed value"]];
|