Enhancement of Updates screen for Patient app#154
Enhancement of Updates screen for Patient app#154hasanravda wants to merge 6 commits intoAOSSIE-Org:mainfrom
Conversation
…deos and articles, added demo blogs link and videos
|
Warning Rate limit exceeded
⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughAdded INTERNET permission and intent queries; added Changes
Sequence DiagramsequenceDiagram
actor User
participant UpdatesScreen as "Updates Screen"
participant URLValidator as "URL Validator"
participant ExternalApp as "External App"
participant PlatformDefault as "Platform Default"
participant InAppWebView as "In-App WebView"
participant ErrorHandler as "Error Handler"
User->>UpdatesScreen: Tap video/article
UpdatesScreen->>URLValidator: validate URL
alt invalid
URLValidator->>ErrorHandler: invalid URL
ErrorHandler->>User: show validation error
else valid
UpdatesScreen->>ExternalApp: try launch (externalApplication)
alt success
ExternalApp->>User: opened externally
else failure
UpdatesScreen->>PlatformDefault: try launch (platformDefault)
alt success
PlatformDefault->>User: opened by platform handler
else failure
UpdatesScreen->>InAppWebView: try launch (inAppWebView)
alt success
InAppWebView->>User: opened in app
else failure
InAppWebView->>ErrorHandler: launch failed
ErrorHandler->>User: show launch error
end
end
end
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~22 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
patient/android/app/src/main/AndroidManifest.xml (1)
4-56:⚠️ Potential issue | 🟠 MajorAdd
android:category="android.intent.category.BROWSABLE"to the http/https intent filters.The official Android documentation for url_launcher on Android 11+ recommends including the
BROWSABLEcategory in intent queries, which is missing from bothVIEWintents. Update both http and https intent filters:Recommended intent structure
<intent> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.BROWSABLE" /> <data android:scheme="https" /> </intent> <intent> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.BROWSABLE" /> <data android:scheme="http" /> </intent>Also verify that
<queries>is placed as a direct child of<manifest>, not nested inside<application>. Additionally, theINTERNETpermission is not required by url_launcher itself for launching external URLs—include it only if your app makes its own network requests.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@patient/android/app/src/main/AndroidManifest.xml` around lines 4 - 56, Add android:category="android.intent.category.BROWSABLE" to both VIEW intent entries under the <queries> block (the intents that have android:action="android.intent.action.VIEW" and android:data android:scheme="http"/"https") and ensure the <queries> element is moved out of the <application> element to be a direct child of the <manifest>; remove or leave android.permission.INTERNET only per app needs (url_launcher doesn't require it).
🧹 Nitpick comments (1)
patient/lib/presentation/notification/updates_screen.dart (1)
270-412: Replace GestureDetector with InkWell for tappable cards to provide focus/hover feedback and better accessibility.GestureDetector lacks visual feedback and keyboard/focus support. Use
Material(color: Colors.transparent, child: InkWell(borderRadius: BorderRadius.circular(16), ...))with matching borderRadius for both video and article cards to enable splash effects, focus indicators, and platform-appropriate hover states.♿ Suggested pattern (apply to both cards)
- return GestureDetector( - onTap: () { + return Material( + color: Colors.transparent, + child: InkWell( + borderRadius: BorderRadius.circular(16), + onTap: () { final url = video['url']?.toString() ?? ''; print('Video card tapped: ${video['title']}'); _launchURL(context, url); - }, - child: Container( + }, + child: Container( width: 240, decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(16), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.06), blurRadius: 12, offset: const Offset(0, 4), ), ], ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ ... ], ), - ), - ); + ), + ), + );Also applies to: 414-556
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@patient/lib/presentation/notification/updates_screen.dart` around lines 270 - 412, The _buildVideoCard currently uses GestureDetector which provides no visual/focus/hover feedback; replace the outer GestureDetector with a Material(color: Colors.transparent, child: InkWell(...)) pattern so taps, hover and keyboard focus show ripples and focus indicators. Specifically, wrap the card Container with Material(color: Colors.transparent, child: InkWell(borderRadius: BorderRadius.circular(16), onTap: () => _launchURL(context, url), child: the existing Container)), ensuring the InkWell and the ClipRRect/Container use the same BorderRadius (16) and apply this same change to the article card code block referenced around lines 414-556.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@patient/lib/presentation/notification/updates_screen.dart`:
- Around line 5-78: The helper _launchURL currently returns silently when
url.isEmpty; update it to show a user-facing SnackBar (using the same pattern as
the rest of the method) before returning: check context.mounted, call
ScaffoldMessenger.of(context).showSnackBar with a short, user-friendly message
like "Link is missing" (or similar), set an appropriate duration and
backgroundColor consistent with other messages, then return; keep the rest of
_launchURL unchanged.
---
Outside diff comments:
In `@patient/android/app/src/main/AndroidManifest.xml`:
- Around line 4-56: Add android:category="android.intent.category.BROWSABLE" to
both VIEW intent entries under the <queries> block (the intents that have
android:action="android.intent.action.VIEW" and android:data
android:scheme="http"/"https") and ensure the <queries> element is moved out of
the <application> element to be a direct child of the <manifest>; remove or
leave android.permission.INTERNET only per app needs (url_launcher doesn't
require it).
---
Nitpick comments:
In `@patient/lib/presentation/notification/updates_screen.dart`:
- Around line 270-412: The _buildVideoCard currently uses GestureDetector which
provides no visual/focus/hover feedback; replace the outer GestureDetector with
a Material(color: Colors.transparent, child: InkWell(...)) pattern so taps,
hover and keyboard focus show ripples and focus indicators. Specifically, wrap
the card Container with Material(color: Colors.transparent, child:
InkWell(borderRadius: BorderRadius.circular(16), onTap: () =>
_launchURL(context, url), child: the existing Container)), ensuring the InkWell
and the ClipRRect/Container use the same BorderRadius (16) and apply this same
change to the article card code block referenced around lines 414-556.
ℹ️ Review info
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
patient/android/app/src/main/AndroidManifest.xmlpatient/lib/presentation/notification/updates_screen.dartpatient/pubspec.yaml
|
@mdmohsin7 @khanjasir90 @jddeep Can you check this PR ?? |
…d intent filters for URL launching
There was a problem hiding this comment.
🧹 Nitpick comments (2)
patient/lib/presentation/notification/updates_screen.dart (2)
279-421: Consider InkWell for ripple + semantics on tappable cards.Wrapping the card with
Material+InkWellimproves accessibility and visual feedback. Apply the same pattern to article cards for consistency.♻️ Possible adjustment
- Widget _buildVideoCard(BuildContext context, Map<String, dynamic> video) { - return GestureDetector( - onTap: () { + Widget _buildVideoCard(BuildContext context, Map<String, dynamic> video) { + return Material( + color: Colors.transparent, + child: InkWell( + borderRadius: BorderRadius.circular(16), + onTap: () { final url = video['url']?.toString() ?? ''; - print('Video card tapped: ${video['title']}'); _launchURL(context, url); - }, - child: Container( + }, + child: Container( width: 240, decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(16), boxShadow: [🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@patient/lib/presentation/notification/updates_screen.dart` around lines 279 - 421, Replace the GestureDetector in _buildVideoCard with a Material widget containing an InkWell (use onTap on InkWell) so taps show ripple and expose proper semantics; keep the Container decoration for the card but move it inside the Material (or apply Material color/shape) so InkWell's splash is visible, and ensure the same pattern is applied to the article card builder (the article card function/class) for consistent accessibility and visual feedback.
6-85: Gate URL logging to debug builds.Avoid printing URLs/titles in release logs; wrap with
kDebugModeand usedebugPrint(or a logger) to keep production logs clean.♻️ Proposed pattern
+import 'package:flutter/foundation.dart'; ... - print('Attempting to launch: $url'); + if (kDebugMode) { + debugPrint('Attempting to launch: $url'); + }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@patient/lib/presentation/notification/updates_screen.dart` around lines 6 - 85, The debug prints in _launchURL (e.g., print('Attempting to launch: $url'), print('Parsed URI: $uri'), and error prints) should be gated to debug builds and use debugPrint or your app logger instead of print; update _launchURL to import foundation.dart for kDebugMode and replace plain prints with if (kDebugMode) { debugPrint(...); } (or logger.debug(...)) and avoid printing full URLs/titles in release by redacting or omitting them in those debug prints, while keeping the existing user-facing SnackBars unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@patient/lib/presentation/notification/updates_screen.dart`:
- Around line 279-421: Replace the GestureDetector in _buildVideoCard with a
Material widget containing an InkWell (use onTap on InkWell) so taps show ripple
and expose proper semantics; keep the Container decoration for the card but move
it inside the Material (or apply Material color/shape) so InkWell's splash is
visible, and ensure the same pattern is applied to the article card builder (the
article card function/class) for consistent accessibility and visual feedback.
- Around line 6-85: The debug prints in _launchURL (e.g., print('Attempting to
launch: $url'), print('Parsed URI: $uri'), and error prints) should be gated to
debug builds and use debugPrint or your app logger instead of print; update
_launchURL to import foundation.dart for kDebugMode and replace plain prints
with if (kDebugMode) { debugPrint(...); } (or logger.debug(...)) and avoid
printing full URLs/titles in release by redacting or omitting them in those
debug prints, while keeping the existing user-facing SnackBars unchanged.
ℹ️ Review info
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
patient/android/app/src/main/AndroidManifest.xmlpatient/lib/presentation/notification/updates_screen.dart
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (2)
patient/lib/core/constants/updates_constants.dart (1)
4-5: Consider typed model classes for compile-time safety.Using
Map<String, dynamic>means key typos (e.g.,'thumbnailURL'vs'thumbnailUrl') won't be caught until runtime. A simple data class would provide IDE autocomplete and compile-time validation:class VideoItem { final String title; final String views; final String duration; final String thumbnailUrl; final String url; const VideoItem({ required this.title, required this.views, required this.duration, required this.thumbnailUrl, required this.url, }); }Also applies to: 31-32
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@patient/lib/core/constants/updates_constants.dart` around lines 4 - 5, Replace the untyped List<Map<String, dynamic>> latestVideos with a typed data class: add a const VideoItem class (fields: title, views, duration, thumbnailUrl, url and a const constructor) and change latestVideos to List<VideoItem> using const VideoItem(...) entries instead of map literals; update any other nearby constants with the same Map<String, dynamic> pattern to use VideoItem as well so you get compile-time safety and IDE autocomplete (symbols: latestVideos, VideoItem).patient/lib/presentation/notification/updates_screen.dart (1)
96-96: Consider extracting colors to theme or constants.Hardcoded colors like
Color(0xFFF8F9FA),Color(0xFF7A86F8), andColor(0xFF1A1A1A)are repeated throughout the file. Extracting them to a theme or a dedicated colors constants file would improve maintainability and ensure consistency across the app.Also applies to: 111-112, 138-139, 179-180
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@patient/lib/presentation/notification/updates_screen.dart` at line 96, Replace hardcoded Color(...) literals with named constants or theme references: create a Colors/Theme constants file (e.g., AppColors with fields like primary=Color(0xFF7A86F8), background=Color(0xFFF8F9FA), textPrimary=Color(0xFF1A1A1A)) or add these to the app ThemeData, then update all usages in updates_screen.dart (the Scaffold/AppBar/Text widgets that currently use Color(0xFFF8F9FA), Color(0xFF7A86F8), Color(0xFF1A1A1A)) to reference AppColors.background, AppColors.primary, AppColors.textPrimary or Theme.of(context).colorScheme/... to ensure consistency and remove duplicated literals.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@patient/lib/core/constants/updates_constants.dart`:
- Around line 1-29: In UpdatesConstants.latestVideos replace the duplicate URL
in the map for the entry titled "Managing Anxiety: Breathing Techniques" so it
points to the correct YouTube link (ensure it's unique and a valid YouTube URL
rather than the same value used by "Understanding Brain Health & Neurotherapy");
update the 'url' field in that map within the latestVideos list accordingly and
verify the format (https://youtu.be/..., or full
https://www.youtube.com/watch?v=...) so the three video entries each have
distinct, correct URLs.
In `@patient/lib/presentation/notification/updates_screen.dart`:
- Line 9: Remove all stray debug print() calls inside the _launchURL method and
replace them with use of the app's logging utility (or a no-op/debug-only
logger) so production builds don't emit console output; locate _launchURL in
updates_screen.dart and delete the print(...) statements at the highlighted
positions (calls currently printing "URL is empty!" and other debug messages)
and instead call the centralized logger (e.g., Logger.logError/Logger.debug or
similar) or nothing for non-error cases, ensuring any real error branches still
report via the app's error-reporting/logging API.
- Around line 220-221: Remove the leftover debug print() calls from the tap
handlers in updates_screen.dart: delete the print('Video card tapped:
${video['title']}') in the video card tap handler and the other print() at the
second card tap (the ones noted near the _launchURL usage), leaving only the
actionable call to _launchURL(context, url) so tap handlers perform production
behavior without logging to stdout.
- Around line 76-86: The catch block that handles URL launch failures currently
shows raw exception text in the SnackBar (see the catch in updates_screen.dart
around the launch URL logic and the ScaffoldMessenger.showSnackBar call); change
the SnackBar content to a user-friendly, non-technical message like "Unable to
open link" or "Could not open the link, please try again" while keeping the
existing context.mounted check, and move the detailed error information (e) into
a debug/internal log (print or app logger) so technical details are not exposed
to users.
---
Nitpick comments:
In `@patient/lib/core/constants/updates_constants.dart`:
- Around line 4-5: Replace the untyped List<Map<String, dynamic>> latestVideos
with a typed data class: add a const VideoItem class (fields: title, views,
duration, thumbnailUrl, url and a const constructor) and change latestVideos to
List<VideoItem> using const VideoItem(...) entries instead of map literals;
update any other nearby constants with the same Map<String, dynamic> pattern to
use VideoItem as well so you get compile-time safety and IDE autocomplete
(symbols: latestVideos, VideoItem).
In `@patient/lib/presentation/notification/updates_screen.dart`:
- Line 96: Replace hardcoded Color(...) literals with named constants or theme
references: create a Colors/Theme constants file (e.g., AppColors with fields
like primary=Color(0xFF7A86F8), background=Color(0xFFF8F9FA),
textPrimary=Color(0xFF1A1A1A)) or add these to the app ThemeData, then update
all usages in updates_screen.dart (the Scaffold/AppBar/Text widgets that
currently use Color(0xFFF8F9FA), Color(0xFF7A86F8), Color(0xFF1A1A1A)) to
reference AppColors.background, AppColors.primary, AppColors.textPrimary or
Theme.of(context).colorScheme/... to ensure consistency and remove duplicated
literals.
ℹ️ Review info
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
patient/lib/core/constants/updates_constants.dartpatient/lib/presentation/notification/updates_screen.dart
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (2)
patient/lib/presentation/notification/updates_screen.dart (2)
246-279: Extract shared thumbnail widget to reduce duplication.The
Image.networkloading/error rendering logic is duplicated in both card builders. Pulling this into a private helper/widget will reduce maintenance overhead and keep styles consistent.Also applies to: 389-422
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@patient/lib/presentation/notification/updates_screen.dart` around lines 246 - 279, Extract the duplicated Image.network thumbnail block (including loadingBuilder and errorBuilder) into a private reusable widget or helper function (e.g., _ThumbnailWidget or buildThumbnail) and replace both occurrences in the two card builders with that widget; ensure the new widget accepts the thumbnail URL and width/height/flexibility props used in the original code and preserves the same loading indicator, progress calculation, error container, colors, sizes and BoxFit so visuals remain identical.
218-225: UseInkWellwithMaterialfor tap feedback and better accessibility on interactive cards.Lines 219 and 363 use
GestureDetectorwithContainer, which provides no Material ripple or visual feedback. For tappable cards,InkWell(requires aMaterialancestor to paint correctly) provides ink splash feedback and built-in focus/hover/keyboard handling. Alternatively, if keepingGestureDetector, addSemantics(button: true)to declare the widget's role for screen readers and improve semantic clarity.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@patient/lib/presentation/notification/updates_screen.dart` around lines 218 - 225, The _buildVideoCard currently uses GestureDetector + Container which provides no Material ripple or accessibility semantics; replace the GestureDetector with an InkWell wrapped by a Material (or wrap the Container in Material and use InkWell as child) so taps produce ripple feedback and get built-in focus/hover/keyboard handling, ensuring you keep the same onTap logic (log and call _launchURL) and reuse the existing video map fields; if you must keep GestureDetector instead, wrap the tappable widget in Semantics(button: true) to expose its role to screen readers—update the widgets referenced in _buildVideoCard accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@patient/lib/presentation/notification/updates_screen.dart`:
- Around line 26-29: Replace the unsafe Uri.parse usage in the updates screen
with a guarded parse: use Uri.tryParse(url.trim()) (replace the current
Uri.parse(url) call that assigns to uri), then explicitly check uri != null,
uri.isAbsolute, uri.scheme is 'http' or 'https', and uri.host is not empty
before attempting launch; if any check fails, show a user-facing error (e.g.,
via a SnackBar/Alert) instead of relying on exceptions. Ensure the validation
occurs where the current try block creates/logs `uri` in updates_screen.dart so
subsequent calls that use `uri` only run when the allowlist checks pass.
---
Nitpick comments:
In `@patient/lib/presentation/notification/updates_screen.dart`:
- Around line 246-279: Extract the duplicated Image.network thumbnail block
(including loadingBuilder and errorBuilder) into a private reusable widget or
helper function (e.g., _ThumbnailWidget or buildThumbnail) and replace both
occurrences in the two card builders with that widget; ensure the new widget
accepts the thumbnail URL and width/height/flexibility props used in the
original code and preserves the same loading indicator, progress calculation,
error container, colors, sizes and BoxFit so visuals remain identical.
- Around line 218-225: The _buildVideoCard currently uses GestureDetector +
Container which provides no Material ripple or accessibility semantics; replace
the GestureDetector with an InkWell wrapped by a Material (or wrap the Container
in Material and use InkWell as child) so taps produce ripple feedback and get
built-in focus/hover/keyboard handling, ensuring you keep the same onTap logic
(log and call _launchURL) and reuse the existing video map fields; if you must
keep GestureDetector instead, wrap the tappable widget in Semantics(button:
true) to expose its role to screen readers—update the widgets referenced in
_buildVideoCard accordingly.
Closes #123
📝 Description
Enhanced the Updates screen UI for the patient app with modern design elements and functional blog/video links. Replaced local placeholder images with online thumbnails from Unsplash and integrated real healthcare content links.
🔧 Changes Made
url_launcherpackage (v6.3.1) for opening external blog and video links📷 Screenshots or Visual Changes (if applicable)
WhatsApp.Video.2026-02-24.at.5.18.34.PM.mp4
✅ Checklist
Summary by CodeRabbit
New Features
Chores