@kud/gh-ink 0.35.0 → 0.36.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/index.js +81 -28
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -676,6 +676,9 @@ var invalidateCache = (key) => {
|
|
|
676
676
|
};
|
|
677
677
|
|
|
678
678
|
// src/inbox/diff.ts
|
|
679
|
+
var MARK_SEP = "\0";
|
|
680
|
+
var markKey = (sectionId, rowKey) => `${sectionId}${MARK_SEP}${rowKey}`;
|
|
681
|
+
var rowKeyOfMark = (mark) => mark.slice(mark.indexOf(MARK_SEP) + 1);
|
|
679
682
|
var keyOf = (item) => {
|
|
680
683
|
if (item.kind === "pr" || item.kind === "issue") return item.url;
|
|
681
684
|
if (item.kind === "task") {
|
|
@@ -707,11 +710,27 @@ var indexRows = (sections) => {
|
|
|
707
710
|
for (const section of sections) {
|
|
708
711
|
section.items.forEach((item, index) => {
|
|
709
712
|
const key = keyOf(item);
|
|
710
|
-
if (key)
|
|
713
|
+
if (key)
|
|
714
|
+
out.set(markKey(section.id, key), {
|
|
715
|
+
item,
|
|
716
|
+
sectionId: section.id,
|
|
717
|
+
index
|
|
718
|
+
});
|
|
711
719
|
});
|
|
712
720
|
}
|
|
713
721
|
return out;
|
|
714
722
|
};
|
|
723
|
+
var rowsOf = (index) => {
|
|
724
|
+
const out = /* @__PURE__ */ new Map();
|
|
725
|
+
for (const [mark, placed] of index) {
|
|
726
|
+
const key = rowKeyOfMark(mark);
|
|
727
|
+
const seen = out.get(key);
|
|
728
|
+
if (seen) seen.add(placed.sectionId);
|
|
729
|
+
else out.set(key, /* @__PURE__ */ new Set([placed.sectionId]));
|
|
730
|
+
}
|
|
731
|
+
return out;
|
|
732
|
+
};
|
|
733
|
+
var sameSections = (a, b) => a.size === b.size && [...a].every((id) => b.has(id));
|
|
715
734
|
var spliceBack = (next, leaving) => {
|
|
716
735
|
if (leaving.length === 0) return next;
|
|
717
736
|
const bySection = /* @__PURE__ */ new Map();
|
|
@@ -732,30 +751,43 @@ var spliceBack = (next, leaving) => {
|
|
|
732
751
|
var diffSections = (prev, next) => {
|
|
733
752
|
const before = indexRows(prev);
|
|
734
753
|
const after = indexRows(next);
|
|
754
|
+
const boardBefore = rowsOf(before);
|
|
755
|
+
const boardAfter = rowsOf(after);
|
|
735
756
|
const transients = /* @__PURE__ */ new Map();
|
|
736
757
|
const leaving = [];
|
|
737
|
-
for (const [
|
|
738
|
-
|
|
739
|
-
|
|
758
|
+
for (const [mark] of after)
|
|
759
|
+
if (!before.has(mark))
|
|
760
|
+
transients.set(
|
|
761
|
+
mark,
|
|
762
|
+
boardBefore.has(rowKeyOfMark(mark)) ? "moved-in" : "in"
|
|
763
|
+
);
|
|
764
|
+
for (const [mark, was] of before) {
|
|
765
|
+
const now = after.get(mark);
|
|
740
766
|
if (!now) {
|
|
741
|
-
transients.set(
|
|
767
|
+
transients.set(
|
|
768
|
+
mark,
|
|
769
|
+
boardAfter.has(rowKeyOfMark(mark)) ? "moved-out" : "out"
|
|
770
|
+
);
|
|
742
771
|
leaving.push(was);
|
|
743
772
|
} else if (renderedState(was.item) !== renderedState(now.item)) {
|
|
744
|
-
transients.set(
|
|
773
|
+
transients.set(mark, "changed");
|
|
745
774
|
}
|
|
746
775
|
}
|
|
747
776
|
let added = 0;
|
|
748
777
|
let removed = 0;
|
|
749
|
-
|
|
750
|
-
for (const [, kind] of transients)
|
|
751
|
-
if (kind === "
|
|
752
|
-
|
|
753
|
-
|
|
778
|
+
const changedRows = /* @__PURE__ */ new Set();
|
|
779
|
+
for (const [mark, kind] of transients)
|
|
780
|
+
if (kind === "changed") changedRows.add(rowKeyOfMark(mark));
|
|
781
|
+
for (const [key, sections] of boardAfter) {
|
|
782
|
+
const had = boardBefore.get(key);
|
|
783
|
+
if (!had) added += 1;
|
|
784
|
+
else if (!sameSections(had, sections)) changedRows.add(key);
|
|
754
785
|
}
|
|
786
|
+
for (const key of boardBefore.keys()) if (!boardAfter.has(key)) removed += 1;
|
|
755
787
|
return {
|
|
756
788
|
transients,
|
|
757
789
|
union: spliceBack(next, leaving),
|
|
758
|
-
counts: { added, removed, changed }
|
|
790
|
+
counts: { added, removed, changed: changedRows.size }
|
|
759
791
|
};
|
|
760
792
|
};
|
|
761
793
|
var summariseDiff = (counts) => {
|
|
@@ -765,17 +797,19 @@ var summariseDiff = (counts) => {
|
|
|
765
797
|
if (counts.changed) parts.push(`${counts.changed} moved`);
|
|
766
798
|
return parts.join(" \xB7 ");
|
|
767
799
|
};
|
|
768
|
-
var transientOf = (transients, item) => {
|
|
800
|
+
var transientOf = (transients, item, sectionId) => {
|
|
769
801
|
if (!transients?.size) return void 0;
|
|
770
802
|
const key = keyOf(item);
|
|
771
|
-
return key ? transients.get(key) : void 0;
|
|
803
|
+
return key ? transients.get(markKey(sectionId, key)) : void 0;
|
|
772
804
|
};
|
|
773
805
|
var tabsOfMarks = (sections, marks) => {
|
|
774
806
|
const out = /* @__PURE__ */ new Map();
|
|
775
807
|
for (const section of sections)
|
|
776
808
|
for (const item of section.items) {
|
|
777
809
|
const key = keyOf(item);
|
|
778
|
-
if (key
|
|
810
|
+
if (!key) continue;
|
|
811
|
+
const mark = markKey(section.id, key);
|
|
812
|
+
if (marks.has(mark)) out.set(mark, section.id);
|
|
779
813
|
}
|
|
780
814
|
return out;
|
|
781
815
|
};
|
|
@@ -1835,13 +1869,26 @@ var TRANSIT_IN_FRAMES = ["\xB7", "\u25CB", "\u25CE", "\u25C9"];
|
|
|
1835
1869
|
var TRANSIT_COLOUR = {
|
|
1836
1870
|
in: "#3FB950",
|
|
1837
1871
|
out: "#8B949E",
|
|
1838
|
-
changed: "#FF8700"
|
|
1872
|
+
changed: "#FF8700",
|
|
1873
|
+
// A move is neither an arrival nor a departure, so it takes the colour of the
|
|
1874
|
+
// third thing that can happen to a row you already had: it changed. Both ends
|
|
1875
|
+
// of one move wear the same colour and the same word, which is what lets you
|
|
1876
|
+
// recognise the row you just watched leave when you land on the tab it went to.
|
|
1877
|
+
"moved-in": "#FF8700",
|
|
1878
|
+
"moved-out": "#FF8700"
|
|
1839
1879
|
};
|
|
1840
1880
|
var TRANSIT_LABEL = {
|
|
1841
1881
|
in: "NEW",
|
|
1842
1882
|
out: "GONE",
|
|
1843
|
-
changed: "UPDATED"
|
|
1844
|
-
|
|
1883
|
+
changed: "UPDATED",
|
|
1884
|
+
// Never GONE. The row is still on the board, one tab over, and telling you it
|
|
1885
|
+
// has gone is the marker lying about work you still own — which was the whole
|
|
1886
|
+
// failure: an epic moving tab said nothing at all and simply vanished.
|
|
1887
|
+
"moved-in": "MOVED",
|
|
1888
|
+
"moved-out": "MOVED"
|
|
1889
|
+
};
|
|
1890
|
+
var isDeparture = (t) => t === "out" || t === "moved-out";
|
|
1891
|
+
var isArrival = (t) => t === "in" || t === "moved-in";
|
|
1845
1892
|
var LEAVING_HOLD_MS = 2500;
|
|
1846
1893
|
var TAB_MARK = "\u25CF";
|
|
1847
1894
|
var tabLabel = (label, marked, id) => marked.size === 0 ? label : `${marked.has(id) ? TAB_MARK : " "} ${label}`;
|
|
@@ -1881,7 +1928,7 @@ var ItemRow = ({
|
|
|
1881
1928
|
] });
|
|
1882
1929
|
if (item.kind === "task") {
|
|
1883
1930
|
const note = item.note ?? "";
|
|
1884
|
-
const transitIcon = !transient ? " " : transient
|
|
1931
|
+
const transitIcon = !transient ? " " : isDeparture(transient) ? TRANSIT_OUT_FRAMES[sparkFrame % TRANSIT_OUT_FRAMES.length] : isArrival(transient) ? TRANSIT_IN_FRAMES[sparkFrame % TRANSIT_IN_FRAMES.length] : "\u25C9";
|
|
1885
1932
|
const transitLabel2 = transient ? TRANSIT_LABEL[transient] : "";
|
|
1886
1933
|
const titleMax2 = Math.max(
|
|
1887
1934
|
20,
|
|
@@ -1896,8 +1943,8 @@ var ItemRow = ({
|
|
|
1896
1943
|
/* @__PURE__ */ jsx(
|
|
1897
1944
|
Text2,
|
|
1898
1945
|
{
|
|
1899
|
-
bold: active || transient
|
|
1900
|
-
dimColor: transient
|
|
1946
|
+
bold: active || !!transient && isArrival(transient),
|
|
1947
|
+
dimColor: !!transient && isDeparture(transient),
|
|
1901
1948
|
strikethrough: transient === "out",
|
|
1902
1949
|
children: truncate(item.summary, titleMax2)
|
|
1903
1950
|
}
|
|
@@ -1907,7 +1954,7 @@ var ItemRow = ({
|
|
|
1907
1954
|
] });
|
|
1908
1955
|
}
|
|
1909
1956
|
const { glyph: healthIcon, color: healthColor2 } = healthDisplay[item.health];
|
|
1910
|
-
const icon = merged ? MERGED_FRAMES[sparkFrame % MERGED_FRAMES.length] : transient
|
|
1957
|
+
const icon = merged ? MERGED_FRAMES[sparkFrame % MERGED_FRAMES.length] : transient && isDeparture(transient) ? TRANSIT_OUT_FRAMES[sparkFrame % TRANSIT_OUT_FRAMES.length] : transient && isArrival(transient) ? TRANSIT_IN_FRAMES[sparkFrame % TRANSIT_IN_FRAMES.length] : healthIcon;
|
|
1911
1958
|
const color = merged ? MERGED_COLOUR : transient ? TRANSIT_COLOUR[transient] : healthColor2;
|
|
1912
1959
|
const spokeLast = !!login && !!item.lastActor && item.lastActor === login;
|
|
1913
1960
|
const [turnIcon, turnColor] = item.pinned ? [PIN_MARK, "#FF8700"] : !login || !item.lastActor ? [" ", "white"] : spokeLast ? ["\u2192", "#888888"] : ["\u2190", "#FF8700"];
|
|
@@ -1936,8 +1983,8 @@ var ItemRow = ({
|
|
|
1936
1983
|
/* @__PURE__ */ jsx(
|
|
1937
1984
|
Text2,
|
|
1938
1985
|
{
|
|
1939
|
-
bold: active || transient
|
|
1940
|
-
dimColor: transient
|
|
1986
|
+
bold: active || !!transient && isArrival(transient),
|
|
1987
|
+
dimColor: !!transient && isDeparture(transient),
|
|
1941
1988
|
strikethrough: transient === "out",
|
|
1942
1989
|
children: truncate(item.title, titleMax) + " "
|
|
1943
1990
|
}
|
|
@@ -2379,11 +2426,12 @@ var BrowseScreen = ({
|
|
|
2379
2426
|
const out = /* @__PURE__ */ new Set();
|
|
2380
2427
|
if (!transients?.size) return out;
|
|
2381
2428
|
for (const s of localSections)
|
|
2382
|
-
if (s.items.some((item) => transientOf(transients, item
|
|
2429
|
+
if (s.items.some((item) => transientOf(transients, item, s.id)))
|
|
2430
|
+
out.add(s.id);
|
|
2383
2431
|
return out;
|
|
2384
2432
|
}, [localSections, transients]);
|
|
2385
2433
|
const [sparkFrame, setSparkFrame] = useState(0);
|
|
2386
|
-
const sparkling = (mergedUrls?.length ?? 0) > 0 || (leavingUrls?.length ?? 0) > 0 || !!transients?.size && section.items.some((item) => transientOf(transients, item));
|
|
2434
|
+
const sparkling = (mergedUrls?.length ?? 0) > 0 || (leavingUrls?.length ?? 0) > 0 || !!transients?.size && section.items.some((item) => transientOf(transients, item, section.id));
|
|
2387
2435
|
useEffect(() => {
|
|
2388
2436
|
if (!sparkling) return;
|
|
2389
2437
|
const id = setInterval(() => setSparkFrame((f) => f + 1), MERGED_FRAME_MS);
|
|
@@ -2853,7 +2901,7 @@ var BrowseScreen = ({
|
|
|
2853
2901
|
login,
|
|
2854
2902
|
merged: (item.kind === "pr" || item.kind === "issue") && !!mergedUrls?.includes(item.url),
|
|
2855
2903
|
leaving: (item.kind === "pr" || item.kind === "issue") && !!leavingUrls?.includes(item.url),
|
|
2856
|
-
transient: transientOf(transients, item),
|
|
2904
|
+
transient: transientOf(transients, item, section.id),
|
|
2857
2905
|
prefix: treePrefix(section.items, viewStart + i),
|
|
2858
2906
|
parent: item.kind === "task" && depthOf(section.items[viewStart + i + 1]) > depthOf(item),
|
|
2859
2907
|
sparkFrame,
|
|
@@ -2986,7 +3034,12 @@ var App = ({
|
|
|
2986
3034
|
const settleTab = (tabId, marks) => {
|
|
2987
3035
|
const keys = [...transitTabs.current].filter(([, tab]) => tab === tabId).map(([key]) => key);
|
|
2988
3036
|
for (const key of keys) transitTabs.current.delete(key);
|
|
2989
|
-
const gone = new Set(
|
|
3037
|
+
const gone = new Set(
|
|
3038
|
+
keys.filter((key) => {
|
|
3039
|
+
const mark = marks.get(key);
|
|
3040
|
+
return !!mark && isDeparture(mark);
|
|
3041
|
+
}).map(rowKeyOfMark)
|
|
3042
|
+
);
|
|
2990
3043
|
setTransients((prev) => {
|
|
2991
3044
|
const next = new Map(prev);
|
|
2992
3045
|
for (const key of keys) next.delete(key);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kud/gh-ink",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.36.0",
|
|
4
4
|
"description": "Ink components for rendering GitHub PR review comments and health — controlled, presentation-only, built on @kud/ink-ui and fed by @kud/gh.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|