@loafmarkets/ui 0.1.427 → 0.1.428
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 +15 -37
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +15 -37
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -3019,7 +3019,7 @@ PropertyTour.displayName = "PropertyTour";
|
|
|
3019
3019
|
var BREAKING_WINDOW_HOURS = 6;
|
|
3020
3020
|
var BREAKING_MEMORY_CAP = 50;
|
|
3021
3021
|
var BREAKING_MEMORY_STORAGE_KEY = "loaf:dismissed-breaking";
|
|
3022
|
-
var emptyBreakingMemory = () => ({ dismissed: {},
|
|
3022
|
+
var emptyBreakingMemory = () => ({ dismissed: {}, blocked: {} });
|
|
3023
3023
|
var isTimestampMap = (v) => typeof v === "object" && v !== null && !Array.isArray(v) && Object.values(v).every((t) => typeof t === "number" && Number.isFinite(t));
|
|
3024
3024
|
var pruneMap = (map, cutoff) => {
|
|
3025
3025
|
const fresh = Object.entries(map).filter(([, t]) => t >= cutoff);
|
|
@@ -3030,44 +3030,30 @@ var prune = (mem, now) => {
|
|
|
3030
3030
|
const cutoff = now - BREAKING_WINDOW_HOURS * 36e5;
|
|
3031
3031
|
return {
|
|
3032
3032
|
dismissed: pruneMap(mem.dismissed, cutoff),
|
|
3033
|
-
|
|
3034
|
-
// An expired watermark can't block anything (every in-window story is newer).
|
|
3035
|
-
watermark: mem.watermark !== null && mem.watermark >= cutoff ? mem.watermark : null
|
|
3033
|
+
blocked: pruneMap(mem.blocked, cutoff)
|
|
3036
3034
|
};
|
|
3037
3035
|
};
|
|
3038
3036
|
function parseBreakingMemory(raw, now) {
|
|
3039
3037
|
if (!raw) return emptyBreakingMemory();
|
|
3040
3038
|
try {
|
|
3041
3039
|
const v = JSON.parse(raw);
|
|
3042
|
-
if (typeof v !== "object" || v === null || Array.isArray(v) || !isTimestampMap(v.dismissed)
|
|
3040
|
+
if (typeof v !== "object" || v === null || Array.isArray(v) || !isTimestampMap(v.dismissed)) {
|
|
3043
3041
|
return emptyBreakingMemory();
|
|
3044
3042
|
}
|
|
3045
|
-
|
|
3043
|
+
const blocked = isTimestampMap(v.blocked) ? v.blocked : {};
|
|
3044
|
+
return prune({ dismissed: v.dismissed, blocked }, now);
|
|
3046
3045
|
} catch {
|
|
3047
3046
|
return emptyBreakingMemory();
|
|
3048
3047
|
}
|
|
3049
3048
|
}
|
|
3050
3049
|
var serializeBreakingMemory = (mem) => JSON.stringify(mem);
|
|
3051
|
-
function recordBreakingDismissal(mem, key, publishedAtMs, now) {
|
|
3052
|
-
|
|
3053
|
-
|
|
3054
|
-
|
|
3055
|
-
pinned: mem.pinned,
|
|
3056
|
-
watermark: Math.max(mem.watermark ?? -Infinity, publishedAtMs)
|
|
3057
|
-
},
|
|
3058
|
-
now
|
|
3059
|
-
);
|
|
3060
|
-
}
|
|
3061
|
-
function recordBreakingPins(mem, pins, now) {
|
|
3062
|
-
if (pins.every((p) => mem.pinned[p.key] !== void 0)) return mem;
|
|
3063
|
-
const pinned = { ...mem.pinned };
|
|
3064
|
-
for (const p of pins) pinned[p.key] = p.publishedAtMs;
|
|
3065
|
-
return prune({ dismissed: mem.dismissed, pinned, watermark: mem.watermark }, now);
|
|
3050
|
+
function recordBreakingDismissal(mem, key, publishedAtMs, now, waiting = []) {
|
|
3051
|
+
const blocked = { ...mem.blocked };
|
|
3052
|
+
for (const w of waiting) blocked[w.key] = w.publishedAtMs;
|
|
3053
|
+
return prune({ dismissed: { ...mem.dismissed, [key]: publishedAtMs }, blocked }, now);
|
|
3066
3054
|
}
|
|
3067
|
-
function mayPinBreaking(mem, key
|
|
3068
|
-
|
|
3069
|
-
if (mem.watermark === null) return true;
|
|
3070
|
-
return publishedAtMs > mem.watermark || mem.pinned[key] !== void 0;
|
|
3055
|
+
function mayPinBreaking(mem, key) {
|
|
3056
|
+
return mem.dismissed[key] === void 0 && mem.blocked[key] === void 0;
|
|
3071
3057
|
}
|
|
3072
3058
|
function loadBreakingMemory(now) {
|
|
3073
3059
|
try {
|
|
@@ -3652,18 +3638,8 @@ var PropertyNewsUpdates = React9.forwardRef(
|
|
|
3652
3638
|
};
|
|
3653
3639
|
const pinnedBreaking = React9.useMemo(() => {
|
|
3654
3640
|
const mem = getBreakingMemory();
|
|
3655
|
-
return breakingEligible.filter((it) => mayPinBreaking(mem, breakingKey(it)
|
|
3641
|
+
return breakingEligible.filter((it) => mayPinBreaking(mem, breakingKey(it))).sort((a, b) => breakingImpact(b) - breakingImpact(a)).slice(0, MAX_PINNED_BREAKING);
|
|
3656
3642
|
}, [breakingEligible, dismissedVersion]);
|
|
3657
|
-
React9.useEffect(() => {
|
|
3658
|
-
if (pinnedBreaking.length === 0) return;
|
|
3659
|
-
const mem = getBreakingMemory();
|
|
3660
|
-
const next = recordBreakingPins(
|
|
3661
|
-
mem,
|
|
3662
|
-
pinnedBreaking.map((it) => ({ key: breakingKey(it), publishedAtMs: breakingPublishedMs(it) })),
|
|
3663
|
-
Date.now()
|
|
3664
|
-
);
|
|
3665
|
-
if (next !== mem) commitBreakingMemory(next);
|
|
3666
|
-
}, [pinnedBreaking]);
|
|
3667
3643
|
const breakingRowKeys = React9.useMemo(
|
|
3668
3644
|
() => new Set(breakingEligible.map(breakingKey)),
|
|
3669
3645
|
[breakingEligible]
|
|
@@ -3769,8 +3745,10 @@ var PropertyNewsUpdates = React9.forwardRef(
|
|
|
3769
3745
|
const k = breakingKey(item);
|
|
3770
3746
|
const dx = breakingSwipe?.key === k ? breakingSwipe.dx : 0;
|
|
3771
3747
|
const persistDismissal = () => {
|
|
3748
|
+
const holding = new Set(pinnedBreaking);
|
|
3749
|
+
const waiting = breakingEligible.filter((c) => !holding.has(c)).map((c) => ({ key: breakingKey(c), publishedAtMs: breakingPublishedMs(c) }));
|
|
3772
3750
|
commitBreakingMemory(
|
|
3773
|
-
recordBreakingDismissal(getBreakingMemory(), k, breakingPublishedMs(item), Date.now())
|
|
3751
|
+
recordBreakingDismissal(getBreakingMemory(), k, breakingPublishedMs(item), Date.now(), waiting)
|
|
3774
3752
|
);
|
|
3775
3753
|
};
|
|
3776
3754
|
const finishDismiss = () => {
|