@gramps-connect/story 0.1.3 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -13,6 +13,11 @@ writes them and presents them with this package's player.
13
13
  **https://dsblank.github.io/gramps-connect-stories/**. Pick or drop a
14
14
  `.story.zip`, or link to one with `?src=<url>`; `#s3` opens a slide.
15
15
  Everything happens in the browser: an opened story is never uploaded.
16
+ - **Change a story, or make one:** the Story Editor, at
17
+ **https://dsblank.github.io/gramps-connect-stories/edit.html** (or
18
+ **Edit** on an open story in the viewer). Titles, dates, text, photos
19
+ and the order of slides; it saves a new `.story.zip`, back into the opened file
20
+ in Chrome and Edge. Also entirely in the browser.
16
21
  - **Put a story on a web page:** the [`<gramps-connect-story>`](#on-any-web-page-gramps-connect-story)
17
22
  element.
18
23
  - **Format specification:** [`spec/1.0/README.md`](spec/1.0/README.md)
@@ -125,6 +130,8 @@ It fills its container. Props:
125
130
  | `keyboard` | Arrow keys change slides: `true` (default) anywhere on the page, `"focus"` only while the player has focus, `false` never. Swiping on a slide always works. |
126
131
  | `onSlideChange(index)` | Called whenever the slide changes. |
127
132
  | `initialSlide` | The slide to open on. |
133
+ | `brand` | Shown before the title, e.g. `ViewerBrand`. |
134
+ | `actions` | Your own buttons, at the right of the title bar. |
128
135
  | `renderMapModeControl` | Replaces the built-in map-mode control with your own, given the same props. |
129
136
 
130
137
  Peer dependencies: `react`, `react-dom` and `maplibre-gl` (5 or later),
@@ -132,6 +139,48 @@ needed only by the player. With TypeScript 6 or later, add `"geojson"` to
132
139
  `compilerOptions.types`: maplibre's own declarations use its global
133
140
  `GeoJSON` namespace.
134
141
 
142
+ ## The editor: `@gramps-connect/story/editor`
143
+
144
+ A React component that edits a story: the slides on the left (drag to
145
+ reorder), the selected slide's title, date, text and photos in the middle,
146
+ and the player on the right showing it as it changes, with undo and redo
147
+ and the format's validation as you go. Photos are added by picking,
148
+ dropping or pasting, prepared in the browser (`optimizeImage`: resized,
149
+ metadata left behind) and stored once however many slides show them. It
150
+ edits the story; opening and saving files is up to you (the Story Editor page uses the File
151
+ System Access API where there is one, a download where not).
152
+
153
+ ```tsx
154
+ import "@mantine/core/styles.css";
155
+ import { MantineProvider } from "@mantine/core";
156
+ import { StoryEditor, pruneMedia } from "@gramps-connect/story/editor";
157
+ import { writeStoryZip } from "@gramps-connect/story";
158
+
159
+ let latest = { doc: story.doc, files: story.files };
160
+ <MantineProvider>
161
+ <StoryEditor initialStory={story.doc} initialFiles={story.files} onChange={(doc, files) => (latest = { doc, files })} />
162
+ </MantineProvider>
163
+
164
+ // Saving: leave out media nothing uses any more, then zip.
165
+ const saved = pruneMedia(latest.doc, latest.files);
166
+ const zip = await writeStoryZip(saved.doc, saved.files);
167
+ ```
168
+
169
+ A date is typed as readers should see it ("about 1850", "um 1850"), and its
170
+ precise form (EDTF, for the timeline and historical maps) is worked out
171
+ from it, in the story's language, by
172
+ [`@gramps-connect/gramps-date`](https://www.npmjs.com/package/@gramps-connect/gramps-date):
173
+ Gramps' own date parser, in all of Gramps' languages. Pass
174
+ `parseDateText` to use another. Fields the editor doesn't know are kept as
175
+ they are, so opening and saving a story never loses anything.
176
+
177
+ The editor is built with [Mantine](https://mantine.dev) 8 (optional peer
178
+ dependencies `@mantine/core` and `@mantine/hooks`, needed only by the
179
+ editor): wrap it in a `MantineProvider` and load Mantine's stylesheet. The
180
+ pieces it's made of (`SlideList`, `StoryTextField`, `DateField`,
181
+ `PhotosField`) and its editing functions (`addSlide`, `moveSlide`,
182
+ `updateSlide`, `addImage`, undo history, ...) are exported too.
183
+
135
184
  ## Writing stories from Python: `python/gramps_connect_story.py`
136
185
 
137
186
  One file, standard library only, for programs that aren't JavaScript.
@@ -168,13 +217,13 @@ identical.
168
217
  npm install
169
218
  npm test # Node tests (examples, versioning, validation, zip handling)
170
219
  npm run test:browser # in headless Google Chrome: optimizeImage(), the player,
171
- # the embed (cross-origin) and the viewer site
220
+ # the embed (cross-origin), the viewer site and the editor
172
221
  npm run test:pack # what npm would get, installed into an empty project
173
222
  npm run test:python # the Python writer, and its output read by this package
174
223
  npm run typecheck
175
224
  npm run generate # after editing spec/*/story.schema.json
176
225
  npm run build # dist/ (what npm users get)
177
- npm run build:site # site-dist/ (the viewer)
226
+ npm run build:site # site-dist/ (the viewer and the editor)
178
227
  ```
179
228
 
180
229
  Gramps Connect includes this repo as a git submodule and compiles `src/`