@kud/gh-ink 0.45.0 → 0.45.2
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 +68 -27
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -703,7 +703,7 @@ var healthLegend = [
|
|
|
703
703
|
|
|
704
704
|
// src/inbox/cache.ts
|
|
705
705
|
var cacheTtlMs = () => inboxConfig().cacheTtlMs;
|
|
706
|
-
var CACHE_VERSION =
|
|
706
|
+
var CACHE_VERSION = 4;
|
|
707
707
|
var cacheDir = () => join(
|
|
708
708
|
process.env.XDG_CACHE_HOME || join(homedir(), ".cache"),
|
|
709
709
|
inboxConfig().cacheNamespace
|
|
@@ -1786,14 +1786,20 @@ var RepoHeaderRow = ({
|
|
|
1786
1786
|
/* @__PURE__ */ jsx(Text3, { dimColor: !active, children: " " + rule })
|
|
1787
1787
|
] });
|
|
1788
1788
|
};
|
|
1789
|
-
var MERGED_HOLD_MS =
|
|
1789
|
+
var MERGED_HOLD_MS = 3e3;
|
|
1790
1790
|
var MERGED_FRAME_MS = 150;
|
|
1791
1791
|
var MERGED_FRAMES = ["\u2726", "\u2727", "\u2736", "\u2727"];
|
|
1792
1792
|
var MERGED_COLOUR = "#A371F7";
|
|
1793
1793
|
var TRANSIT_HOLD_MS = 7e3;
|
|
1794
|
-
var TRANSIT_FRAME_TICKS =
|
|
1795
|
-
var
|
|
1794
|
+
var TRANSIT_FRAME_TICKS = 2;
|
|
1795
|
+
var TRANSIT_FRAME_MS = MERGED_FRAME_MS * TRANSIT_FRAME_TICKS;
|
|
1796
|
+
var rampFrame = (len, loopFrame, transitAt, now = Date.now()) => transitAt == null ? loopFrame % len : Math.max(
|
|
1797
|
+
0,
|
|
1798
|
+
Math.min(len - 1, Math.floor((now - transitAt) / TRANSIT_FRAME_MS))
|
|
1799
|
+
);
|
|
1800
|
+
var PULSE_SETTLE_MS = 12e3;
|
|
1796
1801
|
var PULSE_MAX_FRAMES = Math.ceil(PULSE_SETTLE_MS / MERGED_FRAME_MS);
|
|
1802
|
+
var PULSE_IDLE_MS = 6e4;
|
|
1797
1803
|
var PULSE_SETTLED_FRAME = 3;
|
|
1798
1804
|
var NO_TRANSIENTS = /* @__PURE__ */ new Map();
|
|
1799
1805
|
var NO_HOLDS = /* @__PURE__ */ new Map();
|
|
@@ -1825,6 +1831,7 @@ var ItemRow = ({
|
|
|
1825
1831
|
merged,
|
|
1826
1832
|
transient: refreshMark,
|
|
1827
1833
|
leaving,
|
|
1834
|
+
transitAt,
|
|
1828
1835
|
prefix = "",
|
|
1829
1836
|
parent,
|
|
1830
1837
|
sparkFrame = 0,
|
|
@@ -1833,6 +1840,7 @@ var ItemRow = ({
|
|
|
1833
1840
|
const backdropped = useBackdropped();
|
|
1834
1841
|
const transient = leaving ? "out" : refreshMark;
|
|
1835
1842
|
const transitFrame = Math.floor(sparkFrame / TRANSIT_FRAME_TICKS);
|
|
1843
|
+
const rampAt = (len) => rampFrame(len, transitFrame, transitAt);
|
|
1836
1844
|
const farewellLabel = leaving ? TRANSIT_LABEL.out : "";
|
|
1837
1845
|
if (item.kind === "repo-header")
|
|
1838
1846
|
return /* @__PURE__ */ jsx(RepoHeaderRow, { repo: item.repo, gap: gap ?? false, active });
|
|
@@ -1857,7 +1865,7 @@ var ItemRow = ({
|
|
|
1857
1865
|
] });
|
|
1858
1866
|
if (item.kind === "task") {
|
|
1859
1867
|
const note = item.note ?? "";
|
|
1860
|
-
const transitIcon = !transient ? " " : isDeparture(transient) ? TRANSIT_OUT_FRAMES[
|
|
1868
|
+
const transitIcon = !transient ? " " : isDeparture(transient) ? TRANSIT_OUT_FRAMES[rampAt(TRANSIT_OUT_FRAMES.length)] : isArrival(transient) ? TRANSIT_IN_FRAMES[rampAt(TRANSIT_IN_FRAMES.length)] : "\u25C9";
|
|
1861
1869
|
const titleMax2 = Math.max(
|
|
1862
1870
|
1,
|
|
1863
1871
|
cols - item.key.length - note.length - (item.pill ? pillWidth(item.pill) + 1 : 0) - (farewellLabel ? pillWidth(farewellLabel) + 2 : 0) - prefix.length - 12
|
|
@@ -1889,7 +1897,7 @@ var ItemRow = ({
|
|
|
1889
1897
|
] });
|
|
1890
1898
|
}
|
|
1891
1899
|
const { glyph: healthIcon, color: healthColor2 } = healthDisplay[item.health];
|
|
1892
|
-
const icon = merged ? MERGED_FRAMES[sparkFrame % MERGED_FRAMES.length] : transient && isDeparture(transient) ? TRANSIT_OUT_FRAMES[
|
|
1900
|
+
const icon = merged ? MERGED_FRAMES[sparkFrame % MERGED_FRAMES.length] : transient && isDeparture(transient) ? TRANSIT_OUT_FRAMES[rampAt(TRANSIT_OUT_FRAMES.length)] : transient && isArrival(transient) ? TRANSIT_IN_FRAMES[rampAt(TRANSIT_IN_FRAMES.length)] : healthIcon;
|
|
1893
1901
|
const color = merged ? MERGED_COLOUR : transient ? TRANSIT_COLOUR[transient] : healthColor2;
|
|
1894
1902
|
const spokeLast = !!login && !!item.lastActor && item.lastActor === login;
|
|
1895
1903
|
const [turnIcon, turnColor] = item.pinned ? [PIN_MARK, "#FF8700"] : !login || !item.lastActor ? [" ", "white"] : spokeLast ? ["\u2192", "#888888"] : ["\u2190", "#FF8700"];
|
|
@@ -2311,6 +2319,7 @@ var BrowseScreen = ({
|
|
|
2311
2319
|
brand,
|
|
2312
2320
|
mergedUrls,
|
|
2313
2321
|
leavingUrls,
|
|
2322
|
+
transitSince,
|
|
2314
2323
|
onLeave,
|
|
2315
2324
|
transients,
|
|
2316
2325
|
onTabChange,
|
|
@@ -2414,7 +2423,7 @@ var BrowseScreen = ({
|
|
|
2414
2423
|
out.add(s.id);
|
|
2415
2424
|
return out;
|
|
2416
2425
|
}, [localSections, transients]);
|
|
2417
|
-
const [railOpen, setRailOpen] = useState(
|
|
2426
|
+
const [railOpen, setRailOpen] = useState(false);
|
|
2418
2427
|
const showRail = railOpen && !!sidebar;
|
|
2419
2428
|
const [railFocus, setRailFocus] = useState(false);
|
|
2420
2429
|
const [railCursor, setRailCursor] = useState(0);
|
|
@@ -2434,20 +2443,28 @@ var BrowseScreen = ({
|
|
|
2434
2443
|
mergedUrls?.length ?? 0,
|
|
2435
2444
|
leavingUrls?.length ?? 0
|
|
2436
2445
|
].join("|") : "";
|
|
2446
|
+
const [pulseArm, setPulseArm] = useState(0);
|
|
2447
|
+
const lastKeyAt = useRef(Date.now());
|
|
2448
|
+
const pulseKey = sparkKey ? `${sparkKey}#${pulseArm}` : "";
|
|
2449
|
+
const [pulseSettled, setPulseSettled] = useState(false);
|
|
2437
2450
|
useEffect(() => {
|
|
2438
|
-
if (!
|
|
2451
|
+
if (!pulseKey) return;
|
|
2452
|
+
setPulseSettled(false);
|
|
2439
2453
|
let frames = 0;
|
|
2440
2454
|
const id = setInterval(() => {
|
|
2441
2455
|
frames += 1;
|
|
2442
2456
|
if (frames >= PULSE_MAX_FRAMES) {
|
|
2443
2457
|
clearInterval(id);
|
|
2444
|
-
|
|
2458
|
+
setPulseSettled(true);
|
|
2445
2459
|
return;
|
|
2446
2460
|
}
|
|
2447
2461
|
setSparkFrame((f) => f + 1);
|
|
2448
2462
|
}, MERGED_FRAME_MS);
|
|
2449
2463
|
return () => clearInterval(id);
|
|
2450
|
-
}, [
|
|
2464
|
+
}, [pulseKey]);
|
|
2465
|
+
useEffect(() => {
|
|
2466
|
+
if (sparkKey) setPulseArm((n) => n + 1);
|
|
2467
|
+
}, [tabIdx]);
|
|
2451
2468
|
useEffect(() => {
|
|
2452
2469
|
if (refreshError) showFlash(`\u2717 ${refreshError.message}`);
|
|
2453
2470
|
}, [refreshError]);
|
|
@@ -2482,6 +2499,9 @@ var BrowseScreen = ({
|
|
|
2482
2499
|
menu.open(actions);
|
|
2483
2500
|
};
|
|
2484
2501
|
useInput((input, key) => {
|
|
2502
|
+
const idleFor = Date.now() - lastKeyAt.current;
|
|
2503
|
+
lastKeyAt.current = Date.now();
|
|
2504
|
+
if (idleFor >= PULSE_IDLE_MS && sparkKey) setPulseArm((n) => n + 1);
|
|
2485
2505
|
if (hidden) return;
|
|
2486
2506
|
if (key.ctrl || key.meta) return;
|
|
2487
2507
|
if (help) {
|
|
@@ -2945,7 +2965,11 @@ var BrowseScreen = ({
|
|
|
2945
2965
|
// bar — and free to animate for exactly that reason.
|
|
2946
2966
|
// The ticker undivided — see TAB_PULSE. The row marks' /3 buys quiet
|
|
2947
2967
|
// for motion sitting beside text, and this is not that.
|
|
2948
|
-
marker: tabMarker(
|
|
2968
|
+
marker: tabMarker(
|
|
2969
|
+
markedTabs,
|
|
2970
|
+
s.id,
|
|
2971
|
+
pulseSettled ? PULSE_SETTLED_FRAME : sparkFrame
|
|
2972
|
+
),
|
|
2949
2973
|
markerColor: "#FF8700"
|
|
2950
2974
|
}))
|
|
2951
2975
|
}
|
|
@@ -2979,6 +3003,7 @@ var BrowseScreen = ({
|
|
|
2979
3003
|
merged: (item.kind === "pr" || item.kind === "issue") && !!mergedUrls?.includes(item.url),
|
|
2980
3004
|
leaving: (item.kind === "pr" || item.kind === "issue") && !!leavingUrls?.includes(item.url),
|
|
2981
3005
|
transient: transientOf(transients, item, section.id),
|
|
3006
|
+
transitAt: "url" in item ? transitSince?.get(item.url) : void 0,
|
|
2982
3007
|
prefix: treePrefix(section.items, viewStart + i),
|
|
2983
3008
|
parent: item.kind === "task" && depthOf(section.items[viewStart + i + 1]) > depthOf(item),
|
|
2984
3009
|
sparkFrame,
|
|
@@ -3316,8 +3341,24 @@ var App = ({
|
|
|
3316
3341
|
const [skippedForBudget, setSkippedForBudget] = useState(false);
|
|
3317
3342
|
const [mergedUrls, setMergedUrls] = useState([]);
|
|
3318
3343
|
const [leavingUrls, setLeavingUrls] = useState([]);
|
|
3344
|
+
const leavingSince = useRef(/* @__PURE__ */ new Map());
|
|
3345
|
+
const transitSince = useMemo(() => {
|
|
3346
|
+
const out = new Map(leavingSince.current);
|
|
3347
|
+
for (const [url, tab] of transitTabs.current) {
|
|
3348
|
+
const at = heldSince.get(tab);
|
|
3349
|
+
if (at != null && !out.has(url)) out.set(url, at);
|
|
3350
|
+
}
|
|
3351
|
+
return out;
|
|
3352
|
+
}, [heldSince, transients, leavingUrls]);
|
|
3319
3353
|
const holdTimers = useRef([]);
|
|
3320
3354
|
useEffect(() => () => holdTimers.current.forEach(clearTimeout), []);
|
|
3355
|
+
const holdFor = (fn, ms) => {
|
|
3356
|
+
const id = setTimeout(() => {
|
|
3357
|
+
holdTimers.current = holdTimers.current.filter((t) => t !== id);
|
|
3358
|
+
fn();
|
|
3359
|
+
}, ms);
|
|
3360
|
+
holdTimers.current.push(id);
|
|
3361
|
+
};
|
|
3321
3362
|
if (state.phase === "loading" || state.phase === "empty" || state.phase === "failed")
|
|
3322
3363
|
return /* @__PURE__ */ jsxs(
|
|
3323
3364
|
Box,
|
|
@@ -3367,31 +3408,30 @@ var App = ({
|
|
|
3367
3408
|
const toBrowse = () => setState({ phase: "browse", sections: state.sections, login: state.login });
|
|
3368
3409
|
const markLeaving = (target) => {
|
|
3369
3410
|
if (state.phase !== "browse") toBrowse();
|
|
3411
|
+
if (!leavingSince.current.has(target.url))
|
|
3412
|
+
leavingSince.current.set(target.url, Date.now());
|
|
3370
3413
|
setLeavingUrls(
|
|
3371
3414
|
(prev) => prev.includes(target.url) ? prev : [...prev, target.url]
|
|
3372
3415
|
);
|
|
3373
|
-
|
|
3374
|
-
|
|
3375
|
-
|
|
3376
|
-
|
|
3377
|
-
|
|
3378
|
-
|
|
3379
|
-
|
|
3380
|
-
);
|
|
3416
|
+
holdFor(() => {
|
|
3417
|
+
leavingSince.current.delete(target.url);
|
|
3418
|
+
setLeavingUrls((prev) => prev.filter((u) => u !== target.url));
|
|
3419
|
+
setState(
|
|
3420
|
+
(s) => s.phase === "browse" ? { ...s, sections: withoutItem(s.sections, target) } : s
|
|
3421
|
+
);
|
|
3422
|
+
}, LEAVING_HOLD_MS);
|
|
3381
3423
|
};
|
|
3382
3424
|
const markMerged = (target) => {
|
|
3383
3425
|
toBrowse();
|
|
3384
3426
|
setMergedUrls(
|
|
3385
3427
|
(prev) => prev.includes(target.url) ? prev : [...prev, target.url]
|
|
3386
3428
|
);
|
|
3387
|
-
|
|
3388
|
-
|
|
3389
|
-
|
|
3390
|
-
|
|
3391
|
-
|
|
3392
|
-
|
|
3393
|
-
}, MERGED_HOLD_MS)
|
|
3394
|
-
);
|
|
3429
|
+
holdFor(() => {
|
|
3430
|
+
setMergedUrls((prev) => prev.filter((u) => u !== target.url));
|
|
3431
|
+
setState(
|
|
3432
|
+
(s) => s.phase === "browse" ? { ...s, sections: withoutItem(s.sections, target) } : s
|
|
3433
|
+
);
|
|
3434
|
+
}, MERGED_HOLD_MS);
|
|
3395
3435
|
};
|
|
3396
3436
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3397
3437
|
/* @__PURE__ */ jsx(
|
|
@@ -3417,6 +3457,7 @@ var App = ({
|
|
|
3417
3457
|
hidden: overlay !== null,
|
|
3418
3458
|
mergedUrls,
|
|
3419
3459
|
leavingUrls,
|
|
3460
|
+
transitSince,
|
|
3420
3461
|
onLeave: markLeaving,
|
|
3421
3462
|
transients,
|
|
3422
3463
|
onTabChange: setVisibleTab,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kud/gh-ink",
|
|
3
|
-
"version": "0.45.
|
|
3
|
+
"version": "0.45.2",
|
|
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",
|