Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

## Specs

The specs in `specs/` are the source of truth. Start with `specs/README.md` (reading order, conventions), then `specs/01-architecture.md` (layout, package rules, how the apps are served). App specs: `specs/wonky_write/`, `specs/wonky_sheets/`, `specs/wonky_drive/` and `specs/wonky_slides/` (v2 decisions: `specs/v2-review.md`). Cross-app features: `specs/16-bugs-and-improvements.md` (Bugs & improvements board, M12); the RevLog sync of Sheets and Slides: `specs/17-revlog-sync.md`. When implementation reveals a better approach, update the spec in the same change.
The specs in `specs/` are the source of truth. Start with `specs/README.md` (reading order, conventions), then `specs/01-architecture.md` (layout, package rules, how the apps are served). App specs: `specs/wonky_write/`, `specs/wonky_sheets/`, `specs/wonky_drive/` and `specs/wonky_slides/` (v2 decisions: `specs/v2-review.md`). Cross-app features: `specs/16-bugs-and-improvements.md` (Bugs & improvements board, M12); the RevLog sync of Sheets and Slides: `specs/17-revlog-sync.md`. Blog submissions from Wonky Write (M14, built): `specs/18-publications-and-submissions.md`; the guide for blog owners is `docs/blog-integration.md`. When implementation reveals a better approach, update the spec in the same change.

Key rules from the specs: every user-visible action is a command and every state change is undoable (`specs/08-commands-and-undo.md`); single window, never open new tabs or windows (`specs/03-app-shell-and-navigation.md`); UI is built with `shad` and custom widgets in `wonky_ui` (`specs/02-design-system.md`); everything works in light and dark.

Expand Down
11 changes: 11 additions & 0 deletions TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,17 @@ committed and verified).
- PDF exports (client and server) cover Latin, Greek and Cyrillic with the bundled TTFs; CJK, Arabic and emoji fall back to placeholders until the fallback fonts are added.
- WYSIWYG Markdown composer (`wonky_rich_editor`, specs/16 §7.3): ☐ a code block's language can only be set when typing the fence; ☐ browser check of IME typing (the first keys after a click, fixed in the widget, see §7.3), paste, copy as Markdown, the spelling menu and the link dialog in the release builds; ☐ the composer's spelling language is the device locale (no per-field language).

## Publications & submissions (M14) — open items

Spec: `specs/18-publications-and-submissions.md` §13; guide: `docs/blog-integration.md`.

- [ ] Light/dark goldens of the consent dialog, submit dialog, status chip and Settings ›
Publications.
- [ ] E2E journey J-P1 (link → sign up → write → submit → changes requested → resubmit →
published) against a fake blog receiver, and a walkthrough against the live server.
- [ ] Moderators who sign up later get access only with the next submit or status change; grant
at sign-up instead.

## RevLog sync — open items

Sheets and Slides sync through RevLog (`specs/17-revlog-sync.md`); the CRDT engine, the sync
Expand Down
507 changes: 507 additions & 0 deletions docs/blog-integration.md

Large diffs are not rendered by default.

149 changes: 148 additions & 1 deletion packages/wonky_app/lib/l10n/wonky_app_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -3060,5 +3060,152 @@
"type": "String"
}
}
}
},
"settingsPublications": "Publications",
"@settingsPublications": {"description": "Wonky Work settings section: blogs that take stories from Wonky Write (specs/18)."},
"pubSectionHint": "Let people write for your blog in Wonky Write and send stories to your review queue with one button.",
"pubNew": "New publication",
"pubNewHint": "Wonky sends submitted stories to your webhook. You get the signing secret once, after you create the publication.",
"pubEdit": "Edit “{name}”",
"@pubEdit": {"placeholders": {"name": {"type": "String"}}},
"pubEditButton": "Edit…",
"pubGuide": "Developer guide",
"@pubGuide": {"description": "Opens the integration guide for blog owners."},
"pubEmpty": "You have no publications yet.",
"pubName": "Name",
"pubSiteUrl": "Site URL",
"pubWebhookUrl": "Webhook URL",
"pubTermsUrl": "Contributor terms URL (optional)",
"pubTemplate": "Template document (optional)",
"pubTemplateHint": "Paste a link to one of your Wonky Write documents",
"pubTemplateInvalid": "Paste the link of a Wonky Write document.",
"pubRequired": "Required.",
"pubHttpsOnly": "Use an https:// address.",
"pubFieldSummary": "Summary",
"pubFieldTags": "Tags",
"pubAllowedTags": "Allowed tags (optional)",
"pubAllowedTagsHint": "Comma separated; empty allows any tag",
"pubFieldCover": "Cover image",
"pubFieldBio": "Author bio",
"pubFieldNote": "Note to the moderators",
"pubFieldOff": "Not asked",
"pubFieldOptional": "Optional",
"pubFieldRequired": "Required",
"pubEnabled": "Accept new stories",
"pubHostVerified": "{host} ✓",
"@pubHostVerified": {"placeholders": {"host": {"type": "String"}}},
"pubHostUnverified": "{host} (not verified)",
"@pubHostUnverified": {"placeholders": {"host": {"type": "String"}}},
"pubDisabled": "Not accepting stories",
"pubOpenCount": "{count, plural, =0{No stories in review} =1{1 story in review} other{{count} stories in review}}",
"@pubOpenCount": {"placeholders": {"count": {"type": "int"}}},
"pubManage": "Manage",
"pubHide": "Hide",
"pubContributorLink": "Contributor link (put it behind “Write for us”)",
"pubId": "Publication id",
"pubCopy": "Copy",
"pubCopied": "Copied",
"pubDelete": "Delete",
"pubModerators": "Moderators",
"pubModeratorsHint": "Moderators get comment access to stories when they are submitted. Enter the email addresses of their Wonky accounts, one per line.",
"pubModeratorEmails": "Email addresses",
"pubModeratorsButton": "{count, plural, =0{Add moderators…} =1{1 moderator…} other{{count} moderators…}}",
"@pubModeratorsButton": {"placeholders": {"count": {"type": "int"}}},
"pubVerification": "Verification",
"pubVerifyHint": "Serve this at https://{host}/.well-known/wonky-publications.json, then verify. Until then contributors see your webhook's host and a warning.",
"@pubVerifyHint": {"placeholders": {"host": {"type": "String"}}},
"pubVerifiedAt": "{host} verified {date}",
"@pubVerifiedAt": {"placeholders": {"host": {"type": "String"}, "date": {"type": "String"}}},
"pubVerify": "Verify",
"pubVerified": "{host} is verified",
"@pubVerified": {"placeholders": {"host": {"type": "String"}}},
"pubVerifyFailed": "Not verified",
"pubCredentials": "Signing secret and API key",
"pubSecretHint": "Webhooks are signed with the signing secret. Your server calls the publication API with the API key.",
"pubRotationActive": "The previous signing secret still signs until {date}.",
"@pubRotationActive": {"placeholders": {"date": {"type": "String"}}},
"pubRotateSecret": "Rotate signing secret",
"pubRotateSecretBody": "You get a new secret. For 24 hours, webhooks carry signatures of the old and the new secret.",
"pubRotate": "Rotate",
"pubCreateApiKey": "Create API key",
"pubRotateApiKey": "Rotate API key",
"pubRotateApiKeyLast4": "Rotate API key (…{last4})",
"@pubRotateApiKeyLast4": {"placeholders": {"last4": {"type": "String"}}},
"pubRotateApiKeyBody": "The current key stops working at once.",
"pubApiKey": "API key",
"pubSigningSecret": "Signing secret",
"pubSecretOnce": "Copy the {what} now. It isn't shown again.",
"@pubSecretOnce": {"placeholders": {"what": {"type": "String"}}},
"pubSecretSaved": "I've stored it",
"pubDeliveries": "Deliveries",
"pubSendTest": "Send test",
"pubTestOk": "Your webhook accepted the test.",
"pubTestFailed": "Your webhook didn't accept the test",
"pubNoDeliveries": "No webhooks sent yet.",
"pubDelivered": "Delivered (HTTP {status_code})",
"@pubDelivered": {"placeholders": {"status_code": {"type": "int"}}},
"pubDeliveryFailed": "Failed: {error}",
"@pubDeliveryFailed": {"placeholders": {"error": {"type": "String"}}},
"pubDeliveryQueued": "Queued",
"pubDeliveryRetrying": "{error} · next try {date}",
"@pubDeliveryRetrying": {"placeholders": {"error": {"type": "String"}, "date": {"type": "String"}}},
"pubResend": "Resend",
"pubDeleteTitle": "Delete “{name}”?",
"@pubDeleteTitle": {"placeholders": {"name": {"type": "String"}}},
"pubDeleteBody": "Contributors' documents stay in their drives, but they can't submit them anymore, and moderators lose access. Your blog gets no webhook about it.",
"notifySubmissions": "Stories for publications",
"@notifySubmissions": {"description": "Notification settings: messages and status changes from blogs."},
"notifySubmissionsHint": "Status changes and messages from blogs you write for",
"notifSubmissionChanges": "{publication} asked for changes to “{what}”",
"@notifSubmissionChanges": {"placeholders": {"publication": {"type": "String"}, "what": {"type": "String"}}},
"notifSubmissionDeclined": "{publication} declined “{what}”",
"@notifSubmissionDeclined": {"placeholders": {"publication": {"type": "String"}, "what": {"type": "String"}}},
"notifSubmissionPublished": "{publication} published “{what}”",
"@notifSubmissionPublished": {"placeholders": {"publication": {"type": "String"}, "what": {"type": "String"}}},
"notifSubmissionInReview": "{publication} is reviewing “{what}”",
"@notifSubmissionInReview": {"placeholders": {"publication": {"type": "String"}, "what": {"type": "String"}}},
"notifSubmissionMessage": "{publication} sent a message about “{what}”",
"@notifSubmissionMessage": {"placeholders": {"publication": {"type": "String"}, "what": {"type": "String"}}},
"notifSubmissionFailed": "{publication} couldn't receive “{what}”",
"@notifSubmissionFailed": {"placeholders": {"publication": {"type": "String"}, "what": {"type": "String"}}},
"shareModerator": "Moderator · {publication}",
"@shareModerator": {"placeholders": {"publication": {"type": "String"}}},
"activitySubmitted": "{who} submitted it to {publication}",
"@activitySubmitted": {"placeholders": {"who": {"type": "String"}, "publication": {"type": "String"}}},
"activitySubmissionWithdrawn": "{who} withdrew it from {publication}",
"@activitySubmissionWithdrawn": {"placeholders": {"who": {"type": "String"}, "publication": {"type": "String"}}},
"activitySubmissionDisconnected": "{who} disconnected it from {publication}",
"@activitySubmissionDisconnected": {"placeholders": {"who": {"type": "String"}, "publication": {"type": "String"}}},
"activitySubmissionReconnected": "{who} connected it to {publication} again",
"@activitySubmissionReconnected": {"placeholders": {"who": {"type": "String"}, "publication": {"type": "String"}}},
"activitySubmissionStatus": "{publication}: {status}",
"@activitySubmissionStatus": {"placeholders": {"publication": {"type": "String"}, "status": {"type": "String"}}},
"submissionStatusDraft": "Draft",
"@submissionStatusDraft": {"description": "Status of a story for a publication."},
"submissionStatusInReview": "In review",
"submissionStatusChangesRequested": "Changes requested",
"submissionStatusDeclined": "Declined",
"submissionStatusPublished": "Published",
"submissionStatusWithdrawn": "Withdrawn",
"pubStartTitle": "Write for {name}",
"@pubStartTitle": {"description": "Consent dialog of a contributor link (specs/18 §3).", "placeholders": {"name": {"type": "String"}}},
"pubStartHostVerified": "{host} ✓",
"@pubStartHostVerified": {"placeholders": {"host": {"type": "String"}}},
"pubStartHostUnverified": "Wonky hasn't verified that this publication belongs to {site}. Your story is sent to {webhook}.",
"@pubStartHostUnverified": {"placeholders": {"site": {"type": "String"}, "webhook": {"type": "String"}}},
"pubStartConsent": "You'll write in your own Wonky document. When you press Submit, {name} receives the text and images of the document, the fields you fill in and your display name, and its moderators can read and comment on the document.",
"@pubStartConsent": {"placeholders": {"name": {"type": "String"}}},
"pubStartWhich": "Story",
"pubStartContinue": "Continue “{name}”",
"@pubStartContinue": {"placeholders": {"name": {"type": "String"}}},
"pubStartNew": "Start a new story",
"pubStartTerms": "I agree to {name}'s contributor terms ({url})",
"@pubStartTerms": {"placeholders": {"name": {"type": "String"}, "url": {"type": "String"}}},
"pubStartTermsRequired": "Agree to {name}'s contributor terms to start.",
"@pubStartTermsRequired": {"placeholders": {"name": {"type": "String"}}},
"pubStartButton": "Start writing",
"pubStartBlocked": "{name} isn't accepting stories from you.",
"@pubStartBlocked": {"placeholders": {"name": {"type": "String"}}},
"pubStartClosed": "{name} isn't accepting stories right now.",
"@pubStartClosed": {"placeholders": {"name": {"type": "String"}}}
}
Loading
Loading