@scalemule/news-publication 0.0.67 → 0.0.68

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.
@@ -4,6 +4,38 @@
4
4
  var react = require('react');
5
5
  var jsxRuntime = require('react/jsx-runtime');
6
6
 
7
+ // src/article-presentation.ts
8
+ var standard = {
9
+ id: "standard",
10
+ version: 1,
11
+ name: "Standard article",
12
+ renderer: "standard",
13
+ hero_aspect: "landscape",
14
+ headline_position: "before_hero",
15
+ wide_body: false
16
+ };
17
+ var formats = [
18
+ "news",
19
+ "brief",
20
+ "explainer",
21
+ "interview",
22
+ "opinion",
23
+ "photo_essay",
24
+ "video_story"
25
+ ];
26
+ function articlePresentation(value) {
27
+ const l = value?.layout;
28
+ if (!l || !/^[a-z0-9_-]{1,80}$/.test(l.id) || !Number.isInteger(l.version) || l.version < 1 || !["standard", "feature", "portrait"].includes(l.renderer) || !["landscape", "portrait", "square"].includes(l.hero_aspect) || !["before_hero", "after_hero"].includes(l.headline_position) || typeof l.wide_body !== "boolean") {
29
+ return { layout: standard };
30
+ }
31
+ return {
32
+ format: value?.format && formats.includes(value.format) ? value.format : void 0,
33
+ layout: l
34
+ };
35
+ }
36
+ function articleFormatLabel(format) {
37
+ return format === "opinion" ? "Opinion" : format === "explainer" ? "Explainer" : format === "interview" ? "Interview" : format === "photo_essay" ? "Photo essay" : format === "video_story" ? "Video story" : void 0;
38
+ }
7
39
  var stable = (value) => Array.isArray(value) ? value.map(stable) : value && typeof value === "object" ? Object.fromEntries(Object.keys(value).sort().map((k) => [k, stable(value[k])])) : value;
8
40
  var same = (a, b) => JSON.stringify(stable(a)) === JSON.stringify(stable(b));
9
41
  var hasDraft = (data) => !!data && Object.keys(data).length > 0;
@@ -518,10 +550,12 @@ function StoryReview({
518
550
  publicationFooter,
519
551
  readerAccountUrl,
520
552
  renderSignIn,
521
- feedbackEmail
553
+ feedbackEmail,
554
+ initialReview,
555
+ onReviewLoaded
522
556
  }) {
523
557
  const base = `/api/news/review/${encodeURIComponent(sessionId)}`;
524
- const [review, setReview] = react.useState(null), [error, setError] = react.useState(""), [notice, setNotice] = react.useState(""), [busy, setBusy] = react.useState(false), [panel, setPanelState] = react.useState("article"), [verification, setVerification] = react.useState(false), [code, setCode] = react.useState("");
558
+ const [review, setReview] = react.useState(initialReview ?? null), [error, setError] = react.useState(""), [notice, setNotice] = react.useState(""), [busy, setBusy] = react.useState(false), [panel, setPanelState] = react.useState("article"), [verification, setVerification] = react.useState(false), [code, setCode] = react.useState("");
525
559
  const [shareUrl, setShareUrl] = react.useState(""), [canShare, setCanShare] = react.useState(false);
526
560
  const [contributorName, setContributorName] = react.useState(""), [contributorEmail, setContributorEmail] = react.useState("");
527
561
  const [identityStep, setIdentityStep] = react.useState("name"), [requestedPanel, setRequestedPanel] = react.useState("comment");
@@ -576,6 +610,9 @@ function StoryReview({
576
610
  const responseRef = react.useRef(null);
577
611
  const thanksRef = react.useRef(null);
578
612
  const [moreQuestions, setMoreQuestions] = react.useState(false);
613
+ react.useEffect(() => {
614
+ if (review) onReviewLoaded?.(review);
615
+ }, [review, onReviewLoaded]);
579
616
  const [replacementPhoto, setReplacementPhoto] = react.useState(null);
580
617
  const photoToReplace = pendingPhoto.photo?.replacement || replacementPhoto;
581
618
  function openMedia(photo = null) {
@@ -696,7 +733,7 @@ function StoryReview({
696
733
  const token = new URL(window.location.href).searchParams.get("key") || (/^[a-f0-9]{64}$/.test(window.location.hash.slice(1)) ? window.location.hash.slice(1) : void 0);
697
734
  let exchange = {};
698
735
  try {
699
- exchange = await request("/session", token ? { token } : {});
736
+ exchange = await request("/session", { ...token ? { token } : {}, include_review: true });
700
737
  } catch (e) {
701
738
  if (token) throw e;
702
739
  }
@@ -713,7 +750,7 @@ function StoryReview({
713
750
  }
714
751
  }
715
752
  }
716
- const data = await request();
753
+ const data = exchange.review ?? await request();
717
754
  if (active) {
718
755
  if (data.verification_required) {
719
756
  setVerification(true);
@@ -880,10 +917,33 @@ function StoryReview({
880
917
  /* @__PURE__ */ jsxRuntime.jsx("a", { href: emailLink, children: "Email the newsroom" }),
881
918
  ". Your email app will open; send your message there."
882
919
  ] });
920
+ const presentation = articlePresentation(review?.presentation);
921
+ const formatLabel = articleFormatLabel(presentation.format);
922
+ const sourceHero = review?.revision.document.media.filter((m) => m.position === "hero").map((m) => /* @__PURE__ */ jsxRuntime.jsx(
923
+ PrivatePhoto,
924
+ {
925
+ media: m,
926
+ base,
927
+ onChange: can("UPLOAD_MEDIA") ? () => openMedia(m) : void 0,
928
+ onSuggestCorrection: can("REQUEST_CHANGES") ? () => openCorrection(m) : void 0,
929
+ disabled: busy
930
+ },
931
+ m.file_id
932
+ ));
933
+ const generated = review?.generated_visual;
934
+ const hero = sourceHero?.length ? sourceHero : generated && /^https:\/\//.test(generated.url) ? /* @__PURE__ */ jsxRuntime.jsxs("figure", { children: [
935
+ /* @__PURE__ */ jsxRuntime.jsx("img", { src: generated.url, alt: generated.alt || review?.revision.document.title || "Article illustration" }),
936
+ /* @__PURE__ */ jsxRuntime.jsxs("figcaption", { children: [
937
+ generated.caption,
938
+ " ",
939
+ generated.label
940
+ ] })
941
+ ] }) : null;
942
+ const heroBeforeHeadline = presentation.layout.headline_position === "after_hero";
883
943
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `sm-review-frame${publicationHeader ? " sm-review-publication-frame" : ""}`, children: [
884
944
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "sm-review-banner-wrap", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "sm-review-private", children: [
885
- /* @__PURE__ */ jsxRuntime.jsx("strong", { children: review?.published ? "Private review" : "Private preview \xB7 Not published" }),
886
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: review?.published ? "This revision has been published. This review link remains private." : `Prepared by ${publicationName} for ${celebration ? "family " : ""}review.` })
945
+ /* @__PURE__ */ jsxRuntime.jsx("strong", { children: review?.article_published || review?.published ? "Private review" : "Private preview \xB7 Not published" }),
946
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: review?.published ? "This revision has been published. This review link remains private." : review?.article_published ? "The article is published. This private link preserves the version you were invited to review." : `Prepared by ${publicationName} for ${celebration ? "family " : ""}review.` })
887
947
  ] }) }),
888
948
  publicationHeader ?? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "sm-review-brand-wrap", children: /* @__PURE__ */ jsxRuntime.jsxs("header", { className: "sm-review-masthead", children: [
889
949
  nameplateUrl && /* @__PURE__ */ jsxRuntime.jsx("img", { src: nameplateUrl, alt: "", width: 80, height: 80 }),
@@ -1030,117 +1090,118 @@ function StoryReview({
1030
1090
  "newsroom for final editorial review. It has not been published yet."
1031
1091
  ] })
1032
1092
  ] }),
1033
- /* @__PURE__ */ jsxRuntime.jsxs("article", { className: "sm-review-article", children: [
1034
- /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "sm-review-category", children: [
1035
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: review.revision.document.section }),
1036
- celebration && /* @__PURE__ */ jsxRuntime.jsx("span", { children: human(review.celebration_type || "") })
1037
- ] }),
1038
- /* @__PURE__ */ jsxRuntime.jsx("h1", { children: review.revision.document.title }),
1039
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "sm-review-dek", children: review.revision.document.subtitle }),
1040
- /* @__PURE__ */ jsxRuntime.jsx(EditorialNotices, { editorial: review.revision.editorial }),
1041
- review.revision.document.media.filter((m) => m.position === "hero").map((m) => /* @__PURE__ */ jsxRuntime.jsx(
1042
- PrivatePhoto,
1043
- {
1044
- media: m,
1045
- base,
1046
- onChange: can("UPLOAD_MEDIA") ? () => openMedia(m) : void 0,
1047
- onSuggestCorrection: can("REQUEST_CHANGES") ? () => openCorrection(m) : void 0,
1048
- disabled: busy
1049
- },
1050
- m.file_id
1051
- )),
1052
- celebration && !review.revision.document.media.some(
1053
- (m) => m.position === "hero"
1054
- ) && can("UPLOAD_MEDIA") && /* @__PURE__ */ jsxRuntime.jsxs(
1055
- "aside",
1056
- {
1057
- className: "sm-review-photo-invitation",
1058
- "aria-label": "Family photograph",
1059
- children: [
1060
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
1061
- /* @__PURE__ */ jsxRuntime.jsx("strong", { children: "A photograph makes it yours." }),
1062
- /* @__PURE__ */ jsxRuntime.jsx("p", { children: "Family photograph may be added before publication." })
1063
- ] }),
1064
- /* @__PURE__ */ jsxRuntime.jsx("button", { onClick: () => openMedia(), children: "+ Add a photograph" })
1065
- ]
1066
- }
1067
- ),
1068
- (() => {
1069
- const blocks = parseDocumentBlocks({
1070
- content_markdown: review.revision.document.content_markdown,
1071
- media: review.revision.document.media,
1072
- blocks: review.revision.document.blocks
1073
- });
1074
- const mediaMap = /* @__PURE__ */ new Map();
1075
- for (const m of review.revision.document.media) {
1076
- mediaMap.set(m.file_id, m);
1077
- if (m.contribution_id) mediaMap.set(m.contribution_id, m);
1078
- }
1079
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "sm-review-prose", children: blocks.length === 0 && review.revision.content_html ? /* @__PURE__ */ jsxRuntime.jsx("div", { dangerouslySetInnerHTML: { __html: review.revision.content_html } }) : blocks.map((block, idx) => {
1080
- switch (block.type) {
1081
- case "paragraph":
1082
- return /* @__PURE__ */ jsxRuntime.jsx(
1083
- "p",
1084
- {
1085
- dangerouslySetInnerHTML: { __html: block.html }
1086
- },
1087
- idx
1088
- );
1089
- case "heading": {
1090
- if (block.level === 1)
1091
- return /* @__PURE__ */ jsxRuntime.jsx("h1", { dangerouslySetInnerHTML: { __html: block.html } }, idx);
1092
- if (block.level === 2)
1093
- return /* @__PURE__ */ jsxRuntime.jsx("h2", { dangerouslySetInnerHTML: { __html: block.html } }, idx);
1094
- if (block.level === 3)
1095
- return /* @__PURE__ */ jsxRuntime.jsx("h3", { dangerouslySetInnerHTML: { __html: block.html } }, idx);
1096
- if (block.level === 4)
1097
- return /* @__PURE__ */ jsxRuntime.jsx("h4", { dangerouslySetInnerHTML: { __html: block.html } }, idx);
1098
- if (block.level === 5)
1099
- return /* @__PURE__ */ jsxRuntime.jsx("h5", { dangerouslySetInnerHTML: { __html: block.html } }, idx);
1100
- return /* @__PURE__ */ jsxRuntime.jsx("h6", { dangerouslySetInnerHTML: { __html: block.html } }, idx);
1093
+ /* @__PURE__ */ jsxRuntime.jsxs(
1094
+ "article",
1095
+ {
1096
+ className: "sm-review-article",
1097
+ "data-article-layout": presentation.layout.renderer,
1098
+ "data-wide-body": presentation.layout.wide_body,
1099
+ "data-hero-aspect": presentation.layout.hero_aspect,
1100
+ children: [
1101
+ heroBeforeHeadline && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "sm-review-hero", children: hero }),
1102
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "sm-review-category", children: [
1103
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: review.revision.document.section }),
1104
+ formatLabel && /* @__PURE__ */ jsxRuntime.jsx("span", { children: formatLabel }),
1105
+ celebration && /* @__PURE__ */ jsxRuntime.jsx("span", { children: human(review.celebration_type || "") })
1106
+ ] }),
1107
+ /* @__PURE__ */ jsxRuntime.jsx("h1", { children: review.revision.document.title }),
1108
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "sm-review-dek", children: review.revision.document.subtitle }),
1109
+ /* @__PURE__ */ jsxRuntime.jsx(EditorialNotices, { editorial: review.revision.editorial }),
1110
+ !heroBeforeHeadline && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "sm-review-hero", children: hero }),
1111
+ celebration && !review.revision.document.media.some(
1112
+ (m) => m.position === "hero"
1113
+ ) && can("UPLOAD_MEDIA") && /* @__PURE__ */ jsxRuntime.jsxs(
1114
+ "aside",
1115
+ {
1116
+ className: "sm-review-photo-invitation",
1117
+ "aria-label": "Family photograph",
1118
+ children: [
1119
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
1120
+ /* @__PURE__ */ jsxRuntime.jsx("strong", { children: "A photograph makes it yours." }),
1121
+ /* @__PURE__ */ jsxRuntime.jsx("p", { children: "Family photograph may be added before publication." })
1122
+ ] }),
1123
+ /* @__PURE__ */ jsxRuntime.jsx("button", { onClick: () => openMedia(), children: "+ Add a photograph" })
1124
+ ]
1101
1125
  }
1102
- case "quote":
1103
- return /* @__PURE__ */ jsxRuntime.jsxs("blockquote", { children: [
1104
- /* @__PURE__ */ jsxRuntime.jsx("p", { dangerouslySetInnerHTML: { __html: block.html } }),
1105
- block.attribution && /* @__PURE__ */ jsxRuntime.jsx("cite", { children: block.attribution })
1106
- ] }, idx);
1107
- case "list":
1108
- return block.ordered ? /* @__PURE__ */ jsxRuntime.jsx("ol", { children: block.items.map((it, i) => /* @__PURE__ */ jsxRuntime.jsx("li", { dangerouslySetInnerHTML: { __html: it } }, i)) }, idx) : /* @__PURE__ */ jsxRuntime.jsx("ul", { children: block.items.map((it, i) => /* @__PURE__ */ jsxRuntime.jsx("li", { dangerouslySetInnerHTML: { __html: it } }, i)) }, idx);
1109
- case "divider":
1110
- return /* @__PURE__ */ jsxRuntime.jsx("hr", {}, idx);
1111
- case "inline_media": {
1112
- const m = mediaMap.get(block.media_id);
1113
- if (!m) return null;
1114
- return /* @__PURE__ */ jsxRuntime.jsx(
1115
- PrivatePhoto,
1116
- {
1117
- media: m,
1118
- base,
1119
- onChange: m.kind !== "video" && can("UPLOAD_MEDIA") ? () => openMedia(m) : void 0,
1120
- onSuggestCorrection: can("REQUEST_CHANGES") ? () => openCorrection(m) : void 0,
1121
- disabled: busy,
1122
- isInline: true
1123
- },
1124
- m.file_id
1125
- );
1126
+ ),
1127
+ (() => {
1128
+ const blocks = parseDocumentBlocks({
1129
+ content_markdown: review.revision.document.content_markdown,
1130
+ media: review.revision.document.media,
1131
+ blocks: review.revision.document.blocks
1132
+ });
1133
+ const mediaMap = /* @__PURE__ */ new Map();
1134
+ for (const m of review.revision.document.media) {
1135
+ mediaMap.set(m.file_id, m);
1136
+ if (m.contribution_id) mediaMap.set(m.contribution_id, m);
1126
1137
  }
1127
- default:
1128
- return null;
1129
- }
1130
- }) });
1131
- })(),
1132
- review.revision.document.media.filter((m) => m.position === "gallery").map((m) => /* @__PURE__ */ jsxRuntime.jsx(
1133
- PrivatePhoto,
1134
- {
1135
- media: m,
1136
- base,
1137
- onChange: m.kind !== "video" && can("UPLOAD_MEDIA") ? () => openMedia(m) : void 0,
1138
- onSuggestCorrection: can("REQUEST_CHANGES") ? () => openCorrection(m) : void 0,
1139
- disabled: busy
1140
- },
1141
- m.file_id
1142
- ))
1143
- ] }),
1138
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "sm-review-prose", children: blocks.length === 0 && review.revision.content_html ? /* @__PURE__ */ jsxRuntime.jsx("div", { dangerouslySetInnerHTML: { __html: review.revision.content_html } }) : blocks.map((block, idx) => {
1139
+ switch (block.type) {
1140
+ case "paragraph":
1141
+ return /* @__PURE__ */ jsxRuntime.jsx(
1142
+ "p",
1143
+ {
1144
+ dangerouslySetInnerHTML: { __html: block.html }
1145
+ },
1146
+ idx
1147
+ );
1148
+ case "heading": {
1149
+ if (block.level === 1)
1150
+ return /* @__PURE__ */ jsxRuntime.jsx("h1", { dangerouslySetInnerHTML: { __html: block.html } }, idx);
1151
+ if (block.level === 2)
1152
+ return /* @__PURE__ */ jsxRuntime.jsx("h2", { dangerouslySetInnerHTML: { __html: block.html } }, idx);
1153
+ if (block.level === 3)
1154
+ return /* @__PURE__ */ jsxRuntime.jsx("h3", { dangerouslySetInnerHTML: { __html: block.html } }, idx);
1155
+ if (block.level === 4)
1156
+ return /* @__PURE__ */ jsxRuntime.jsx("h4", { dangerouslySetInnerHTML: { __html: block.html } }, idx);
1157
+ if (block.level === 5)
1158
+ return /* @__PURE__ */ jsxRuntime.jsx("h5", { dangerouslySetInnerHTML: { __html: block.html } }, idx);
1159
+ return /* @__PURE__ */ jsxRuntime.jsx("h6", { dangerouslySetInnerHTML: { __html: block.html } }, idx);
1160
+ }
1161
+ case "quote":
1162
+ return /* @__PURE__ */ jsxRuntime.jsxs("blockquote", { children: [
1163
+ /* @__PURE__ */ jsxRuntime.jsx("p", { dangerouslySetInnerHTML: { __html: block.html } }),
1164
+ block.attribution && /* @__PURE__ */ jsxRuntime.jsx("cite", { children: block.attribution })
1165
+ ] }, idx);
1166
+ case "list":
1167
+ return block.ordered ? /* @__PURE__ */ jsxRuntime.jsx("ol", { children: block.items.map((it, i) => /* @__PURE__ */ jsxRuntime.jsx("li", { dangerouslySetInnerHTML: { __html: it } }, i)) }, idx) : /* @__PURE__ */ jsxRuntime.jsx("ul", { children: block.items.map((it, i) => /* @__PURE__ */ jsxRuntime.jsx("li", { dangerouslySetInnerHTML: { __html: it } }, i)) }, idx);
1168
+ case "divider":
1169
+ return /* @__PURE__ */ jsxRuntime.jsx("hr", {}, idx);
1170
+ case "inline_media": {
1171
+ const m = mediaMap.get(block.media_id);
1172
+ if (!m) return null;
1173
+ return /* @__PURE__ */ jsxRuntime.jsx(
1174
+ PrivatePhoto,
1175
+ {
1176
+ media: m,
1177
+ base,
1178
+ onChange: m.kind !== "video" && can("UPLOAD_MEDIA") ? () => openMedia(m) : void 0,
1179
+ onSuggestCorrection: can("REQUEST_CHANGES") ? () => openCorrection(m) : void 0,
1180
+ disabled: busy,
1181
+ isInline: true
1182
+ },
1183
+ m.file_id
1184
+ );
1185
+ }
1186
+ default:
1187
+ return null;
1188
+ }
1189
+ }) });
1190
+ })(),
1191
+ review.revision.document.media.filter((m) => m.position === "gallery").map((m) => /* @__PURE__ */ jsxRuntime.jsx(
1192
+ PrivatePhoto,
1193
+ {
1194
+ media: m,
1195
+ base,
1196
+ onChange: m.kind !== "video" && can("UPLOAD_MEDIA") ? () => openMedia(m) : void 0,
1197
+ onSuggestCorrection: can("REQUEST_CHANGES") ? () => openCorrection(m) : void 0,
1198
+ disabled: busy
1199
+ },
1200
+ m.file_id
1201
+ ))
1202
+ ]
1203
+ }
1204
+ ),
1144
1205
  celebration && /* @__PURE__ */ jsxRuntime.jsxs("section", { id: "review-options", className: "sm-review-welcome", children: [
1145
1206
  /* @__PURE__ */ jsxRuntime.jsx("h2", { children: "Help us make this just right" }),
1146
1207
  /* @__PURE__ */ jsxRuntime.jsxs("p", { children: [
@@ -1,6 +1,15 @@
1
+ import { A as ArticleFormat, a as ArticlePresentation } from './article-presentation-0d1FiDgA.cjs';
1
2
  import React__default from 'react';
2
3
  import { C as ContentBlock } from './article-blocks-DsabIDmH.cjs';
3
4
 
5
+ type Data = Record<string, any>;
6
+ type Draft = {
7
+ panel: string;
8
+ version: number;
9
+ data: Data;
10
+ updated_at?: string;
11
+ };
12
+
4
13
  type Media = {
5
14
  kind?: "image" | "video";
6
15
  contribution_id: string;
@@ -18,6 +27,11 @@ type Media = {
18
27
  rights_status?: string;
19
28
  };
20
29
  type Document = {
30
+ format?: ArticleFormat;
31
+ layout?: {
32
+ id: string;
33
+ version: number;
34
+ };
21
35
  title: string;
22
36
  subtitle: string;
23
37
  content_markdown: string;
@@ -41,7 +55,59 @@ type Revision = {
41
55
  document: Document;
42
56
  content_html: string;
43
57
  };
44
- declare function StoryReview({ sessionId, publicationName, nameplateUrl, publicationHeader, publicationFooter, readerAccountUrl, renderSignIn, feedbackEmail, }: {
58
+ type StoryReviewData = {
59
+ session_id?: string;
60
+ identity_required?: boolean;
61
+ participant?: boolean;
62
+ response_drafts?: Record<string, Draft>;
63
+ publication: {
64
+ name: string;
65
+ };
66
+ reviewer: string;
67
+ revision: Revision;
68
+ history: Revision[];
69
+ permissions: string[];
70
+ questions: {
71
+ id: string;
72
+ prompt: string;
73
+ required: boolean;
74
+ }[];
75
+ contributions: {
76
+ id: string;
77
+ kind: string;
78
+ state: string;
79
+ payload: {
80
+ message?: string;
81
+ file_id?: string;
82
+ caption?: string;
83
+ credit?: string;
84
+ answers?: Record<string, string>;
85
+ target?: {
86
+ kind: string;
87
+ reference?: string;
88
+ };
89
+ alt?: string;
90
+ };
91
+ }[];
92
+ review_policy: string;
93
+ published: boolean;
94
+ article_published?: boolean;
95
+ presentation?: ArticlePresentation;
96
+ generated_visual?: {
97
+ url: string;
98
+ alt?: string;
99
+ caption?: string;
100
+ label?: string;
101
+ };
102
+ permalink_path?: string;
103
+ public_article?: {
104
+ id: string;
105
+ path: string;
106
+ } | null;
107
+ celebration_type?: string | null;
108
+ decision?: string | null;
109
+ };
110
+ declare function StoryReview({ sessionId, publicationName, nameplateUrl, publicationHeader, publicationFooter, readerAccountUrl, renderSignIn, feedbackEmail, initialReview, onReviewLoaded, }: {
45
111
  sessionId: string;
46
112
  publicationName: string;
47
113
  nameplateUrl?: string;
@@ -52,6 +118,9 @@ declare function StoryReview({ sessionId, publicationName, nameplateUrl, publica
52
118
  readerAccountUrl?: string;
53
119
  renderSignIn?: (returnTo: string) => React__default.ReactNode;
54
120
  feedbackEmail?: string;
121
+ /** Only a server-validated private capability may supply this snapshot. Never cache publicly. */
122
+ initialReview?: StoryReviewData;
123
+ onReviewLoaded?: (review: StoryReviewData) => void;
55
124
  }): React__default.JSX.Element;
56
125
  /** Paragraph comparisons preserve readable prose and identify title/dek and media changes. */
57
126
  declare function ReviewDiff({ before, after, }: {
@@ -59,4 +128,4 @@ declare function ReviewDiff({ before, after, }: {
59
128
  after: Revision;
60
129
  }): React__default.JSX.Element;
61
130
 
62
- export { type Document, type Media, ReviewDiff, StoryReview };
131
+ export { type Document, type Media, ReviewDiff, StoryReview, type StoryReviewData };
@@ -1,6 +1,15 @@
1
+ import { A as ArticleFormat, a as ArticlePresentation } from './article-presentation-0d1FiDgA.js';
1
2
  import React__default from 'react';
2
3
  import { C as ContentBlock } from './article-blocks-DsabIDmH.js';
3
4
 
5
+ type Data = Record<string, any>;
6
+ type Draft = {
7
+ panel: string;
8
+ version: number;
9
+ data: Data;
10
+ updated_at?: string;
11
+ };
12
+
4
13
  type Media = {
5
14
  kind?: "image" | "video";
6
15
  contribution_id: string;
@@ -18,6 +27,11 @@ type Media = {
18
27
  rights_status?: string;
19
28
  };
20
29
  type Document = {
30
+ format?: ArticleFormat;
31
+ layout?: {
32
+ id: string;
33
+ version: number;
34
+ };
21
35
  title: string;
22
36
  subtitle: string;
23
37
  content_markdown: string;
@@ -41,7 +55,59 @@ type Revision = {
41
55
  document: Document;
42
56
  content_html: string;
43
57
  };
44
- declare function StoryReview({ sessionId, publicationName, nameplateUrl, publicationHeader, publicationFooter, readerAccountUrl, renderSignIn, feedbackEmail, }: {
58
+ type StoryReviewData = {
59
+ session_id?: string;
60
+ identity_required?: boolean;
61
+ participant?: boolean;
62
+ response_drafts?: Record<string, Draft>;
63
+ publication: {
64
+ name: string;
65
+ };
66
+ reviewer: string;
67
+ revision: Revision;
68
+ history: Revision[];
69
+ permissions: string[];
70
+ questions: {
71
+ id: string;
72
+ prompt: string;
73
+ required: boolean;
74
+ }[];
75
+ contributions: {
76
+ id: string;
77
+ kind: string;
78
+ state: string;
79
+ payload: {
80
+ message?: string;
81
+ file_id?: string;
82
+ caption?: string;
83
+ credit?: string;
84
+ answers?: Record<string, string>;
85
+ target?: {
86
+ kind: string;
87
+ reference?: string;
88
+ };
89
+ alt?: string;
90
+ };
91
+ }[];
92
+ review_policy: string;
93
+ published: boolean;
94
+ article_published?: boolean;
95
+ presentation?: ArticlePresentation;
96
+ generated_visual?: {
97
+ url: string;
98
+ alt?: string;
99
+ caption?: string;
100
+ label?: string;
101
+ };
102
+ permalink_path?: string;
103
+ public_article?: {
104
+ id: string;
105
+ path: string;
106
+ } | null;
107
+ celebration_type?: string | null;
108
+ decision?: string | null;
109
+ };
110
+ declare function StoryReview({ sessionId, publicationName, nameplateUrl, publicationHeader, publicationFooter, readerAccountUrl, renderSignIn, feedbackEmail, initialReview, onReviewLoaded, }: {
45
111
  sessionId: string;
46
112
  publicationName: string;
47
113
  nameplateUrl?: string;
@@ -52,6 +118,9 @@ declare function StoryReview({ sessionId, publicationName, nameplateUrl, publica
52
118
  readerAccountUrl?: string;
53
119
  renderSignIn?: (returnTo: string) => React__default.ReactNode;
54
120
  feedbackEmail?: string;
121
+ /** Only a server-validated private capability may supply this snapshot. Never cache publicly. */
122
+ initialReview?: StoryReviewData;
123
+ onReviewLoaded?: (review: StoryReviewData) => void;
55
124
  }): React__default.JSX.Element;
56
125
  /** Paragraph comparisons preserve readable prose and identify title/dek and media changes. */
57
126
  declare function ReviewDiff({ before, after, }: {
@@ -59,4 +128,4 @@ declare function ReviewDiff({ before, after, }: {
59
128
  after: Revision;
60
129
  }): React__default.JSX.Element;
61
130
 
62
- export { type Document, type Media, ReviewDiff, StoryReview };
131
+ export { type Document, type Media, ReviewDiff, StoryReview, type StoryReviewData };