@kubohiroya/turbowarp-plus-editor-git 0.14.1 → 0.16.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/README.ja.md +7 -3
- package/README.md +7 -3
- package/dist/file-diff-view.d.ts +3 -1
- package/dist/filesystem.d.ts +2 -2
- package/dist/history-graph-view.d.ts +40 -0
- package/dist/history-graph.d.ts +44 -0
- package/dist/index.d.ts +27 -1
- package/dist/index.js +778 -32
- package/dist/local-operations.d.ts +36 -0
- package/dist/messages.d.ts +74 -0
- package/dist/{project-comparison-LAyP_beL.js → project-comparison-MU0qD2wo.js} +213 -16
- package/dist/project-source-diff.d.ts +2 -0
- package/dist/project-source-diff.js +2 -2
- package/dist/project-source-review.d.ts +43 -0
- package/dist/project-source-tabs.d.ts +35 -0
- package/dist/pull-request-panel.d.ts +6 -1
- package/dist/{repository-CtvWYPQ8.js → repository-BYno-5f8.js} +927 -5
- package/dist/repository.d.ts +47 -0
- package/dist/repository.js +1 -1
- package/dist/style.css +30 -3
- package/package.json +1 -1
- package/src/file-diff-view.tsx +7 -3
- package/src/filesystem.ts +3 -1
- package/src/history-graph-view.tsx +233 -0
- package/src/history-graph.ts +90 -0
- package/src/index.tsx +175 -15
- package/src/local-operations.ts +134 -0
- package/src/messages.ts +40 -2
- package/src/project-source-diff.tsx +2 -0
- package/src/project-source-review.tsx +127 -15
- package/src/project-source-tabs.tsx +118 -0
- package/src/pull-request-panel.tsx +26 -5
- package/src/repository.ts +160 -1
- package/src/style.css +30 -3
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/** The name and email a commit records. */
|
|
2
|
+
export type GitAuthor = {
|
|
3
|
+
name: string;
|
|
4
|
+
email: string;
|
|
5
|
+
};
|
|
6
|
+
export type LocalOperation = {
|
|
7
|
+
kind: 'stage';
|
|
8
|
+
paths: readonly string[];
|
|
9
|
+
} | {
|
|
10
|
+
kind: 'unstage';
|
|
11
|
+
paths: readonly string[];
|
|
12
|
+
} | {
|
|
13
|
+
kind: 'commit';
|
|
14
|
+
message: string;
|
|
15
|
+
author?: GitAuthor;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Creates `name` at HEAD, at the commit `at`, or at `origin/<name>` with `fromRemote`, and switches to it with
|
|
19
|
+
* `checkout`.
|
|
20
|
+
*/
|
|
21
|
+
| {
|
|
22
|
+
kind: 'createBranch';
|
|
23
|
+
name: string;
|
|
24
|
+
fromRemote?: boolean;
|
|
25
|
+
at?: string;
|
|
26
|
+
checkout: boolean;
|
|
27
|
+
} | {
|
|
28
|
+
kind: 'switchBranch';
|
|
29
|
+
name: string;
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Stages, unstages or commits in the granted repository. Like pull, Git's writes are collected first and applied
|
|
33
|
+
* after the files they replace are checked again; a failure part way puts back what was applied. Only `.git/index`,
|
|
34
|
+
* objects and the current branch ref are written. The work tree and `.git/config` are never written.
|
|
35
|
+
*/
|
|
36
|
+
export declare function runLocalOperation(root: FileSystemDirectoryHandle, operation: LocalOperation, guard: () => void): Promise<void>;
|
package/dist/messages.d.ts
CHANGED
|
@@ -41,6 +41,11 @@ export declare const messages: {
|
|
|
41
41
|
changed: string;
|
|
42
42
|
outdated: string;
|
|
43
43
|
unsupported: string;
|
|
44
|
+
commitMessage: string;
|
|
45
|
+
switchUnsafe: string;
|
|
46
|
+
branchExists: string;
|
|
47
|
+
locked: string;
|
|
48
|
+
branchName: string;
|
|
44
49
|
pullUnsafe: string;
|
|
45
50
|
diverged: string;
|
|
46
51
|
session: string;
|
|
@@ -49,6 +54,26 @@ export declare const messages: {
|
|
|
49
54
|
rollbackFailed: string;
|
|
50
55
|
remoteFailed: string;
|
|
51
56
|
remoteDone: string;
|
|
57
|
+
stage: string;
|
|
58
|
+
unstage: string;
|
|
59
|
+
stageAll: string;
|
|
60
|
+
commitLabel: string;
|
|
61
|
+
commitButton: string;
|
|
62
|
+
committed: string;
|
|
63
|
+
commitAuthor: string;
|
|
64
|
+
saveFirst: string;
|
|
65
|
+
author: string;
|
|
66
|
+
nothingStaged: string;
|
|
67
|
+
switchTo: string;
|
|
68
|
+
currentBranch: string;
|
|
69
|
+
createBranch: string;
|
|
70
|
+
newBranch: string;
|
|
71
|
+
switchAfterCreate: string;
|
|
72
|
+
createFromRemote: string;
|
|
73
|
+
remoteBranches: string;
|
|
74
|
+
switched: string;
|
|
75
|
+
branchCreated: string;
|
|
76
|
+
projectMissing: string;
|
|
52
77
|
pulledProject: string;
|
|
53
78
|
confirmPush: string;
|
|
54
79
|
details: string;
|
|
@@ -69,6 +94,18 @@ export declare const messages: {
|
|
|
69
94
|
records: string;
|
|
70
95
|
checkedAt: string;
|
|
71
96
|
failed: string;
|
|
97
|
+
historyMore: string;
|
|
98
|
+
historyLoading: string;
|
|
99
|
+
historyFailed: string;
|
|
100
|
+
historyActions: string;
|
|
101
|
+
historyCreateHere: string;
|
|
102
|
+
historySwitch: string;
|
|
103
|
+
historyCreateFromRemote: string;
|
|
104
|
+
historyCopy: string;
|
|
105
|
+
historyCopied: string;
|
|
106
|
+
historyCopyFailed: string;
|
|
107
|
+
historyRefs: string;
|
|
108
|
+
cancel: string;
|
|
72
109
|
};
|
|
73
110
|
ja: {
|
|
74
111
|
pullRequests: string;
|
|
@@ -112,6 +149,11 @@ export declare const messages: {
|
|
|
112
149
|
changed: string;
|
|
113
150
|
outdated: string;
|
|
114
151
|
unsupported: string;
|
|
152
|
+
commitMessage: string;
|
|
153
|
+
switchUnsafe: string;
|
|
154
|
+
branchExists: string;
|
|
155
|
+
locked: string;
|
|
156
|
+
branchName: string;
|
|
115
157
|
pullUnsafe: string;
|
|
116
158
|
diverged: string;
|
|
117
159
|
session: string;
|
|
@@ -120,6 +162,26 @@ export declare const messages: {
|
|
|
120
162
|
rollbackFailed: string;
|
|
121
163
|
remoteFailed: string;
|
|
122
164
|
remoteDone: string;
|
|
165
|
+
stage: string;
|
|
166
|
+
unstage: string;
|
|
167
|
+
stageAll: string;
|
|
168
|
+
commitLabel: string;
|
|
169
|
+
commitButton: string;
|
|
170
|
+
committed: string;
|
|
171
|
+
commitAuthor: string;
|
|
172
|
+
saveFirst: string;
|
|
173
|
+
author: string;
|
|
174
|
+
nothingStaged: string;
|
|
175
|
+
switchTo: string;
|
|
176
|
+
currentBranch: string;
|
|
177
|
+
createBranch: string;
|
|
178
|
+
newBranch: string;
|
|
179
|
+
switchAfterCreate: string;
|
|
180
|
+
createFromRemote: string;
|
|
181
|
+
remoteBranches: string;
|
|
182
|
+
switched: string;
|
|
183
|
+
branchCreated: string;
|
|
184
|
+
projectMissing: string;
|
|
123
185
|
pulledProject: string;
|
|
124
186
|
confirmPush: string;
|
|
125
187
|
details: string;
|
|
@@ -140,6 +202,18 @@ export declare const messages: {
|
|
|
140
202
|
records: string;
|
|
141
203
|
checkedAt: string;
|
|
142
204
|
failed: string;
|
|
205
|
+
historyMore: string;
|
|
206
|
+
historyLoading: string;
|
|
207
|
+
historyFailed: string;
|
|
208
|
+
historyActions: string;
|
|
209
|
+
historyCreateHere: string;
|
|
210
|
+
historySwitch: string;
|
|
211
|
+
historyCreateFromRemote: string;
|
|
212
|
+
historyCopy: string;
|
|
213
|
+
historyCopied: string;
|
|
214
|
+
historyCopyFailed: string;
|
|
215
|
+
historyRefs: string;
|
|
216
|
+
cancel: string;
|
|
143
217
|
};
|
|
144
218
|
};
|
|
145
219
|
export type Labels = typeof messages.en;
|
|
@@ -1569,17 +1569,22 @@ function useBlockLocation(comparison, locateBlock) {
|
|
|
1569
1569
|
status: (side) => (location === null || location === void 0 ? void 0 : location.comparison) === comparison && location.locator === locateBlock && location.key === sideKey(side) ? location.status : void 0
|
|
1570
1570
|
};
|
|
1571
1571
|
}
|
|
1572
|
-
|
|
1573
|
-
|
|
1572
|
+
/** What a script is called in a review: its hat block, or both hat blocks when the change replaced it. */
|
|
1573
|
+
function scriptReviewTitle(script, labels) {
|
|
1574
|
+
const beforeTitle = script.before[0] && scriptTitle(script.before[0], labels);
|
|
1575
|
+
const afterTitle = script.after[0] && scriptTitle(script.after[0], labels);
|
|
1576
|
+
return beforeTitle && afterTitle && beforeTitle !== afterTitle ? beforeTitle + " → " + afterTitle : afterTitle !== null && afterTitle !== void 0 ? afterTitle : beforeTitle;
|
|
1577
|
+
}
|
|
1578
|
+
function ScriptComparison({ script, labels, reviewed = false, setReviewed, renderBlock, loadAsset, location, expanded = false }) {
|
|
1579
|
+
const [open, setOpen] = useState(expanded);
|
|
1574
1580
|
const { sync, toggle } = usePreviewSync(labels === ja ? "ja" : "en");
|
|
1575
1581
|
const status = script.kind;
|
|
1576
1582
|
const locale = labels === ja ? "ja" : "en";
|
|
1577
1583
|
const summary = script.summary.map((item) => summaryPhrase(item, locale)).join(labels === ja ? "、" : ", ");
|
|
1578
|
-
const
|
|
1579
|
-
const afterTitle = script.after[0] && scriptTitle(script.after[0], labels);
|
|
1580
|
-
const title = beforeTitle && afterTitle && beforeTitle !== afterTitle ? beforeTitle + " → " + afterTitle : afterTitle !== null && afterTitle !== void 0 ? afterTitle : beforeTitle;
|
|
1584
|
+
const title = scriptReviewTitle(script, labels);
|
|
1581
1585
|
return /* @__PURE__ */ React.createElement("details", {
|
|
1582
1586
|
className: "twgit-review-script",
|
|
1587
|
+
open: expanded || void 0,
|
|
1583
1588
|
onToggle: (event) => setOpen(event.currentTarget.open)
|
|
1584
1589
|
}, /* @__PURE__ */ React.createElement("summary", null, /* @__PURE__ */ React.createElement("span", { className: "twgit-review-status" }, labels[status]), /* @__PURE__ */ React.createElement("strong", null, title), status === "reorganized" && /* @__PURE__ */ React.createElement("small", null, script.before.length, " → ", script.after.length), summary && /* @__PURE__ */ React.createElement("small", { className: "twgit-review-summary" }, summary), reviewed && /* @__PURE__ */ React.createElement("small", null, labels.reviewed)), open && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("div", { className: "twgit-block-diff-sides" }, ["before", "after"].map((version) => /* @__PURE__ */ React.createElement("div", { key: version }, script[version].length ? script[version].map((side, index, sides) => /* @__PURE__ */ React.createElement(BlockPreview, {
|
|
1585
1590
|
key: side.id,
|
|
@@ -1781,7 +1786,20 @@ var scriptPrint = (script) => fingerprint([
|
|
|
1781
1786
|
script.after.map(scriptBlocks)
|
|
1782
1787
|
]);
|
|
1783
1788
|
var storageKey = (name) => `turbowarp-plus-git:reviewed:${name}`;
|
|
1784
|
-
var
|
|
1789
|
+
var memoryMarks = /* @__PURE__ */ new Map();
|
|
1790
|
+
var markListeners = /* @__PURE__ */ new Map();
|
|
1791
|
+
var subscribeMarks = (name, listener) => {
|
|
1792
|
+
var _markListeners$get;
|
|
1793
|
+
const listeners = (_markListeners$get = markListeners.get(name)) !== null && _markListeners$get !== void 0 ? _markListeners$get : /* @__PURE__ */ new Set();
|
|
1794
|
+
markListeners.set(name, listeners.add(listener));
|
|
1795
|
+
return () => {
|
|
1796
|
+
listeners.delete(listener);
|
|
1797
|
+
if (!listeners.size) markListeners.delete(name);
|
|
1798
|
+
};
|
|
1799
|
+
};
|
|
1800
|
+
var readMarks = (name, remember = true) => {
|
|
1801
|
+
var _memoryMarks$get;
|
|
1802
|
+
if (!remember) return (_memoryMarks$get = memoryMarks.get(name)) !== null && _memoryMarks$get !== void 0 ? _memoryMarks$get : {};
|
|
1785
1803
|
try {
|
|
1786
1804
|
var _globalThis$localStor, _globalThis$localStor2;
|
|
1787
1805
|
const value = JSON.parse((_globalThis$localStor = (_globalThis$localStor2 = globalThis.localStorage) === null || _globalThis$localStor2 === void 0 ? void 0 : _globalThis$localStor2.getItem(storageKey(name))) !== null && _globalThis$localStor !== void 0 ? _globalThis$localStor : "{}");
|
|
@@ -1790,12 +1808,18 @@ var readMarks = (name) => {
|
|
|
1790
1808
|
return {};
|
|
1791
1809
|
}
|
|
1792
1810
|
};
|
|
1793
|
-
var writeMarks = (name, marks) => {
|
|
1811
|
+
var writeMarks = (name, marks, remember = true) => {
|
|
1812
|
+
var _markListeners$get2;
|
|
1813
|
+
if (!remember) {
|
|
1814
|
+
if (Object.keys(marks).length) memoryMarks.set(name, marks);
|
|
1815
|
+
else memoryMarks.delete(name);
|
|
1816
|
+
}
|
|
1794
1817
|
try {
|
|
1795
1818
|
var _globalThis$localStor3, _globalThis$localStor4;
|
|
1796
|
-
if (Object.keys(marks).length) (_globalThis$localStor3 = globalThis.localStorage) === null || _globalThis$localStor3 === void 0 || _globalThis$localStor3.setItem(storageKey(name), JSON.stringify(marks));
|
|
1797
|
-
else (_globalThis$localStor4 = globalThis.localStorage) === null || _globalThis$localStor4 === void 0 || _globalThis$localStor4.removeItem(storageKey(name));
|
|
1819
|
+
if (remember && Object.keys(marks).length) (_globalThis$localStor3 = globalThis.localStorage) === null || _globalThis$localStor3 === void 0 || _globalThis$localStor3.setItem(storageKey(name), JSON.stringify(marks));
|
|
1820
|
+
else if (remember) (_globalThis$localStor4 = globalThis.localStorage) === null || _globalThis$localStor4 === void 0 || _globalThis$localStor4.removeItem(storageKey(name));
|
|
1798
1821
|
} catch (_unused4) {}
|
|
1822
|
+
(_markListeners$get2 = markListeners.get(name)) === null || _markListeners$get2 === void 0 || _markListeners$get2.forEach((listener) => listener());
|
|
1799
1823
|
};
|
|
1800
1824
|
function ProjectSourceReview({ title, description, verification, files, renderBlock, locale = "en", rememberAs }) {
|
|
1801
1825
|
const labels = locale.startsWith("ja") ? ja : en;
|
|
@@ -1826,20 +1850,24 @@ function ProjectSourceReview({ title, description, verification, files, renderBl
|
|
|
1826
1850
|
return prints;
|
|
1827
1851
|
}, [entries]);
|
|
1828
1852
|
const [checked, setChecked] = useState();
|
|
1853
|
+
const [, refresh] = useState(0);
|
|
1854
|
+
useEffect(() => rememberAs ? subscribeMarks(rememberAs, () => {
|
|
1855
|
+
setChecked(void 0);
|
|
1856
|
+
refresh((count) => count + 1);
|
|
1857
|
+
}) : void 0, [rememberAs]);
|
|
1829
1858
|
const marks = (checked === null || checked === void 0 ? void 0 : checked.entries) === entries ? checked.marks : rememberAs ? readMarks(rememberAs) : {};
|
|
1830
1859
|
const reviewed = new Set([...scriptPrints].filter(([key, print]) => marks[key] === print).map(([key]) => key));
|
|
1831
|
-
const setReviewed = (key, value) =>
|
|
1832
|
-
const current = (previous === null || previous === void 0 ? void 0 : previous.entries) === entries ? previous.marks : rememberAs ? readMarks(rememberAs) : {};
|
|
1860
|
+
const setReviewed = (key, value) => {
|
|
1833
1861
|
const next = {};
|
|
1834
|
-
for (const [name, print] of scriptPrints) if (
|
|
1862
|
+
for (const [name, print] of scriptPrints) if (marks[name] === print) next[name] = print;
|
|
1835
1863
|
if (value) next[key] = scriptPrints.get(key);
|
|
1836
1864
|
else delete next[key];
|
|
1837
1865
|
if (rememberAs) writeMarks(rememberAs, next);
|
|
1838
|
-
|
|
1866
|
+
setChecked({
|
|
1839
1867
|
entries,
|
|
1840
1868
|
marks: next
|
|
1841
|
-
};
|
|
1842
|
-
}
|
|
1869
|
+
});
|
|
1870
|
+
};
|
|
1843
1871
|
const targets = entries.reduce((total, entry) => {
|
|
1844
1872
|
var _entry$comparison$tar, _entry$comparison;
|
|
1845
1873
|
return total + ((_entry$comparison$tar = (_entry$comparison = entry.comparison) === null || _entry$comparison === void 0 ? void 0 : _entry$comparison.targets.length) !== null && _entry$comparison$tar !== void 0 ? _entry$comparison$tar : 0);
|
|
@@ -1871,6 +1899,62 @@ function ProjectSourceReview({ title, description, verification, files, renderBl
|
|
|
1871
1899
|
}
|
|
1872
1900
|
}))));
|
|
1873
1901
|
}
|
|
1902
|
+
/** The words of one tab of a project comparison opened as tabs. */
|
|
1903
|
+
function reviewTabWords(locale) {
|
|
1904
|
+
const labels = locale.startsWith("ja") ? ja : en;
|
|
1905
|
+
return {
|
|
1906
|
+
script: (script) => `${scriptReviewTitle(script, labels)} · ${labels[script.kind]}`,
|
|
1907
|
+
target: (target) => target.isStage ? labels.stage : target.name,
|
|
1908
|
+
targetDetails: labels.properties,
|
|
1909
|
+
project: labels.comparison,
|
|
1910
|
+
noChanges: labels.noChanges
|
|
1911
|
+
};
|
|
1912
|
+
}
|
|
1913
|
+
function useReviewMark(place, script) {
|
|
1914
|
+
const [, refresh] = useState(0);
|
|
1915
|
+
useEffect(() => place && subscribeMarks(place.name, () => refresh((count) => count + 1)), [place === null || place === void 0 ? void 0 : place.name]);
|
|
1916
|
+
if (!place) return {};
|
|
1917
|
+
const key = reviewKey(place.file, place.target, script);
|
|
1918
|
+
const print = scriptPrint(script);
|
|
1919
|
+
return {
|
|
1920
|
+
reviewed: readMarks(place.name, place.remember)[key] === print,
|
|
1921
|
+
setReviewed(value) {
|
|
1922
|
+
const marks = _objectSpread2({}, readMarks(place.name, place.remember));
|
|
1923
|
+
if (value) marks[key] = print;
|
|
1924
|
+
else delete marks[key];
|
|
1925
|
+
writeMarks(place.name, marks, place.remember);
|
|
1926
|
+
}
|
|
1927
|
+
};
|
|
1928
|
+
}
|
|
1929
|
+
/** One script of a comparison, open, for a tab of its own. */
|
|
1930
|
+
function ScriptReviewTab({ comparison, script, renderBlock, locale = "en", loadAsset, locateBlock, mark }) {
|
|
1931
|
+
const labels = locale.startsWith("ja") ? ja : en;
|
|
1932
|
+
const location = useBlockLocation(comparison, locateBlock);
|
|
1933
|
+
const { reviewed, setReviewed } = useReviewMark(mark, script);
|
|
1934
|
+
return /* @__PURE__ */ React.createElement("section", { className: "twgit-block-diff twgit-review twgit-review-tab" }, /* @__PURE__ */ React.createElement(ScriptComparison, {
|
|
1935
|
+
script,
|
|
1936
|
+
labels,
|
|
1937
|
+
renderBlock,
|
|
1938
|
+
loadAsset,
|
|
1939
|
+
location,
|
|
1940
|
+
expanded: true,
|
|
1941
|
+
reviewed,
|
|
1942
|
+
setReviewed
|
|
1943
|
+
}), /* @__PURE__ */ React.createElement(Legend, { labels }));
|
|
1944
|
+
}
|
|
1945
|
+
/**
|
|
1946
|
+
* What changed in a stage or sprite outside its code, or in the project as a whole when no target is given,
|
|
1947
|
+
* for a tab of its own.
|
|
1948
|
+
*/
|
|
1949
|
+
function TargetReviewTab({ comparison, target, locale = "en", loadAsset }) {
|
|
1950
|
+
const labels = locale.startsWith("ja") ? ja : en;
|
|
1951
|
+
if (!target) return /* @__PURE__ */ React.createElement("section", { className: "twgit-block-diff twgit-review twgit-review-tab" }, comparison.properties.length > 0 ? /* @__PURE__ */ React.createElement("p", null, labels.properties, " · ", propertyNames(comparison.properties, labels)) : /* @__PURE__ */ React.createElement("p", null, labels.noChanges));
|
|
1952
|
+
return /* @__PURE__ */ React.createElement("section", { className: "twgit-block-diff twgit-review twgit-review-tab" }, /* @__PURE__ */ React.createElement("h5", null, /* @__PURE__ */ React.createElement(TargetThumbnails, {
|
|
1953
|
+
target,
|
|
1954
|
+
labels,
|
|
1955
|
+
loadAsset
|
|
1956
|
+
}), target.isStage ? labels.stage : target.name), target.status !== "updated" && /* @__PURE__ */ React.createElement("p", { className: "twgit-review-target-status" }, (target.status === "added" ? labels.targetAdded : labels.targetRemoved)(target.name, target.isStage)), target.status === "updated" && target.properties.length > 0 && /* @__PURE__ */ React.createElement("p", null, labels.properties, " · ", propertyNames(target.properties, labels)), target.scripts.length > 0 && /* @__PURE__ */ React.createElement("p", null, labels.scriptCount(target.scripts.length)));
|
|
1957
|
+
}
|
|
1874
1958
|
// src/github-pull-requests.ts
|
|
1875
1959
|
init_objectSpread2();
|
|
1876
1960
|
var PullRequestError = class extends Error {
|
|
@@ -2116,6 +2200,119 @@ function createGitHubPullRequests(repository, send = fetch) {
|
|
|
2116
2200
|
}
|
|
2117
2201
|
};
|
|
2118
2202
|
}
|
|
2203
|
+
// src/project-source-tabs.tsx
|
|
2204
|
+
var providerId = "turbowarp-plus-git";
|
|
2205
|
+
var statusColor = {
|
|
2206
|
+
added: "green",
|
|
2207
|
+
removed: "red",
|
|
2208
|
+
updated: "blue"
|
|
2209
|
+
};
|
|
2210
|
+
/** Renders its content once the tab is first shown, so a comparison with many scripts draws only what is looked at. */
|
|
2211
|
+
function WhenShown({ children }) {
|
|
2212
|
+
const element = useRef(null);
|
|
2213
|
+
const [shown, setShown] = useState(false);
|
|
2214
|
+
useEffect(() => {
|
|
2215
|
+
var _element$current;
|
|
2216
|
+
const view = (_element$current = element.current) === null || _element$current === void 0 ? void 0 : _element$current.ownerDocument.defaultView;
|
|
2217
|
+
if (shown || !element.current) return;
|
|
2218
|
+
if (!(view === null || view === void 0 ? void 0 : view.IntersectionObserver)) {
|
|
2219
|
+
setShown(true);
|
|
2220
|
+
return;
|
|
2221
|
+
}
|
|
2222
|
+
const observer = new view.IntersectionObserver((entries) => {
|
|
2223
|
+
if (entries.some((entry) => entry.isIntersecting)) setShown(true);
|
|
2224
|
+
});
|
|
2225
|
+
observer.observe(element.current);
|
|
2226
|
+
return () => observer.disconnect();
|
|
2227
|
+
}, [shown]);
|
|
2228
|
+
return /* @__PURE__ */ React.createElement("div", {
|
|
2229
|
+
ref: element,
|
|
2230
|
+
className: "twgit-review-tab-body"
|
|
2231
|
+
}, shown && children);
|
|
2232
|
+
}
|
|
2233
|
+
/**
|
|
2234
|
+
* Opens a comparison of project.source.json files as tabs of the host's workspace: a tab group for each changed
|
|
2235
|
+
* stage or sprite, holding a tab for each changed script and one for its changes outside the code.
|
|
2236
|
+
* Returns how many tabs were asked for, or `0` when the host has no workspace to take them.
|
|
2237
|
+
*/
|
|
2238
|
+
function openProjectSourceTabs(openPanel, { key, files, renderBlock, locale = "en", rememberAs }) {
|
|
2239
|
+
if (!openPanel) return 0;
|
|
2240
|
+
const words = reviewTabWords(locale);
|
|
2241
|
+
const area = `${providerId}:diff:${key}`;
|
|
2242
|
+
const requests = [];
|
|
2243
|
+
const tab = (documentId, title, content, tabGroup) => ({
|
|
2244
|
+
reference: {
|
|
2245
|
+
providerId,
|
|
2246
|
+
documentId: `diff:${key}:${documentId}`
|
|
2247
|
+
},
|
|
2248
|
+
filename: title,
|
|
2249
|
+
title,
|
|
2250
|
+
transient: true,
|
|
2251
|
+
area,
|
|
2252
|
+
tabGroup,
|
|
2253
|
+
inactive: requests.length > 0,
|
|
2254
|
+
mount(element) {
|
|
2255
|
+
element.classList.add("twgit-panel-tab", "twgit-review-tab-slot");
|
|
2256
|
+
render(/* @__PURE__ */ React.createElement(WhenShown, null, content()), element);
|
|
2257
|
+
return {
|
|
2258
|
+
requestClose: () => {},
|
|
2259
|
+
dispose: () => {
|
|
2260
|
+
unmountComponentAtNode(element);
|
|
2261
|
+
}
|
|
2262
|
+
};
|
|
2263
|
+
}
|
|
2264
|
+
});
|
|
2265
|
+
for (const file of files) {
|
|
2266
|
+
const comparison = compareProjectForReview(file.before, file.after);
|
|
2267
|
+
const prefix = files.length > 1 ? file.path.split("/").slice(0, -1).join("/") : "";
|
|
2268
|
+
const labelOf = (target) => prefix ? `${prefix}: ${words.target(target)}` : words.target(target);
|
|
2269
|
+
if (comparison.properties.length || !comparison.targets.length) {
|
|
2270
|
+
const title = prefix ? `${prefix}: ${words.project}` : words.project;
|
|
2271
|
+
requests.push(tab(`${file.path}:project`, title, () => /* @__PURE__ */ React.createElement(TargetReviewTab, {
|
|
2272
|
+
comparison,
|
|
2273
|
+
locale
|
|
2274
|
+
})));
|
|
2275
|
+
}
|
|
2276
|
+
for (const target of comparison.targets) {
|
|
2277
|
+
const targetKey = JSON.stringify([
|
|
2278
|
+
file.path,
|
|
2279
|
+
target.isStage,
|
|
2280
|
+
target.name
|
|
2281
|
+
]);
|
|
2282
|
+
const tabGroup = {
|
|
2283
|
+
id: `${area}:${targetKey}`,
|
|
2284
|
+
label: labelOf(target),
|
|
2285
|
+
color: statusColor[target.status]
|
|
2286
|
+
};
|
|
2287
|
+
if (target.status !== "updated" || target.properties.length || !target.scripts.length) requests.push(tab(`${targetKey}:details`, words.targetDetails, () => /* @__PURE__ */ React.createElement(TargetReviewTab, {
|
|
2288
|
+
comparison,
|
|
2289
|
+
target,
|
|
2290
|
+
locale,
|
|
2291
|
+
loadAsset: file.loadAsset
|
|
2292
|
+
}), tabGroup));
|
|
2293
|
+
for (const script of target.scripts) requests.push(tab(`${targetKey}:${script.id}`, words.script(script), () => /* @__PURE__ */ React.createElement(ScriptReviewTab, {
|
|
2294
|
+
comparison,
|
|
2295
|
+
script,
|
|
2296
|
+
renderBlock,
|
|
2297
|
+
locale,
|
|
2298
|
+
loadAsset: file.loadAsset,
|
|
2299
|
+
locateBlock: file.locateBlock,
|
|
2300
|
+
mark: {
|
|
2301
|
+
name: rememberAs !== null && rememberAs !== void 0 ? rememberAs : area,
|
|
2302
|
+
remember: !!rememberAs,
|
|
2303
|
+
file: file.path,
|
|
2304
|
+
target
|
|
2305
|
+
}
|
|
2306
|
+
}), tabGroup));
|
|
2307
|
+
}
|
|
2308
|
+
}
|
|
2309
|
+
let opened = 0;
|
|
2310
|
+
for (const request of requests) {
|
|
2311
|
+
if (!openPanel(request)) break;
|
|
2312
|
+
opened++;
|
|
2313
|
+
}
|
|
2314
|
+
return opened;
|
|
2315
|
+
}
|
|
2119
2316
|
// src/block-diff-location.ts
|
|
2120
2317
|
function markBlockLocation(block, parts) {
|
|
2121
2318
|
const root = block.getSvgRoot();
|
|
@@ -2546,4 +2743,4 @@ function openProjectComparison(document, options) {
|
|
|
2546
2743
|
render(/* @__PURE__ */ React.createElement(ProjectComparisonDialog, _objectSpread2(_objectSpread2({}, options), {}, { onChoose: choose })), root);
|
|
2547
2744
|
});
|
|
2548
2745
|
}
|
|
2549
|
-
export {
|
|
2746
|
+
export { parseProjectSource as C, createProjectSourceDiff as S, usePreviewSync as _, openProjectSourceTabs as a, useCostumeImage as b, gitHubRepositoryFromOrigin as c, assetFileName as d, organizeProjectChanges as f, createPreviewSync as g, BlockPreview as h, createScratchBlocksDiffLocator as i, ProjectSourceComparison as l, compareProjectForReview as m, openProjectComparison as n, PullRequestError as o, projectPropertyLabel as p, createScratchBlocksDiffRenderer as r, createGitHubPullRequests as s, ProjectComparisonDialog as t, ProjectSourceReview as u, currentCostume as v, readProjectSourceDiff as w, compareProjectBlocks as x, useAssetImage as y };
|
|
@@ -5,6 +5,8 @@ import './project-source-diff.css';
|
|
|
5
5
|
export { createGitHubPullRequests, gitHubRepositoryFromOrigin } from './github-pull-requests.js';
|
|
6
6
|
export { ProjectSourceComparison, ProjectSourceReview } from './project-source-review.js';
|
|
7
7
|
export { ProjectComparisonDialog, openProjectComparison } from './project-comparison.js';
|
|
8
|
+
export { openProjectSourceTabs } from './project-source-tabs.js';
|
|
9
|
+
export type { ProjectSourceTabsFile, ProjectSourceTabsOptions } from './project-source-tabs.js';
|
|
8
10
|
export type { ProjectComparisonAction, ProjectComparisonDialogProps, ProjectComparisonOptions, ProjectComparisonSection } from './project-comparison.js';
|
|
9
11
|
export type { ProjectSourceComparisonProps, ProjectSourceReviewFile, ProjectSourceReviewProps } from './project-source-review.js';
|
|
10
12
|
export { createScratchBlocksDiffLocator } from './block-diff-location.js';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { S as createProjectSourceDiff, _ as usePreviewSync, a as openProjectSourceTabs, c as gitHubRepositoryFromOrigin, d as assetFileName, f as organizeProjectChanges, g as createPreviewSync, h as BlockPreview, i as createScratchBlocksDiffLocator, l as ProjectSourceComparison, m as compareProjectForReview, n as openProjectComparison, p as projectPropertyLabel, r as createScratchBlocksDiffRenderer, s as createGitHubPullRequests, t as ProjectComparisonDialog, u as ProjectSourceReview, v as currentCostume, w as readProjectSourceDiff, x as compareProjectBlocks } from "./project-comparison-MU0qD2wo.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 { ProjectComparisonDialog, ProjectSourceBlockDiff, ProjectSourceComparison, ProjectSourceReview, assetFileName, compareProjectForReview, createGitHubPullRequests, createPreviewSync, createProjectSourceDiff, createScratchBlocksDiffLocator, createScratchBlocksDiffRenderer, currentCostume, gitHubRepositoryFromOrigin, openProjectComparison, organizeProjectChanges, projectPropertyLabel };
|
|
172
|
+
export { ProjectComparisonDialog, ProjectSourceBlockDiff, ProjectSourceComparison, ProjectSourceReview, assetFileName, compareProjectForReview, createGitHubPullRequests, createPreviewSync, createProjectSourceDiff, createScratchBlocksDiffLocator, createScratchBlocksDiffRenderer, currentCostume, gitHubRepositoryFromOrigin, openProjectComparison, openProjectSourceTabs, organizeProjectChanges, projectPropertyLabel };
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
import { compareProjectForReview } from './project-source-review-model.js';
|
|
3
|
+
import type { ScriptReview, TargetReview } from './project-source-review-model.js';
|
|
2
4
|
import type { ProjectBlockRenderer } from './scratch-block-diff-renderer.js';
|
|
3
5
|
import type { ProjectBlockLocator } from './block-diff-location.js';
|
|
4
6
|
import type { ProjectAssetLoader } from './project-assets.js';
|
|
7
|
+
type Comparison = ReturnType<typeof compareProjectForReview>;
|
|
5
8
|
export type ProjectSourceReviewFile = {
|
|
6
9
|
path: string;
|
|
7
10
|
summary?: string;
|
|
@@ -51,3 +54,43 @@ export interface ProjectSourceComparisonProps {
|
|
|
51
54
|
/** Compares two versions of a project.source.json by stage, sprite and code, as the pull request review does. */
|
|
52
55
|
export declare function ProjectSourceComparison({ before, after, renderBlock, locale, fallback, loadAsset, locateBlock, target }: ProjectSourceComparisonProps): React.JSX.Element;
|
|
53
56
|
export declare function ProjectSourceReview({ title, description, verification, files, renderBlock, locale, rememberAs }: ProjectSourceReviewProps): React.JSX.Element;
|
|
57
|
+
/** The words of one tab of a project comparison opened as tabs. */
|
|
58
|
+
export declare function reviewTabWords(locale: string): {
|
|
59
|
+
script: (script: ScriptReview) => string;
|
|
60
|
+
target: (target: TargetReview) => string;
|
|
61
|
+
targetDetails: string;
|
|
62
|
+
project: string;
|
|
63
|
+
noChanges: string;
|
|
64
|
+
};
|
|
65
|
+
/**
|
|
66
|
+
* Where a tab keeps its reviewed mark: under `name` with the review of the same name, in the browser when
|
|
67
|
+
* `remember` is set, or else while the page is open.
|
|
68
|
+
*/
|
|
69
|
+
export interface ReviewMarkPlace {
|
|
70
|
+
name: string;
|
|
71
|
+
remember: boolean;
|
|
72
|
+
file: string;
|
|
73
|
+
target: TargetReview;
|
|
74
|
+
}
|
|
75
|
+
/** One script of a comparison, open, for a tab of its own. */
|
|
76
|
+
export declare function ScriptReviewTab({ comparison, script, renderBlock, locale, loadAsset, locateBlock, mark }: {
|
|
77
|
+
comparison: Comparison;
|
|
78
|
+
script: ScriptReview;
|
|
79
|
+
renderBlock: ProjectBlockRenderer;
|
|
80
|
+
locale?: string;
|
|
81
|
+
loadAsset?: ProjectAssetLoader;
|
|
82
|
+
locateBlock?: ProjectBlockLocator;
|
|
83
|
+
/** Offers the reviewed mark, shared with the review panel and other tabs that use the same place. */
|
|
84
|
+
mark?: ReviewMarkPlace;
|
|
85
|
+
}): React.JSX.Element;
|
|
86
|
+
/**
|
|
87
|
+
* What changed in a stage or sprite outside its code, or in the project as a whole when no target is given,
|
|
88
|
+
* for a tab of its own.
|
|
89
|
+
*/
|
|
90
|
+
export declare function TargetReviewTab({ comparison, target, locale, loadAsset }: {
|
|
91
|
+
comparison: Comparison;
|
|
92
|
+
target?: TargetReview;
|
|
93
|
+
locale?: string;
|
|
94
|
+
loadAsset?: ProjectAssetLoader;
|
|
95
|
+
}): React.JSX.Element;
|
|
96
|
+
export {};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { ProjectSource } from './project-source-patch.js';
|
|
2
|
+
import type { ProjectBlockRenderer } from './scratch-block-diff-renderer.js';
|
|
3
|
+
import type { ProjectAssetLoader } from './project-assets.js';
|
|
4
|
+
import type { ProjectBlockLocator } from './block-diff-location.js';
|
|
5
|
+
import type { GitPanelRequest } from './index.js';
|
|
6
|
+
/** One project.source.json of a comparison, read into both versions. */
|
|
7
|
+
export interface ProjectSourceTabsFile {
|
|
8
|
+
path: string;
|
|
9
|
+
before: ProjectSource;
|
|
10
|
+
after: ProjectSource;
|
|
11
|
+
loadAsset?: ProjectAssetLoader;
|
|
12
|
+
/** Offers "Highlight in Editor" on the after version, which the caller has matched with the open project. */
|
|
13
|
+
locateBlock?: ProjectBlockLocator;
|
|
14
|
+
}
|
|
15
|
+
export interface ProjectSourceTabsOptions {
|
|
16
|
+
/**
|
|
17
|
+
* Names this comparison, such as `owner/repo#42@<head>` or `<commit>:project.source.json`. Its tabs share one
|
|
18
|
+
* split, and opening the same comparison again brings its tabs forward instead of adding them twice.
|
|
19
|
+
*/
|
|
20
|
+
key: string;
|
|
21
|
+
files: readonly ProjectSourceTabsFile[];
|
|
22
|
+
renderBlock: ProjectBlockRenderer;
|
|
23
|
+
locale?: string;
|
|
24
|
+
/**
|
|
25
|
+
* Shares the reviewed marks of the script tabs with the review of this name, such as `owner/repo#42`, and keeps
|
|
26
|
+
* them in the browser. Without it, the marks are kept for this comparison while the page is open.
|
|
27
|
+
*/
|
|
28
|
+
rememberAs?: string;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Opens a comparison of project.source.json files as tabs of the host's workspace: a tab group for each changed
|
|
32
|
+
* stage or sprite, holding a tab for each changed script and one for its changes outside the code.
|
|
33
|
+
* Returns how many tabs were asked for, or `0` when the host has no workspace to take them.
|
|
34
|
+
*/
|
|
35
|
+
export declare function openProjectSourceTabs(openPanel: ((request: GitPanelRequest) => boolean) | undefined, { key, files, renderBlock, locale, rememberAs }: ProjectSourceTabsOptions): number;
|
|
@@ -2,10 +2,15 @@ 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
|
-
|
|
5
|
+
import type { ProjectSourceTabsFile } from './project-source-tabs.js';
|
|
6
|
+
type OpenTabs = (key: string, files: readonly ProjectSourceTabsFile[], rememberAs?: string) => number;
|
|
7
|
+
export declare function PullRequestReviewPanel({ repository, locale, renderBlock, locateFor, openTabs }: {
|
|
6
8
|
repository: Repository;
|
|
7
9
|
locale: string;
|
|
8
10
|
renderBlock: ProjectBlockRenderer;
|
|
11
|
+
/** Opens a pull request's project changes as tabs of the host's layout. */
|
|
12
|
+
openTabs?: OpenTabs;
|
|
9
13
|
/** Returns a locator for a project file whose PR head matches the open project, or `undefined`. */
|
|
10
14
|
locateFor?(path: string, headSha: string): ProjectBlockLocator | undefined;
|
|
11
15
|
}): React.JSX.Element;
|
|
16
|
+
export {};
|