From d61062f4139b621c3e58f6c69f815e46ba83ec65 Mon Sep 17 00:00:00 2001 From: Bruce Liu Date: Sat, 30 Jan 2021 20:11:35 +0800 Subject: [PATCH] add unread sources only option --- assets/article/article.html | 1 + lib/l10n/intl_en.arb | 3 +- lib/l10n/intl_zh.arb | 3 +- lib/models/sources_model.dart | 12 ++++ lib/pages/subscription_list_page.dart | 90 ++++++++++++++++++++++++++- lib/utils/store.dart | 1 + pubspec.lock | 7 +++ pubspec.yaml | 3 +- 8 files changed, 115 insertions(+), 5 deletions(-) diff --git a/assets/article/article.html b/assets/article/article.html index 454f883..938b45a 100644 --- a/assets/article/article.html +++ b/assets/article/article.html @@ -3,6 +3,7 @@ + Article diff --git a/lib/l10n/intl_en.arb b/lib/l10n/intl_en.arb index 6d1ed51..a31d735 100644 --- a/lib/l10n/intl_en.arb +++ b/lib/l10n/intl_en.arb @@ -87,5 +87,6 @@ "wentWrong": "Something went wrong.", "retry": "Retry", "copy": "Copy", - "errorLog": "Error log" + "errorLog": "Error log", + "unreadSourceTip": "You can long press on the title of this page to toggle between all and unread subscriptions." } \ No newline at end of file diff --git a/lib/l10n/intl_zh.arb b/lib/l10n/intl_zh.arb index e3dc545..66032d0 100644 --- a/lib/l10n/intl_zh.arb +++ b/lib/l10n/intl_zh.arb @@ -87,5 +87,6 @@ "wentWrong": "发生错误", "retry": "重试", "copy": "复制", - "errorLog": "错误日志" + "errorLog": "错误日志", + "unreadSourceTip": "您可以长按此页面的标题来切换全部订阅源或仅未读订阅源。" } \ No newline at end of file diff --git a/lib/models/sources_model.dart b/lib/models/sources_model.dart index ac516b9..8cf244b 100644 --- a/lib/models/sources_model.dart +++ b/lib/models/sources_model.dart @@ -1,5 +1,8 @@ +import 'dart:collection'; + import 'package:fluent_reader_lite/models/source.dart'; import 'package:fluent_reader_lite/utils/global.dart'; +import 'package:fluent_reader_lite/utils/store.dart'; import 'package:fluent_reader_lite/utils/utils.dart'; import 'package:flutter/material.dart'; import 'package:html/parser.dart'; @@ -11,6 +14,15 @@ import 'item.dart'; class SourcesModel with ChangeNotifier { Map _sources = Map(); Map _deleted = Map(); + bool _showUnreadTip = Store.sp.getBool(StoreKeys.UNREAD_SOURCE_TIP) ?? true; + + bool get showUnreadTip => _showUnreadTip; + set showUnreadTip(bool value) { + if (_showUnreadTip != value) { + _showUnreadTip = value; + Store.sp.setBool(StoreKeys.UNREAD_SOURCE_TIP, value); + } + } bool has(String id) => _sources.containsKey(id); diff --git a/lib/pages/subscription_list_page.dart b/lib/pages/subscription_list_page.dart index a92953b..011c425 100644 --- a/lib/pages/subscription_list_page.dart +++ b/lib/pages/subscription_list_page.dart @@ -33,6 +33,7 @@ class _SubscriptionListPageState extends State { List sids; String title; bool transitioning = false; + bool unreadOnly = false; void _onScrollTop() { if (widget.scrollTopNotifier.index == 1 && !Navigator.of(context).canPop()) { @@ -106,15 +107,93 @@ class _SubscriptionListPageState extends State { } } + void _toggleUnreadOnly() { + HapticFeedback.mediumImpact(); + setState(() { unreadOnly = !unreadOnly; }); + _onScrollTop(); + } + + void _dismissTip() { + if (Global.sourcesModel.showUnreadTip) { + Global.sourcesModel.showUnreadTip = false; + setState(() {}); + } + } + + Widget _buildUnreadTip() { + return SliverToBoxAdapter(child: Container( + padding: EdgeInsets.all(16), + child: ClipRRect( + borderRadius: BorderRadius.circular(16), + child: Container( + padding: EdgeInsets.all(12), + color: CupertinoColors.secondarySystemBackground.resolveFrom(context), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: EdgeInsets.only(right: 12), + child: Icon(Icons.radio_button_checked), + ), + Flexible(child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + S.of(context).unreadSourceTip, + style: TextStyle( + color: CupertinoColors.label.resolveFrom(context), + fontWeight: FontWeight.bold, + ), + ), + Padding(padding: EdgeInsets.only(bottom: 6)), + CupertinoButton( + minSize: 28, + padding: EdgeInsets.zero, + child: Text(S.of(context).confirm), + onPressed: _dismissTip, + ), + ], + )), + ], + ), + ), + ), + )); + } + @override Widget build(BuildContext context) { + final titleWidget = GestureDetector( + onLongPress: _toggleUnreadOnly, + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Container( + constraints: BoxConstraints( + maxWidth: Global.isTablet + ? 260 + : MediaQuery.of(context).size.width - 60, + ), + child: Text( + title ?? S.of(context).subscriptions, + overflow: TextOverflow.ellipsis, + ), + ), + if (unreadOnly) Padding( + padding: EdgeInsets.only(left: 4), + child: Icon(Icons.radio_button_checked, size: 18), + ), + ], + ), + ); final navigationBar = CupertinoSliverNavigationBar( stretch: false, - largeTitle: Text(title ?? S.of(context).subscriptions), + largeTitle: titleWidget, heroTag: "subscriptions", transitionBetweenRoutes: true, backgroundColor: transitioning ? MyColors.tileBackground : CupertinoColors.systemBackground, leading: CupertinoButton( + minSize: 36, padding: EdgeInsets.zero, child: Text(S.of(context).groups), onPressed: _openGroups, @@ -149,10 +228,16 @@ class _SubscriptionListPageState extends State { List sources; if (sids == null) { sources = Global.sourcesModel.getSources().toList(); + if (unreadOnly) { + sources = sources.where((s) => s.unreadCount > 0).toList(); + } } else { sources = []; for (var sid in sids) { - sources.add(Global.sourcesModel.getSource(sid)); + final source = Global.sourcesModel.getSource(sid); + if (!unreadOnly || source.unreadCount > 0) { + sources.add(source); + } } } // Latest sources first @@ -203,6 +288,7 @@ class _SubscriptionListPageState extends State { slivers: [ navigationBar, SyncControl(), + if (Global.sourcesModel.showUnreadTip) _buildUnreadTip(), if (sids != null) Consumer( builder: (context, sourcesModel, child) { var count = sids diff --git a/lib/utils/store.dart b/lib/utils/store.dart index 3ecc734..210b91b 100644 --- a/lib/utils/store.dart +++ b/lib/utils/store.dart @@ -24,6 +24,7 @@ abstract class StoreKeys { static const DIM_READ = "dimRead"; static const FEED_SWIPE_R = "feedSwipeR"; static const FEED_SWIPE_L = "feedSwipeL"; + static const UNREAD_SOURCE_TIP = "unreadSourceTip"; // Reading preferences static const ARTICLE_FONT_SIZE = "articleFontSize"; diff --git a/pubspec.lock b/pubspec.lock index 32c4e01..7aca0ae 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -238,6 +238,13 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "0.11.4" + lpinyin: + dependency: "direct main" + description: + name: lpinyin + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.1.0" matcher: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 612f7d1..7921732 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -15,7 +15,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. # Read more about iOS versioning at # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+4 +version: 1.0.1+5 environment: sdk: ">=2.7.0 <3.0.0" @@ -43,6 +43,7 @@ dependencies: responsive_builder: ^0.3.0 cached_network_image: ^2.5.0 flutter_cache_manager: ^2.1.0 + lpinyin: ^1.1.0 modal_bottom_sheet: ^1.0.0+1 overlay_dialog: ^0.0.3 -- 2.38.5