| @@ -1,4 +1,5 @@ |
| 1 | import 'package:flutter/material.dart'; | 1 | import 'package:flutter/material.dart'; |
| | 2 | +import 'package:url_launcher/url_launcher.dart'; |
| 2 | | 3 | |
| 3 | import '../api/client.dart'; | 4 | import '../api/client.dart'; |
| 4 | import '../app_state.dart'; | 5 | import '../app_state.dart'; |
| @@ -6,7 +7,6 @@ import '../models/models.dart'; |
| 6 | import '../theme.dart'; | 7 | import '../theme.dart'; |
| 7 | import '../widgets/article_tile.dart'; | 8 | import '../widgets/article_tile.dart'; |
| 8 | import '../widgets/common.dart'; | 9 | import '../widgets/common.dart'; |
| 9 | -import 'article_screen.dart'; | | |
| 10 | | 10 | |
| 11 | /// The reading list, scoped by the feed selected in the drawer. | 11 | /// The reading list, scoped by the feed selected in the drawer. |
| 12 | class ArticlesScreen extends StatefulWidget { | 12 | class ArticlesScreen extends StatefulWidget { |
| @@ -73,16 +73,24 @@ class _ArticlesScreenState extends State<ArticlesScreen> { |
| 73 | } | 73 | } |
| 74 | | 74 | |
| 75 | Future<void> _open(Article a) async { | 75 | Future<void> _open(Article a) async { |
| 76 | - // Read the state up front: after the await the element may be gone, and | | |
| 77 | - // a lint about context across an async gap is pointing at a real one. | | |
| 78 | final app = AppScope.read(context); | 76 | final app = AppScope.read(context); |
| 79 | - await Navigator.of(context).push( | 77 | + final uri = Uri.tryParse(a.url); |
| 80 | - MaterialPageRoute(builder: (_) => ArticleScreen(articleId: a.id)), | 78 | + if (uri == null || (uri.scheme != 'http' && uri.scheme != 'https')) { |
| 81 | - ); | 79 | + showToast(context, 'This article does not have a valid link.'); |
| 82 | - if (!mounted || a.isRead) return; | 80 | + return; |
| 83 | - // Opening marks it read server-side. | 81 | + } |
| 84 | - setState(() => _patched[a.id] = a.copyWith(isRead: true)); | 82 | + if (!await launchUrl( |
| 85 | - app.adjustUnread(-1); | 83 | + uri, |
| | 84 | + mode: LaunchMode.platformDefault, |
| | 85 | + webOnlyWindowName: '_blank', |
| | 86 | + )) { |
| | 87 | + if (mounted) showToast(context, 'Could not open the link.'); |
| | 88 | + return; |
| | 89 | + } |
| | 90 | + if (mounted && !a.isRead) { |
| | 91 | + setState(() => _patched[a.id] = a.copyWith(isRead: true)); |
| | 92 | + app.adjustUnread(-1); |
| | 93 | + } |
| 86 | } | 94 | } |
| 87 | | 95 | |
| 88 | @override | 96 | @override |