@openrails/contentkit-ui 0.103.2 → 0.104.0-rc.1

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.
Files changed (120) hide show
  1. package/README.md +105 -43
  2. package/dist/client/beacons.d.ts +3 -13
  3. package/dist/client/beacons.js +4 -45
  4. package/dist/client/beacons.js.map +1 -1
  5. package/dist/client/client.d.ts +3 -0
  6. package/dist/client/client.js +45 -43
  7. package/dist/client/client.js.map +1 -1
  8. package/dist/client/content/favorites.d.ts +2 -0
  9. package/dist/client/content/favorites.js.map +1 -1
  10. package/dist/client/content/types.d.ts +3 -0
  11. package/dist/client/content/types.js.map +1 -1
  12. package/dist/client/discovery.d.ts +28 -3
  13. package/dist/client/discovery.js +22 -1
  14. package/dist/client/discovery.js.map +1 -1
  15. package/dist/client/engagement.d.ts +70 -0
  16. package/dist/client/engagement.js +191 -0
  17. package/dist/client/engagement.js.map +1 -0
  18. package/dist/client/generated/routes.d.ts +35 -9
  19. package/dist/client/generated/routes.js +59 -2
  20. package/dist/client/generated/routes.js.map +1 -1
  21. package/dist/client/generated/wire.d.ts +53 -12
  22. package/dist/client/generated/wire.js.map +1 -1
  23. package/dist/client/guest-reading-history.d.ts +40 -0
  24. package/dist/client/guest-reading-history.js +144 -0
  25. package/dist/client/guest-reading-history.js.map +1 -0
  26. package/dist/client/index.d.ts +4 -2
  27. package/dist/client/stats.d.ts +5 -5
  28. package/dist/client/stats.js.map +1 -1
  29. package/dist/client.js +24 -22
  30. package/dist/components/admin/content-manager.js +30 -32
  31. package/dist/components/admin/content-manager.js.map +1 -1
  32. package/dist/components/admin/quick-search.d.ts +14 -0
  33. package/dist/components/admin/quick-search.js +60 -0
  34. package/dist/components/admin/quick-search.js.map +1 -0
  35. package/dist/components/admin/reader-content-editor.js +452 -428
  36. package/dist/components/admin/reader-content-editor.js.map +1 -1
  37. package/dist/components/admin/stats-dashboard.d.ts +4 -4
  38. package/dist/components/admin/stats-dashboard.js +132 -134
  39. package/dist/components/admin/stats-dashboard.js.map +1 -1
  40. package/dist/components/content/daily-releases.js +143 -191
  41. package/dist/components/content/daily-releases.js.map +1 -1
  42. package/dist/components/content/favorites.d.ts +6 -0
  43. package/dist/components/content/favorites.js +33 -0
  44. package/dist/components/content/favorites.js.map +1 -0
  45. package/dist/components/content/filter-dialog.js +19 -15
  46. package/dist/components/content/filter-dialog.js.map +1 -1
  47. package/dist/components/content/filters.d.ts +2 -0
  48. package/dist/components/content/filters.js +5 -1
  49. package/dist/components/content/filters.js.map +1 -1
  50. package/dist/components/content/grid.d.ts +34 -13
  51. package/dist/components/content/grid.js +300 -271
  52. package/dist/components/content/grid.js.map +1 -1
  53. package/dist/components/content/history.d.ts +6 -0
  54. package/dist/components/content/history.js +91 -0
  55. package/dist/components/content/history.js.map +1 -0
  56. package/dist/components/content/index.d.ts +1 -0
  57. package/dist/components/content/search.d.ts +11 -4
  58. package/dist/components/content/search.js +22 -11
  59. package/dist/components/content/search.js.map +1 -1
  60. package/dist/components/content/summary-tile.d.ts +14 -0
  61. package/dist/components/content/summary-tile.js +63 -0
  62. package/dist/components/content/summary-tile.js.map +1 -0
  63. package/dist/components/media-folder-editor.js +1 -1
  64. package/dist/components/media-folder-editor.js.map +1 -1
  65. package/dist/components/video-mini-player.d.ts +4 -1
  66. package/dist/components/video-mini-player.js +77 -71
  67. package/dist/components/video-mini-player.js.map +1 -1
  68. package/dist/components/video-player.d.ts +4 -1
  69. package/dist/components/video-player.js +280 -276
  70. package/dist/components/video-player.js.map +1 -1
  71. package/dist/index.d.ts +1 -0
  72. package/dist/index.js +17 -14
  73. package/dist/locales/admin/de.js +8 -8
  74. package/dist/locales/admin/de.js.map +1 -1
  75. package/dist/locales/admin/en.d.ts +4 -4
  76. package/dist/locales/admin/en.js +8 -8
  77. package/dist/locales/admin/en.js.map +1 -1
  78. package/dist/locales/admin/es.js +8 -8
  79. package/dist/locales/admin/es.js.map +1 -1
  80. package/dist/locales/admin/ja.js +8 -8
  81. package/dist/locales/admin/ja.js.map +1 -1
  82. package/dist/locales/admin/ko.js +8 -8
  83. package/dist/locales/admin/ko.js.map +1 -1
  84. package/dist/locales/admin/zh.js +8 -8
  85. package/dist/locales/admin/zh.js.map +1 -1
  86. package/dist/locales/discovery/de.js +0 -1
  87. package/dist/locales/discovery/de.js.map +1 -1
  88. package/dist/locales/discovery/en.d.ts +0 -1
  89. package/dist/locales/discovery/en.js +0 -1
  90. package/dist/locales/discovery/en.js.map +1 -1
  91. package/dist/locales/discovery/es.js +0 -1
  92. package/dist/locales/discovery/es.js.map +1 -1
  93. package/dist/locales/discovery/ja.js +0 -1
  94. package/dist/locales/discovery/ja.js.map +1 -1
  95. package/dist/locales/discovery/ko.js +0 -1
  96. package/dist/locales/discovery/ko.js.map +1 -1
  97. package/dist/locales/discovery/zh.js +0 -1
  98. package/dist/locales/discovery/zh.js.map +1 -1
  99. package/dist/locales/en.d.ts +4 -5
  100. package/dist/react/discovery.d.ts +20 -17
  101. package/dist/react/discovery.js +273 -221
  102. package/dist/react/discovery.js.map +1 -1
  103. package/dist/react/index.d.ts +2 -1
  104. package/dist/react/resources.d.ts +3 -1
  105. package/dist/react/resources.js +4 -0
  106. package/dist/react/resources.js.map +1 -1
  107. package/dist/react/stats.d.ts +2 -2
  108. package/dist/react/stats.js.map +1 -1
  109. package/dist/react/use-engagement.d.ts +26 -0
  110. package/dist/react/use-engagement.js +221 -0
  111. package/dist/react/use-engagement.js.map +1 -0
  112. package/dist/react/use-resource.d.ts +4 -3
  113. package/dist/react/use-resource.js +2 -1
  114. package/dist/react/use-resource.js.map +1 -1
  115. package/dist/react.js +12 -11
  116. package/dist/styles.css +1 -1
  117. package/dist/ui/dialog.d.ts +2 -1
  118. package/dist/ui/dialog.js +23 -20
  119. package/dist/ui/dialog.js.map +1 -1
  120. package/package.json +1 -1
@@ -1,119 +1,117 @@
1
- import { RenditionImg as e } from "../rendition-img.js";
2
- import { ratio as t } from "../../client/aspect.js";
3
- import { useMessages as n } from "../../i18n/context.js";
4
- import { ContentKitUiRoot as r } from "../../scope.js";
5
- import { ContentKitContext as i } from "../../react/context.js";
6
- import { useContentScope as a } from "../../react/use-resource.js";
7
- import { usePresets as o } from "../../react/public.js";
8
- import { Button as s } from "../../ui/button.js";
9
- import { useNearViewport as c } from "../../react/viewport.js";
10
- import { Skeleton as l } from "../../ui/skeleton.js";
11
- import { contentError as u } from "../social/parts.js";
12
- import { useDailyReleases as d, useExposure as f } from "../../react/discovery.js";
13
- import { ContentCard as p } from "./card.js";
1
+ import { useMessages as e } from "../../i18n/context.js";
2
+ import { ContentKitUiRoot as t } from "../../scope.js";
3
+ import { ContentKitContext as n } from "../../react/context.js";
4
+ import { useContentScope as r } from "../../react/use-resource.js";
5
+ import { Button as i } from "../../ui/button.js";
6
+ import { useNearViewport as a } from "../../react/viewport.js";
7
+ import { Skeleton as o } from "../../ui/skeleton.js";
8
+ import { contentError as s } from "../social/parts.js";
9
+ import { useDailyReleases as c, useExposure as l } from "../../react/discovery.js";
10
+ import { ContentCard as u } from "./card.js";
11
+ import { ContentFilterDialog as d } from "./filter-dialog.js";
12
+ import { useReleaseReveal as f } from "./release-reveal.js";
13
+ import { ContentSummaryTile as p } from "./summary-tile.js";
14
14
  import { cardGridLayout as m } from "./grid.js";
15
- import { ContentFilterDialog as h } from "./filter-dialog.js";
16
- import { useReleaseReveal as g } from "./release-reveal.js";
17
- import { useCallback as _, useContext as v, useId as y, useMemo as b, useRef as x, useState as S } from "react";
18
- import { jsx as C, jsxs as w } from "react/jsx-runtime";
19
- import { cn as T } from "cn";
20
- import { ArrowDown01Icon as E, LockIcon as D, Settings01Icon as O } from "@hugeicons/core-free-icons";
21
- import { HugeiconsIcon as k } from "@hugeicons/react";
15
+ import { useCallback as h, useContext as g, useId as _, useMemo as v, useRef as y, useState as b } from "react";
16
+ import { jsx as x, jsxs as S } from "react/jsx-runtime";
17
+ import { cn as C } from "cn";
18
+ import { ArrowDown01Icon as w } from "@hugeicons/core-free-icons";
19
+ import { HugeiconsIcon as T } from "@hugeicons/react";
22
20
  //#region src/components/content/daily-releases.tsx
23
- var A = (e, t) => Number.isFinite(e) ? Math.max(0, Math.floor(e)) : t;
24
- function j({ query: e, initialVisible: t = 30, revealStep: o = 30, collapsePremium: c = !1, summaryLabels: f, ...p }) {
25
- let h = n(), { client: g, viewer: _ } = a(p.client), y = v(i), x = b(() => ({
21
+ var E = (e, t) => Number.isFinite(e) ? Math.max(0, Math.floor(e)) : t;
22
+ function D({ query: a, initialVisible: l = 30, revealStep: u = 30, collapsePremium: d = !1, summaryLabels: f, ...p }) {
23
+ let h = e(), { client: _, viewer: y } = r(p.client), w = g(n), T = v(() => ({
26
24
  days: 10,
27
25
  time_zone: Intl.DateTimeFormat().resolvedOptions().timeZone,
28
- ...e
29
- }), [e]), E = d(x, { client: p.client }), D = m(p.grid), O = JSON.stringify(x), k = b(() => ({
30
- client: g,
31
- viewer: _,
32
- language: y?.language,
33
- accessRevision: y?.accessRevision,
34
- requestKey: O
26
+ ...a
27
+ }), [a]), D = c(T, { client: p.client }), O = m(p.grid), A = JSON.stringify(T), j = v(() => ({
28
+ client: _,
29
+ viewer: y,
30
+ language: w?.language,
31
+ accessRevision: w?.accessRevision,
32
+ requestKey: A
35
33
  }), [
36
- g,
37
34
  _,
38
- y?.language,
39
- y?.accessRevision,
40
- O
41
- ]), [j, M] = S({
42
- identity: k,
43
- data: E.data,
35
+ y,
36
+ w?.language,
37
+ w?.accessRevision,
38
+ A
39
+ ]), [M, N] = b({
40
+ identity: j,
41
+ data: D.data,
44
42
  revision: 0
45
43
  });
46
- (j.identity !== k || E.data && j.data !== E.data) && M({
47
- identity: k,
48
- data: E.data,
49
- revision: j.revision + (j.identity === k ? 0 : 1)
44
+ (M.identity !== j || D.data && M.data !== D.data) && N({
45
+ identity: j,
46
+ data: D.data,
47
+ revision: M.revision + (M.identity === j ? 0 : 1)
50
48
  });
51
- let P = E.data ?? (j.identity === k ? j.data : void 0), F = !E.data && !!P, I = b(() => P?.days.filter((e) => e.contents.length || e.filtered_count > 0).sort((e, t) => t.date.localeCompare(e.date)) ?? [], [P]), L = A(t, 30);
52
- return /* @__PURE__ */ w(r, {
49
+ let P = D.data ?? (M.identity === j ? M.data : void 0), F = !D.data && !!P, I = v(() => P?.days.filter((e) => e.contents.length || e.filtered_count > 0).sort((e, t) => t.date.localeCompare(e.date)) ?? [], [P]), L = E(l, 30);
50
+ return /* @__PURE__ */ S(t, {
53
51
  appearance: p.appearance,
54
- className: T("grid gap-6 text-sm", p.className),
52
+ className: C("grid gap-6 text-sm", p.className),
55
53
  "data-ckui": "daily-releases",
56
- "aria-busy": E.loading,
57
- children: [P && E.error && /* @__PURE__ */ w("div", {
54
+ "aria-busy": D.loading,
55
+ children: [P && D.error && /* @__PURE__ */ S("div", {
58
56
  role: "alert",
59
57
  className: "grid justify-items-start gap-2",
60
- children: [/* @__PURE__ */ C("p", {
58
+ children: [/* @__PURE__ */ x("p", {
61
59
  className: "text-destructive",
62
- children: u(h, E.error)
63
- }), /* @__PURE__ */ C(s, {
60
+ children: s(h, D.error)
61
+ }), /* @__PURE__ */ x(i, {
64
62
  type: "button",
65
63
  variant: "outline",
66
- onClick: E.reload,
64
+ onClick: D.reload,
67
65
  children: h.t("common.retry")
68
66
  })]
69
- }), E.loading && !P ? /* @__PURE__ */ C("div", {
70
- className: D.className,
71
- style: D.style,
72
- children: Array.from({ length: 6 }, (e, t) => /* @__PURE__ */ C(l, {
67
+ }), D.loading && !P ? /* @__PURE__ */ x("div", {
68
+ className: O.className,
69
+ style: O.style,
70
+ children: Array.from({ length: 6 }, (e, t) => /* @__PURE__ */ x(o, {
73
71
  className: p.aspectRatio === void 0 ? p.shape === "landscape" ? "aspect-video" : "aspect-[3/4]" : void 0,
74
72
  style: p.aspectRatio === void 0 ? void 0 : { aspectRatio: p.aspectRatio }
75
73
  }, t))
76
- }) : E.error && !P ? /* @__PURE__ */ w("div", {
74
+ }) : D.error && !P ? /* @__PURE__ */ S("div", {
77
75
  role: "alert",
78
76
  className: "grid justify-items-start gap-2",
79
- children: [/* @__PURE__ */ C("p", {
77
+ children: [/* @__PURE__ */ x("p", {
80
78
  className: "text-destructive",
81
- children: u(h, E.error)
82
- }), /* @__PURE__ */ C(s, {
79
+ children: s(h, D.error)
80
+ }), /* @__PURE__ */ x(i, {
83
81
  size: "sm",
84
82
  variant: "outline",
85
- onClick: E.reload,
83
+ onClick: D.reload,
86
84
  children: h.t("common.retry")
87
85
  })]
88
86
  }) : I.length ? I.map((e) => {
89
87
  let t = Math.min(L, e.contents.length);
90
- return L -= t, /* @__PURE__ */ C(N, {
88
+ return L -= t, /* @__PURE__ */ x(k, {
91
89
  day: e,
92
90
  pending: F,
93
- collapsePremium: c,
91
+ collapsePremium: d,
94
92
  summaryLabels: f,
95
- language: x.display_language ?? x.language,
96
- kinds: x.kind ? [x.kind] : void 0,
93
+ language: T.display_language ?? T.language,
94
+ kinds: T.kind ? [T.kind] : void 0,
97
95
  initial: t,
98
- step: Math.max(1, A(o, 30)),
96
+ step: Math.max(1, E(u, 30)),
99
97
  cardProps: p
100
98
  }, JSON.stringify([
101
- O,
99
+ A,
102
100
  P?.from_date,
103
101
  e.date
104
102
  ]));
105
- }) : /* @__PURE__ */ C("p", {
103
+ }) : /* @__PURE__ */ x("p", {
106
104
  role: "status",
107
105
  className: "text-muted-foreground",
108
106
  children: p.empty ?? h.t("contents.empty")
109
107
  })]
110
- }, j.revision);
108
+ }, M.revision);
111
109
  }
112
- var M = (e) => !e.access.allowed && e.access.level === "tier";
113
- function N({ day: e, initial: t, step: r, pending: i, cardProps: a, collapsePremium: o, summaryLabels: c, language: u, kinds: d }) {
114
- let p = n(), _ = y(), [v, D] = S(t > 0 || !e.contents.length && e.filtered_count > 0), [O, A] = S(t), [j, N] = S(!1), [I, L] = S(!1), R = x(null), z = x(null), B = b(() => e.contents.slice(0, O), [e.contents, O]), V = b(() => e.contents.filter(M).length, [e.contents]), H = d?.[0], U = b(() => {
110
+ var O = (e) => !e.access.allowed && e.access.level === "tier";
111
+ function k({ day: t, initial: n, step: r, pending: a, cardProps: s, collapsePremium: c, summaryLabels: u, language: h, kinds: g }) {
112
+ let E = e(), D = _(), [k, j] = b(n > 0 || !t.contents.length && t.filtered_count > 0), [M, N] = b(n), [P, F] = b(!1), [I, L] = b(!1), R = y(null), z = y(null), B = v(() => t.contents.slice(0, M), [t.contents, M]), V = v(() => t.contents.filter(O).length, [t.contents]), H = g?.[0], U = v(() => {
115
113
  let e = !1;
116
- return B.flatMap((t, n) => !o || j || !M(t) ? [{
114
+ return B.flatMap((t, n) => !c || P || !O(t) ? [{
117
115
  key: t.id,
118
116
  card: t,
119
117
  summary: !1,
@@ -126,187 +124,141 @@ function N({ day: e, initial: t, step: r, pending: i, cardProps: a, collapsePrem
126
124
  }]));
127
125
  }, [
128
126
  B,
129
- o,
130
- j
131
- ]), W = b(() => v && !i ? U.filter((e) => !e.summary).map((e) => e.card) : [], [
132
- v,
133
- i,
127
+ c,
128
+ P
129
+ ]), W = v(() => k && !a ? U.filter((e) => !e.summary).map((e) => ({
130
+ ...e.card,
131
+ position: e.position
132
+ })) : [], [
133
+ k,
134
+ a,
134
135
  U
135
- ]), G = f(W, {
136
- surface: a.surface ?? "releases",
137
- render: e.date,
138
- client: a.client
139
- }), K = m(a.grid), q = g(`${O}|${U.map((e) => e.key).join("\0")}`), J = new Intl.DateTimeFormat(p.language, {
136
+ ]), G = l(W, {
137
+ surface: s.surface ?? "releases",
138
+ render: t.date,
139
+ client: s.client
140
+ }), K = m(s.grid), q = f(`${M}|${U.map((e) => e.key).join("\0")}`), J = new Intl.DateTimeFormat(E.language, {
140
141
  dateStyle: "full",
141
142
  timeZone: "UTC"
142
- }).format(/* @__PURE__ */ new Date(`${e.date}T12:00:00Z`)), Y = () => {
143
- !v && !O && A(Math.min(r, e.contents.length)), D(!v);
143
+ }).format(/* @__PURE__ */ new Date(`${t.date}T12:00:00Z`)), Y = () => {
144
+ !k && !M && N(Math.min(r, t.contents.length)), j(!k);
144
145
  }, X = (e) => {
145
- q.prepare(e.detail === 0), N(!0);
146
+ q.prepare(e.detail === 0), F(!0);
146
147
  };
147
- return /* @__PURE__ */ w("section", {
148
+ return /* @__PURE__ */ S("section", {
148
149
  "data-ckui": "release-day",
149
- "data-date": e.date,
150
+ "data-date": t.date,
150
151
  children: [
151
- /* @__PURE__ */ C("h2", { children: /* @__PURE__ */ w(s, {
152
+ /* @__PURE__ */ x("h2", { children: /* @__PURE__ */ S(i, {
152
153
  ref: z,
153
- id: `${_}-heading`,
154
+ id: `${D}-heading`,
154
155
  type: "button",
155
156
  variant: "ghost",
156
157
  className: "h-auto w-full justify-start gap-3 px-0 py-3 text-start text-lg font-semibold",
157
- "aria-expanded": v,
158
- "aria-controls": `${_}-contents`,
158
+ "aria-expanded": k,
159
+ "aria-controls": `${D}-contents`,
159
160
  onClick: Y,
160
- children: [/* @__PURE__ */ C(k, {
161
- icon: E,
161
+ children: [/* @__PURE__ */ x(T, {
162
+ icon: w,
162
163
  strokeWidth: 2,
163
- className: T("size-5 shrink-0 transition-transform duration-200 motion-reduce:transition-none", !v && "-rotate-90"),
164
+ className: C("size-5 shrink-0 transition-transform duration-200 motion-reduce:transition-none", !k && "-rotate-90"),
164
165
  "aria-hidden": !0
165
- }), /* @__PURE__ */ C("time", {
166
- dateTime: e.date,
166
+ }), /* @__PURE__ */ x("time", {
167
+ dateTime: t.date,
167
168
  children: J
168
169
  })]
169
170
  }) }),
170
- v && i && /* @__PURE__ */ C(l, { className: "h-24 w-full" }),
171
- /* @__PURE__ */ C("div", {
172
- hidden: i,
173
- style: i ? { display: "none" } : void 0,
174
- id: `${_}-contents`,
171
+ k && a && /* @__PURE__ */ x(o, { className: "h-24 w-full" }),
172
+ /* @__PURE__ */ x("div", {
173
+ hidden: a,
174
+ style: a ? { display: "none" } : void 0,
175
+ id: `${D}-contents`,
175
176
  role: "region",
176
- "aria-labelledby": `${_}-heading`,
177
- "aria-hidden": !v || i,
178
- inert: !v || i,
179
- className: T("grid transition-[grid-template-rows,opacity] duration-250 ease-out motion-reduce:transition-none", v ? "grid-rows-[1fr] opacity-100" : "grid-rows-[0fr] opacity-0"),
180
- children: /* @__PURE__ */ w("div", {
177
+ "aria-labelledby": `${D}-heading`,
178
+ "aria-hidden": !k || a,
179
+ inert: !k || a,
180
+ className: C("grid transition-[grid-template-rows,opacity] duration-250 ease-out motion-reduce:transition-none", k ? "grid-rows-[1fr] opacity-100" : "grid-rows-[0fr] opacity-0"),
181
+ children: /* @__PURE__ */ S("div", {
181
182
  className: "min-h-0 overflow-hidden",
182
- children: [/* @__PURE__ */ w("ol", {
183
+ children: [/* @__PURE__ */ S("ol", {
183
184
  ref: q.grid,
184
- className: T(K.className, "pt-2"),
185
+ className: C(K.className, "pt-2"),
185
186
  style: K.style,
186
- children: [U.map((e) => e.summary ? /* @__PURE__ */ C(P, {
187
+ children: [U.map((e) => e.summary ? /* @__PURE__ */ x(p, {
187
188
  tileKey: e.key,
188
- contentKind: d?.[0] ?? e.card.kind,
189
- open: v && !i,
189
+ contentKind: g?.[0] ?? e.card.kind,
190
+ open: k && !a,
190
191
  preview: e.card,
191
- cardProps: a,
192
+ cardProps: s,
192
193
  kind: "premium",
193
- label: c?.premium?.(V) ?? p.plural("releases.premiumMore", V),
194
+ label: u?.premium?.(V) ?? E.plural("releases.premiumMore", V),
194
195
  onClick: X
195
- }, e.key) : /* @__PURE__ */ C(F, {
196
+ }, e.key) : /* @__PURE__ */ x(A, {
196
197
  card: e.card,
197
- open: v && !i,
198
+ open: k && !a,
198
199
  position: e.position,
199
200
  exposure: G,
200
- cardProps: a
201
- }, e.key)), e.filtered_count > 0 && /* @__PURE__ */ C(P, {
201
+ cardProps: s
202
+ }, e.key)), t.filtered_count > 0 && /* @__PURE__ */ x(p, {
202
203
  tileKey: "filtered-summary",
203
204
  contentKind: H,
204
- open: v && !i,
205
- cardProps: a,
205
+ open: k && !a,
206
+ cardProps: s,
206
207
  kind: "filtered",
207
- label: c?.filtered?.(e.filtered_count) ?? p.plural("releases.filteredMore", e.filtered_count),
208
+ label: u?.filtered?.(t.filtered_count) ?? E.plural("releases.filteredMore", t.filtered_count),
208
209
  onClick: (e) => {
209
210
  R.current = e.currentTarget, L(!0);
210
211
  }
211
212
  })]
212
- }), O < e.contents.length && /* @__PURE__ */ C("div", {
213
+ }), M < t.contents.length && /* @__PURE__ */ x("div", {
213
214
  className: "flex justify-center pt-5 pb-1",
214
- children: /* @__PURE__ */ C(s, {
215
+ children: /* @__PURE__ */ x(i, {
215
216
  type: "button",
216
217
  variant: "outline",
217
- onClick: (t) => {
218
- q.prepare(t.detail === 0), A((t) => Math.min(t + r, e.contents.length));
218
+ onClick: (e) => {
219
+ q.prepare(e.detail === 0), N((e) => Math.min(e + r, t.contents.length));
219
220
  },
220
- children: p.t("contents.showMore")
221
+ children: E.t("contents.showMore")
221
222
  })
222
223
  })]
223
224
  })
224
225
  }),
225
- /* @__PURE__ */ C(h, {
226
- returnFocus: () => !i && R.current?.isConnected ? R.current : z.current,
226
+ /* @__PURE__ */ x(d, {
227
+ returnFocus: () => !a && R.current?.isConnected ? R.current : z.current,
227
228
  open: I,
228
229
  onOpenChange: L,
229
- client: a.client,
230
- kinds: d,
231
- language: u,
232
- counts: e.filtered_entities ?? [],
233
- description: p.t("releases.filterContext", { date: J }),
234
- appearance: a.appearance
230
+ client: s.client,
231
+ kinds: g,
232
+ language: h,
233
+ counts: t.filtered_entities ?? [],
234
+ description: E.t("releases.filterContext", { date: J }),
235
+ appearance: s.appearance
235
236
  })
236
237
  ]
237
238
  });
238
239
  }
239
- function P({ tileKey: r, kind: i, contentKind: a, preview: l, open: u, label: d, onClick: f, cardProps: p }) {
240
- let { t: m } = n(), [h, g] = c({
241
- margin: "0px",
242
- leaveMargin: "1200px 0px"
243
- }), { presets: _ } = o({ client: p.client }), v = p.aspectRatio ?? t(_.find((e) => e.kind === a && e.name === "cover")?.aspect) ?? (p.shape === "landscape" ? "16 / 9" : "3 / 4");
244
- return /* @__PURE__ */ w("li", {
245
- ref: h,
246
- "data-release-key": r,
247
- children: [/* @__PURE__ */ w(s, {
248
- type: "button",
249
- variant: "outline",
250
- "data-ckui": `${i}-release-tile`,
251
- "aria-label": d,
252
- "aria-expanded": i !== "premium" && void 0,
253
- "aria-haspopup": i === "filtered" ? "dialog" : void 0,
254
- className: "relative flex h-auto w-full flex-col justify-center overflow-hidden rounded-lg p-0 text-center whitespace-normal",
255
- style: { aspectRatio: v },
256
- onClick: f,
257
- children: [l && u && g && /* @__PURE__ */ C(e, {
258
- outputs: l.cover,
259
- alt: "",
260
- fit: "cover",
261
- loading: "lazy",
262
- className: "absolute inset-0 size-full opacity-20"
263
- }), /* @__PURE__ */ w("span", {
264
- className: "relative grid justify-items-center gap-3 p-4",
265
- children: [
266
- /* @__PURE__ */ C(k, {
267
- icon: i === "premium" ? D : O,
268
- strokeWidth: 2,
269
- className: "size-8",
270
- "aria-hidden": !0
271
- }),
272
- /* @__PURE__ */ C("span", {
273
- className: "text-xl font-semibold",
274
- children: d
275
- }),
276
- /* @__PURE__ */ C("span", {
277
- className: "text-sm text-muted-foreground",
278
- children: m(i === "premium" ? "releases.premiumHint" : "releases.manageFilters")
279
- })
280
- ]
281
- })]
282
- }), l && /* @__PURE__ */ C("p", {
283
- className: "mt-2 line-clamp-2 text-lg leading-snug text-muted-foreground",
284
- children: l.title
285
- })]
286
- });
287
- }
288
- function F({ card: e, open: t, position: n, exposure: r, cardProps: i }) {
289
- let [a, o] = c({
240
+ function A({ card: e, open: t, position: n, exposure: r, cardProps: i }) {
241
+ let [o, s] = a({
290
242
  margin: "0px",
291
243
  leaveMargin: "1200px 0px"
292
- }), s = b(() => r.track(e.id, n), [
244
+ }), c = v(() => r.track(e.id, n), [
293
245
  r,
294
246
  e.id,
295
247
  n
296
- ]), l = _((e) => {
297
- a(e), s(e);
298
- }, [a, s]);
299
- return /* @__PURE__ */ C("li", {
248
+ ]), l = h((e) => {
249
+ o(e), c(e);
250
+ }, [o, c]);
251
+ return /* @__PURE__ */ x("li", {
300
252
  ref: l,
301
253
  "data-release-key": e.id,
302
- children: /* @__PURE__ */ C(p, {
254
+ children: /* @__PURE__ */ x(u, {
303
255
  card: e,
304
256
  client: i.client,
305
257
  href: i.href,
306
258
  shape: i.shape,
307
259
  aspectRatio: i.aspectRatio,
308
260
  titlePosition: i.titlePosition,
309
- loadMedia: t && o,
261
+ loadMedia: t && s,
310
262
  groupKinds: i.groupKinds,
311
263
  chips: i.chips,
312
264
  filterEntity: i.filterEntity,
@@ -324,6 +276,6 @@ function F({ card: e, open: t, position: n, exposure: r, cardProps: i }) {
324
276
  });
325
277
  }
326
278
  //#endregion
327
- export { j as DailyReleases };
279
+ export { D as DailyReleases };
328
280
 
329
281
  //# sourceMappingURL=daily-releases.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"daily-releases.js","names":[],"sources":["../../../src/components/content/daily-releases.tsx"],"sourcesContent":["import { ArrowDown01Icon, LockIcon, Settings01Icon } from \"@hugeicons/core-free-icons\";\nimport { HugeiconsIcon } from \"@hugeicons/react\";\nimport { cn } from \"cn\";\nimport { useCallback, useContext, useId, useMemo, useState, useRef, type CSSProperties, type MouseEvent } from \"react\";\nimport type { DailyReleasesQuery } from \"../../client/discovery.js\";\nimport type { Card, ReleaseDay } from \"../../client/generated/wire.js\";\nimport { useMessages } from \"../../i18n/context.js\";\nimport { useDailyReleases, useExposure } from \"../../react/discovery.js\";\nimport { ContentKitContext } from \"../../react/context.js\";\nimport { useContentScope } from \"../../react/use-resource.js\";\nimport { usePresets } from \"../../react/public.js\";\nimport { ratio } from \"../../client/aspect.js\";\nimport { RenditionImg } from \"../rendition-img.js\";\nimport { useNearViewport } from \"../../react/viewport.js\";\nimport { ContentKitUiRoot } from \"../../scope.js\";\nimport { Button } from \"#ckui/ui/button\";\nimport { Skeleton } from \"#ckui/ui/skeleton\";\nimport { contentError } from \"../social/parts.js\";\nimport { ContentFilterDialog } from \"./filter-dialog.js\";\nimport { useReleaseReveal } from \"./release-reveal.js\";\nimport { ContentCard } from \"./card.js\";\nimport { cardGridLayout, type CardListProps } from \"./grid.js\";\n\nexport interface DailyReleasesProps extends Omit<CardListProps, \"infinite\" | \"pageSize\" | \"renderCard\" | \"loadMedia\"> {\n /** One complete calendar window. Defaults to 10 days in the browser's time zone. */\n query?: DailyReleasesQuery;\n /** Cards initially revealed across the whole window, allocated newest first. Default 30. */\n initialVisible?: number;\n /** Collapse locked tier previews per day; expansion never grants access. Default false. */\n collapsePremium?: boolean;\n /** Host-specific nouns; defaults use localized generic item labels. */\n summaryLabels?: { premium?: (count: number) => string; filtered?: (count: number) => string };\n /** Additional cached cards revealed by a day's Show more button. Default 30. */\n revealStep?: number;\n}\n\nconst count = (value: number, fallback: number) => Number.isFinite(value) ? Math.max(0, Math.floor(value)) : fallback;\n\n/**\n * One metadata request for a calendar window, with no requests when a day is\n * opened or expanded. Only revealed, visible cards mount images and previews.\n */\nexport function DailyReleases({ query, initialVisible = 30, revealStep = 30, collapsePremium = false, summaryLabels, ...p }: DailyReleasesProps) {\n const m = useMessages();\n const { client, viewer } = useContentScope(p.client);\n const context = useContext(ContentKitContext);\n const request = useMemo(() => ({ days: 10, time_zone: Intl.DateTimeFormat().resolvedOptions().timeZone, ...query }), [query]);\n const releases = useDailyReleases(request, { client: p.client });\n const layout = cardGridLayout(p.grid);\n const requestKey = JSON.stringify(request);\n // Guest preference changes create a fresh read scope. Keep the open day/dialog\n // while it loads, but never show the old cards or carry data across accounts.\n const identity = useMemo(() => ({ client, viewer, language: context?.language, accessRevision: context?.accessRevision, requestKey }), [client, viewer, context?.language, context?.accessRevision, requestKey]);\n const [previous, setPrevious] = useState({ identity, data: releases.data, revision: 0 });\n if (previous.identity !== identity || (releases.data && previous.data !== releases.data)) setPrevious({ identity, data: releases.data, revision: previous.revision + (previous.identity === identity ? 0 : 1) });\n const data = releases.data ?? (previous.identity === identity ? previous.data : undefined);\n const pending = !releases.data && Boolean(data);\n const days = useMemo(() => data?.days.filter((day) => (day.contents.length || day.filtered_count > 0)).sort((a, b) => b.date.localeCompare(a.date)) ?? [], [data]);\n let remaining = count(initialVisible, 30);\n return (\n <ContentKitUiRoot key={previous.revision} appearance={p.appearance} className={cn(\"grid gap-6 text-sm\", p.className)} data-ckui=\"daily-releases\" aria-busy={releases.loading}>\n {data && releases.error && <div role=\"alert\" className=\"grid justify-items-start gap-2\"><p className=\"text-destructive\">{contentError(m, releases.error)}</p><Button type=\"button\" variant=\"outline\" onClick={releases.reload}>{m.t(\"common.retry\")}</Button></div>}\n {releases.loading && !data ? <div className={layout.className} style={layout.style}>{Array.from({ length: 6 }, (_, i) => <Skeleton key={i} className={p.aspectRatio === undefined ? p.shape === \"landscape\" ? \"aspect-video\" : \"aspect-[3/4]\" : undefined} style={p.aspectRatio === undefined ? undefined : { aspectRatio: p.aspectRatio }} />)}</div> : releases.error && !data ? (\n <div role=\"alert\" className=\"grid justify-items-start gap-2\">\n <p className=\"text-destructive\">{contentError(m, releases.error)}</p>\n <Button size=\"sm\" variant=\"outline\" onClick={releases.reload}>{m.t(\"common.retry\")}</Button>\n </div>\n ) : !days.length ? <p role=\"status\" className=\"text-muted-foreground\">{p.empty ?? m.t(\"contents.empty\")}</p> : days.map((day) => {\n const initial = Math.min(remaining, day.contents.length);\n remaining -= initial;\n return <ReleaseDaySection key={JSON.stringify([requestKey, data?.from_date, day.date])} day={day} pending={pending} collapsePremium={collapsePremium} summaryLabels={summaryLabels} language={request.display_language ?? request.language} kinds={request.kind ? [request.kind] : undefined} initial={initial} step={Math.max(1, count(revealStep, 30))} cardProps={p} />;\n })}\n </ContentKitUiRoot>\n );\n}\n\ntype ReleaseCardProps = Omit<DailyReleasesProps, \"query\" | \"initialVisible\" | \"revealStep\" | \"collapsePremium\" | \"summaryLabels\">;\nconst lockedPremium = (card: Card) => !card.access.allowed && card.access.level === \"tier\";\n\nfunction ReleaseDaySection({ day, initial, step, pending, cardProps: p, collapsePremium, summaryLabels, language, kinds }: {\n day: ReleaseDay; initial: number; step: number; pending: boolean; cardProps: ReleaseCardProps;\n collapsePremium: boolean; summaryLabels?: DailyReleasesProps[\"summaryLabels\"]; language?: string; kinds?: string[];\n}) {\n const m = useMessages();\n const id = useId();\n const [open, setOpen] = useState(initial > 0 || (!day.contents.length && day.filtered_count > 0));\n const [visible, setVisible] = useState(initial);\n const [premiumExpanded, setPremiumExpanded] = useState(false);\n const [filtersOpen, setFiltersOpen] = useState(false);\n const filterTrigger = useRef<HTMLElement | null>(null);\n const dayHeading = useRef<HTMLButtonElement>(null);\n const cards = useMemo(() => day.contents.slice(0, visible), [day.contents, visible]);\n const premiumCount = useMemo(() => day.contents.filter(lockedPremium).length, [day.contents]);\n const summaryContentKind = kinds?.[0];\n const entries = useMemo(() => {\n let inserted = false;\n return cards.flatMap((card, i): { key: string; card: Card; summary: boolean; position: number }[] => {\n if (!collapsePremium || premiumExpanded || !lockedPremium(card)) return [{ key: card.id, card, summary: false, position: i + 1 }];\n if (inserted) return [];\n inserted = true;\n return [{ key: \"premium-summary\", card, summary: true, position: i + 1 }];\n });\n }, [cards, collapsePremium, premiumExpanded]);\n const exposed = useMemo(() => open && !pending ? entries.filter((entry) => !entry.summary).map((entry) => entry.card) : [], [open, pending, entries]);\n const exposure = useExposure(exposed, { surface: p.surface ?? \"releases\", render: day.date, client: p.client });\n const layout = cardGridLayout(p.grid);\n const reveal = useReleaseReveal(`${visible}|${entries.map((entry) => entry.key).join(\"\\0\")}`);\n const label = new Intl.DateTimeFormat(m.language, { dateStyle: \"full\", timeZone: \"UTC\" }).format(new Date(`${day.date}T12:00:00Z`));\n const toggle = () => {\n if (!open && !visible) setVisible(Math.min(step, day.contents.length));\n setOpen(!open);\n };\n const expandPremium = (event: MouseEvent<HTMLButtonElement>) => {\n reveal.prepare(event.detail === 0);\n setPremiumExpanded(true);\n };\n return (\n <section data-ckui=\"release-day\" data-date={day.date}>\n <h2>\n <Button ref={dayHeading} id={`${id}-heading`} type=\"button\" variant=\"ghost\" className=\"h-auto w-full justify-start gap-3 px-0 py-3 text-start text-lg font-semibold\" aria-expanded={open} aria-controls={`${id}-contents`} onClick={toggle}>\n <HugeiconsIcon icon={ArrowDown01Icon} strokeWidth={2} className={cn(\"size-5 shrink-0 transition-transform duration-200 motion-reduce:transition-none\", !open && \"-rotate-90\")} aria-hidden />\n <time dateTime={day.date}>{label}</time>\n </Button>\n </h2>\n {open && pending && <Skeleton className=\"h-24 w-full\" />}\n <div hidden={pending} style={pending ? { display: \"none\" } : undefined} id={`${id}-contents`} role=\"region\" aria-labelledby={`${id}-heading`} aria-hidden={!open || pending} inert={!open || pending} className={cn(\"grid transition-[grid-template-rows,opacity] duration-250 ease-out motion-reduce:transition-none\", open ? \"grid-rows-[1fr] opacity-100\" : \"grid-rows-[0fr] opacity-0\")}>\n <div className=\"min-h-0 overflow-hidden\">\n <ol ref={reveal.grid} className={cn(layout.className, \"pt-2\")} style={layout.style}>\n {entries.map((entry) => entry.summary ?\n <ReleaseSummaryTile key={entry.key} tileKey={entry.key} contentKind={kinds?.[0] ?? entry.card.kind} open={open && !pending} preview={entry.card} cardProps={p} kind=\"premium\" label={summaryLabels?.premium?.(premiumCount) ?? m.plural(\"releases.premiumMore\", premiumCount)} onClick={expandPremium} /> :\n <ReleaseCard key={entry.key} card={entry.card} open={open && !pending} position={entry.position} exposure={exposure} cardProps={p} />)}\n {day.filtered_count > 0 && <ReleaseSummaryTile tileKey=\"filtered-summary\" contentKind={summaryContentKind} open={open && !pending} cardProps={p} kind=\"filtered\" label={summaryLabels?.filtered?.(day.filtered_count) ?? m.plural(\"releases.filteredMore\", day.filtered_count)} onClick={(event) => { filterTrigger.current = event.currentTarget; setFiltersOpen(true); }} />}\n </ol>\n {visible < day.contents.length && <div className=\"flex justify-center pt-5 pb-1\"><Button type=\"button\" variant=\"outline\" onClick={(event) => { reveal.prepare(event.detail === 0); setVisible((n) => Math.min(n + step, day.contents.length)); }}>{m.t(\"contents.showMore\")}</Button></div>}\n </div>\n </div>\n <ContentFilterDialog returnFocus={() => !pending && filterTrigger.current?.isConnected ? filterTrigger.current : dayHeading.current} open={filtersOpen} onOpenChange={setFiltersOpen} client={p.client} kinds={kinds} language={language} counts={day.filtered_entities ?? []} description={m.t(\"releases.filterContext\", { date: label })} appearance={p.appearance} />\n </section>\n );\n}\n\nfunction ReleaseSummaryTile({ tileKey, kind, contentKind, preview, open, label, onClick, cardProps: p }: {\n tileKey: string; kind: \"premium\" | \"filtered\"; contentKind?: string; preview?: Card; open: boolean; label: string; onClick: (event: MouseEvent<HTMLButtonElement>) => void; cardProps: ReleaseCardProps;\n}) {\n const { t } = useMessages();\n const [ref, near] = useNearViewport({ margin: \"0px\", leaveMargin: \"1200px 0px\" });\n const { presets } = usePresets({ client: p.client });\n const aspect: CSSProperties[\"aspectRatio\"] = p.aspectRatio ?? ratio(presets.find((preset) => preset.kind === contentKind && preset.name === \"cover\")?.aspect) ?? (p.shape === \"landscape\" ? \"16 / 9\" : \"3 / 4\");\n return <li ref={ref} data-release-key={tileKey}>\n <Button type=\"button\" variant=\"outline\" data-ckui={`${kind}-release-tile`} aria-label={label} aria-expanded={kind === \"premium\" ? false : undefined} aria-haspopup={kind === \"filtered\" ? \"dialog\" : undefined} className=\"relative flex h-auto w-full flex-col justify-center overflow-hidden rounded-lg p-0 text-center whitespace-normal\" style={{ aspectRatio: aspect }} onClick={onClick}>\n {preview && open && near && <RenditionImg outputs={preview.cover} alt=\"\" fit=\"cover\" loading=\"lazy\" className=\"absolute inset-0 size-full opacity-20\" />}\n <span className=\"relative grid justify-items-center gap-3 p-4\">\n <HugeiconsIcon icon={kind === \"premium\" ? LockIcon : Settings01Icon} strokeWidth={2} className=\"size-8\" aria-hidden />\n <span className=\"text-xl font-semibold\">{label}</span>\n <span className=\"text-sm text-muted-foreground\">{t(kind === \"premium\" ? \"releases.premiumHint\" : \"releases.manageFilters\")}</span>\n </span>\n </Button>\n {preview && <p className=\"mt-2 line-clamp-2 text-lg leading-snug text-muted-foreground\">{preview.title}</p>}\n </li>;\n}\n\nfunction ReleaseCard({ card, open, position, exposure, cardProps: p }: { card: Card; open: boolean; position: number; exposure: ReturnType<typeof useExposure>; cardProps: ReleaseCardProps }) {\n const [viewport, visible] = useNearViewport({ margin: \"0px\", leaveMargin: \"1200px 0px\" });\n const tracked = useMemo(() => exposure.track(card.id, position), [exposure, card.id, position]);\n const ref = useCallback((element: HTMLLIElement | null) => { viewport(element); tracked(element); }, [viewport, tracked]);\n return <li ref={ref} data-release-key={card.id}>\n <ContentCard card={card} client={p.client} href={p.href} shape={p.shape} aspectRatio={p.aspectRatio} titlePosition={p.titlePosition} loadMedia={open && visible} groupKinds={p.groupKinds} chips={p.chips} filterEntity={p.filterEntity} entityStyle={p.entityStyle} entityLayout={p.entityLayout} metadata={p.metadata} showCounts={p.showCounts} tiers={p.tiers} labels={p.labels} owner={p.owner} ownerHref={p.ownerHref} decorate={p.decorate} onOpen={() => exposure.click(card.id, position)} />\n </li>;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAoCA,IAAM,KAAS,GAAe,MAAqB,OAAO,SAAS,CAAK,IAAI,KAAK,IAAI,GAAG,KAAK,MAAM,CAAK,CAAC,IAAI;AAM7G,SAAgB,EAAc,EAAE,UAAO,oBAAiB,IAAI,gBAAa,IAAI,qBAAkB,IAAO,kBAAe,GAAG,KAAyB;CAC/I,IAAM,IAAI,EAAY,GAChB,EAAE,WAAQ,cAAW,EAAgB,EAAE,MAAM,GAC7C,IAAU,EAAW,CAAiB,GACtC,IAAU,SAAe;EAAE,MAAM;EAAI,WAAW,KAAK,eAAe,CAAC,CAAC,gBAAgB,CAAC,CAAC;EAAU,GAAG;CAAM,IAAI,CAAC,CAAK,CAAC,GACtH,IAAW,EAAiB,GAAS,EAAE,QAAQ,EAAE,OAAO,CAAC,GACzD,IAAS,EAAe,EAAE,IAAI,GAC9B,IAAa,KAAK,UAAU,CAAO,GAGnC,IAAW,SAAe;EAAE;EAAQ;EAAQ,UAAU,GAAS;EAAU,gBAAgB,GAAS;EAAgB;CAAW,IAAI;EAAC;EAAQ;EAAQ,GAAS;EAAU,GAAS;EAAgB;CAAU,CAAC,GACzM,CAAC,GAAU,KAAe,EAAS;EAAE;EAAU,MAAM,EAAS;EAAM,UAAU;CAAE,CAAC;CACvF,CAAI,EAAS,aAAa,KAAa,EAAS,QAAQ,EAAS,SAAS,EAAS,SAAO,EAAY;EAAE;EAAU,MAAM,EAAS;EAAM,UAAU,EAAS,YAAY,EAAS,aAAa,IAAW,IAAI;CAAG,CAAC;CAC/M,IAAM,IAAO,EAAS,SAAS,EAAS,aAAa,IAAW,EAAS,OAAO,KAAA,IAC1E,IAAU,CAAC,EAAS,QAAQ,EAAQ,GACpC,IAAO,QAAc,GAAM,KAAK,QAAQ,MAAS,EAAI,SAAS,UAAU,EAAI,iBAAiB,CAAE,CAAC,CAAC,MAAM,GAAG,MAAM,EAAE,KAAK,cAAc,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAI,CAAC,GAC7J,IAAY,EAAM,GAAgB,EAAE;CACxC,OACE,kBAAC,GAAD;EAA0C,YAAY,EAAE;EAAY,WAAW,EAAG,sBAAsB,EAAE,SAAS;EAAG,aAAU;EAAiB,aAAW,EAAS;EAArK,UAAA,CACG,KAAQ,EAAS,SAAS,kBAAC,OAAD;GAAK,MAAK;GAAQ,WAAU;GAA5B,UAAA,CAA6D,kBAAC,KAAD;IAAG,WAAU;IAAoB,UAAA,EAAa,GAAG,EAAS,KAAK;GAAK,CAAA,GAAC,kBAAC,GAAD;IAAQ,MAAK;IAAS,SAAQ;IAAU,SAAS,EAAS;IAAS,UAAA,EAAE,EAAE,cAAc;GAAU,CAAA,CAAM;EACjQ,CAAA,GAAA,EAAS,WAAW,CAAC,IAAO,kBAAC,OAAD;GAAK,WAAW,EAAO;GAAW,OAAO,EAAO;GAAQ,UAAA,MAAM,KAAK,EAAE,QAAQ,EAAE,IAAI,GAAG,MAAM,kBAAC,GAAD;IAAkB,WAAW,EAAE,gBAAgB,KAAA,IAAY,EAAE,UAAU,cAAc,iBAAiB,iBAAiB,KAAA;IAAW,OAAO,EAAE,gBAAgB,KAAA,IAAY,KAAA,IAAY,EAAE,aAAa,EAAE,YAAY;GAAI,GAArM,CAAqM,CAAC;EAAO,CAAA,IAAI,EAAS,SAAS,CAAC,IAC1W,kBAAC,OAAD;GAAK,MAAK;GAAQ,WAAU;GAA5B,UAAA,CACE,kBAAC,KAAD;IAAG,WAAU;IAAoB,UAAA,EAAa,GAAG,EAAS,KAAK;GAAK,CAAA,GACpE,kBAAC,GAAD;IAAQ,MAAK;IAAK,SAAQ;IAAU,SAAS,EAAS;IAAS,UAAA,EAAE,EAAE,cAAc;GAAU,CAAA,CACxF;EACH,CAAA,IAAC,EAAK,SAAqG,EAAK,KAAK,MAAQ;GAC/H,IAAM,IAAU,KAAK,IAAI,GAAW,EAAI,SAAS,MAAM;GAEvD,OADA,KAAa,GACN,kBAAC,GAAD;IAAsF;IAAc;IAA0B;IAAgC;IAAe,UAAU,EAAQ,oBAAoB,EAAQ;IAAU,OAAO,EAAQ,OAAO,CAAC,EAAQ,IAAI,IAAI,KAAA;IAAoB;IAAS,MAAM,KAAK,IAAI,GAAG,EAAM,GAAY,EAAE,CAAC;IAAG,WAAW;GAAI,GAA1U,KAAK,UAAU;IAAC;IAAY,GAAM;IAAW,EAAI;GAAI,CAAC,CAAoR;EAC3W,CAAC,IAJkB,kBAAC,KAAD;GAAG,MAAK;GAAS,WAAU;GAAyB,UAAA,EAAE,SAAS,EAAE,EAAE,gBAAgB;EAAK,CAAA,CAK3F;CAZK,GAAA,EAAS,QAYd;AAEtB;AAGA,IAAM,KAAiB,MAAe,CAAC,EAAK,OAAO,WAAW,EAAK,OAAO,UAAU;AAEpF,SAAS,EAAkB,EAAE,QAAK,YAAS,SAAM,YAAS,WAAW,GAAG,oBAAiB,kBAAe,aAAU,YAG/G;CACD,IAAM,IAAI,EAAY,GAChB,IAAK,EAAM,GACX,CAAC,GAAM,KAAW,EAAS,IAAU,KAAM,CAAC,EAAI,SAAS,UAAU,EAAI,iBAAiB,CAAE,GAC1F,CAAC,GAAS,KAAc,EAAS,CAAO,GACxC,CAAC,GAAiB,KAAsB,EAAS,EAAK,GACtD,CAAC,GAAa,KAAkB,EAAS,EAAK,GAC9C,IAAgB,EAA2B,IAAI,GAC/C,IAAa,EAA0B,IAAI,GAC3C,IAAQ,QAAc,EAAI,SAAS,MAAM,GAAG,CAAO,GAAG,CAAC,EAAI,UAAU,CAAO,CAAC,GAC7E,IAAe,QAAc,EAAI,SAAS,OAAO,CAAa,CAAC,CAAC,QAAQ,CAAC,EAAI,QAAQ,CAAC,GACtF,IAAqB,IAAQ,IAC7B,IAAU,QAAc;EAC5B,IAAI,IAAW;EACf,OAAO,EAAM,SAAS,GAAM,MACtB,CAAC,KAAmB,KAAmB,CAAC,EAAc,CAAI,IAAU,CAAC;GAAE,KAAK,EAAK;GAAI;GAAM,SAAS;GAAO,UAAU,IAAI;EAAE,CAAC,IAC5H,IAAiB,CAAC,KACtB,IAAW,IACJ,CAAC;GAAE,KAAK;GAAmB;GAAM,SAAS;GAAM,UAAU,IAAI;EAAE,CAAC,EACzE;CACH,GAAG;EAAC;EAAO;EAAiB;CAAe,CAAC,GACtC,IAAU,QAAc,KAAQ,CAAC,IAAU,EAAQ,QAAQ,MAAU,CAAC,EAAM,OAAO,CAAC,CAAC,KAAK,MAAU,EAAM,IAAI,IAAI,CAAC,GAAG;EAAC;EAAM;EAAS;CAAO,CAAC,GAC9I,IAAW,EAAY,GAAS;EAAE,SAAS,EAAE,WAAW;EAAY,QAAQ,EAAI;EAAM,QAAQ,EAAE;CAAO,CAAC,GACxG,IAAS,EAAe,EAAE,IAAI,GAC9B,IAAS,EAAiB,GAAG,EAAQ,GAAG,EAAQ,KAAK,MAAU,EAAM,GAAG,CAAC,CAAC,KAAK,IAAI,GAAG,GACtF,IAAQ,IAAI,KAAK,eAAe,EAAE,UAAU;EAAE,WAAW;EAAQ,UAAU;CAAM,CAAC,CAAC,CAAC,uBAAO,IAAI,KAAK,GAAG,EAAI,KAAK,WAAW,CAAC,GAC5H,UAAe;EAEnB,AADI,CAAC,KAAQ,CAAC,KAAS,EAAW,KAAK,IAAI,GAAM,EAAI,SAAS,MAAM,CAAC,GACrE,EAAQ,CAAC,CAAI;CACf,GACM,KAAiB,MAAyC;EAE9D,AADA,EAAO,QAAQ,EAAM,WAAW,CAAC,GACjC,EAAmB,EAAI;CACzB;CACA,OACE,kBAAC,WAAD;EAAS,aAAU;EAAc,aAAW,EAAI;EAAhD,UAAA;GACE,kBAAC,MAAD,EAAA,UACE,kBAAC,GAAD;IAAQ,KAAK;IAAY,IAAI,GAAG,EAAG;IAAW,MAAK;IAAS,SAAQ;IAAQ,WAAU;IAA+E,iBAAe;IAAM,iBAAe,GAAG,EAAG;IAAY,SAAS;IAApO,UAAA,CACE,kBAAC,GAAD;KAAe,MAAM;KAAiB,aAAa;KAAG,WAAW,EAAG,mFAAmF,CAAC,KAAQ,YAAY;KAAG,eAAA;IAAa,CAAA,GAC5L,kBAAC,QAAD;KAAM,UAAU,EAAI;KAAO,UAAA;IAAY,CAAA,CACjC;GACN,CAAA,EAAA,CAAA;GACH,KAAQ,KAAW,kBAAC,GAAD,EAAU,WAAU,cAAe,CAAA;GACvD,kBAAC,OAAD;IAAK,QAAQ;IAAS,OAAO,IAAU,EAAE,SAAS,OAAO,IAAI,KAAA;IAAW,IAAI,GAAG,EAAG;IAAY,MAAK;IAAS,mBAAiB,GAAG,EAAG;IAAW,eAAa,CAAC,KAAQ;IAAS,OAAO,CAAC,KAAQ;IAAS,WAAW,EAAG,oGAAoG,IAAO,gCAAgC,2BAA2B;IACxX,UAAA,kBAAC,OAAD;KAAK,WAAU;KAAf,UAAA,CACE,kBAAC,MAAD;MAAI,KAAK,EAAO;MAAM,WAAW,EAAG,EAAO,WAAW,MAAM;MAAG,OAAO,EAAO;MAA7E,UAAA,CACG,EAAQ,KAAK,MAAU,EAAM,UAC5B,kBAAC,GAAD;OAAoC,SAAS,EAAM;OAAK,aAAa,IAAQ,MAAM,EAAM,KAAK;OAAM,MAAM,KAAQ,CAAC;OAAS,SAAS,EAAM;OAAM,WAAW;OAAG,MAAK;OAAU,OAAO,GAAe,UAAU,CAAY,KAAK,EAAE,OAAO,wBAAwB,CAAY;OAAG,SAAS;MAAgB,GAA/Q,EAAM,GAAyQ,IACxS,kBAAC,GAAD;OAA6B,MAAM,EAAM;OAAM,MAAM,KAAQ,CAAC;OAAS,UAAU,EAAM;OAAoB;OAAU,WAAW;MAAI,GAAlH,EAAM,GAA4G,CAAC,GACtI,EAAI,iBAAiB,KAAK,kBAAC,GAAD;OAAoB,SAAQ;OAAmB,aAAa;OAAoB,MAAM,KAAQ,CAAC;OAAS,WAAW;OAAG,MAAK;OAAW,OAAO,GAAe,WAAW,EAAI,cAAc,KAAK,EAAE,OAAO,yBAAyB,EAAI,cAAc;OAAG,UAAU,MAAU;QAA+C,AAA7C,EAAc,UAAU,EAAM,eAAe,EAAe,EAAI;OAAG;MAAI,CAAA,CAC3W;KACH,CAAA,GAAA,IAAU,EAAI,SAAS,UAAU,kBAAC,OAAD;MAAK,WAAU;MAAgC,UAAA,kBAAC,GAAD;OAAQ,MAAK;OAAS,SAAQ;OAAU,UAAU,MAAU;QAAsC,AAApC,EAAO,QAAQ,EAAM,WAAW,CAAC,GAAG,GAAY,MAAM,KAAK,IAAI,IAAI,GAAM,EAAI,SAAS,MAAM,CAAC;OAAG;OAAI,UAAA,EAAE,EAAE,mBAAmB;MAAU,CAAA;KAAM,CAAA,CACvR;;GACF,CAAA;GACL,kBAAC,GAAD;IAAqB,mBAAmB,CAAC,KAAW,EAAc,SAAS,cAAc,EAAc,UAAU,EAAW;IAAS,MAAM;IAAa,cAAc;IAAgB,QAAQ,EAAE;IAAe;IAAiB;IAAU,QAAQ,EAAI,qBAAqB,CAAC;IAAG,aAAa,EAAE,EAAE,0BAA0B,EAAE,MAAM,EAAM,CAAC;IAAG,YAAY,EAAE;GAAa,CAAA;EAChW;;AAEb;AAEA,SAAS,EAAmB,EAAE,YAAS,SAAM,gBAAa,YAAS,SAAM,UAAO,YAAS,WAAW,KAEjG;CACD,IAAM,EAAE,SAAM,EAAY,GACpB,CAAC,GAAK,KAAQ,EAAgB;EAAE,QAAQ;EAAO,aAAa;CAAa,CAAC,GAC1E,EAAE,eAAY,EAAW,EAAE,QAAQ,EAAE,OAAO,CAAC,GAC7C,IAAuC,EAAE,eAAe,EAAM,EAAQ,MAAM,MAAW,EAAO,SAAS,KAAe,EAAO,SAAS,OAAO,CAAC,EAAE,MAAM,MAAM,EAAE,UAAU,cAAc,WAAW;CACvM,OAAO,kBAAC,MAAD;EAAS;EAAK,oBAAkB;EAAhC,UAAA,CACL,kBAAC,GAAD;GAAQ,MAAK;GAAS,SAAQ;GAAU,aAAW,GAAG,EAAK;GAAgB,cAAY;GAAO,iBAAe,MAAS,aAAoB,KAAA;GAAW,iBAAe,MAAS,aAAa,WAAW,KAAA;GAAW,WAAU;GAAmH,OAAO,EAAE,aAAa,EAAO;GAAY;GAAtX,UAAA,CACG,KAAW,KAAQ,KAAQ,kBAAC,GAAD;IAAc,SAAS,EAAQ;IAAO,KAAI;IAAG,KAAI;IAAQ,SAAQ;IAAO,WAAU;GAAyC,CAAA,GACvJ,kBAAC,QAAD;IAAM,WAAU;IAAhB,UAAA;KACE,kBAAC,GAAD;MAAe,MAAM,MAAS,YAAY,IAAW;MAAgB,aAAa;MAAG,WAAU;MAAS,eAAA;KAAa,CAAA;KACrH,kBAAC,QAAD;MAAM,WAAU;MAAyB,UAAA;KAAY,CAAA;KACrD,kBAAC,QAAD;MAAM,WAAU;MAAiC,UAAA,EAAE,MAAS,YAAY,yBAAyB,wBAAwB;KAAQ,CAAA;IAC7H;GACA,CAAA,CAAA;EACP,CAAA,GAAA,KAAW,kBAAC,KAAD;GAAG,WAAU;GAAgE,UAAA,EAAQ;EAAS,CAAA,CACxG;;AACN;AAEA,SAAS,EAAY,EAAE,SAAM,SAAM,aAAU,aAAU,WAAW,KAA6H;CAC7L,IAAM,CAAC,GAAU,KAAW,EAAgB;EAAE,QAAQ;EAAO,aAAa;CAAa,CAAC,GAClF,IAAU,QAAc,EAAS,MAAM,EAAK,IAAI,CAAQ,GAAG;EAAC;EAAU,EAAK;EAAI;CAAQ,CAAC,GACxF,IAAM,GAAa,MAAkC;EAAqB,AAAnB,EAAS,CAAO,GAAG,EAAQ,CAAO;CAAG,GAAG,CAAC,GAAU,CAAO,CAAC;CACxH,OAAO,kBAAC,MAAD;EAAS;EAAK,oBAAkB,EAAK;EAC1C,UAAA,kBAAC,GAAD;GAAmB;GAAM,QAAQ,EAAE;GAAQ,MAAM,EAAE;GAAM,OAAO,EAAE;GAAO,aAAa,EAAE;GAAa,eAAe,EAAE;GAAe,WAAW,KAAQ;GAAS,YAAY,EAAE;GAAY,OAAO,EAAE;GAAO,cAAc,EAAE;GAAc,aAAa,EAAE;GAAa,cAAc,EAAE;GAAc,UAAU,EAAE;GAAU,YAAY,EAAE;GAAY,OAAO,EAAE;GAAO,QAAQ,EAAE;GAAQ,OAAO,EAAE;GAAO,WAAW,EAAE;GAAW,UAAU,EAAE;GAAU,cAAc,EAAS,MAAM,EAAK,IAAI,CAAQ;EAAI,CAAA;CACne,CAAA;AACN"}
1
+ {"version":3,"file":"daily-releases.js","names":[],"sources":["../../../src/components/content/daily-releases.tsx"],"sourcesContent":["import { ArrowDown01Icon } from \"@hugeicons/core-free-icons\";\nimport { HugeiconsIcon } from \"@hugeicons/react\";\nimport { cn } from \"cn\";\nimport { useCallback, useContext, useId, useMemo, useState, useRef, type MouseEvent } from \"react\";\nimport type { DailyReleasesQuery } from \"../../client/discovery.js\";\nimport type { Card, ReleaseDay } from \"../../client/generated/wire.js\";\nimport { useMessages } from \"../../i18n/context.js\";\nimport { useDailyReleases, useExposure } from \"../../react/discovery.js\";\nimport { ContentKitContext } from \"../../react/context.js\";\nimport { useContentScope } from \"../../react/use-resource.js\";\nimport { useNearViewport } from \"../../react/viewport.js\";\nimport { ContentKitUiRoot } from \"../../scope.js\";\nimport { Button } from \"#ckui/ui/button\";\nimport { Skeleton } from \"#ckui/ui/skeleton\";\nimport { contentError } from \"../social/parts.js\";\nimport { ContentSummaryTile } from \"./summary-tile.js\";\nimport { ContentFilterDialog } from \"./filter-dialog.js\";\nimport { useReleaseReveal } from \"./release-reveal.js\";\nimport { ContentCard } from \"./card.js\";\nimport { cardGridLayout, type CardListProps } from \"./grid.js\";\n\nexport interface DailyReleasesProps extends Omit<CardListProps, \"infinite\" | \"pageSize\" | \"renderCard\" | \"loadMedia\"> {\n /** One complete calendar window. Defaults to 10 days in the browser's time zone. */\n query?: DailyReleasesQuery;\n /** Cards initially revealed across the whole window, allocated newest first. Default 30. */\n initialVisible?: number;\n /** Collapse locked tier previews per day; expansion never grants access. Default false. */\n collapsePremium?: boolean;\n /** Host-specific nouns; defaults use localized generic item labels. */\n summaryLabels?: { premium?: (count: number) => string; filtered?: (count: number) => string };\n /** Additional cached cards revealed by a day's Show more button. Default 30. */\n revealStep?: number;\n}\n\nconst count = (value: number, fallback: number) => Number.isFinite(value) ? Math.max(0, Math.floor(value)) : fallback;\n\n/**\n * One metadata request for a calendar window, with no requests when a day is\n * opened or expanded. Only revealed, visible cards mount images and previews.\n */\nexport function DailyReleases({ query, initialVisible = 30, revealStep = 30, collapsePremium = false, summaryLabels, ...p }: DailyReleasesProps) {\n const m = useMessages();\n const { client, viewer } = useContentScope(p.client);\n const context = useContext(ContentKitContext);\n const request = useMemo(() => ({ days: 10, time_zone: Intl.DateTimeFormat().resolvedOptions().timeZone, ...query }), [query]);\n const releases = useDailyReleases(request, { client: p.client });\n const layout = cardGridLayout(p.grid);\n const requestKey = JSON.stringify(request);\n // Guest preference changes create a fresh read scope. Keep the open day/dialog\n // while it loads, but never show the old cards or carry data across accounts.\n const identity = useMemo(() => ({ client, viewer, language: context?.language, accessRevision: context?.accessRevision, requestKey }), [client, viewer, context?.language, context?.accessRevision, requestKey]);\n const [previous, setPrevious] = useState({ identity, data: releases.data, revision: 0 });\n if (previous.identity !== identity || (releases.data && previous.data !== releases.data)) setPrevious({ identity, data: releases.data, revision: previous.revision + (previous.identity === identity ? 0 : 1) });\n const data = releases.data ?? (previous.identity === identity ? previous.data : undefined);\n const pending = !releases.data && Boolean(data);\n const days = useMemo(() => data?.days.filter((day) => (day.contents.length || day.filtered_count > 0)).sort((a, b) => b.date.localeCompare(a.date)) ?? [], [data]);\n let remaining = count(initialVisible, 30);\n return (\n <ContentKitUiRoot key={previous.revision} appearance={p.appearance} className={cn(\"grid gap-6 text-sm\", p.className)} data-ckui=\"daily-releases\" aria-busy={releases.loading}>\n {data && releases.error && <div role=\"alert\" className=\"grid justify-items-start gap-2\"><p className=\"text-destructive\">{contentError(m, releases.error)}</p><Button type=\"button\" variant=\"outline\" onClick={releases.reload}>{m.t(\"common.retry\")}</Button></div>}\n {releases.loading && !data ? <div className={layout.className} style={layout.style}>{Array.from({ length: 6 }, (_, i) => <Skeleton key={i} className={p.aspectRatio === undefined ? p.shape === \"landscape\" ? \"aspect-video\" : \"aspect-[3/4]\" : undefined} style={p.aspectRatio === undefined ? undefined : { aspectRatio: p.aspectRatio }} />)}</div> : releases.error && !data ? (\n <div role=\"alert\" className=\"grid justify-items-start gap-2\">\n <p className=\"text-destructive\">{contentError(m, releases.error)}</p>\n <Button size=\"sm\" variant=\"outline\" onClick={releases.reload}>{m.t(\"common.retry\")}</Button>\n </div>\n ) : !days.length ? <p role=\"status\" className=\"text-muted-foreground\">{p.empty ?? m.t(\"contents.empty\")}</p> : days.map((day) => {\n const initial = Math.min(remaining, day.contents.length);\n remaining -= initial;\n return <ReleaseDaySection key={JSON.stringify([requestKey, data?.from_date, day.date])} day={day} pending={pending} collapsePremium={collapsePremium} summaryLabels={summaryLabels} language={request.display_language ?? request.language} kinds={request.kind ? [request.kind] : undefined} initial={initial} step={Math.max(1, count(revealStep, 30))} cardProps={p} />;\n })}\n </ContentKitUiRoot>\n );\n}\n\ntype ReleaseCardProps = Omit<DailyReleasesProps, \"query\" | \"initialVisible\" | \"revealStep\" | \"collapsePremium\" | \"summaryLabels\">;\nconst lockedPremium = (card: Card) => !card.access.allowed && card.access.level === \"tier\";\n\nfunction ReleaseDaySection({ day, initial, step, pending, cardProps: p, collapsePremium, summaryLabels, language, kinds }: {\n day: ReleaseDay; initial: number; step: number; pending: boolean; cardProps: ReleaseCardProps;\n collapsePremium: boolean; summaryLabels?: DailyReleasesProps[\"summaryLabels\"]; language?: string; kinds?: string[];\n}) {\n const m = useMessages();\n const id = useId();\n const [open, setOpen] = useState(initial > 0 || (!day.contents.length && day.filtered_count > 0));\n const [visible, setVisible] = useState(initial);\n const [premiumExpanded, setPremiumExpanded] = useState(false);\n const [filtersOpen, setFiltersOpen] = useState(false);\n const filterTrigger = useRef<HTMLElement | null>(null);\n const dayHeading = useRef<HTMLButtonElement>(null);\n const cards = useMemo(() => day.contents.slice(0, visible), [day.contents, visible]);\n const premiumCount = useMemo(() => day.contents.filter(lockedPremium).length, [day.contents]);\n const summaryContentKind = kinds?.[0];\n const entries = useMemo(() => {\n let inserted = false;\n return cards.flatMap((card, i): { key: string; card: Card; summary: boolean; position: number }[] => {\n if (!collapsePremium || premiumExpanded || !lockedPremium(card)) return [{ key: card.id, card, summary: false, position: i + 1 }];\n if (inserted) return [];\n inserted = true;\n return [{ key: \"premium-summary\", card, summary: true, position: i + 1 }];\n });\n }, [cards, collapsePremium, premiumExpanded]);\n const exposed = useMemo(() => open && !pending ? entries.filter((entry) => !entry.summary).map((entry) => ({ ...entry.card, position: entry.position })) : [], [open, pending, entries]);\n const exposure = useExposure(exposed, { surface: p.surface ?? \"releases\", render: day.date, client: p.client });\n const layout = cardGridLayout(p.grid);\n const reveal = useReleaseReveal(`${visible}|${entries.map((entry) => entry.key).join(\"\\0\")}`);\n const label = new Intl.DateTimeFormat(m.language, { dateStyle: \"full\", timeZone: \"UTC\" }).format(new Date(`${day.date}T12:00:00Z`));\n const toggle = () => {\n if (!open && !visible) setVisible(Math.min(step, day.contents.length));\n setOpen(!open);\n };\n const expandPremium = (event: MouseEvent<HTMLButtonElement>) => {\n reveal.prepare(event.detail === 0);\n setPremiumExpanded(true);\n };\n return (\n <section data-ckui=\"release-day\" data-date={day.date}>\n <h2>\n <Button ref={dayHeading} id={`${id}-heading`} type=\"button\" variant=\"ghost\" className=\"h-auto w-full justify-start gap-3 px-0 py-3 text-start text-lg font-semibold\" aria-expanded={open} aria-controls={`${id}-contents`} onClick={toggle}>\n <HugeiconsIcon icon={ArrowDown01Icon} strokeWidth={2} className={cn(\"size-5 shrink-0 transition-transform duration-200 motion-reduce:transition-none\", !open && \"-rotate-90\")} aria-hidden />\n <time dateTime={day.date}>{label}</time>\n </Button>\n </h2>\n {open && pending && <Skeleton className=\"h-24 w-full\" />}\n <div hidden={pending} style={pending ? { display: \"none\" } : undefined} id={`${id}-contents`} role=\"region\" aria-labelledby={`${id}-heading`} aria-hidden={!open || pending} inert={!open || pending} className={cn(\"grid transition-[grid-template-rows,opacity] duration-250 ease-out motion-reduce:transition-none\", open ? \"grid-rows-[1fr] opacity-100\" : \"grid-rows-[0fr] opacity-0\")}>\n <div className=\"min-h-0 overflow-hidden\">\n <ol ref={reveal.grid} className={cn(layout.className, \"pt-2\")} style={layout.style}>\n {entries.map((entry) => entry.summary ?\n <ContentSummaryTile key={entry.key} tileKey={entry.key} contentKind={kinds?.[0] ?? entry.card.kind} open={open && !pending} preview={entry.card} cardProps={p} kind=\"premium\" label={summaryLabels?.premium?.(premiumCount) ?? m.plural(\"releases.premiumMore\", premiumCount)} onClick={expandPremium} /> :\n <ReleaseCard key={entry.key} card={entry.card} open={open && !pending} position={entry.position} exposure={exposure} cardProps={p} />)}\n {day.filtered_count > 0 && <ContentSummaryTile tileKey=\"filtered-summary\" contentKind={summaryContentKind} open={open && !pending} cardProps={p} kind=\"filtered\" label={summaryLabels?.filtered?.(day.filtered_count) ?? m.plural(\"releases.filteredMore\", day.filtered_count)} onClick={(event) => { filterTrigger.current = event.currentTarget; setFiltersOpen(true); }} />}\n </ol>\n {visible < day.contents.length && <div className=\"flex justify-center pt-5 pb-1\"><Button type=\"button\" variant=\"outline\" onClick={(event) => { reveal.prepare(event.detail === 0); setVisible((n) => Math.min(n + step, day.contents.length)); }}>{m.t(\"contents.showMore\")}</Button></div>}\n </div>\n </div>\n <ContentFilterDialog returnFocus={() => !pending && filterTrigger.current?.isConnected ? filterTrigger.current : dayHeading.current} open={filtersOpen} onOpenChange={setFiltersOpen} client={p.client} kinds={kinds} language={language} counts={day.filtered_entities ?? []} description={m.t(\"releases.filterContext\", { date: label })} appearance={p.appearance} />\n </section>\n );\n}\n\n\nfunction ReleaseCard({ card, open, position, exposure, cardProps: p }: { card: Card; open: boolean; position: number; exposure: ReturnType<typeof useExposure>; cardProps: ReleaseCardProps }) {\n const [viewport, visible] = useNearViewport({ margin: \"0px\", leaveMargin: \"1200px 0px\" });\n const tracked = useMemo(() => exposure.track(card.id, position), [exposure, card.id, position]);\n const ref = useCallback((element: HTMLLIElement | null) => { viewport(element); tracked(element); }, [viewport, tracked]);\n return <li ref={ref} data-release-key={card.id}>\n <ContentCard card={card} client={p.client} href={p.href} shape={p.shape} aspectRatio={p.aspectRatio} titlePosition={p.titlePosition} loadMedia={open && visible} groupKinds={p.groupKinds} chips={p.chips} filterEntity={p.filterEntity} entityStyle={p.entityStyle} entityLayout={p.entityLayout} metadata={p.metadata} showCounts={p.showCounts} tiers={p.tiers} labels={p.labels} owner={p.owner} ownerHref={p.ownerHref} decorate={p.decorate} onOpen={() => exposure.click(card.id, position)} />\n </li>;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAkCA,IAAM,KAAS,GAAe,MAAqB,OAAO,SAAS,CAAK,IAAI,KAAK,IAAI,GAAG,KAAK,MAAM,CAAK,CAAC,IAAI;AAM7G,SAAgB,EAAc,EAAE,UAAO,oBAAiB,IAAI,gBAAa,IAAI,qBAAkB,IAAO,kBAAe,GAAG,KAAyB;CAC/I,IAAM,IAAI,EAAY,GAChB,EAAE,WAAQ,cAAW,EAAgB,EAAE,MAAM,GAC7C,IAAU,EAAW,CAAiB,GACtC,IAAU,SAAe;EAAE,MAAM;EAAI,WAAW,KAAK,eAAe,CAAC,CAAC,gBAAgB,CAAC,CAAC;EAAU,GAAG;CAAM,IAAI,CAAC,CAAK,CAAC,GACtH,IAAW,EAAiB,GAAS,EAAE,QAAQ,EAAE,OAAO,CAAC,GACzD,IAAS,EAAe,EAAE,IAAI,GAC9B,IAAa,KAAK,UAAU,CAAO,GAGnC,IAAW,SAAe;EAAE;EAAQ;EAAQ,UAAU,GAAS;EAAU,gBAAgB,GAAS;EAAgB;CAAW,IAAI;EAAC;EAAQ;EAAQ,GAAS;EAAU,GAAS;EAAgB;CAAU,CAAC,GACzM,CAAC,GAAU,KAAe,EAAS;EAAE;EAAU,MAAM,EAAS;EAAM,UAAU;CAAE,CAAC;CACvF,CAAI,EAAS,aAAa,KAAa,EAAS,QAAQ,EAAS,SAAS,EAAS,SAAO,EAAY;EAAE;EAAU,MAAM,EAAS;EAAM,UAAU,EAAS,YAAY,EAAS,aAAa,IAAW,IAAI;CAAG,CAAC;CAC/M,IAAM,IAAO,EAAS,SAAS,EAAS,aAAa,IAAW,EAAS,OAAO,KAAA,IAC1E,IAAU,CAAC,EAAS,QAAQ,EAAQ,GACpC,IAAO,QAAc,GAAM,KAAK,QAAQ,MAAS,EAAI,SAAS,UAAU,EAAI,iBAAiB,CAAE,CAAC,CAAC,MAAM,GAAG,MAAM,EAAE,KAAK,cAAc,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAI,CAAC,GAC7J,IAAY,EAAM,GAAgB,EAAE;CACxC,OACE,kBAAC,GAAD;EAA0C,YAAY,EAAE;EAAY,WAAW,EAAG,sBAAsB,EAAE,SAAS;EAAG,aAAU;EAAiB,aAAW,EAAS;EAArK,UAAA,CACG,KAAQ,EAAS,SAAS,kBAAC,OAAD;GAAK,MAAK;GAAQ,WAAU;GAA5B,UAAA,CAA6D,kBAAC,KAAD;IAAG,WAAU;IAAoB,UAAA,EAAa,GAAG,EAAS,KAAK;GAAK,CAAA,GAAC,kBAAC,GAAD;IAAQ,MAAK;IAAS,SAAQ;IAAU,SAAS,EAAS;IAAS,UAAA,EAAE,EAAE,cAAc;GAAU,CAAA,CAAM;EACjQ,CAAA,GAAA,EAAS,WAAW,CAAC,IAAO,kBAAC,OAAD;GAAK,WAAW,EAAO;GAAW,OAAO,EAAO;GAAQ,UAAA,MAAM,KAAK,EAAE,QAAQ,EAAE,IAAI,GAAG,MAAM,kBAAC,GAAD;IAAkB,WAAW,EAAE,gBAAgB,KAAA,IAAY,EAAE,UAAU,cAAc,iBAAiB,iBAAiB,KAAA;IAAW,OAAO,EAAE,gBAAgB,KAAA,IAAY,KAAA,IAAY,EAAE,aAAa,EAAE,YAAY;GAAI,GAArM,CAAqM,CAAC;EAAO,CAAA,IAAI,EAAS,SAAS,CAAC,IAC1W,kBAAC,OAAD;GAAK,MAAK;GAAQ,WAAU;GAA5B,UAAA,CACE,kBAAC,KAAD;IAAG,WAAU;IAAoB,UAAA,EAAa,GAAG,EAAS,KAAK;GAAK,CAAA,GACpE,kBAAC,GAAD;IAAQ,MAAK;IAAK,SAAQ;IAAU,SAAS,EAAS;IAAS,UAAA,EAAE,EAAE,cAAc;GAAU,CAAA,CACxF;EACH,CAAA,IAAC,EAAK,SAAqG,EAAK,KAAK,MAAQ;GAC/H,IAAM,IAAU,KAAK,IAAI,GAAW,EAAI,SAAS,MAAM;GAEvD,OADA,KAAa,GACN,kBAAC,GAAD;IAAsF;IAAc;IAA0B;IAAgC;IAAe,UAAU,EAAQ,oBAAoB,EAAQ;IAAU,OAAO,EAAQ,OAAO,CAAC,EAAQ,IAAI,IAAI,KAAA;IAAoB;IAAS,MAAM,KAAK,IAAI,GAAG,EAAM,GAAY,EAAE,CAAC;IAAG,WAAW;GAAI,GAA1U,KAAK,UAAU;IAAC;IAAY,GAAM;IAAW,EAAI;GAAI,CAAC,CAAoR;EAC3W,CAAC,IAJkB,kBAAC,KAAD;GAAG,MAAK;GAAS,WAAU;GAAyB,UAAA,EAAE,SAAS,EAAE,EAAE,gBAAgB;EAAK,CAAA,CAK3F;CAZK,GAAA,EAAS,QAYd;AAEtB;AAGA,IAAM,KAAiB,MAAe,CAAC,EAAK,OAAO,WAAW,EAAK,OAAO,UAAU;AAEpF,SAAS,EAAkB,EAAE,QAAK,YAAS,SAAM,YAAS,WAAW,GAAG,oBAAiB,kBAAe,aAAU,YAG/G;CACD,IAAM,IAAI,EAAY,GAChB,IAAK,EAAM,GACX,CAAC,GAAM,KAAW,EAAS,IAAU,KAAM,CAAC,EAAI,SAAS,UAAU,EAAI,iBAAiB,CAAE,GAC1F,CAAC,GAAS,KAAc,EAAS,CAAO,GACxC,CAAC,GAAiB,KAAsB,EAAS,EAAK,GACtD,CAAC,GAAa,KAAkB,EAAS,EAAK,GAC9C,IAAgB,EAA2B,IAAI,GAC/C,IAAa,EAA0B,IAAI,GAC3C,IAAQ,QAAc,EAAI,SAAS,MAAM,GAAG,CAAO,GAAG,CAAC,EAAI,UAAU,CAAO,CAAC,GAC7E,IAAe,QAAc,EAAI,SAAS,OAAO,CAAa,CAAC,CAAC,QAAQ,CAAC,EAAI,QAAQ,CAAC,GACtF,IAAqB,IAAQ,IAC7B,IAAU,QAAc;EAC5B,IAAI,IAAW;EACf,OAAO,EAAM,SAAS,GAAM,MACtB,CAAC,KAAmB,KAAmB,CAAC,EAAc,CAAI,IAAU,CAAC;GAAE,KAAK,EAAK;GAAI;GAAM,SAAS;GAAO,UAAU,IAAI;EAAE,CAAC,IAC5H,IAAiB,CAAC,KACtB,IAAW,IACJ,CAAC;GAAE,KAAK;GAAmB;GAAM,SAAS;GAAM,UAAU,IAAI;EAAE,CAAC,EACzE;CACH,GAAG;EAAC;EAAO;EAAiB;CAAe,CAAC,GACtC,IAAU,QAAc,KAAQ,CAAC,IAAU,EAAQ,QAAQ,MAAU,CAAC,EAAM,OAAO,CAAC,CAAC,KAAK,OAAW;EAAE,GAAG,EAAM;EAAM,UAAU,EAAM;CAAS,EAAE,IAAI,CAAC,GAAG;EAAC;EAAM;EAAS;CAAO,CAAC,GACjL,IAAW,EAAY,GAAS;EAAE,SAAS,EAAE,WAAW;EAAY,QAAQ,EAAI;EAAM,QAAQ,EAAE;CAAO,CAAC,GACxG,IAAS,EAAe,EAAE,IAAI,GAC9B,IAAS,EAAiB,GAAG,EAAQ,GAAG,EAAQ,KAAK,MAAU,EAAM,GAAG,CAAC,CAAC,KAAK,IAAI,GAAG,GACtF,IAAQ,IAAI,KAAK,eAAe,EAAE,UAAU;EAAE,WAAW;EAAQ,UAAU;CAAM,CAAC,CAAC,CAAC,uBAAO,IAAI,KAAK,GAAG,EAAI,KAAK,WAAW,CAAC,GAC5H,UAAe;EAEnB,AADI,CAAC,KAAQ,CAAC,KAAS,EAAW,KAAK,IAAI,GAAM,EAAI,SAAS,MAAM,CAAC,GACrE,EAAQ,CAAC,CAAI;CACf,GACM,KAAiB,MAAyC;EAE9D,AADA,EAAO,QAAQ,EAAM,WAAW,CAAC,GACjC,EAAmB,EAAI;CACzB;CACA,OACE,kBAAC,WAAD;EAAS,aAAU;EAAc,aAAW,EAAI;EAAhD,UAAA;GACE,kBAAC,MAAD,EAAA,UACE,kBAAC,GAAD;IAAQ,KAAK;IAAY,IAAI,GAAG,EAAG;IAAW,MAAK;IAAS,SAAQ;IAAQ,WAAU;IAA+E,iBAAe;IAAM,iBAAe,GAAG,EAAG;IAAY,SAAS;IAApO,UAAA,CACE,kBAAC,GAAD;KAAe,MAAM;KAAiB,aAAa;KAAG,WAAW,EAAG,mFAAmF,CAAC,KAAQ,YAAY;KAAG,eAAA;IAAa,CAAA,GAC5L,kBAAC,QAAD;KAAM,UAAU,EAAI;KAAO,UAAA;IAAY,CAAA,CACjC;GACN,CAAA,EAAA,CAAA;GACH,KAAQ,KAAW,kBAAC,GAAD,EAAU,WAAU,cAAe,CAAA;GACvD,kBAAC,OAAD;IAAK,QAAQ;IAAS,OAAO,IAAU,EAAE,SAAS,OAAO,IAAI,KAAA;IAAW,IAAI,GAAG,EAAG;IAAY,MAAK;IAAS,mBAAiB,GAAG,EAAG;IAAW,eAAa,CAAC,KAAQ;IAAS,OAAO,CAAC,KAAQ;IAAS,WAAW,EAAG,oGAAoG,IAAO,gCAAgC,2BAA2B;IACxX,UAAA,kBAAC,OAAD;KAAK,WAAU;KAAf,UAAA,CACE,kBAAC,MAAD;MAAI,KAAK,EAAO;MAAM,WAAW,EAAG,EAAO,WAAW,MAAM;MAAG,OAAO,EAAO;MAA7E,UAAA,CACG,EAAQ,KAAK,MAAU,EAAM,UAC5B,kBAAC,GAAD;OAAoC,SAAS,EAAM;OAAK,aAAa,IAAQ,MAAM,EAAM,KAAK;OAAM,MAAM,KAAQ,CAAC;OAAS,SAAS,EAAM;OAAM,WAAW;OAAG,MAAK;OAAU,OAAO,GAAe,UAAU,CAAY,KAAK,EAAE,OAAO,wBAAwB,CAAY;OAAG,SAAS;MAAgB,GAA/Q,EAAM,GAAyQ,IACxS,kBAAC,GAAD;OAA6B,MAAM,EAAM;OAAM,MAAM,KAAQ,CAAC;OAAS,UAAU,EAAM;OAAoB;OAAU,WAAW;MAAI,GAAlH,EAAM,GAA4G,CAAC,GACtI,EAAI,iBAAiB,KAAK,kBAAC,GAAD;OAAoB,SAAQ;OAAmB,aAAa;OAAoB,MAAM,KAAQ,CAAC;OAAS,WAAW;OAAG,MAAK;OAAW,OAAO,GAAe,WAAW,EAAI,cAAc,KAAK,EAAE,OAAO,yBAAyB,EAAI,cAAc;OAAG,UAAU,MAAU;QAA+C,AAA7C,EAAc,UAAU,EAAM,eAAe,EAAe,EAAI;OAAG;MAAI,CAAA,CAC3W;KACH,CAAA,GAAA,IAAU,EAAI,SAAS,UAAU,kBAAC,OAAD;MAAK,WAAU;MAAgC,UAAA,kBAAC,GAAD;OAAQ,MAAK;OAAS,SAAQ;OAAU,UAAU,MAAU;QAAsC,AAApC,EAAO,QAAQ,EAAM,WAAW,CAAC,GAAG,GAAY,MAAM,KAAK,IAAI,IAAI,GAAM,EAAI,SAAS,MAAM,CAAC;OAAG;OAAI,UAAA,EAAE,EAAE,mBAAmB;MAAU,CAAA;KAAM,CAAA,CACvR;;GACF,CAAA;GACL,kBAAC,GAAD;IAAqB,mBAAmB,CAAC,KAAW,EAAc,SAAS,cAAc,EAAc,UAAU,EAAW;IAAS,MAAM;IAAa,cAAc;IAAgB,QAAQ,EAAE;IAAe;IAAiB;IAAU,QAAQ,EAAI,qBAAqB,CAAC;IAAG,aAAa,EAAE,EAAE,0BAA0B,EAAE,MAAM,EAAM,CAAC;IAAG,YAAY,EAAE;GAAa,CAAA;EAChW;;AAEb;AAGA,SAAS,EAAY,EAAE,SAAM,SAAM,aAAU,aAAU,WAAW,KAA6H;CAC7L,IAAM,CAAC,GAAU,KAAW,EAAgB;EAAE,QAAQ;EAAO,aAAa;CAAa,CAAC,GAClF,IAAU,QAAc,EAAS,MAAM,EAAK,IAAI,CAAQ,GAAG;EAAC;EAAU,EAAK;EAAI;CAAQ,CAAC,GACxF,IAAM,GAAa,MAAkC;EAAqB,AAAnB,EAAS,CAAO,GAAG,EAAQ,CAAO;CAAG,GAAG,CAAC,GAAU,CAAO,CAAC;CACxH,OAAO,kBAAC,MAAD;EAAS;EAAK,oBAAkB,EAAK;EAC1C,UAAA,kBAAC,GAAD;GAAmB;GAAM,QAAQ,EAAE;GAAQ,MAAM,EAAE;GAAM,OAAO,EAAE;GAAO,aAAa,EAAE;GAAa,eAAe,EAAE;GAAe,WAAW,KAAQ;GAAS,YAAY,EAAE;GAAY,OAAO,EAAE;GAAO,cAAc,EAAE;GAAc,aAAa,EAAE;GAAa,cAAc,EAAE;GAAc,UAAU,EAAE;GAAU,YAAY,EAAE;GAAY,OAAO,EAAE;GAAO,QAAQ,EAAE;GAAQ,OAAO,EAAE;GAAO,WAAW,EAAE;GAAW,UAAU,EAAE;GAAU,cAAc,EAAS,MAAM,EAAK,IAAI,CAAQ;EAAI,CAAA;CACne,CAAA;AACN"}
@@ -0,0 +1,6 @@
1
+ import { MineQuery } from '../../client/content/favorites.js';
2
+ import { CardListProps } from './grid.js';
3
+ /** Favorite contents, with the same filtering, paid previews and pagination as public lists. */
4
+ export declare function ContentFavorites({ query, ...p }: CardListProps & {
5
+ query?: Omit<MineQuery, "target">;
6
+ }): import('react').JSX.Element;
@@ -0,0 +1,33 @@
1
+ import { useMyFavorites as e } from "../../react/discovery.js";
2
+ import { CardGrid as t, cardListMode as n } from "./grid.js";
3
+ import { useMemo as r } from "react";
4
+ import { jsx as i } from "react/jsx-runtime";
5
+ //#region src/components/content/favorites.tsx
6
+ function a({ query: a = {}, ...o }) {
7
+ let s = r(() => ({
8
+ ...a,
9
+ target: "contents",
10
+ mode: n(o.locked, a.mode),
11
+ summary: a.summary ?? !0,
12
+ limit: a.limit ?? o.pageSize
13
+ }), [
14
+ a,
15
+ o.pageSize,
16
+ o.locked
17
+ ]), c = e(s, { client: o.client }), l = r(() => c.items.flatMap((e) => e.content ? [e.content] : []), [c.items]);
18
+ return /* @__PURE__ */ i(t, {
19
+ surface: "favorites",
20
+ ...o,
21
+ list: {
22
+ ...c,
23
+ items: l
24
+ },
25
+ render: JSON.stringify(s),
26
+ filterKinds: s.kind ? [s.kind] : void 0,
27
+ filterLanguage: s.display_language ?? s.language
28
+ });
29
+ }
30
+ //#endregion
31
+ export { a as ContentFavorites };
32
+
33
+ //# sourceMappingURL=favorites.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"favorites.js","names":[],"sources":["../../../src/components/content/favorites.tsx"],"sourcesContent":["import { useMemo } from \"react\";\nimport type { MineQuery } from \"../../client/content/favorites.js\";\nimport { useMyFavorites } from \"../../react/discovery.js\";\nimport { CardGrid, cardListMode, type CardListProps } from \"./grid.js\";\n\n/** Favorite contents, with the same filtering, paid previews and pagination as public lists. */\nexport function ContentFavorites({ query = {}, ...p }: CardListProps & { query?: Omit<MineQuery, \"target\"> }) {\n const q = useMemo(\n () => ({ ...query, target: \"contents\" as const, mode: cardListMode(p.locked, query.mode), summary: query.summary ?? true, limit: query.limit ?? p.pageSize }),\n [query, p.pageSize, p.locked],\n );\n const favorites = useMyFavorites(q, { client: p.client });\n const items = useMemo(() => favorites.items.flatMap((item) => (item.content ? [item.content] : [])), [favorites.items]);\n return (\n <CardGrid\n surface=\"favorites\"\n {...p}\n list={{ ...favorites, items }}\n render={JSON.stringify(q)}\n filterKinds={q.kind ? [q.kind] : undefined}\n filterLanguage={q.display_language ?? q.language}\n />\n );\n}\n"],"mappings":";;;;;AAMA,SAAgB,EAAiB,EAAE,WAAQ,CAAC,GAAG,GAAG,KAA4D;CAC5G,IAAM,IAAI,SACD;EAAE,GAAG;EAAO,QAAQ;EAAqB,MAAM,EAAa,EAAE,QAAQ,EAAM,IAAI;EAAG,SAAS,EAAM,WAAW;EAAM,OAAO,EAAM,SAAS,EAAE;CAAS,IAC3J;EAAC;EAAO,EAAE;EAAU,EAAE;CAAM,CAC9B,GACM,IAAY,EAAe,GAAG,EAAE,QAAQ,EAAE,OAAO,CAAC,GAClD,IAAQ,QAAc,EAAU,MAAM,SAAS,MAAU,EAAK,UAAU,CAAC,EAAK,OAAO,IAAI,CAAC,CAAE,GAAG,CAAC,EAAU,KAAK,CAAC;CACtH,OACE,kBAAC,GAAD;EACE,SAAQ;EACR,GAAI;EACJ,MAAM;GAAE,GAAG;GAAW;EAAM;EAC5B,QAAQ,KAAK,UAAU,CAAC;EACxB,aAAa,EAAE,OAAO,CAAC,EAAE,IAAI,IAAI,KAAA;EACjC,gBAAgB,EAAE,oBAAoB,EAAE;CACzC,CAAA;AAEL"}