M ios/Runner.xcodeproj/project.pbxproj => ios/Runner.xcodeproj/project.pbxproj +3 -0
@@ 32,6 32,7 @@
/* Begin PBXFileReference section */
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
+ 324ACECE25C909AD00CD3591 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/LaunchScreen.strings; sourceTree = "<group>"; };
32561D9E25BE823400DBD252 /* Runner.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Runner.entitlements; sourceTree = "<group>"; };
3271990C25BBF9C8008EA00E /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/LaunchScreen.strings"; sourceTree = "<group>"; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
@@ 175,6 176,7 @@
en,
Base,
"zh-Hans",
+ es,
);
mainGroup = 97C146E51CF9000F007C117D;
productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
@@ 296,6 298,7 @@
children = (
97C147001CF9000F007C117D /* Base */,
3271990C25BBF9C8008EA00E /* zh-Hans */,
+ 324ACECE25C909AD00CD3591 /* es */,
);
name = LaunchScreen.storyboard;
sourceTree = "<group>";
A ios/Runner/es.lproj/LaunchScreen.strings => ios/Runner/es.lproj/LaunchScreen.strings +1 -0
M lib/l10n/intl_en.arb => lib/l10n/intl_en.arb +4 -1
@@ 1,5 1,8 @@
{
- "allArticles": "All Articles",
+ "all": "All Articles",
+ "unread": "Unread",
+ "starred": "Starred",
+ "allArticles": "All articles",
"allSubscriptions": "All subscriptions",
"filter": "Filter",
"feed": "Feed",
M lib/l10n/intl_es.arb => lib/l10n/intl_es.arb +4 -1
@@ 1,8 1,11 @@
{
+ "all": "Todos",
+ "unread": "Sin leídos",
+ "starred": "Favoritos",
"allArticles": "Todos los artículos",
"allSubscriptions": "Todas las suscripciones",
"filter": "Filtrar",
- "feed": "Alimentador",
+ "feed": "Artículos",
"subscriptions": "Suscriptores",
"groups": "Grupos",
"settings": "Ajustes",
M lib/l10n/intl_zh.arb => lib/l10n/intl_zh.arb +3 -0
@@ 1,4 1,7 @@
{
+ "all": "全部文章",
+ "unread": "未读文章",
+ "starred": "星标文章",
"allArticles": "全部文章",
"allSubscriptions": "全部订阅源",
"filter": "筛选",
M lib/main.dart => lib/main.dart +1 -0
@@ 111,6 111,7 @@ class MyApp extends StatelessWidget {
locale: globalModel.locale,
supportedLocales: [
const Locale("en"),
+ const Locale("es"),
const Locale("zh"),
],
localeResolutionCallback: (_locale, supportedLocales) {
M lib/pages/item_list_page.dart => lib/pages/item_list_page.dart +20 -2
@@ 263,6 263,24 @@ class _ItemListPageState extends State<ItemListPage> {
);
}
+ Widget _titleFromFilter() => Consumer<FeedsModel>(
+ builder: (context, feedsModel, child) {
+ String text;
+ switch (getFeed().filterType) {
+ case FilterType.Unread:
+ text = S.of(context).unread;
+ break;
+ case FilterType.Starred:
+ text = S.of(context).starred;
+ break;
+ default:
+ text = S.of(context).all;
+ break;
+ }
+ return Text(text, overflow: TextOverflow.ellipsis);
+ },
+ );
+
@override
Widget build(BuildContext context) {
final String title = ModalRoute.of(context).settings.arguments;
@@ 275,8 293,8 @@ class _ItemListPageState extends State<ItemListPage> {
? 260
: MediaQuery.of(context).size.width - 60,
),
- child: Text(
- title ?? S.of(context).allArticles,
+ child: title == null ? _titleFromFilter() : Text(
+ title,
overflow: TextOverflow.ellipsis,
),
),
M lib/pages/settings/general_page.dart => lib/pages/settings/general_page.dart +3 -2
@@ 131,8 131,9 @@ class _GeneralPageState extends State<GeneralPage> {
final localeItems = ListTileGroup.fromOptions(
[
Tuple2(S.of(context).followSystem, null),
- Tuple2("English", Locale("en")),
- Tuple2("中文(简体)", Locale("zh")),
+ const Tuple2("English", Locale("en")),
+ const Tuple2("Español", Locale("es")),
+ const Tuple2("中文(简体)", Locale("zh")),
],
globalModel.locale,
(l) { globalModel.locale = l; },
M lib/pages/subscription_list_page.dart => lib/pages/subscription_list_page.dart +4 -2
@@ 11,6 11,7 @@ import 'package:fluent_reader_lite/pages/group_list_page.dart';
import 'package:fluent_reader_lite/pages/home_page.dart';
import 'package:fluent_reader_lite/utils/colors.dart';
import 'package:fluent_reader_lite/utils/global.dart';
+import 'package:fluent_reader_lite/utils/store.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
@@ 33,7 34,7 @@ class _SubscriptionListPageState extends State<SubscriptionListPage> {
List<String> sids;
String title;
bool transitioning = false;
- bool unreadOnly = false;
+ bool unreadOnly = Store.sp.getBool(StoreKeys.UNREAD_SUBS_ONLY) ?? false;
void _onScrollTop() {
if (widget.scrollTopNotifier.index == 1 && !Navigator.of(context).canPop()) {
@@ 117,6 118,7 @@ class _SubscriptionListPageState extends State<SubscriptionListPage> {
HapticFeedback.mediumImpact();
setState(() { unreadOnly = !unreadOnly; });
_onScrollTop();
+ Store.sp.setBool(StoreKeys.UNREAD_SUBS_ONLY, unreadOnly);
}
void _dismissTip() {
@@ 295,7 297,7 @@ class _SubscriptionListPageState extends State<SubscriptionListPage> {
navigationBar,
SyncControl(),
if (Global.sourcesModel.showUnreadTip) _buildUnreadTip(),
- if (sids != null) Consumer<SourcesModel>(
+ if (sids != null && sids.length > 0) Consumer<SourcesModel>(
builder: (context, sourcesModel, child) {
var count = sids
.map((sid) => sourcesModel.getSource(sid))
M lib/utils/store.dart => lib/utils/store.dart +1 -0
@@ 8,6 8,7 @@ abstract class StoreKeys {
static const GROUPS = "groups";
static const ERROR_LOG = "errorLog";
static const UNCATEGORIZED = "uncategorized";
+ static const UNREAD_SUBS_ONLY = "unreadSubsOnly";
// General
static const THEME = "theme";
M lib/utils/utils.dart => lib/utils/utils.dart +1 -1
@@ 44,7 44,7 @@ abstract class Utils {
}
static final _urlRegex = RegExp(
- r"^https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*$)",
+ r"^https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,63}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*$)",
caseSensitive: false,
);
static bool testUrl(String url) => url != null && _urlRegex.hasMatch(url.trim());
M pubspec.yaml => pubspec.yaml +1 -1
@@ 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.1+5
+version: 1.0.1+6
environment:
sdk: ">=2.7.0 <3.0.0"