Skip to content

feat(digest): inline file thumbnails in the daily activity digest email#2548

Open
karlitschek wants to merge 1 commit intomasterfrom
feat/digest-email-previews
Open

feat(digest): inline file thumbnails in the daily activity digest email#2548
karlitschek wants to merge 1 commit intomasterfrom
feat/digest-email-previews

Conversation

@karlitschek
Copy link
Copy Markdown
Member

The daily activity digest currently lists each event with the provider's small icon URL. For file-related events that's a generic mime-type icon, which makes the digest feel like a server log rather than a "things that happened to your stuff today" summary. Show the actual file preview instead, when one is available.

DigestSender::getPreviewDataUri() resolves the file as the affected user (so access mirrors what the recipient sees in the web UI), generates a 96×96 preview via IPreview, and returns a base64 data URI inlined directly into the email — no public preview endpoint needed, and the digest renders fully offline.

Returns null on any failure (not a file event, file deleted, no read permission, preview generation unsupported, anything thrown). The existing $event->getIcon() is the seamless fallback, so existing behaviour is preserved for non-file or no-preview events.

The 96px cap keeps each thumbnail around 3-5 KB; even at the 20-event ACTIVITY_LIMIT the digest stays well under common message-size thresholds.

IRootFolder and IPreview are auto-wired through standard DI; DigestSender is not explicitly registered in Application.php, so no AppInfo change is needed.

The daily activity digest currently lists each event with the
provider's small icon URL. For file-related events that's a generic
mime-type icon, which makes the digest feel like a server log rather
than a "things that happened to your stuff today" summary. Show the
actual file preview instead, when one is available.

`DigestSender::getPreviewDataUri()` resolves the file as the affected
user (so access mirrors what the recipient sees in the web UI),
generates a 96×96 preview via `IPreview`, and returns a base64 data
URI inlined directly into the email — no public preview endpoint
needed, and the digest renders fully offline.

Returns null on any failure (not a file event, file deleted, no read
permission, preview generation unsupported, anything thrown). The
existing `$event->getIcon()` is the seamless fallback, so existing
behaviour is preserved for non-file or no-preview events.

The 96px cap keeps each thumbnail around 3-5 KB; even at the 20-event
ACTIVITY_LIMIT the digest stays well under common message-size
thresholds.

`IRootFolder` and `IPreview` are auto-wired through standard DI;
`DigestSender` is not explicitly registered in `Application.php`,
so no AppInfo change is needed.

Signed-off-by: Frank Karlitschek <frank@nextcloud.com>
@cypress
Copy link
Copy Markdown

cypress Bot commented May 2, 2026

Activity    Run #3636

Run Properties:  status check failed Failed #3636  •  git commit 3ef5825684: feat(digest): inline file thumbnails in the daily activity digest email
Project Activity
Branch Review feat/digest-email-previews
Run status status check failed Failed #3636
Run duration 01m 22s
Commit git commit 3ef5825684: feat(digest): inline file thumbnails in the daily activity digest email
Committer Frank Karlitschek
View all properties for this run ↗︎

Test results
Tests that failed  Failures 4
Tests that were flaky  Flaky 0
Tests that did not run due to a developer annotating a test with .skip  Pending 0
Tests that did not run due to a failure in a mocha hook  Skipped 13
Tests that passed  Passing 0
View all changes introduced in this branch ↗︎

Tests for review

Failed  sidebar.cy.ts • 1 failed test • Run E2E

View Output

Test Artifacts
Check activity listing in the sidebar > Has creation activity Test Replay Screenshots
Failed  screenshots.cy.ts • 2 failed tests • Run E2E

View Output

Test Artifacts
Documentation screenshots — user views > Activity stream > Activity app — main stream (all filter) Test Replay Screenshots
Documentation screenshots — admin views > Admin settings — notification toggle and default settings Test Replay Screenshots
Failed  settings.cy.ts • 1 failed test • Run E2E

View Output

Test Artifacts
Check that user's settings survive a reload > Form survive a reload Test Replay Screenshots

Comment thread lib/DigestSender.php
Comment on lines +249 to +264
$userFolder = $this->rootFolder->getUserFolder($uid);
$node = $userFolder->getFirstNodeById($event->getObjectId());
if (!$node instanceof File) {
return null;
}

if (!$this->previewManager->isAvailable($node)) {
return null;
}

$preview = $this->previewManager->getPreview($node, self::PREVIEW_PIXELS, self::PREVIEW_PIXELS, true);
$content = $preview->getContent();
if ($content === '') {
return null;
}
$mime = $preview->getMimeType() ?: 'image/png';
Copy link
Copy Markdown
Collaborator

@miaulalala miaulalala May 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This does image processing for every preview - and may be quite heavy for documents such as pdfs and office documents.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants