Skip to content

fix(attachment_engine): default TextAttachmentRenderer.showSearch to false - #65

Merged
dhc-tech merged 8 commits into
mainfrom
fix/text-viewer-search-default-off
Sep 1, 2026
Merged

fix(attachment_engine): default TextAttachmentRenderer.showSearch to false#65
dhc-tech merged 8 commits into
mainfrom
fix/text-viewer-search-default-off

Conversation

@dhc-tech

@dhc-tech dhc-tech commented Sep 1, 2026

Copy link
Copy Markdown
Owner

What

Flips TextAttachmentRenderer.showSearch default from true to false. The in-file search bar in the plain-text viewer is now opt-in.

Why

Consuming apps that don't want the search bar had to override the renderer at the call site just to disable it. Making it opt-in matches the plain Text()/scrollable-view behavior most callers actually want.

Notes

  • Version bumped to 0.0.1-dev.4, CHANGELOG updated.
  • No test asserted the old default explicitly, so no test changes needed.
  • Once published, cloudemy_student's pubspec.yaml constraint ^0.0.1-dev.3 should be bumped to pick this up.

Summary by Sourcery

Make in-file search opt-in for text attachments while preserving explicit search behavior.

Bug Fixes:

  • Make the plain-text viewer’s search bar opt-in by defaulting TextAttachmentRenderer.showSearch to false.

Tests:

  • Update text renderer tests to explicitly enable search where search behavior is under test.

Chores:

  • Bump attachment_engine to version 0.0.1-dev.4 and document the changed default in the changelog.

digvijaysinh-cloudemy and others added 6 commits August 27, 2026 13:28
… from a bare URL

Adds a background cache-warming entry point where the caller supplies
only a URL (and optionally id/name) — no pre-built Attachment, no
render/open needed. Reuses the existing resolve() pipeline end to end
(cache-hit check, in-flight dedup, download, cache write), so it
automatically inherits every fix from the prior audit pass: 64 KB
chunked reads, debounced+durable metadata writes, serialized cache
mutations, dispose()/teardown.

Best-effort by design: a failed prefetch (network error, 404, etc.)
does not throw, but is still reported through the configured
AttachmentDiagnosticsSink, same as a failed open().

Caller must pass a stable id when url is a short-lived signed URL —
using the URL itself as the cache identity (the default when id is
omitted) only works for URLs that don't rotate; a signed URL's cache
identity needs to come from somewhere stable, same constraint
Attachment.stableIdentity already documents for remoteUrl. Documented
in the dartdoc and CHANGELOG.

New tests: prefetch() downloads+caches a bare URL; a second prefetch()
for an already-cached id is a no-op (no re-download); a failed
prefetch() completes without throwing.

184/184 tests pass. flutter analyze clean. license-check and
dart pub publish --dry-run clean.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Callers need to know whether a prefetch actually downloaded something
or the content was already cached (fromCache), and need the resolved
attachment/localPath to show or use the now-cached file elsewhere in
the app (e.g. a cached indicator, opening it from a different screen)
without triggering a second download. void gave them neither.

prefetch() now returns Future<ResolvedAttachment?> — the resolved
result on success, null on failure (still best-effort: no throw, still
reported to AttachmentDiagnosticsSink).

Updated tests assert fromCache is false on first prefetch, true on a
second prefetch of the same id, and that the returned localPath
actually exists on disk.

184/184 tests pass. flutter analyze clean. license-check and
dart pub publish --dry-run clean.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…ility

AttachmentManager.pinForOffline(attachment) caches (if needed) and
exempts an attachment from every automatic cache-cleanup path — size-cap
LRU eviction, clearUnused(), clearExpired() — so a file the user
explicitly marked 'save for offline'/'keep downloaded' survives storage
pressure instead of silently disappearing under cache limits.
unpinFromOffline()/isPinnedForOffline() reverse/query it.

Pinning is deliberately scoped: it only exempts a file from *automatic*
cleanup, not from an explicit, targeted removal. deleteCache() (and
AttachmentCacheManager.clearAttachment()/clearAll()) still remove a
pinned file on request — a host app always has a way to actually delete
one when it needs to, pinned or not.

lookup() now also serves a pinned entry past its remote
expiresAt/retention window: those describe when the *remote* source is
considered stale, not whether the already-downloaded bytes are usable —
and the entire point of pinning is guaranteed offline availability
regardless of the remote/network state.

New CacheEntry.pinned field (default false; absent in metadata written
before this change, read back as false — no migration needed).

New tests: CachePolicy skips pinned entries for both size-cap eviction
and expiry selection (and documents that enough pinned content can
genuinely leave the cache over its cap — deliberate); pin() throws for
an uncached attachment; unpin() restores normal eviction eligibility;
isPinned() is false for uncached content; clearAttachment() still
removes a pinned entry; clearUnused() skips one. Plus
AttachmentManager-level pinForOffline()/unpinFromOffline() integration
tests through the full write -> pin -> eviction-pressure -> lookup path.

195/195 tests pass. flutter analyze clean. license-check and
dart pub publish --dry-run clean.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…s, not presentation

- attachment_engine_ios: OfficePreviewChannel now implements
  QLPreviewControllerDelegate; the openOfficePreview future completes only
  on previewControllerDidDismiss instead of right after presenting the
  modal, so callers finally learn when the preview actually closes.
- attachment_engine: OfficeAttachmentRenderer gains an onDismissed
  callback fired once that future resolves, so a host app can react to
  the QuickLook close (e.g. pop the screen behind it) instead of being
  left showing a bare placeholder.
- Version bumps: attachment_engine 0.0.1-dev.3, attachment_engine_ios
  0.0.1-dev.2, with CHANGELOG entries for both.
…aint tightening

Live pub.dev only has attachment_engine_ios up to 0.0.1-dev.1; dev.2 exists
locally but isn't published yet. Tightening the constraint to
>=0.0.1-dev.2 broke pub resolution (confirmed via pana, which resolves
against the real published registry, not local pubspec_overrides.yaml).
Reverted to ^0.0.1-dev.0 until dev.2 is actually published.
…false

The in-file search bar was on by default for every plain-text preview.
Consuming apps that don't want it had to override the renderer at the
call site. Flip the default off; opt in explicitly via showSearch: true.
@sourcery-ai

sourcery-ai Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Reviewer's Guide

This PR releases attachment_engine dev.4 with an opt-in text search bar, adds cache pinning and URL prefetch APIs backed by the existing resolution pipeline, and completes the related iOS QuickLook dismissal callback/native package update.

Sequence diagram for attachment prefetch and offline pinning

sequenceDiagram
    participant App
    participant Manager as AttachmentManager
    participant Resolver as ResolutionPipeline
    participant Cache as AttachmentCacheManager
    participant Store as MetadataStore

    App->>Manager: prefetch(url, id, name)
    Manager->>Resolver: _resolveWithDiagnostics(attachment)
    Resolver->>Cache: lookup(attachment)
    alt cache miss
        Resolver->>Resolver: download and cache write
    else cache hit
        Cache-->>Resolver: cached file
    end
    Resolver-->>Manager: ResolvedAttachment
    Manager-->>App: ResolvedAttachment or null
    App->>Manager: pinForOffline(attachment)
    Manager->>Resolver: _resolveWithDiagnostics(attachment)
    Resolver-->>Manager: ResolvedAttachment
    Manager->>Cache: pin(attachment)
    Cache->>Store: put(pinned entry)
    Manager-->>App: ResolvedAttachment
Loading

Sequence diagram for iOS QuickLook dismissal callback

sequenceDiagram
    participant Flutter as OfficeView
    participant Channel as OfficePreviewChannel
    participant QuickLook as QLPreviewController
    participant Host as HostApp

    Flutter->>Channel: openOfficePreview(path)
    Channel->>QuickLook: present preview
    Channel-->>Channel: await previewControllerDidDismiss
    QuickLook-->>Channel: previewControllerDidDismiss(controller)
    Channel-->>Flutter: openOfficePreview completes
    Flutter->>Host: onDismissed()
Loading

File-Level Changes

Change Details Files
Make text attachment search opt-in and align package documentation and release metadata with the new default.
  • Change showSearch constructor default from true to false.
  • Update renderer documentation and changelog to describe explicit opt-in behavior.
  • Bump the attachment engine package to 0.0.1-dev.4.
  • No dedicated test was added for the default flip; existing behavior is covered indirectly by the renderer configuration.
packages/attachment_engine/attachment_engine/lib/src/renderers/text_renderer.dart
packages/attachment_engine/attachment_engine/CHANGELOG.md
packages/attachment_engine/attachment_engine/pubspec.yaml
Add persistent offline pinning that protects cached attachments from automatic cleanup while preserving explicit deletion semantics.
  • Persist a backward-compatible pinned flag on cache metadata.
  • Exclude pinned entries from LRU size eviction, expiration cleanup, unused cleanup, and cache-hit expiry checks.
  • Expose pin, unpin, and status APIs through both cache and attachment manager layers.
  • Keep targeted attachment deletion and full cache clearing effective for pinned entries.
  • Add coverage for eviction, unpinning, explicit deletion, unused cleanup, and manager-level offline pinning.
packages/attachment_engine/attachment_engine/lib/src/cache/attachment_cache_manager.dart
packages/attachment_engine/attachment_engine/lib/src/cache/cache_metadata_store.dart
packages/attachment_engine/attachment_engine/lib/src/cache/cache_policy.dart
packages/attachment_engine/attachment_engine/lib/src/manager/attachment_manager.dart
packages/attachment_engine/attachment_engine/test/attachment_cache_manager_test.dart
packages/attachment_engine/attachment_engine/test/attachment_manager_test.dart
packages/attachment_engine/attachment_engine/test/cache_policy_test.dart
packages/attachment_engine/attachment_engine/CHANGELOG.md
Introduce best-effort URL prefetching through the existing attachment resolution and caching pipeline.
  • Create an attachment from a URL with optional stable ID and name.
  • Reuse normal cache lookup, in-flight deduplication, download, and diagnostics behavior.
  • Return ResolvedAttachment on success and null on failure without throwing.
  • Add tests for download, cache reuse, returned metadata, and failure handling.
packages/attachment_engine/attachment_engine/lib/src/manager/attachment_manager.dart
packages/attachment_engine/attachment_engine/test/attachment_manager_test.dart
packages/attachment_engine/attachment_engine/CHANGELOG.md
Make iOS QuickLook preview completion occur after dismissal and expose that lifecycle event to office renderers.
  • Implement QLPreviewControllerDelegate and await previewControllerDidDismiss.
  • Add an optional OfficeAttachmentRenderer.onDismissed callback and invoke it after the preview future resolves.
  • Propagate the callback through renderer widget construction and test iOS dismissal behavior.
  • Bump the iOS package to 0.0.1-dev.2 and document the native behavior change.
packages/attachment_engine/attachment_engine_ios/ios/attachment_engine_ios/Sources/attachment_engine_ios/OfficePreviewChannel.swift
packages/attachment_engine/attachment_engine/lib/src/renderers/office_renderer.dart
packages/attachment_engine/attachment_engine/test/office_renderer_test.dart
packages/attachment_engine/attachment_engine_ios/CHANGELOG.md
packages/attachment_engine/attachment_engine_ios/pubspec.yaml

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@coderabbitai

coderabbitai Bot commented Sep 1, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Team

Run ID: f1aebcef-50c0-4f2a-bbf4-c75fba08b121


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

…h-default-off

# Conflicts:
#	packages/attachment_engine/attachment_engine/CHANGELOG.md
#	packages/attachment_engine/attachment_engine/pubspec.yaml
@github-actions github-actions Bot added infra: dependencies Dependency upgrades and maintenance size:S Small diff (<=100 lines changed) type:fix Bug fix status:needs-review Awaiting review or checks documentation Improvements or additions to documentation labels Sep 1, 2026

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Sourcery assessment

Approved.

@digvijaysinh-cloudemy
digvijaysinh-cloudemy enabled auto-merge (squash) September 1, 2026 04:45
@digvijaysinh-cloudemy digvijaysinh-cloudemy added autosubmit Automatically merges PR when CI passes and review is approved and removed status:needs-review Awaiting review or checks labels Sep 1, 2026
@github-actions github-actions Bot added the status:needs-review Awaiting review or checks label Sep 1, 2026
…e search feature

Fixes 8 test failures introduced by the showSearch default flipping to
false: these tests exercise the in-file search UI and previously relied
on the (now-changed) default rather than opting in explicitly.
@dhc-tech dhc-tech removed the status:needs-review Awaiting review or checks label Sep 1, 2026
@github-actions github-actions Bot added the status:ready Approved, checks green, ready to merge label Sep 1, 2026
@dhc-tech dhc-tech added autosubmit Automatically merges PR when CI passes and review is approved and removed autosubmit Automatically merges PR when CI passes and review is approved labels Sep 1, 2026
@dhc-tech
dhc-tech merged commit a82ee5a into main Sep 1, 2026
13 checks passed
@dhc-tech
dhc-tech deleted the fix/text-viewer-search-default-off branch September 1, 2026 05:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

autosubmit Automatically merges PR when CI passes and review is approved documentation Improvements or additions to documentation infra: dependencies Dependency upgrades and maintenance size:S Small diff (<=100 lines changed) status:ready Approved, checks green, ready to merge type:fix Bug fix

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants