import 'package:fluent_reader_lite/components/badge.dart';
import 'package:fluent_reader_lite/components/dismissible_background.dart';
import 'package:fluent_reader_lite/components/list_tile_group.dart';
import 'package:fluent_reader_lite/components/mark_all_action_sheet.dart';
import 'package:fluent_reader_lite/components/my_list_tile.dart';
import 'package:fluent_reader_lite/generated/l10n.dart';
import 'package:fluent_reader_lite/models/groups_model.dart';
import 'package:fluent_reader_lite/models/source.dart';
import 'package:fluent_reader_lite/models/sources_model.dart';
import 'package:fluent_reader_lite/utils/colors.dart';
import 'package:fluent_reader_lite/utils/global.dart';
import 'package:fluent_reader_lite/utils/utils.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/services.dart';
import 'package:provider/provider.dart';
import 'package:tuple/tuple.dart';
class GroupListPage extends StatefulWidget {
@override
_GroupListPageState createState() => _GroupListPageState();
}
class _GroupListPageState extends State<GroupListPage> {
static const List<String> _uncategorizedIndicator = ["_", "_"];
int _unreadCount(Iterable<RSSSource?> sources) {
return sources.fold(0, (c, s) => c + (s != null ? s.unreadCount : 0));
}
void _showGroupSettings(BuildContext context, String groupName) {
HapticFeedback.mediumImpact();
Navigator.of(context).push(CupertinoPageRoute(
builder: (context) => _GroupSettingsPage(groupName: groupName),
));
}
static const _dismissThresholds = {
DismissDirection.startToEnd: 0.25,
};
@override
Widget build(BuildContext context) {
final navigationBar = CupertinoSliverNavigationBar(
largeTitle: Text(S.of(context).groups),
automaticallyImplyLeading: false,
backgroundColor: Global.isTablet ? CupertinoColors.systemBackground : null,
leading: CupertinoButton(
minSize: 36,
padding: EdgeInsets.zero,
child: Text(S.of(context).cancel),
onPressed: () { Navigator.of(context).pop(); },
),
);
final allSources = Consumer<SourcesModel>(
builder: (context, sourcesModel, child) {
var count = _unreadCount(sourcesModel.getSources());
return SliverToBoxAdapter(child: MyListTile(
title: Text(S.of(context).allSubscriptions),
trailing: count > 0 ? Badge(count) : null,
onTap: () { Navigator.of(context).pop(List<String>.empty()); },
background: CupertinoColors.systemBackground,
));
},
);
final dismissBg = DismissibleBackground(CupertinoIcons.checkmark_circle, true);
final groupList = Consumer2<GroupsModel, SourcesModel>(
builder: (context, groupsModel, sourcesModel, child) {
final sortedKeys = groupsModel.groups.keys.toList();
sortedKeys.sort(Utils.localStringCompare);
final hasUncategorized = groupsModel.uncategorized != null;
final totalCount = sortedKeys.length + (hasUncategorized ? 1 : 0);
return SliverList(
delegate: SliverChildBuilderDelegate((context, index) {
String groupName;
List<String> group;
final isUncategorized = groupsModel.showUncategorized && hasUncategorized && index == 0;
if (isUncategorized) {
groupName = S.of(context).uncategorized;
group = groupsModel.uncategorized!;
} else {
final adjustedIndex = hasUncategorized ? index - 1 : index;
groupName = sortedKeys[adjustedIndex];
group = groupsModel.groups[groupName]!;
}
final count = _unreadCount(
group.map((sid) => sourcesModel.getSource(sid))
);
final tile = GestureDetector(
onLongPress: isUncategorized ? null : () {
_showGroupSettings(context, groupName);
},
child: MyListTile(
title: Flexible(child: Text(groupName, overflow: TextOverflow.ellipsis)),
trailing: count > 0 ? Badge(count) : null,
onTap: () {
Navigator.of(context).pop(
isUncategorized ? _uncategorizedIndicator : [groupName]
);
},
background: CupertinoColors.systemBackground,
),
);
return Dismissible(
key: Key("$groupName$index"),
child: tile,
background: dismissBg,
direction: DismissDirection.startToEnd,
dismissThresholds: _dismissThresholds,
confirmDismiss: (_) async {
HapticFeedback.mediumImpact();
Set<String> sids = Set.from(group);
showCupertinoModalPopup(
context: context,
builder: (context) => MarkAllActionSheet(sids),
);
return false;
},
);
}, childCount: totalCount),
);
},
);
final padding = SliverToBoxAdapter(child: Padding(
padding: EdgeInsets.only(bottom: 80),
),);
return CupertinoPageScaffold(
backgroundColor: CupertinoColors.systemBackground,
child: CupertinoScrollbar(child: CustomScrollView(
slivers: [
navigationBar,
allSources,
groupList,
padding,
],
))
);
}
}
class _GroupSettingsPage extends StatelessWidget {
final String groupName;
const _GroupSettingsPage({required this.groupName});
@override
Widget build(BuildContext context) {
return Consumer<GroupsModel>(
builder: (context, groupsModel, child) {
final openTarget = ListTileGroup.fromOptions(
[
Tuple2(S.of(context).inheritDefault, SourceOpenTarget.Inherit),
Tuple2(S.of(context).rssText, SourceOpenTarget.Local),
Tuple2(S.of(context).loadFull, SourceOpenTarget.FullContent),
Tuple2(S.of(context).loadWebpage, SourceOpenTarget.Webpage),
Tuple2(S.of(context).openExternal, SourceOpenTarget.External),
],
groupsModel.getGroupOpenTarget(groupName),
(v) {
groupsModel.setGroupOpenTarget(groupName, v);
},
title: S.of(context).openTarget,
);
return CupertinoPageScaffold(
backgroundColor: MyColors.background,
navigationBar: CupertinoNavigationBar(
middle: Text(groupName, overflow: TextOverflow.ellipsis),
),
child: ListView(children: [
openTarget,
]),
);
},
);
}
}