Conversation
There was a problem hiding this comment.
Pull request overview
Adds support for attaching screenshot images to issue reports, flowing from the Flutter UI through platform/FFI layers into lantern-core so Radiance can receive the additional attachments (in addition to the existing logs/config attachments).
Changes:
- Introduces attachment picking (file selector + desktop drag/drop), draft persistence, validation rules, and UI presentation for up to 3 images.
- Extends the report-issue submission pipeline (Flutter submitter + platform channel + FFI + Go core) to accept and forward attachments as JSON metadata and file contents.
- Adds unit/widget tests covering attachment rules, budgeting, draft behavior, and submitter forwarding.
Reviewed changes
Copilot reviewed 35 out of 37 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| windows/flutter/generated_plugins.cmake | Registers new Windows plugins required for file picking / desktop drop. |
| windows/flutter/generated_plugin_registrant.cc | Registers new Windows plugins required for file picking / desktop drop. |
| linux/flutter/generated_plugins.cmake | Registers new Linux plugins required for file picking / desktop drop. |
| linux/flutter/generated_plugin_registrant.cc | Registers new Linux plugins required for file picking / desktop drop. |
| macos/Flutter/GeneratedPluginRegistrant.swift | Registers new macOS plugins required for file picking / desktop drop. |
| macos/Runner/Handlers/MethodHandler.swift | Passes attachment JSON through the macOS method channel into the mobile/core layer. |
| ios/Runner/Handlers/MethodHandler.swift | Passes attachment JSON through the iOS method channel into the mobile/core layer. |
| android/app/src/main/kotlin/org/getlantern/lantern/handler/MethodHandler.kt | Builds attachment JSON from method-channel args and forwards into Mobile.reportIssue. |
| pubspec.yaml | Adds file_selector, desktop_drop, cross_file dependencies. |
| pubspec.lock | Locks new direct and transitive dependency versions. |
| lib/lantern/lantern_core_service.dart | Updates core service API to include attachments in reportIssue. |
| lib/lantern/lantern_service.dart | Threads attachments through the service wrapper to FFI/platform implementations. |
| lib/lantern/lantern_platform_service.dart | Sends attachments over method channel as JSON maps. |
| lib/lantern/lantern_generated_bindings.dart | Updates FFI binding signature to include attachmentsJSON. |
| lib/lantern/lantern_ffi_service.dart | Encodes attachments JSON and forwards via FFI to Go. |
| lib/features/report_issue/models/report_issue_attachment.dart | Adds attachment model + JSON serialization. |
| lib/features/report_issue/models/report_issue_attachment_rules.dart | Defines attachment limits/validation and formatting helpers. |
| lib/features/report_issue/provider/report_issue_draft_notifier.dart | Persists attachments + attachment errors in the report-issue draft state. |
| lib/features/report_issue/services/report_issue_attachment_picker.dart | Implements image picking + dropped-file loading and macOS security-scoped bookmark capture. |
| lib/features/report_issue/services/report_issue_attachment_access.dart | Restores/releases macOS security-scoped access during submission. |
| lib/features/report_issue/services/report_issue_attachment_budget.dart | Computes reserved byte budget from existing logs/config so image limits account for them. |
| lib/features/report_issue/services/report_issue_submitter.dart | Centralizes submission: validates totals, resolves device/log file, scopes access, calls LanternService. |
| lib/features/report_issue/widgets/report_issue_attachment_dropzone.dart | Adds UI dropzone with dashed border + desktop drag/drop handling. |
| lib/features/report_issue/report_issue.dart | Integrates attachment section into the report issue screen and submission flow. |
| lantern-core/utils/common.go | Sets MIME type for the flutter log attachment. |
| lantern-core/report_issue_attachments.go | Parses attachment JSON, reads files from disk, creates Radiance attachments. |
| lantern-core/report_issue_attachments_test.go | Tests attachment parsing/loading and size-mismatch rejection. |
| lantern-core/mobile/mobile.go | Extends mobile wrapper ReportIssue signature to accept attachmentsJSON. |
| lantern-core/ffi/ffi.go | Extends exported FFI reportIssue signature to accept attachmentsJSON. |
| lantern-core/core.go | Extends core ReportIssue to load/append issue attachments and updates interface signature. |
| go.mod | Updates radiance dependency version used for attachments behavior. |
| go.sum | Adds checksums for updated radiance pseudo-version. |
| test/features/report_issue/report_issue_test.dart | Expands widget tests to cover attachment add/remove, validation, and legacy no-attachments path. |
| test/features/report_issue/report_issue_submitter_test.dart | Adds tests verifying forwarding, oversize rejection, and security-scoped access failure handling. |
| test/features/report_issue/report_issue_draft_notifier_test.dart | Adds tests for storing/removing attachments and validation errors in the draft notifier. |
| test/features/report_issue/report_issue_attachment_rules_test.dart | Adds tests for MIME canonicalization behavior. |
| test/features/report_issue/report_issue_attachment_budget_test.dart | Adds tests for reserved byte computation across config/log sources. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
#8704 (Add screenshot attachments to issue reports — open against main) changes LanternCore.ReportIssue in a different direction: it adds an attachmentsJSON string param with a ReportIssueAttachment struct (name/path/mimeType/sizeBytes), whereas this PR had added a separate ReportIssueWithAttachments method taking []string. Two conflicting APIs for the same concept would collide hard when refactor eventually absorbs main. Defer the UI log auto-attach to a follow-up that adopts #8704's mechanism once it lands. Immediate impact for Derek: lantern-core.log still gets written (the general SetupLogging fix is unchanged), but he'll have to grab it manually from C:\Users\Public\Lantern\logs until #8704 propagates here and we wire auto-attach through its attachmentsJSON. Reverts just the ReportIssueWithAttachments plumbing from the previous commit. SetupLogging + apps_windows slog summaries stay. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Heads up — there's a use case on the refactor branch that would benefit from the mechanism in this PR. Context: in #8706 I added I also had an auto-attach of Proposal: when this PR lands and the refactor branch picks it up, add a small FFI-side helper that appends the UI-logDir No action for you here. Just flagging so you're not surprised when refactor starts depending on your signature. |
Two corrections: 1) SetupLogging doc was wrong about which platforms run the daemon in-process. Only Android does (UI + VPN service share a process). iOS and macOS talk to Network/System Extensions over XPC; Windows and Linux talk to lanternd over a named pipe. On all four of those, the UI process loads lanterncore as a library without the daemon's common.Init ever running, so slog goes to stderr = nowhere. Updated the doc accordingly — the fix is useful everywhere except Android. 2) Report Issue already globs *.log from the daemon's logDir via buildIssueArchive, but the UI process writes flutter.log and (now) lantern-core.log to a DIFFERENT dir — the daemon's glob never sees them. Added lanterncore.LogDir() which returns the logDir registered by SetupLogging, and have LanternCore.ReportIssue glob *.log from it and append to the additional attachments before handing off to the IPC client. No Core interface change — LogDir() is a package-level accessor that just reads the dir SetupLogging stashed. On Android (where SetupLogging is never called) LogDir() returns "" and ReportIssue behaves exactly as before. Also leaves Core.ReportIssue signature untouched so this stays compatible with #8704 (screenshot attachments); that PR's attachmentsJSON is layered on top of this same additional-path mechanism, not a replacement for it. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…screenshot # Conflicts: # go.mod # go.sum # lib/lantern/lantern_ffi_service.dart
…screenshot # Conflicts: # go.mod # go.sum
Resolves https://github.com/getlantern/engineering/issues/3164