Per-user intro versioning + admin pending-delivery view
Replaces "clear intro after first send", which dropped the message for any subscriber still queued on a slower cadence. - Each non-empty admin save bumps a per-locale version counter on the tree. The dispatcher includes the intro only for recipients whose last-seen version is behind, then advances their watermark after a successful send. Webtrees users get a per-user watermark; external addresses share one tree-level watermark. Re-saving the same text is a no-op. - The preferences page now shows delivery progress per locale: "Delivered to X of Y subscriber(s)" plus a collapsible Pending list with name + email of each subscriber who hasn't received the current intro yet, and a single "External recipients (N)" row when the external watermark is behind. - README rewritten to reflect every feature shipped since the initial commit (BockenTheme skin, embedded avatars, relationship labels, kin-distance filter, per-user cadence, bilingual subject prefix, locale-aware subject date, SiteUser as From, three subscriber sources, Markdown intro with personalisation tokens).
This commit is contained in:
@@ -173,9 +173,16 @@ class Module extends AbstractModule implements ModuleCustomInterface, ModuleConf
|
||||
'Intro paragraph for the next email' => 'Einleitungsabsatz für die nächste E-Mail',
|
||||
'Shown once, above the upcoming events. Cleared automatically after the next successful send.'
|
||||
=> 'Wird einmalig über den anstehenden Ereignissen angezeigt. Wird nach dem nächsten erfolgreichen Versand automatisch geleert.',
|
||||
'Delivered once to every subscriber on their own cadence. Edit and save the text to send a new intro to everyone.'
|
||||
=> 'Wird jedem Abonnenten einmalig in seinem eigenen Versandrhythmus zugestellt. Text bearbeiten und speichern, um eine neue Einleitung an alle zu versenden.',
|
||||
'Personalisation tokens:' => 'Personalisierungs-Platzhalter:',
|
||||
'Formatted as Markdown — e.g. %1$s for emphasis, %2$s for a link.'
|
||||
=> 'Formatiert als Markdown — z. B. %1$s für Hervorhebung, %2$s für einen Link.',
|
||||
'Delivered to all %d subscriber(s).' => 'An alle %d Abonnenten zugestellt.',
|
||||
'Delivered to %1$d of %2$d subscriber(s).' => 'An %1$d von %2$d Abonnenten zugestellt.',
|
||||
'Pending' => 'Ausstehend',
|
||||
'External recipients (%d)' => 'Externe Empfänger (%d)',
|
||||
'Save to schedule delivery.' => 'Speichern, um die Zustellung zu starten.',
|
||||
],
|
||||
'nl' => [
|
||||
'Email Newsletter' => 'E-mailnieuwsbrief',
|
||||
@@ -293,7 +300,17 @@ class Module extends AbstractModule implements ModuleCustomInterface, ModuleConf
|
||||
$intro = Validator::parsedBody($request)
|
||||
->string('intro-' . $id . '-' . $code, '');
|
||||
|
||||
// Bump the version only when the saved text actually
|
||||
// changed AND is non-empty. That makes "save the same
|
||||
// intro again" a no-op (no resends), while saving a
|
||||
// new non-empty paragraph re-delivers it to every
|
||||
// subscriber on their own cadence.
|
||||
$previous = Configuration::introForLocale($this, $tree, $code);
|
||||
Configuration::setIntroForLocale($this, $tree, $code, $intro);
|
||||
|
||||
if ($intro !== '' && $intro !== $previous) {
|
||||
Configuration::bumpIntroVersion($this, $tree, $code);
|
||||
}
|
||||
}
|
||||
|
||||
// Per-user subscription toggles. A users-roster marker is
|
||||
|
||||
Reference in New Issue
Block a user