Skip to content

Polish Clean Air Forum selfie filter: branding copy, loader UX, camer…#3781

Merged
Baalmart merged 2 commits into
stagingfrom
feature/clean-air-forum-selfie-filter-mobile-fixes
Jul 9, 2026
Merged

Polish Clean Air Forum selfie filter: branding copy, loader UX, camer…#3781
Baalmart merged 2 commits into
stagingfrom
feature/clean-air-forum-selfie-filter-mobile-fixes

Conversation

@2phonebabykeem

@2phonebabykeem 2phonebabykeem commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

…a reliability

  • Correct the filter card wordmark ("Africa Clean Air Forum") and event date range (13TH-16TH JULY)
  • Stop echoing the submitter's display name/email in the "sent to wall" toast — the wall submission still carries it, just not shown in-app
  • Add a bordered status-banner palette (AppAlertColors) and inline loading state to the share sheet's message banner
  • Harden the camera screen against overlapping sessions, hung native camera calls, and lock-screen interruptions mid-capture

Summary of Changes (What does this PR do?)

  • Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. List any dependencies that are required for this change.

Status of maturity (all need to be checked before merging):

  • I've tested this locally
  • I consider this code done
  • This change ready to hit production in its current state
  • The title of the PR states what changed and the related issues number (used for the release note).
  • I've included issue number in the "Closes #ISSUE-NUMBER" part of the "What are the relevant tickets?" section to link the issue.
  • I've updated corresponding documentation for the changes in this PR.
  • I have written unit and/or e2e tests for my change(s).

How should this be manually tested?

  • Please include the steps to be done inorder to setup and test this PR.

What are the relevant tickets?

Screenshots (optional)

Summary by CodeRabbit

  • New Features
    • Share sheets now provide inline loading, success, and error states with a consistent banner.
    • Forum wall submissions start immediately when consent is enabled or after updating the selfie/filter preview.
  • Bug Fixes
    • Improved camera handling with timeouts and safer lifecycle reopen behavior to prevent freezes and stuck captures.
    • Failed wall submissions now offer a retry path and show clearer progress feedback.
  • Style
    • Updated forum branding text and corrected the event date range.

…a reliability

- Correct the filter card wordmark ("Africa Clean Air Forum") and event
  date range (13TH-16TH JULY)
- Stop echoing the submitter's display name/email in the "sent to wall"
  toast — the wall submission still carries it, just not shown in-app
- Add a bordered status-banner palette (AppAlertColors) and inline
  loading state to the share sheet's message banner
- Harden the camera screen against overlapping sessions, hung native
  camera calls, and lock-screen interruptions mid-capture
@coderabbitai

coderabbitai Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: e7766936-a8ca-48fc-bb1a-012eae9c39ff

📥 Commits

Reviewing files that changed from the base of the PR and between 0f82baa and b9ebee7.

📒 Files selected for processing (2)
  • src/mobile/lib/src/app/dashboard/widgets/clean_air_forum_camera_screen.dart
  • src/mobile/lib/src/app/dashboard/widgets/clean_air_forum_filter_tab.dart
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/mobile/lib/src/app/dashboard/widgets/clean_air_forum_camera_screen.dart
  • src/mobile/lib/src/app/dashboard/widgets/clean_air_forum_filter_tab.dart

📝 Walkthrough

Walkthrough

Updates Clean Air Forum branding text, adds alert colors and loading-aware inline messaging, hardens camera open/capture lifecycle handling, and changes selfie submission so it starts earlier and reports status through the shared banner.

Changes

Clean Air Forum branding, camera reliability, and wall submission with inline messaging

Layer / File(s) Summary
Branding text constants
src/mobile/lib/src/app/dashboard/utils/clean_air_forum_branding.dart
Updates the forum title and date range constants.
Alert color palette
src/mobile/lib/src/meta/utils/colors.dart
Adds AppAlertColors with theme-aware error/success background, border, and foreground colors.
Inline banner and messenger loading contract
src/mobile/lib/src/app/dashboard/widgets/share_sheet_widgets.dart
Extends ShareSheetMessenger and InlineMessageBanner with loading support, and updates banner rendering, layout, and action styling for loading, error, and success states.
Air quality share sheet loading state
src/mobile/lib/src/app/dashboard/widgets/air_quality_share_sheet.dart
Tracks inline loading state, extends _showMessage to accept loading, updates the accessibility announcement call, and wires the loading flag into the banner.
Camera controller timeout and lifecycle hardening
src/mobile/lib/src/app/dashboard/widgets/clean_air_forum_camera_screen.dart
Adds a camera operation timeout, serializes controller setup, applies timeout/recovery around capture, and adjusts lifecycle reopen behavior.
Selfie-to-wall submission flow
src/mobile/lib/src/app/dashboard/widgets/clean_air_forum_filter_tab.dart
Moves wall submission earlier in the selfie/consent flow, adds loading-based progress messaging, updates success/failure handling, and removes the inline sending indicator.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Possibly related PRs

Suggested labels: mobile-app

Suggested reviewers: Baalmart

Poem

A banner hums with loading light,
The camera wakes and stays in sight,
A selfie sails to wall and glow,
With colors calm and status shown,
The forum’s name walks out refined,
And timing keeps a steadier mind.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the branding, loader, and camera reliability updates in the Clean Air Forum selfie filter flow.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/clean-air-forum-selfie-filter-mobile-fixes

Warning

Review ran into problems

🔥 Problems

Errors were encountered while retrieving linked issues.

Errors (1)
  • JIRA integration encountered authorization issues. Please disconnect and reconnect the integration in the CodeRabbit UI.

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.

@coderabbitai coderabbitai 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.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/mobile/lib/src/app/dashboard/widgets/clean_air_forum_filter_tab.dart (1)

256-302: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Queue the latest wall submission instead of returning early

_isSendingToWall only blocks concurrent runs, so a second selfie picked while the first upload is in flight can capture the newer card but still exit at if (_isSendingToWall) return;. That makes the success message refer to the older photo, and consent off/on will submit the same selfie again. Store the latest pending bytes and rerun once the current submission settles.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/mobile/lib/src/app/dashboard/widgets/clean_air_forum_filter_tab.dart`
around lines 256 - 302, _queue the latest wall submission instead of dropping it
when `_isSendingToWall` is true. In `_submitToConferenceWall`, keep the most
recent `Uint8List` in a pending field (set from
`_submitCurrentSelfieToWall`/retry path) and, in the `finally` block, rerun the
submission once the in-flight upload finishes if a newer payload was queued.
This should be wired through `_submitCurrentSelfieToWall`,
`_submitToConferenceWall`, and the `_isSendingToWall` guard so the latest selfie
is submitted and the message/analytics match the newest card.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/mobile/lib/src/app/dashboard/widgets/clean_air_forum_camera_screen.dart`:
- Around line 165-176: Guard the AppLifecycleState.resumed reopen path in
CleanAirForumCameraScreen so it does not call _openCamera(_cameraIndex) when no
cameras were discovered. In the resume branch, check that _cameras is not empty
before reopening, since _openCamera indexes into _cameras directly and can crash
after permission denial or on devices without a camera. Keep the reopen call
unawaited for consistency with the existing camera open flows, and make the
check alongside the current _controller null/initialized guard in the lifecycle
handler.
- Around line 93-122: The _openCamera flow in clean_air_forum_camera_screen.dart
needs an in-flight guard because clearing _controller before initialization
completes allows resumed or retry-triggered calls to start another open while
the previous CameraController is still disposing or initializing. Add a
dedicated “camera opening”/“initializing” state check around _openCamera, set it
before teardown/init starts, and clear it on success, timeout, and dispose paths
so only one CameraController session can be active or transitioning at a time.

---

Outside diff comments:
In `@src/mobile/lib/src/app/dashboard/widgets/clean_air_forum_filter_tab.dart`:
- Around line 256-302: _queue the latest wall submission instead of dropping it
when `_isSendingToWall` is true. In `_submitToConferenceWall`, keep the most
recent `Uint8List` in a pending field (set from
`_submitCurrentSelfieToWall`/retry path) and, in the `finally` block, rerun the
submission once the in-flight upload finishes if a newer payload was queued.
This should be wired through `_submitCurrentSelfieToWall`,
`_submitToConferenceWall`, and the `_isSendingToWall` guard so the latest selfie
is submitted and the message/analytics match the newest card.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 2d03585c-1c90-4011-8512-07f9aec6eb4d

📥 Commits

Reviewing files that changed from the base of the PR and between 54bfeea and 0f82baa.

⛔ Files ignored due to path filters (1)
  • src/mobile/assets/icons/alert-circle.svg is excluded by !**/*.svg
📒 Files selected for processing (6)
  • src/mobile/lib/src/app/dashboard/utils/clean_air_forum_branding.dart
  • src/mobile/lib/src/app/dashboard/widgets/air_quality_share_sheet.dart
  • src/mobile/lib/src/app/dashboard/widgets/clean_air_forum_camera_screen.dart
  • src/mobile/lib/src/app/dashboard/widgets/clean_air_forum_filter_tab.dart
  • src/mobile/lib/src/app/dashboard/widgets/share_sheet_widgets.dart
  • src/mobile/lib/src/meta/utils/colors.dart

Copilot AI 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.

Pull request overview

Improves the Clean Air Forum selfie filter/share-sheet UX and reliability in the mobile app by aligning branding copy, adding clearer inline status feedback, and hardening camera/wall-submission flows.

Changes:

  • Introduces a new alert/banner color palette (AppAlertColors) and updates the share sheet inline banner to support loading + bordered success/error states.
  • Adjusts Clean Air Forum filter behavior to submit to the wall immediately upon consent/photo changes, and avoids displaying submitter identity in success copy.
  • Improves camera-session reliability by ensuring proper teardown between sessions and bounding camera operations with timeouts.

Reviewed changes

Copilot reviewed 6 out of 7 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/mobile/lib/src/meta/utils/colors.dart Adds AppAlertColors for theme-aware bordered success/error banner styling.
src/mobile/lib/src/app/dashboard/widgets/share_sheet_widgets.dart Extends share-sheet messenger API with loading and updates inline banner visuals (spinner/icons, borders).
src/mobile/lib/src/app/dashboard/widgets/clean_air_forum_filter_tab.dart Auto-submits to wall on consent/selfie changes; revises messaging to avoid echoing user identity.
src/mobile/lib/src/app/dashboard/widgets/clean_air_forum_camera_screen.dart Prevents overlapping camera sessions; adds timeouts and recovery paths for hung capture/init flows.
src/mobile/lib/src/app/dashboard/widgets/air_quality_share_sheet.dart Adds inline banner loading state support and updates accessibility announcement call.
src/mobile/lib/src/app/dashboard/utils/clean_air_forum_branding.dart Updates CAF wordmark copy and date range string.
src/mobile/assets/icons/alert-circle.svg Adds alert icon asset used by the updated inline banner.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +256 to +258
Future<void> _submitCurrentSelfieToWall() async {
if (widget.selfieFile == null) return;
final imageBytes = await captureShareBoundary(context, _filterKey);
Comment thread src/mobile/lib/src/app/dashboard/widgets/clean_air_forum_camera_screen.dart Outdated
// interruption case that surfaced it.
final controller = _controller;
if (controller == null || !controller.value.isInitialized) {
_openCamera(_cameraIndex);
- Guard _openCamera against re-entrancy: retry-on-failure and
  lifecycle-resume could both call it close together, opening two
  CameraController sessions at once and tripping the Camera2 HAL
- Don't reopen the camera on resume when no cameras were discovered
  (permission denied / cameraless device) — indexed into an empty list
- Check _isSendingToWall before rasterizing the filter card, not just
  before the network call, so a fast consent+photo-change race doesn't
  do a wasted capture pass
- Wrap the inactive-branch controller.dispose() in unawaited(), matching
  the rest of the file
@Baalmart
Baalmart merged commit 4bbb1f3 into staging Jul 9, 2026
22 of 24 checks passed
@Baalmart
Baalmart deleted the feature/clean-air-forum-selfie-filter-mobile-fixes branch July 9, 2026 17:11
@Baalmart Baalmart mentioned this pull request Jul 9, 2026
4 tasks
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.

3 participants