Convert timeline selector to single dropdown menu

This commit is contained in:
Hank Grabowski 2023-11-16 16:21:06 -05:00
parent 1157e2cb56
commit 6ede657c57
2 changed files with 85 additions and 86 deletions

View file

@ -27,15 +27,32 @@ enum TimelineType {
class TimelineIdentifiers {
final TimelineType timeline;
final String auxData;
final String label;
TimelineIdentifiers({required this.timeline, this.auxData = ''});
const TimelineIdentifiers({
required this.timeline,
this.auxData = '',
this.label = '',
});
String toHumanKey() {
return auxData.isEmpty ? timeline.name : '${timeline.name}_$auxData';
}
String toLabel() {
if (label.isNotEmpty) {
return label;
}
if (timeline != TimelineType.circle) {
return timeline.toLabel();
}
return '${timeline.toLabel()} $auxData';
}
factory TimelineIdentifiers.home() =>
TimelineIdentifiers(timeline: TimelineType.home);
const TimelineIdentifiers(timeline: TimelineType.home);
factory TimelineIdentifiers.profile(String profileId) => TimelineIdentifiers(
timeline: TimelineType.profile,

View file

@ -6,13 +6,11 @@ import 'package:provider/provider.dart';
import '../controls/app_bottom_nav_bar.dart';
import '../controls/linear_status_indicator.dart';
import '../controls/login_aware_cached_network_image.dart';
import '../controls/padding.dart';
import '../controls/responsive_max_width.dart';
import '../controls/standard_app_drawer.dart';
import '../controls/timeline/timeline_panel.dart';
import '../globals.dart';
import '../models/TimelineIdentifiers.dart';
import '../models/circle_data.dart';
import '../services/auth_service.dart';
import '../services/network_status_service.dart';
import '../services/timeline_manager.dart';
@ -28,22 +26,11 @@ class HomeScreen extends StatefulWidget {
class _HomeScreenState extends State<HomeScreen> {
final _logger = Logger('$HomeScreen');
final postText = TextEditingController();
var currentType = TimelineType.home;
CircleData? currentCircle;
final types = [
TimelineType.self,
TimelineType.home,
TimelineType.circle,
TimelineType.local,
TimelineType.circle,
];
TimelineIdentifiers currentTimeline = const TimelineIdentifiers(
timeline: TimelineType.home,
);
void updateTimeline(TimelineManager manager) {
if (currentType == TimelineType.circle && currentCircle == null) {
_logger.finest('Circle timeline but no circle selected so not updating');
return;
}
_logger.finest('Updating timeline: $currentTimeline');
Future.delayed(const Duration(milliseconds: 100), () async {
await manager.updateTimeline(
@ -51,11 +38,6 @@ class _HomeScreenState extends State<HomeScreen> {
});
}
TimelineIdentifiers get currentTimeline => TimelineIdentifiers(
timeline: currentType,
auxData: currentCircle?.id ?? '',
);
@override
void initState() {
super.initState();
@ -69,15 +51,6 @@ class _HomeScreenState extends State<HomeScreen> {
_logger.finest('Build');
final accountService = getIt<AccountsService>();
final nss = getIt<NetworkStatusService>();
final manager = context
.watch<ActiveProfileSelector<TimelineManager>>()
.activeEntry
.value;
final circles = manager.getCircles().getValueOrElse(() => []).toList();
circles.sort((g1, g2) => g1.name.compareTo(g2.name));
if (!circles.contains(currentCircle)) {
currentCircle = null;
}
final timeline = TimelinePanel(timeline: currentTimeline);
@ -94,60 +67,7 @@ class _HomeScreenState extends State<HomeScreen> {
})
: null,
backgroundColor: Theme.of(context).canvasColor,
title: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
if (currentType == TimelineType.circle)
PopupMenuButton<TimelineType>(
initialValue: currentType,
// Callback that sets the selected popup menu item.
onSelected: (value) {
setState(() {
currentType = value;
});
updateTimeline(manager);
},
itemBuilder: (BuildContext context) => types
.map((e) => PopupMenuItem<TimelineType>(
value: e,
child: Text(e.toLabel()),
))
.toList()),
if (currentType != TimelineType.circle)
DropdownButton<TimelineType>(
value: currentType,
items: types
.map((e) => DropdownMenuItem<TimelineType>(
value: e,
child: Text(e.toLabel()),
))
.toList(),
onChanged: (value) {
setState(() {
currentType = value!;
});
updateTimeline(manager);
}),
const HorizontalPadding(
width: 5.0,
),
if (currentType == TimelineType.circle)
DropdownButton<CircleData>(
value: currentCircle,
items: circles
.map((g) => DropdownMenuItem<CircleData>(
value: g,
child: Text(g.name),
))
.toList(),
onChanged: (value) {
setState(() {
currentCircle = value;
});
updateTimeline(manager);
}),
],
),
title: buildTimelineSelector(context),
),
body: Center(
child: Column(
@ -171,4 +91,66 @@ class _HomeScreenState extends State<HomeScreen> {
child: const Icon(Icons.add),
));
}
Widget buildTimelineSelector(BuildContext context) {
final standardTypes = [
TimelineType.self,
TimelineType.home,
TimelineType.global,
TimelineType.local,
];
final manager = context
.watch<ActiveProfileSelector<TimelineManager>>()
.activeEntry
.value;
final circles = manager.getCircles().getValueOrElse(() => []).toList();
circles.sort((g1, g2) => g1.name.compareTo(g2.name));
final items = [
...standardTypes
.map((t) => TimelineIdentifiers(timeline: t))
.map((e) => DropdownMenuItem(value: e, child: Text(e.toLabel()))),
const DropdownMenuItem(
value: null,
enabled: false,
child: Divider(),
),
const DropdownMenuItem(
value: null,
enabled: false,
child: Text(
'Circles',
style: TextStyle(
fontWeight: FontWeight.bold,
fontStyle: FontStyle.italic,
decoration: TextDecoration.underline,
),
)),
...circles
.map((c) => TimelineIdentifiers(
timeline: TimelineType.circle, auxData: c.id, label: c.name))
.map((e) => DropdownMenuItem(
value: e,
child: Text(
e.toLabel(),
overflow: TextOverflow.fade,
))),
];
return DropdownButton<TimelineIdentifiers?>(
value: currentTimeline,
items: items,
isExpanded: true,
onChanged: (value) {
setState(() {
if (value == null) {
return;
}
currentTimeline = value;
updateTimeline(manager);
});
});
}
}