@openrails/contentkit-ui 0.103.2 → 0.104.0-rc.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/README.md +111 -49
- package/dist/client/beacons.d.ts +3 -13
- package/dist/client/beacons.js +8 -46
- package/dist/client/beacons.js.map +1 -1
- package/dist/client/client.d.ts +3 -0
- package/dist/client/client.js +45 -43
- package/dist/client/client.js.map +1 -1
- package/dist/client/content/favorites.d.ts +2 -0
- package/dist/client/content/favorites.js.map +1 -1
- package/dist/client/content/types.d.ts +3 -0
- package/dist/client/content/types.js.map +1 -1
- package/dist/client/contents.d.ts +7 -1
- package/dist/client/contents.js +8 -0
- package/dist/client/contents.js.map +1 -1
- package/dist/client/discovery.d.ts +34 -5
- package/dist/client/discovery.js +23 -2
- package/dist/client/discovery.js.map +1 -1
- package/dist/client/engagement.d.ts +70 -0
- package/dist/client/engagement.js +191 -0
- package/dist/client/engagement.js.map +1 -0
- package/dist/client/generated/routes.d.ts +74 -35
- package/dist/client/generated/routes.js +119 -60
- package/dist/client/generated/routes.js.map +1 -1
- package/dist/client/generated/wire.d.ts +88 -85
- package/dist/client/generated/wire.js.map +1 -1
- package/dist/client/guest-reading-history.d.ts +40 -0
- package/dist/client/guest-reading-history.js +144 -0
- package/dist/client/guest-reading-history.js.map +1 -0
- package/dist/client/index.d.ts +5 -3
- package/dist/client/media/windows.d.ts +2 -0
- package/dist/client/media/windows.js +4 -1
- package/dist/client/media/windows.js.map +1 -1
- package/dist/client/stats.d.ts +4 -20
- package/dist/client/stats.js +0 -11
- package/dist/client/stats.js.map +1 -1
- package/dist/client/versions.d.ts +8 -6
- package/dist/client/versions.js +15 -10
- package/dist/client/versions.js.map +1 -1
- package/dist/client.js +24 -22
- package/dist/components/admin/bulk-drafts.d.ts +17 -0
- package/dist/components/admin/bulk-drafts.js +41 -0
- package/dist/components/admin/bulk-drafts.js.map +1 -0
- package/dist/components/admin/content-admin.d.ts +1 -1
- package/dist/components/admin/content-admin.js.map +1 -1
- package/dist/components/admin/content-manager.d.ts +11 -3
- package/dist/components/admin/content-manager.js +751 -394
- package/dist/components/admin/content-manager.js.map +1 -1
- package/dist/components/admin/group-manager.d.ts +8 -3
- package/dist/components/admin/group-manager.js +218 -146
- package/dist/components/admin/group-manager.js.map +1 -1
- package/dist/components/admin/page-notices.d.ts +16 -0
- package/dist/components/admin/page-notices.js +113 -0
- package/dist/components/admin/page-notices.js.map +1 -0
- package/dist/components/admin/page-picker.d.ts +38 -0
- package/dist/components/admin/page-picker.js +159 -0
- package/dist/components/admin/page-picker.js.map +1 -0
- package/dist/components/admin/quick-search.d.ts +14 -0
- package/dist/components/admin/quick-search.js +60 -0
- package/dist/components/admin/quick-search.js.map +1 -0
- package/dist/components/admin/reader-content-editor.js +382 -321
- package/dist/components/admin/reader-content-editor.js.map +1 -1
- package/dist/components/admin/reader-manifest.js +181 -179
- package/dist/components/admin/reader-manifest.js.map +1 -1
- package/dist/components/admin/shell.d.ts +10 -2
- package/dist/components/admin/shell.js +114 -42
- package/dist/components/admin/shell.js.map +1 -1
- package/dist/components/admin/stats-dashboard.d.ts +4 -9
- package/dist/components/admin/stats-dashboard.js +303 -207
- package/dist/components/admin/stats-dashboard.js.map +1 -1
- package/dist/components/admin/upload-queue.d.ts +14 -0
- package/dist/components/admin/upload-queue.js +115 -98
- package/dist/components/admin/upload-queue.js.map +1 -1
- package/dist/components/content/card.d.ts +31 -3
- package/dist/components/content/card.js +324 -158
- package/dist/components/content/card.js.map +1 -1
- package/dist/components/content/daily-releases.js +144 -190
- package/dist/components/content/daily-releases.js.map +1 -1
- package/dist/components/content/editor-save.js +27 -25
- package/dist/components/content/editor-save.js.map +1 -1
- package/dist/components/content/editors.js +274 -253
- package/dist/components/content/editors.js.map +1 -1
- package/dist/components/content/favorites.d.ts +6 -0
- package/dist/components/content/favorites.js +47 -0
- package/dist/components/content/favorites.js.map +1 -0
- package/dist/components/content/filter-dialog.js +19 -15
- package/dist/components/content/filter-dialog.js.map +1 -1
- package/dist/components/content/filters.d.ts +2 -0
- package/dist/components/content/filters.js +5 -1
- package/dist/components/content/filters.js.map +1 -1
- package/dist/components/content/grid.d.ts +44 -16
- package/dist/components/content/grid.js +308 -270
- package/dist/components/content/grid.js.map +1 -1
- package/dist/components/content/history.d.ts +6 -0
- package/dist/components/content/history.js +111 -0
- package/dist/components/content/history.js.map +1 -0
- package/dist/components/content/index.d.ts +6 -3
- package/dist/components/content/listing.d.ts +14 -3
- package/dist/components/content/listing.js +65 -56
- package/dist/components/content/listing.js.map +1 -1
- package/dist/components/content/offer-fields.js +6 -6
- package/dist/components/content/paged-grid.d.ts +10 -0
- package/dist/components/content/paged-grid.js +116 -0
- package/dist/components/content/paged-grid.js.map +1 -0
- package/dist/components/content/pagination.d.ts +19 -0
- package/dist/components/content/pagination.js +97 -0
- package/dist/components/content/pagination.js.map +1 -0
- package/dist/components/content/paywall.d.ts +9 -0
- package/dist/components/content/paywall.js +27 -3
- package/dist/components/content/paywall.js.map +1 -1
- package/dist/components/content/post-list.d.ts +37 -0
- package/dist/components/content/post-list.js +203 -0
- package/dist/components/content/post-list.js.map +1 -0
- package/dist/components/content/reader-settings.d.ts +2 -0
- package/dist/components/content/reader-settings.js +1 -1
- package/dist/components/content/reader-settings.js.map +1 -1
- package/dist/components/content/search.d.ts +11 -4
- package/dist/components/content/search.js +22 -11
- package/dist/components/content/search.js.map +1 -1
- package/dist/components/content/summary-tile.d.ts +14 -0
- package/dist/components/content/summary-tile.js +63 -0
- package/dist/components/content/summary-tile.js.map +1 -0
- package/dist/components/groups/banner.d.ts +6 -2
- package/dist/components/groups/banner.js +79 -61
- package/dist/components/groups/banner.js.map +1 -1
- package/dist/components/groups/directory.d.ts +12 -2
- package/dist/components/groups/directory.js +168 -105
- package/dist/components/groups/directory.js.map +1 -1
- package/dist/components/groups/editor.js +10 -10
- package/dist/components/groups/editor.js.map +1 -1
- package/dist/components/groups/entity-chips.d.ts +61 -0
- package/dist/components/groups/entity-chips.js +382 -0
- package/dist/components/groups/entity-chips.js.map +1 -0
- package/dist/components/groups/group-members.d.ts +29 -0
- package/dist/components/groups/group-members.js +474 -0
- package/dist/components/groups/group-members.js.map +1 -0
- package/dist/components/groups/header.js +53 -45
- package/dist/components/groups/header.js.map +1 -1
- package/dist/components/groups/index.d.ts +3 -1
- package/dist/components/groups/memberships.d.ts +3 -36
- package/dist/components/groups/memberships.js +105 -480
- package/dist/components/groups/memberships.js.map +1 -1
- package/dist/components/groups/scoped.d.ts +23 -0
- package/dist/components/groups/scoped.js +92 -0
- package/dist/components/groups/scoped.js.map +1 -0
- package/dist/components/media-folder-editor.d.ts +5 -0
- package/dist/components/media-folder-editor.js +419 -231
- package/dist/components/media-folder-editor.js.map +1 -1
- package/dist/components/sortable-list.d.ts +5 -1
- package/dist/components/sortable-list.js +97 -81
- package/dist/components/sortable-list.js.map +1 -1
- package/dist/components/video-mini-player.d.ts +4 -1
- package/dist/components/video-mini-player.js +77 -71
- package/dist/components/video-mini-player.js.map +1 -1
- package/dist/components/video-player.d.ts +4 -1
- package/dist/components/video-player.js +280 -276
- package/dist/components/video-player.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +41 -34
- package/dist/locales/admin/de.js +80 -47
- package/dist/locales/admin/de.js.map +1 -1
- package/dist/locales/admin/en.d.ts +74 -41
- package/dist/locales/admin/en.js +80 -47
- package/dist/locales/admin/en.js.map +1 -1
- package/dist/locales/admin/es.js +80 -47
- package/dist/locales/admin/es.js.map +1 -1
- package/dist/locales/admin/ja.js +80 -47
- package/dist/locales/admin/ja.js.map +1 -1
- package/dist/locales/admin/ko.js +80 -47
- package/dist/locales/admin/ko.js.map +1 -1
- package/dist/locales/admin/zh.js +80 -47
- package/dist/locales/admin/zh.js.map +1 -1
- package/dist/locales/de.js +1 -0
- package/dist/locales/de.js.map +1 -1
- package/dist/locales/discovery/de.js +25 -2
- package/dist/locales/discovery/de.js.map +1 -1
- package/dist/locales/discovery/en.d.ts +24 -1
- package/dist/locales/discovery/en.js +25 -2
- package/dist/locales/discovery/en.js.map +1 -1
- package/dist/locales/discovery/es.js +25 -2
- package/dist/locales/discovery/es.js.map +1 -1
- package/dist/locales/discovery/ja.js +25 -2
- package/dist/locales/discovery/ja.js.map +1 -1
- package/dist/locales/discovery/ko.js +25 -2
- package/dist/locales/discovery/ko.js.map +1 -1
- package/dist/locales/discovery/zh.js +25 -2
- package/dist/locales/discovery/zh.js.map +1 -1
- package/dist/locales/en.d.ts +119 -44
- package/dist/locales/en.js +1 -0
- package/dist/locales/en.js.map +1 -1
- package/dist/locales/es.js +1 -0
- package/dist/locales/es.js.map +1 -1
- package/dist/locales/groups/de.js +22 -4
- package/dist/locales/groups/de.js.map +1 -1
- package/dist/locales/groups/en.d.ts +20 -2
- package/dist/locales/groups/en.js +22 -4
- package/dist/locales/groups/en.js.map +1 -1
- package/dist/locales/groups/es.js +22 -4
- package/dist/locales/groups/es.js.map +1 -1
- package/dist/locales/groups/ja.js +22 -4
- package/dist/locales/groups/ja.js.map +1 -1
- package/dist/locales/groups/ko.js +22 -4
- package/dist/locales/groups/ko.js.map +1 -1
- package/dist/locales/groups/zh.js +22 -4
- package/dist/locales/groups/zh.js.map +1 -1
- package/dist/locales/ja.js +1 -0
- package/dist/locales/ja.js.map +1 -1
- package/dist/locales/ko.js +1 -0
- package/dist/locales/ko.js.map +1 -1
- package/dist/locales/zh.js +1 -0
- package/dist/locales/zh.js.map +1 -1
- package/dist/react/discovery.d.ts +36 -17
- package/dist/react/discovery.js +305 -221
- package/dist/react/discovery.js.map +1 -1
- package/dist/react/groups.d.ts +19 -3
- package/dist/react/groups.js +49 -22
- package/dist/react/groups.js.map +1 -1
- package/dist/react/index.d.ts +7 -4
- package/dist/react/page-notices.d.ts +13 -0
- package/dist/react/page-notices.js +38 -0
- package/dist/react/page-notices.js.map +1 -0
- package/dist/react/post-reads.d.ts +23 -0
- package/dist/react/post-reads.js +90 -0
- package/dist/react/post-reads.js.map +1 -0
- package/dist/react/remembered-sort.d.ts +5 -0
- package/dist/react/remembered-sort.js +29 -0
- package/dist/react/remembered-sort.js.map +1 -0
- package/dist/react/resources.d.ts +3 -1
- package/dist/react/resources.js +6 -2
- package/dist/react/resources.js.map +1 -1
- package/dist/react/stats.d.ts +3 -7
- package/dist/react/stats.js +2 -6
- package/dist/react/stats.js.map +1 -1
- package/dist/react/use-engagement.d.ts +28 -0
- package/dist/react/use-engagement.js +226 -0
- package/dist/react/use-engagement.js.map +1 -0
- package/dist/react/use-resource.d.ts +4 -3
- package/dist/react/use-resource.js +2 -1
- package/dist/react/use-resource.js.map +1 -1
- package/dist/react.js +29 -26
- package/dist/styles.css +1 -1
- package/dist/ui/dialog.d.ts +2 -1
- package/dist/ui/dialog.js +23 -20
- package/dist/ui/dialog.js.map +1 -1
- package/dist/urls/index.d.ts +1 -1
- package/dist/urls.js +2 -2
- package/dist/urls.js.map +1 -1
- package/package.json +1 -1
- package/dist/components/admin/page-review.d.ts +0 -13
- package/dist/components/admin/page-review.js +0 -225
- package/dist/components/admin/page-review.js.map +0 -1
- package/dist/react/page-review.d.ts +0 -14
- package/dist/react/page-review.js +0 -37
- package/dist/react/page-review.js.map +0 -1
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
import { ContentKitContext as e, useContentKitClient as t } from "./context.js";
|
|
2
|
+
import { readerSession as n } from "../client/beacons.js";
|
|
3
|
+
import { EngagementTracker as r } from "../client/engagement.js";
|
|
4
|
+
import { useCallback as i, useContext as a, useEffect as o, useLayoutEffect as s, useMemo as c, useRef as l, useSyncExternalStore as u } from "react";
|
|
5
|
+
//#region src/react/use-engagement.ts
|
|
6
|
+
function d(e) {
|
|
7
|
+
if (!e.isConnected) return;
|
|
8
|
+
let t = getComputedStyle(e);
|
|
9
|
+
if (t.display === "none" || t.visibility === "hidden" || t.opacity !== "" && Number(t.opacity) === 0) return;
|
|
10
|
+
let n = e.getBoundingClientRect();
|
|
11
|
+
if (n.width <= 0 || n.height <= 0) return;
|
|
12
|
+
let r = n.top, i = n.left, a = n.width, o = n.height;
|
|
13
|
+
if (e instanceof HTMLImageElement && t.objectFit === "contain") {
|
|
14
|
+
let n = Math.min(a / e.naturalWidth, o / e.naturalHeight), s = e.naturalWidth * n, c = e.naturalHeight * n, [l = "50%", u = "50%"] = t.objectPosition.split(" "), d = (e, t) => e.endsWith("%") ? t * Number.parseFloat(e) / 100 : t / 2;
|
|
15
|
+
i += d(l, a - s), r += d(u, o - c), a = s, o = c;
|
|
16
|
+
}
|
|
17
|
+
let s = e.closest("[data-reader-viewport]")?.getBoundingClientRect(), c = Math.max(r, 0, s?.top ?? 0), l = Math.min(r + o, window.innerHeight, s?.bottom ?? window.innerHeight), u = Math.max(i, 0, s?.left ?? 0), d = Math.min(i + a, window.innerWidth, s?.right ?? window.innerWidth);
|
|
18
|
+
if (!(l <= c || d <= u)) return {
|
|
19
|
+
from: Math.max(0, Math.floor((c - r) / o * 1e4)),
|
|
20
|
+
to: Math.min(1e4, Math.ceil((l - r) / o * 1e4)),
|
|
21
|
+
area: (l - c) * (d - u)
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
function f(f, p, m = {}) {
|
|
25
|
+
let h = t(m.client), g = a(e), _ = u(h.preferences.subscribeIdentity, h.preferences.identity, h.preferences.identity), v = g ? g.viewer : _, y = g?.viewer === null, b = !!f && m.enabled !== !1 && v !== void 0, x = l({
|
|
26
|
+
owner: v,
|
|
27
|
+
permitted: b
|
|
28
|
+
});
|
|
29
|
+
x.current = {
|
|
30
|
+
owner: v,
|
|
31
|
+
permitted: b
|
|
32
|
+
};
|
|
33
|
+
let S = l(m.kind);
|
|
34
|
+
S.current = m.kind;
|
|
35
|
+
let C = l(g?.language);
|
|
36
|
+
C.current = g?.language;
|
|
37
|
+
let w = c(() => {
|
|
38
|
+
let e = /* @__PURE__ */ new Map(), t = /* @__PURE__ */ new WeakMap(), i, a = !1, o = !1, s = !1, c = null, l, u = () => b && x.current.permitted && x.current.owner === v && h.preferences.identity() === v, g, _ = () => v === null ? g ??= n() : void 0, w = new r({
|
|
39
|
+
contentId: f ?? "",
|
|
40
|
+
versionId: p,
|
|
41
|
+
idleAfter: m.idleAfter,
|
|
42
|
+
checkpointInterval: m.checkpointInterval,
|
|
43
|
+
begin: async () => {
|
|
44
|
+
if (!u()) return null;
|
|
45
|
+
let e = await h.discovery.activityContexts([{
|
|
46
|
+
content_id: f,
|
|
47
|
+
version_id: p
|
|
48
|
+
}], _(), C.current);
|
|
49
|
+
return !u() || !e.enabled ? null : e.contexts.find((e) => e.content_id === f && (!p || e.version_id === p)) ?? null;
|
|
50
|
+
},
|
|
51
|
+
submit: async (e, t) => {
|
|
52
|
+
u() && await h.discovery.engagement([e], {
|
|
53
|
+
session: _(),
|
|
54
|
+
...t
|
|
55
|
+
});
|
|
56
|
+
},
|
|
57
|
+
onSnapshot: (e) => {
|
|
58
|
+
u() && v === null && y && h.guestHistory.record({
|
|
59
|
+
...e,
|
|
60
|
+
...S.current ? { kind: S.current } : {}
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
}), T = () => {
|
|
64
|
+
if (!a || !u()) return;
|
|
65
|
+
let n = [], r;
|
|
66
|
+
for (let [i, a] of e) {
|
|
67
|
+
let e = a.element;
|
|
68
|
+
if (!e || e instanceof HTMLImageElement && (!e.complete || e.naturalWidth <= 0) || t.get(e) === !1) continue;
|
|
69
|
+
let o = d(e);
|
|
70
|
+
o && (n.push({
|
|
71
|
+
index: i,
|
|
72
|
+
ranges: [{
|
|
73
|
+
from: o.from,
|
|
74
|
+
to: o.to
|
|
75
|
+
}]
|
|
76
|
+
}), (!r || o.area > r.area) && (r = {
|
|
77
|
+
area: o.area,
|
|
78
|
+
resume: a.resume
|
|
79
|
+
}));
|
|
80
|
+
}
|
|
81
|
+
let i = {
|
|
82
|
+
pages: n,
|
|
83
|
+
resume: l ?? r?.resume
|
|
84
|
+
};
|
|
85
|
+
c && c.readyState >= 2 && d(c) && (i.video = {
|
|
86
|
+
positionMs: Math.max(0, Math.round(c.currentTime * 1e3)),
|
|
87
|
+
playing: !s && !c.paused && !c.ended && !c.seeking,
|
|
88
|
+
seeking: c.seeking
|
|
89
|
+
}), i.video && (i.resume = String(c.currentTime)), w.observe(i), w.attention(!o && document.visibilityState !== "hidden" && document.hasFocus());
|
|
90
|
+
}, E = (t, n) => {
|
|
91
|
+
let r = e.get(t);
|
|
92
|
+
return r || (r = {
|
|
93
|
+
element: null,
|
|
94
|
+
resume: n,
|
|
95
|
+
ref: (e) => {
|
|
96
|
+
r.element && (r.element.removeEventListener("load", T), i?.unobserve(r.element)), r.element = e, e && i?.observe(e), e?.addEventListener("load", T), T();
|
|
97
|
+
}
|
|
98
|
+
}, e.set(t, r)), r.resume = n, r.ref;
|
|
99
|
+
}, D = [
|
|
100
|
+
"play",
|
|
101
|
+
"playing",
|
|
102
|
+
"canplay",
|
|
103
|
+
"pause",
|
|
104
|
+
"seeking",
|
|
105
|
+
"seeked",
|
|
106
|
+
"ended",
|
|
107
|
+
"loadeddata",
|
|
108
|
+
"ratechange",
|
|
109
|
+
"waiting",
|
|
110
|
+
"stalled"
|
|
111
|
+
], O = (e) => {
|
|
112
|
+
e.type === "waiting" || e.type === "stalled" ? s = !0 : [
|
|
113
|
+
"playing",
|
|
114
|
+
"canplay",
|
|
115
|
+
"seeked",
|
|
116
|
+
"loadeddata"
|
|
117
|
+
].includes(e.type) && (s = !1), T();
|
|
118
|
+
};
|
|
119
|
+
return {
|
|
120
|
+
tracker: w,
|
|
121
|
+
sample: T,
|
|
122
|
+
owns: u,
|
|
123
|
+
page: E,
|
|
124
|
+
bindVideo: (e) => {
|
|
125
|
+
for (let e of D) c?.removeEventListener(e, O);
|
|
126
|
+
c && i?.unobserve(c), c = e, s = !1, c && i?.observe(c);
|
|
127
|
+
for (let e of D) c?.addEventListener(e, O);
|
|
128
|
+
T();
|
|
129
|
+
},
|
|
130
|
+
flush: () => (T(), u() ? w.flush() : Promise.resolve()),
|
|
131
|
+
setResume: (e) => {
|
|
132
|
+
l = e, T();
|
|
133
|
+
},
|
|
134
|
+
start: () => {
|
|
135
|
+
if (a = !0, !i && typeof IntersectionObserver < "u") {
|
|
136
|
+
i = new IntersectionObserver((e) => {
|
|
137
|
+
for (let n of e) t.set(n.target, n.isIntersecting);
|
|
138
|
+
T();
|
|
139
|
+
});
|
|
140
|
+
for (let t of e.values()) t.element && i.observe(t.element);
|
|
141
|
+
c && i.observe(c);
|
|
142
|
+
}
|
|
143
|
+
T();
|
|
144
|
+
},
|
|
145
|
+
stop: () => {
|
|
146
|
+
a = !1;
|
|
147
|
+
},
|
|
148
|
+
isActive: () => a,
|
|
149
|
+
hide: () => {
|
|
150
|
+
T(), o = !0, w.attention(!1), w.flush(!0);
|
|
151
|
+
},
|
|
152
|
+
show: () => {
|
|
153
|
+
o = !1, w.activity(), T();
|
|
154
|
+
},
|
|
155
|
+
activity: () => {
|
|
156
|
+
T(), w.activity();
|
|
157
|
+
},
|
|
158
|
+
cleanup: () => {
|
|
159
|
+
i?.disconnect();
|
|
160
|
+
for (let t of e.values()) t.element?.removeEventListener("load", T);
|
|
161
|
+
for (let e of D) c?.removeEventListener(e, O);
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
}, [
|
|
165
|
+
h,
|
|
166
|
+
f,
|
|
167
|
+
p,
|
|
168
|
+
v,
|
|
169
|
+
y,
|
|
170
|
+
b,
|
|
171
|
+
m.idleAfter,
|
|
172
|
+
m.checkpointInterval
|
|
173
|
+
]);
|
|
174
|
+
s(() => h.preferences.subscribeIdentity(() => {
|
|
175
|
+
w.owns() || w.tracker.discard();
|
|
176
|
+
}), [h, w]), o(() => {
|
|
177
|
+
if (!b || !w.owns()) return;
|
|
178
|
+
w.start();
|
|
179
|
+
let e = setInterval(w.sample, 250), t = [
|
|
180
|
+
"pointerdown",
|
|
181
|
+
"pointermove",
|
|
182
|
+
"keydown",
|
|
183
|
+
"wheel",
|
|
184
|
+
"touchstart",
|
|
185
|
+
"touchmove"
|
|
186
|
+
];
|
|
187
|
+
for (let e of t) window.addEventListener(e, w.activity, {
|
|
188
|
+
passive: !0,
|
|
189
|
+
capture: !0
|
|
190
|
+
});
|
|
191
|
+
let n = () => {
|
|
192
|
+
document.visibilityState === "hidden" ? w.hide() : w.show();
|
|
193
|
+
}, r = () => {
|
|
194
|
+
w.sample(), w.tracker.attention(!1);
|
|
195
|
+
};
|
|
196
|
+
return window.addEventListener("scroll", w.sample, !0), window.addEventListener("resize", w.sample), window.addEventListener("focus", w.show), window.addEventListener("blur", r), window.addEventListener("pagehide", w.hide), window.addEventListener("pageshow", w.show), window.addEventListener("online", w.flush), document.addEventListener("visibilitychange", n), () => {
|
|
197
|
+
w.stop(), clearInterval(e);
|
|
198
|
+
for (let e of t) window.removeEventListener(e, w.activity, !0);
|
|
199
|
+
window.removeEventListener("scroll", w.sample, !0), window.removeEventListener("resize", w.sample), window.removeEventListener("focus", w.show), window.removeEventListener("blur", r), window.removeEventListener("pagehide", w.hide), window.removeEventListener("pageshow", w.show), window.removeEventListener("online", w.flush), document.removeEventListener("visibilitychange", n), queueMicrotask(() => {
|
|
200
|
+
if (!w.isActive()) {
|
|
201
|
+
if (w.cleanup(), !w.owns()) {
|
|
202
|
+
w.tracker.discard();
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
w.tracker.attention(!1), w.tracker.flush(!0).finally(() => w.tracker.discard());
|
|
206
|
+
}
|
|
207
|
+
});
|
|
208
|
+
};
|
|
209
|
+
}, [b, w]);
|
|
210
|
+
let T = i((e) => w.bindVideo(e), [w]), E = i((e) => w.page(0)(e), [w]);
|
|
211
|
+
return c(() => ({
|
|
212
|
+
page: w.page,
|
|
213
|
+
video: T,
|
|
214
|
+
text: E,
|
|
215
|
+
setResume: w.setResume,
|
|
216
|
+
flush: w.flush
|
|
217
|
+
}), [
|
|
218
|
+
w,
|
|
219
|
+
T,
|
|
220
|
+
E
|
|
221
|
+
]);
|
|
222
|
+
}
|
|
223
|
+
//#endregion
|
|
224
|
+
export { f as useReadingEngagement };
|
|
225
|
+
|
|
226
|
+
//# sourceMappingURL=use-engagement.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-engagement.js","names":[],"sources":["../../src/react/use-engagement.ts"],"sourcesContent":["import { useCallback, useContext, useEffect, useLayoutEffect, useMemo, useRef, useSyncExternalStore } from \"react\";\nimport { readerSession } from \"../client/beacons.js\";\nimport type { ContentKitClient } from \"../client/client.js\";\nimport { EngagementTracker, type ReadingObservation, type VisiblePage } from \"../client/engagement.js\";\nimport { ContentKitContext, useContentKitClient } from \"./context.js\";\n\nexport interface ReadingEngagementOptions {\n client?: ContentKitClient;\n enabled?: boolean;\n /** Local guest history grouping only; the server infers kind from content. */\n kind?: string;\n /** Genuine input renews attention for this long; default 60 seconds. */\n idleAfter?: number;\n /** Snapshot interval, at most 120 seconds. Page changes never send requests. */\n checkpointInterval?: number;\n}\n\nexport interface ReadingEngagement {\n /** Attach to the actual loaded image, not its placeholder or thumbnail. */\n page: (index: number, resume?: string) => (element: HTMLImageElement | null) => void;\n /** Attach to the playing video. Seeks do not count as watched intervals. */\n video: (element: HTMLVideoElement | null) => void;\n /** Attach to a text post's body: one unit covered by its visible share. */\n text: (element: HTMLElement | null) => void;\n /** Existing filename/anchor selector to restore, independent of page index. */\n setResume: (resume: string | undefined) => void;\n flush: () => Promise<void>;\n}\n\ninterface PageBinding {\n element: HTMLElement | null;\n resume?: string;\n ref: (element: HTMLElement | null) => void;\n}\n\nfunction visibleRange(element: HTMLElement): { from: number; to: number; area: number } | undefined {\n if (!element.isConnected) return;\n const style = getComputedStyle(element);\n if (style.display === \"none\" || style.visibility === \"hidden\" || (style.opacity !== \"\" && Number(style.opacity) === 0)) return;\n const box = element.getBoundingClientRect();\n if (box.width <= 0 || box.height <= 0) return;\n let top = box.top, left = box.left, width = box.width, height = box.height;\n if (element instanceof HTMLImageElement && style.objectFit === \"contain\") {\n const scale = Math.min(width / element.naturalWidth, height / element.naturalHeight);\n const imageWidth = element.naturalWidth * scale, imageHeight = element.naturalHeight * scale;\n const [x = \"50%\", y = \"50%\"] = style.objectPosition.split(\" \");\n const offset = (position: string, space: number) => position.endsWith(\"%\") ? space * Number.parseFloat(position) / 100 : space / 2;\n left += offset(x, width - imageWidth); top += offset(y, height - imageHeight);\n width = imageWidth; height = imageHeight;\n }\n const viewport = element.closest(\"[data-reader-viewport]\")?.getBoundingClientRect();\n const visibleTop = Math.max(top, 0, viewport?.top ?? 0);\n const visibleBottom = Math.min(top + height, window.innerHeight, viewport?.bottom ?? window.innerHeight);\n const visibleLeft = Math.max(left, 0, viewport?.left ?? 0);\n const visibleRight = Math.min(left + width, window.innerWidth, viewport?.right ?? window.innerWidth);\n if (visibleBottom <= visibleTop || visibleRight <= visibleLeft) return;\n return { from: Math.max(0, Math.floor((visibleTop - top) / height * 10_000)),\n to: Math.min(10_000, Math.ceil((visibleBottom - top) / height * 10_000)),\n area: (visibleBottom - visibleTop) * (visibleRight - visibleLeft) };\n}\n\n/**\n * Keep this hook in the content page, above horizontal/vertical renderer switches.\n * It records loaded, visible attention, with one visit and bounded access receipts;\n * preloads and route opens alone produce no engagement or network writes.\n */\nexport function useReadingEngagement(contentId: string | null | undefined, versionId?: string, options: ReadingEngagementOptions = {}): ReadingEngagement {\n const client = useContentKitClient(options.client);\n const context = useContext(ContentKitContext);\n const identity = useSyncExternalStore(client.preferences.subscribeIdentity, client.preferences.identity, client.preferences.identity);\n const owner = context ? context.viewer : identity;\n const explicitGuest = context?.viewer === null;\n const permitted = !!contentId && options.enabled !== false && owner !== undefined;\n const current = useRef({ owner, permitted });\n current.current = { owner, permitted };\n const kind = useRef(options.kind);\n kind.current = options.kind;\n const language = useRef(context?.language);\n language.current = context?.language;\n\n const state = useMemo(() => {\n const pages = new Map<number, PageBinding>();\n const intersections = new WeakMap<Element, boolean>();\n let observer: IntersectionObserver | undefined;\n let active = false, hidden = false, buffering = false, video: HTMLVideoElement | null = null, resume: string | undefined;\n const owns = () => permitted && current.current.permitted && current.current.owner === owner && client.preferences.identity() === owner;\n let session: string | undefined;\n const getSession = () => owner === null ? (session ??= readerSession()) : undefined;\n const tracker = new EngagementTracker({\n contentId: contentId ?? \"\", versionId, idleAfter: options.idleAfter, checkpointInterval: options.checkpointInterval,\n begin: async () => {\n if (!owns()) return null;\n const result = await client.discovery.activityContexts([{ content_id: contentId!, version_id: versionId }], getSession(), language.current);\n if (!owns() || !result.enabled) return null;\n return result.contexts.find((receipt) => receipt.content_id === contentId && (!versionId || receipt.version_id === versionId)) ?? null;\n },\n submit: async (snapshot, submitOptions) => {\n if (!owns()) return;\n await client.discovery.engagement([snapshot], { session: getSession(), ...submitOptions });\n },\n onSnapshot: (snapshot) => {\n if (owns() && owner === null && explicitGuest) client.guestHistory.record({ ...snapshot, ...(kind.current ? { kind: kind.current } : {}) });\n },\n });\n const sample = () => {\n if (!active || !owns()) return;\n const visible: VisiblePage[] = [];\n let selected: { area: number; resume?: string } | undefined;\n for (const [index, binding] of pages) {\n const image = binding.element;\n // An image counts once loaded; a text body as soon as it shows.\n if (!image || image instanceof HTMLImageElement && (!image.complete || image.naturalWidth <= 0) || intersections.get(image) === false) continue;\n const range = visibleRange(image);\n if (!range) continue;\n visible.push({ index, ranges: [{ from: range.from, to: range.to }] });\n if (!selected || range.area > selected.area) selected = { area: range.area, resume: binding.resume };\n }\n const observation: ReadingObservation = { pages: visible, resume: resume ?? selected?.resume };\n if (video && video.readyState >= 2 && visibleRange(video)) observation.video = {\n positionMs: Math.max(0, Math.round(video.currentTime * 1000)), playing: !buffering && !video.paused && !video.ended && !video.seeking,\n seeking: video.seeking,\n };\n if (observation.video) observation.resume = String(video!.currentTime);\n tracker.observe(observation);\n tracker.attention(!hidden && document.visibilityState !== \"hidden\" && document.hasFocus());\n };\n const page = (index: number, selector?: string) => {\n let binding = pages.get(index);\n if (!binding) {\n binding = { element: null, resume: selector, ref: (element) => {\n if (binding!.element) {\n binding!.element.removeEventListener(\"load\", sample);\n observer?.unobserve(binding!.element);\n }\n binding!.element = element;\n if (element) observer?.observe(element);\n element?.addEventListener(\"load\", sample);\n sample();\n } };\n pages.set(index, binding);\n }\n binding.resume = selector;\n return binding.ref;\n };\n const mediaEvents = [\"play\", \"playing\", \"canplay\", \"pause\", \"seeking\", \"seeked\", \"ended\", \"loadeddata\", \"ratechange\", \"waiting\", \"stalled\"];\n const mediaEvent = (event: Event) => {\n if (event.type === \"waiting\" || event.type === \"stalled\") buffering = true;\n else if ([\"playing\", \"canplay\", \"seeked\", \"loadeddata\"].includes(event.type)) buffering = false;\n sample();\n };\n const bindVideo = (element: HTMLVideoElement | null) => {\n for (const event of mediaEvents) video?.removeEventListener(event, mediaEvent);\n if (video) observer?.unobserve(video);\n video = element; buffering = false;\n if (video) observer?.observe(video);\n for (const event of mediaEvents) video?.addEventListener(event, mediaEvent);\n sample();\n };\n const flush = () => { sample(); return owns() ? tracker.flush() : Promise.resolve(); };\n return {\n tracker, sample, owns, page, bindVideo, flush,\n setResume: (value: string | undefined) => { resume = value; sample(); },\n start: () => {\n active = true;\n if (!observer && typeof IntersectionObserver !== \"undefined\") {\n observer = new IntersectionObserver((entries) => {\n for (const entry of entries) intersections.set(entry.target, entry.isIntersecting);\n sample();\n });\n for (const binding of pages.values()) if (binding.element) observer.observe(binding.element);\n if (video) observer.observe(video);\n }\n sample();\n },\n stop: () => { active = false; },\n isActive: () => active,\n hide: () => { sample(); hidden = true; tracker.attention(false); void tracker.flush(true); },\n show: () => { hidden = false; tracker.activity(); sample(); },\n activity: () => { sample(); tracker.activity(); },\n cleanup: () => {\n observer?.disconnect();\n for (const binding of pages.values()) binding.element?.removeEventListener(\"load\", sample);\n for (const event of mediaEvents) video?.removeEventListener(event, mediaEvent);\n },\n };\n // Language and renderer mode do not start new visits. Owner changes do.\n }, [client, contentId, versionId, owner, explicitGuest, permitted, options.idleAfter, options.checkpointInterval]);\n\n useLayoutEffect(() => client.preferences.subscribeIdentity(() => {\n if (!state.owns()) state.tracker.discard();\n }), [client, state]);\n\n useEffect(() => {\n if (!permitted || !state.owns()) return;\n state.start();\n const timer = setInterval(state.sample, 250);\n const inputEvents = [\"pointerdown\", \"pointermove\", \"keydown\", \"wheel\", \"touchstart\", \"touchmove\"];\n for (const event of inputEvents) window.addEventListener(event, state.activity, { passive: true, capture: true });\n const visibility = () => { if (document.visibilityState === \"hidden\") state.hide(); else state.show(); };\n const blur = () => { state.sample(); state.tracker.attention(false); };\n window.addEventListener(\"scroll\", state.sample, true);\n window.addEventListener(\"resize\", state.sample);\n window.addEventListener(\"focus\", state.show);\n window.addEventListener(\"blur\", blur);\n window.addEventListener(\"pagehide\", state.hide);\n window.addEventListener(\"pageshow\", state.show);\n window.addEventListener(\"online\", state.flush);\n document.addEventListener(\"visibilitychange\", visibility);\n return () => {\n state.stop(); clearInterval(timer);\n for (const event of inputEvents) window.removeEventListener(event, state.activity, true);\n window.removeEventListener(\"scroll\", state.sample, true);\n window.removeEventListener(\"resize\", state.sample);\n window.removeEventListener(\"focus\", state.show);\n window.removeEventListener(\"blur\", blur);\n window.removeEventListener(\"pagehide\", state.hide);\n window.removeEventListener(\"pageshow\", state.show);\n window.removeEventListener(\"online\", state.flush);\n document.removeEventListener(\"visibilitychange\", visibility);\n // StrictMode's immediate setup replay must keep the same visit alive.\n queueMicrotask(() => {\n if (state.isActive()) return;\n state.cleanup();\n if (!state.owns()) { state.tracker.discard(); return; }\n state.tracker.attention(false);\n void state.tracker.flush(true).finally(() => state.tracker.discard());\n });\n };\n }, [permitted, state]);\n\n const video = useCallback((element: HTMLVideoElement | null) => state.bindVideo(element), [state]);\n const text = useCallback((element: HTMLElement | null) => state.page(0)(element), [state]);\n return useMemo(() => ({ page: state.page, video, text, setResume: state.setResume, flush: state.flush }), [state, video, text]);\n}\n"],"mappings":"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"}
|
|
@@ -18,7 +18,7 @@ export declare function useResource<T>(store: ResourceStore | null, key: string
|
|
|
18
18
|
reload: () => void;
|
|
19
19
|
};
|
|
20
20
|
/** A shared list, a page at a time. */
|
|
21
|
-
export interface UseList<T> {
|
|
21
|
+
export interface UseList<T, M = unknown> {
|
|
22
22
|
items: T[];
|
|
23
23
|
/** The first page is loading (also on reload). */
|
|
24
24
|
loading: boolean;
|
|
@@ -27,11 +27,12 @@ export interface UseList<T> {
|
|
|
27
27
|
hasMore: boolean;
|
|
28
28
|
loadMore: () => Promise<void>;
|
|
29
29
|
reload: () => void;
|
|
30
|
+
metadata?: M;
|
|
30
31
|
}
|
|
31
|
-
export type PageFetcher<T> = (cursor: string | number | undefined, signal: AbortSignal) => Promise<Page<T>>;
|
|
32
|
+
export type PageFetcher<T, M = unknown> = (cursor: string | number | undefined, signal: AbortSignal) => Promise<Page<T, M>>;
|
|
32
33
|
export declare function useList<T extends {
|
|
33
34
|
id: string;
|
|
34
|
-
}>(store: ResourceStore, key: string | null, tag: Tag, page: PageFetcher<T>): UseList<T>;
|
|
35
|
+
}, M = unknown>(store: ResourceStore, key: string | null, tag: Tag, page: PageFetcher<T, M>): UseList<T, M>;
|
|
35
36
|
/**
|
|
36
37
|
* A limit/offset list as pages. A full page means more may follow; with
|
|
37
38
|
* underfill (the latest feed drops items the caller may not see) only an
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-resource.js","names":[],"sources":["../../src/react/use-resource.ts"],"sourcesContent":["import { useCallback, useContext, useEffect, useMemo, useSyncExternalStore } from \"react\";\nimport type { ContentKitClient } from \"../client/client.js\";\nimport type { ContentKitError } from \"../client/errors.js\";\nimport { ContentKitContext, useContentKitClient, useReadScope } from \"./context.js\";\nimport { resourcesFor, type Fetcher, type Page, type Resource, type ResourceStore, type Tag } from \"./resources.js\";\n\n/** The client, its shared store, and the provider's viewer, language and sign-in. */\nexport function useContentScope(own?: ContentKitClient | null) {\n const ctx = useContext(ContentKitContext);\n const client = useContentKitClient(own);\n return { client, store: resourcesFor(client), scope: useReadScope(), viewer: ctx?.viewer, language: ctx?.language, onSignIn: ctx?.onSignIn };\n}\n\nconst IDLE: Resource<never> = { data: undefined, loading: false, loaded: false };\nconst none = () => () => {};\n\n/** A shared read: fetched once per key while shown; initial is shown (and seeds the store) until it loads. */\nexport function useResource<T>(\n store: ResourceStore | null,\n key: string | null,\n tag: Tag,\n fetcher: Fetcher<T>,\n o: { initial?: T; more?: (cursor: string | number, signal: AbortSignal) => Promise<Page<unknown>> } = {},\n): Resource<T> & { reload: () => void } {\n const scope = useReadScope();\n // Each key owns its closure cell: switching this subscriber to another key\n // cannot redirect a binding still used by a different subscriber.\n const source = useMemo(() => ({ fetcher, more: o.more, initial: o.initial }),\n // Fetcher identity changes on ordinary renders; only a key change creates a cell.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [store, key]);\n useEffect(() => {\n source.fetcher = fetcher;\n source.more = o.more;\n source.initial = o.initial;\n });\n const subscribe = useCallback(\n (l: () => void) => (key && store ? store.subscribe(key, { ...tag, readScope: scope }, l) : none()),\n // The tag is part of the key.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [store, key, scope],\n );\n const snapshot = useCallback(() => (key && store ? store.snapshot<T>(key) : IDLE), [store, key]);\n const entry = useSyncExternalStore(subscribe, snapshot, snapshot);\n useEffect(() => {\n if (!key || !store) return;\n const unbind = store.bind(key, (s) => source.fetcher(s), source.more && ((c, s) => source.more!(c, s)));\n if (source.initial !== undefined && !store.snapshot(key).loaded && !store.snapshot(key).loading) store.set(key, source.initial);\n else store.load(key);\n return unbind;\n }, [store, key, source]);\n const reload = useCallback(() => key && store?.load(key, true), [store, key]);\n if (!entry.loaded && o.initial !== undefined) return { ...entry, data: o.initial, reload };\n return { ...entry, reload };\n}\n\n/** A shared list, a page at a time. */\nexport interface UseList<T> {\n items: T[];\n /** The first page is loading (also on reload). */\n loading: boolean;\n loadingMore: boolean;\n error?: ContentKitError;\n hasMore: boolean;\n loadMore: () => Promise<void>;\n reload: () => void;\n}\n\nexport type PageFetcher<T> = (cursor: string | number | undefined, signal: AbortSignal) => Promise<Page<T>>;\n\n// The items of a list not loaded: one array, so effects keyed on items don't run every render.\nconst NO_ITEMS: never[] = [];\n\nexport function useList<T extends { id: string }>(store: ResourceStore, key: string | null, tag: Tag, page: PageFetcher<T>): UseList<T> {\n const r = useResource<Page<T>>(store, key, tag, (s) => page(undefined, s), { more: (c, s) => page(c, s) });\n const loadMore = useCallback(() => (key ? store.loadMore(key) : Promise.resolve()), [store, key]);\n return {\n items: r.data?.items ?? NO_ITEMS,\n loading: r.loading || (!!key && !r.loaded),\n loadingMore: !!r.loadingMore,\n error: r.error,\n hasMore: r.data ? r.data.next !== null : false,\n loadMore,\n reload: r.reload,\n };\n}\n\n/**\n * A limit/offset list as pages. A full page means more may follow; with\n * underfill (the latest feed drops items the caller may not see) only an\n * empty page ends it.\n */\nexport function offsetPages<T>(limit: number, list: (q: { limit: number; offset: number }, signal: AbortSignal) => Promise<T[]>, underfill = false): PageFetcher<T> {\n return async (cursor, signal) => {\n const offset = typeof cursor === \"number\" ? cursor : 0;\n const items = await list({ limit, offset }, signal);\n const end = underfill ? items.length === 0 : items.length < limit;\n return { items, next: end ? null : offset + limit };\n };\n}\n\n/** A stable store key. */\nexport const keyOf = (...parts: unknown[]) => JSON.stringify(parts);\n\n/** One numbered page of a list. */\nexport interface UsePaged<T> {\n items: T[];\n loading: boolean;\n error?: ContentKitError;\n /** Another page follows. */\n hasNext: boolean;\n reload: () => void;\n}\n\n/** Page `page` (from 1) of a limit/offset list: one read of limit + 1 tells whether another follows. */\nexport function usePaged<T extends { id: string }>(\n store: ResourceStore,\n key: string | null,\n tag: Tag,\n page: number,\n limit: number,\n list: (q: { limit: number; offset: number }, signal: AbortSignal) => Promise<T[]>,\n): UsePaged<T> {\n const offset = (Math.max(1, page) - 1) * limit;\n const r = useResource<Page<T>>(store, key === null ? null : `${key}#${offset}`, tag, async (signal) => {\n const items = await list({ limit: limit + 1, offset }, signal);\n return { items: items.slice(0, limit), next: items.length > limit ? offset + limit : null };\n });\n return { items: r.data?.items ?? NO_ITEMS, loading: r.loading || (!!key && !r.loaded), error: r.error, hasNext: r.data ? r.data.next !== null : false, reload: r.reload };\n}\n"],"mappings":";;;;AAOA,SAAgB,EAAgB,GAA+B;CAC7D,IAAM,IAAM,EAAW,CAAiB,GAClC,IAAS,EAAoB,CAAG;CACtC,OAAO;EAAE;EAAQ,OAAO,EAAa,CAAM;EAAG,OAAO,EAAa;EAAG,QAAQ,GAAK;EAAQ,UAAU,GAAK;EAAU,UAAU,GAAK;CAAS;AAC7I;AAEA,IAAM,IAAwB;CAAE,MAAM,KAAA;CAAW,SAAS;CAAO,QAAQ;AAAM,GACzE,gBAAmB,CAAC;AAG1B,SAAgB,EACd,GACA,GACA,GACA,GACA,IAAsG,CAAC,GACjE;CACtC,IAAM,IAAQ,EAAa,GAGrB,IAAS,SAAe;EAAE;EAAS,MAAM,EAAE;EAAM,SAAS,EAAE;CAAQ,IAGxE,CAAC,GAAO,CAAG,CAAC;CACd,QAAgB;EAGd,AAFA,EAAO,UAAU,GACjB,EAAO,OAAO,EAAE,MAChB,EAAO,UAAU,EAAE;CACrB,CAAC;CACD,IAAM,IAAY,GACf,MAAmB,KAAO,IAAQ,EAAM,UAAU,GAAK;EAAE,GAAG;EAAK,WAAW;CAAM,GAAG,CAAC,IAAI,EAAK,GAGhG;EAAC;EAAO;EAAK;CAAK,CACpB,GACM,IAAW,QAAmB,KAAO,IAAQ,EAAM,SAAY,CAAG,IAAI,GAAO,CAAC,GAAO,CAAG,CAAC,GACzF,IAAQ,EAAqB,GAAW,GAAU,CAAQ;CAChE,QAAgB;EACd,IAAI,CAAC,KAAO,CAAC,GAAO;EACpB,IAAM,IAAS,EAAM,KAAK,IAAM,MAAM,EAAO,QAAQ,CAAC,GAAG,EAAO,UAAU,GAAG,MAAM,EAAO,KAAM,GAAG,CAAC,EAAE;EAGtG,OAFI,EAAO,YAAY,KAAA,KAAa,CAAC,EAAM,SAAS,CAAG,CAAC,CAAC,UAAU,CAAC,EAAM,SAAS,CAAG,CAAC,CAAC,UAAS,EAAM,IAAI,GAAK,EAAO,OAAO,IACzH,EAAM,KAAK,CAAG,GACZ;CACT,GAAG;EAAC;EAAO;EAAK;CAAM,CAAC;CACvB,IAAM,IAAS,QAAkB,KAAO,GAAO,KAAK,GAAK,EAAI,GAAG,CAAC,GAAO,CAAG,CAAC;CAE5E,OADI,CAAC,EAAM,UAAU,EAAE,YAAY,KAAA,IAAkB;EAAE,GAAG;EAAO,MAAM,EAAE;EAAS;CAAO,IAClF;EAAE,GAAG;EAAO;CAAO;AAC5B;
|
|
1
|
+
{"version":3,"file":"use-resource.js","names":[],"sources":["../../src/react/use-resource.ts"],"sourcesContent":["import { useCallback, useContext, useEffect, useMemo, useSyncExternalStore } from \"react\";\nimport type { ContentKitClient } from \"../client/client.js\";\nimport type { ContentKitError } from \"../client/errors.js\";\nimport { ContentKitContext, useContentKitClient, useReadScope } from \"./context.js\";\nimport { resourcesFor, type Fetcher, type Page, type Resource, type ResourceStore, type Tag } from \"./resources.js\";\n\n/** The client, its shared store, and the provider's viewer, language and sign-in. */\nexport function useContentScope(own?: ContentKitClient | null) {\n const ctx = useContext(ContentKitContext);\n const client = useContentKitClient(own);\n return { client, store: resourcesFor(client), scope: useReadScope(), viewer: ctx?.viewer, language: ctx?.language, onSignIn: ctx?.onSignIn };\n}\n\nconst IDLE: Resource<never> = { data: undefined, loading: false, loaded: false };\nconst none = () => () => {};\n\n/** A shared read: fetched once per key while shown; initial is shown (and seeds the store) until it loads. */\nexport function useResource<T>(\n store: ResourceStore | null,\n key: string | null,\n tag: Tag,\n fetcher: Fetcher<T>,\n o: { initial?: T; more?: (cursor: string | number, signal: AbortSignal) => Promise<Page<unknown>> } = {},\n): Resource<T> & { reload: () => void } {\n const scope = useReadScope();\n // Each key owns its closure cell: switching this subscriber to another key\n // cannot redirect a binding still used by a different subscriber.\n const source = useMemo(() => ({ fetcher, more: o.more, initial: o.initial }),\n // Fetcher identity changes on ordinary renders; only a key change creates a cell.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [store, key]);\n useEffect(() => {\n source.fetcher = fetcher;\n source.more = o.more;\n source.initial = o.initial;\n });\n const subscribe = useCallback(\n (l: () => void) => (key && store ? store.subscribe(key, { ...tag, readScope: scope }, l) : none()),\n // The tag is part of the key.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [store, key, scope],\n );\n const snapshot = useCallback(() => (key && store ? store.snapshot<T>(key) : IDLE), [store, key]);\n const entry = useSyncExternalStore(subscribe, snapshot, snapshot);\n useEffect(() => {\n if (!key || !store) return;\n const unbind = store.bind(key, (s) => source.fetcher(s), source.more && ((c, s) => source.more!(c, s)));\n if (source.initial !== undefined && !store.snapshot(key).loaded && !store.snapshot(key).loading) store.set(key, source.initial);\n else store.load(key);\n return unbind;\n }, [store, key, source]);\n const reload = useCallback(() => key && store?.load(key, true), [store, key]);\n if (!entry.loaded && o.initial !== undefined) return { ...entry, data: o.initial, reload };\n return { ...entry, reload };\n}\n\n/** A shared list, a page at a time. */\nexport interface UseList<T, M = unknown> {\n items: T[];\n /** The first page is loading (also on reload). */\n loading: boolean;\n loadingMore: boolean;\n error?: ContentKitError;\n hasMore: boolean;\n loadMore: () => Promise<void>;\n reload: () => void;\n metadata?: M;\n}\n\nexport type PageFetcher<T, M = unknown> = (cursor: string | number | undefined, signal: AbortSignal) => Promise<Page<T, M>>;\n\n// The items of a list not loaded: one array, so effects keyed on items don't run every render.\nconst NO_ITEMS: never[] = [];\n\nexport function useList<T extends { id: string }, M = unknown>(store: ResourceStore, key: string | null, tag: Tag, page: PageFetcher<T, M>): UseList<T, M> {\n const r = useResource<Page<T, M>>(store, key, tag, (s) => page(undefined, s), { more: (c, s) => page(c, s) });\n const loadMore = useCallback(() => (key ? store.loadMore(key) : Promise.resolve()), [store, key]);\n return {\n items: r.data?.items ?? NO_ITEMS,\n loading: r.loading || (!!key && !r.loaded),\n loadingMore: !!r.loadingMore,\n error: r.error,\n hasMore: r.data ? r.data.next !== null : false,\n loadMore,\n reload: r.reload,\n metadata: r.data?.metadata,\n };\n}\n\n/**\n * A limit/offset list as pages. A full page means more may follow; with\n * underfill (the latest feed drops items the caller may not see) only an\n * empty page ends it.\n */\nexport function offsetPages<T>(limit: number, list: (q: { limit: number; offset: number }, signal: AbortSignal) => Promise<T[]>, underfill = false): PageFetcher<T> {\n return async (cursor, signal) => {\n const offset = typeof cursor === \"number\" ? cursor : 0;\n const items = await list({ limit, offset }, signal);\n const end = underfill ? items.length === 0 : items.length < limit;\n return { items, next: end ? null : offset + limit };\n };\n}\n\n/** A stable store key. */\nexport const keyOf = (...parts: unknown[]) => JSON.stringify(parts);\n\n/** One numbered page of a list. */\nexport interface UsePaged<T> {\n items: T[];\n loading: boolean;\n error?: ContentKitError;\n /** Another page follows. */\n hasNext: boolean;\n reload: () => void;\n}\n\n/** Page `page` (from 1) of a limit/offset list: one read of limit + 1 tells whether another follows. */\nexport function usePaged<T extends { id: string }>(\n store: ResourceStore,\n key: string | null,\n tag: Tag,\n page: number,\n limit: number,\n list: (q: { limit: number; offset: number }, signal: AbortSignal) => Promise<T[]>,\n): UsePaged<T> {\n const offset = (Math.max(1, page) - 1) * limit;\n const r = useResource<Page<T>>(store, key === null ? null : `${key}#${offset}`, tag, async (signal) => {\n const items = await list({ limit: limit + 1, offset }, signal);\n return { items: items.slice(0, limit), next: items.length > limit ? offset + limit : null };\n });\n return { items: r.data?.items ?? NO_ITEMS, loading: r.loading || (!!key && !r.loaded), error: r.error, hasNext: r.data ? r.data.next !== null : false, reload: r.reload };\n}\n"],"mappings":"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"}
|
package/dist/react.js
CHANGED
|
@@ -3,29 +3,32 @@ import { GuardContext as i, useContentKit as a, useContentKitClient as o, useCon
|
|
|
3
3
|
import { useCrop as d, useEncodeProgress as f, useUpload as p, useUploadQueue as m } from "./react/upload.js";
|
|
4
4
|
import { ResourceStore as h, resourcesFor as g } from "./react/resources.js";
|
|
5
5
|
import { useContentScope as _, usePaged as v } from "./react/use-resource.js";
|
|
6
|
-
import { memberId as y, useContentGroups as b, useGroup as x, useGroupMembers as S, useGroups as C,
|
|
7
|
-
import { useMediaRead as
|
|
8
|
-
import { useAvatar as
|
|
9
|
-
import { editOutput as
|
|
10
|
-
import { round3 as
|
|
11
|
-
import { GALLERY_VIEW_KEY as
|
|
12
|
-
import { useEditorCrop as
|
|
13
|
-
import { nameIn as
|
|
14
|
-
import { useNearViewport as
|
|
15
|
-
import { useAdminComments as
|
|
16
|
-
import { useContentConfig as
|
|
17
|
-
import { useFavorite as
|
|
18
|
-
import { usePoll as
|
|
19
|
-
import { useVersionParam as
|
|
20
|
-
import { useAdminLocation as
|
|
21
|
-
import { beaconsFor as
|
|
22
|
-
import { defaultVersion as
|
|
23
|
-
import {
|
|
24
|
-
import {
|
|
25
|
-
import {
|
|
26
|
-
import {
|
|
27
|
-
import {
|
|
28
|
-
import {
|
|
29
|
-
import {
|
|
30
|
-
import {
|
|
31
|
-
|
|
6
|
+
import { memberId as y, useContentGroups as b, useGroup as x, useGroupMembers as S, useGroups as C, useGroupsPage as w, useKinds as T, useMyGroups as E } from "./react/groups.js";
|
|
7
|
+
import { useMediaRead as D } from "./react/read.js";
|
|
8
|
+
import { useAvatar as O, usePresets as k, usePublicImage as A } from "./react/public.js";
|
|
9
|
+
import { editOutput as j, useSlotCrop as M, useSlotImage as N } from "./react/slot.js";
|
|
10
|
+
import { round3 as P, useFrameStrip as F, useVideoFrame as I, useVideoImages as L, useVideoPoster as R } from "./react/video.js";
|
|
11
|
+
import { GALLERY_VIEW_KEY as z, PLAYER_QUALITY_KEY as B, useCarousel as V, useGalleryView as H, useHlsPlayer as U, useRefreshBeforeExpiry as W } from "./react/gallery.js";
|
|
12
|
+
import { useEditorCrop as G } from "./react/crop.js";
|
|
13
|
+
import { nameIn as K, thumbnailOf as q, useMediaFolder as J } from "./react/folder.js";
|
|
14
|
+
import { useNearViewport as Y } from "./react/viewport.js";
|
|
15
|
+
import { useAdminComments as X, useBannedWords as Z, useCanComment as Q, useCommentBans as $, useCommentReplies as ee, useComments as te, useGlobalCommentBan as ne, useIPBans as re, useLatestComments as ie, useModerationQueue as ae, withReaction as oe } from "./react/comments.js";
|
|
16
|
+
import { useContentConfig as se } from "./react/config.js";
|
|
17
|
+
import { useFavorite as ce, useReaction as le } from "./react/engagement.js";
|
|
18
|
+
import { usePoll as ue, usePollEditor as de, usePolls as fe, withVote as pe } from "./react/polls.js";
|
|
19
|
+
import { useVersionParam as me } from "./react/location.js";
|
|
20
|
+
import { useAdminLocation as he, useFlowClient as ge, useStaffAccess as _e } from "./react/admin.js";
|
|
21
|
+
import { beaconsFor as ve, useBeacons as ye, useContentFilters as be, useContents as xe, useContentsPage as Se, useDailyReleases as Ce, useExposure as we, useHistory as Te, useLockedCount as Ee, useMyFavorites as De, useMyReactions as Oe, useRecentSearches as ke, useRecommendations as Ae, useReleaseDates as je, useSearch as Me, useSearchPage as Ne, useSimilar as Pe, useTypeahead as Fe } from "./react/discovery.js";
|
|
22
|
+
import { defaultVersion as Ie, editionOf as Le, findVersion as Re, liveVersions as ze, useContentDetail as Be } from "./react/detail.js";
|
|
23
|
+
import { useContent as Ve, useManagedContents as He } from "./react/contents.js";
|
|
24
|
+
import { usePageNotices as Ue } from "./react/page-notices.js";
|
|
25
|
+
import { downloadMessage as We, nextRelease as Ge, startDownload as Ke, useReaderPlan as qe, useSegmentPages as Je, useVersionDownload as Ye } from "./react/versions.js";
|
|
26
|
+
import { useActivity as Xe, useMyStats as Ze } from "./react/stats.js";
|
|
27
|
+
import { useReadingEngagement as Qe } from "./react/use-engagement.js";
|
|
28
|
+
import { usePostReading as $e, usePostReads as et } from "./react/post-reads.js";
|
|
29
|
+
import { useNotificationUnread as tt, useNotifications as nt } from "./react/notifications.js";
|
|
30
|
+
import { ContentKitProvider as rt } from "./react/provider.js";
|
|
31
|
+
import { useReaderPreferences as it } from "./react/reader-preferences.js";
|
|
32
|
+
import { useCanonicalContent as at } from "./react/canonical.js";
|
|
33
|
+
import { useRememberedSort as ot } from "./react/remembered-sort.js";
|
|
34
|
+
export { rt as ContentKitProvider, z as GALLERY_VIEW_KEY, i as GuardContext, e as HOVER_DELAY, t as InlinePreviewContext, B as PLAYER_QUALITY_KEY, h as ResourceStore, ve as beaconsFor, Ie as defaultVersion, We as downloadMessage, j as editOutput, Le as editionOf, Re as findVersion, ze as liveVersions, y as memberId, K as nameIn, Ge as nextRelease, g as resourcesFor, P as round3, Ke as startDownload, q as thumbnailOf, Xe as useActivity, X as useAdminComments, he as useAdminLocation, O as useAvatar, Z as useBannedWords, ye as useBeacons, Q as useCanComment, at as useCanonicalContent, V as useCarousel, $ as useCommentBans, ee as useCommentReplies, te as useComments, Ve as useContent, se as useContentConfig, Be as useContentDetail, be as useContentFilters, b as useContentGroups, a as useContentKit, o as useContentKitClient, _ as useContentScope, s as useContentURLs, xe as useContents, Se as useContentsPage, d as useCrop, Ce as useDailyReleases, G as useEditorCrop, f as useEncodeProgress, c as useErrorReporter, we as useExposure, ce as useFavorite, ge as useFlowClient, F as useFrameStrip, H as useGalleryView, ne as useGlobalCommentBan, x as useGroup, S as useGroupMembers, C as useGroups, w as useGroupsPage, l as useGuarded, Te as useHistory, U as useHlsPlayer, re as useIPBans, n as useInlinePreview, T as useKinds, ie as useLatestComments, Ee as useLockedCount, He as useManagedContents, J as useMediaFolder, D as useMediaRead, ae as useModerationQueue, De as useMyFavorites, E as useMyGroups, Oe as useMyReactions, Ze as useMyStats, Y as useNearViewport, tt as useNotificationUnread, nt as useNotifications, u as useOptionalContentKitClient, Ue as usePageNotices, v as usePaged, ue as usePoll, de as usePollEditor, fe as usePolls, $e as usePostReading, et as usePostReads, k as usePresets, A as usePublicImage, le as useReaction, qe as useReaderPlan, it as useReaderPreferences, Qe as useReadingEngagement, ke as useRecentSearches, Ae as useRecommendations, r as useReducedMotion, W as useRefreshBeforeExpiry, je as useReleaseDates, ot as useRememberedSort, Me as useSearch, Ne as useSearchPage, Je as useSegmentPages, Pe as useSimilar, M as useSlotCrop, N as useSlotImage, _e as useStaffAccess, Fe as useTypeahead, p as useUpload, m as useUploadQueue, Ye as useVersionDownload, me as useVersionParam, I as useVideoFrame, L as useVideoImages, R as useVideoPoster, oe as withReaction, pe as withVote };
|