@@ -4,6 +4,7 @@ import 'package:flutter/material.dart';
44import 'package:flutter_bloc/flutter_bloc.dart' ;
55import 'package:flutter_news_app_mobile_client_full_source_code/ads/services/interstitial_ad_manager.dart' ;
66import 'package:flutter_news_app_mobile_client_full_source_code/app/bloc/app_bloc.dart' ;
7+ import 'package:ui_kit/ui_kit.dart' ;
78import 'package:url_launcher/url_launcher_string.dart' ;
89
910/// {@template headline_tap_handler}
@@ -69,12 +70,14 @@ abstract final class HeadlineTapHandler {
6970 String headlineId,
7071 ) async {
7172 // Show a loading dialog as fetching the headline may take time.
72- showDialog <void >(
73- context: context,
74- barrierDismissible: false ,
75- builder: (BuildContext context) =>
76- const Center (child: CircularProgressIndicator ()),
77- );
73+ if (context.mounted) {
74+ showDialog <void >(
75+ context: context,
76+ barrierDismissible: false ,
77+ builder: (BuildContext context) =>
78+ const Center (child: CircularProgressIndicator ()),
79+ );
80+ }
7881
7982 final headline = await context.read <DataRepository <Headline >>().read (
8083 id: headlineId,
@@ -84,4 +87,39 @@ abstract final class HeadlineTapHandler {
8487 Navigator .of (context).pop (); // Dismiss the loading dialog.
8588 await handleHeadlineTap (context, headline);
8689 }
90+
91+ /// Handles a tap on a headline from a system notification.
92+ ///
93+ /// This method is specifically for taps that originate from the OS
94+ /// notification tray. It fetches the headline by its ID and then **always**
95+ /// opens it in an in-app browser, overriding any user or remote settings.
96+ /// This provides a smoother, more integrated user experience for notification
97+ /// interactions.
98+ ///
99+ /// - [context] : The current [BuildContext] to access BLoCs and for navigation.
100+ /// - [headlineId] : The ID of the [Headline] item that was tapped.
101+ static Future <void > handleTapFromSystemNotification (
102+ BuildContext context,
103+ String headlineId,
104+ ) async {
105+ if (context.mounted) {
106+ showDialog <void >(
107+ context: context,
108+ barrierDismissible: false ,
109+ builder: (BuildContext context) =>
110+ const Center (child: CircularProgressIndicator ()),
111+ );
112+ }
113+
114+ final headline = await context.read <DataRepository <Headline >>().read (
115+ id: headlineId,
116+ );
117+
118+ if (! context.mounted) return ;
119+ Navigator .of (context).pop (); // Dismiss the loading dialog.
120+
121+ if (await canLaunchUrlString (headline.url)) {
122+ await launchUrlString (headline.url, mode: LaunchMode .inAppWebView);
123+ }
124+ }
87125}
0 commit comments