relatica/lib/screens/home.dart

159 wiersze
4.8 KiB
Dart

import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:logging/logging.dart';
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/responsive_max_width.dart';
import '../controls/standard_app_drawer.dart';
import '../controls/timeline/timeline_panel.dart';
import '../globals.dart';
import '../models/TimelineIdentifiers.dart';
import '../services/auth_service.dart';
import '../services/network_status_service.dart';
import '../services/timeline_manager.dart';
import '../utils/active_profile_selector.dart';
class HomeScreen extends StatefulWidget {
const HomeScreen({super.key});
@override
State<HomeScreen> createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
final _logger = Logger('$HomeScreen');
TimelineIdentifiers currentTimeline = TimelineIdentifiers.home();
void updateTimeline(TimelineManager manager) {
_logger.finer('Updating timeline: $currentTimeline');
Future.delayed(const Duration(milliseconds: 100), () async {
await manager.updateTimeline(
currentTimeline, TimelineRefreshType.refresh);
});
}
@override
void initState() {
super.initState();
getIt<ActiveProfileSelector<TimelineManager>>()
.activeEntry
.andThenSuccess((m) => updateTimeline(m));
}
@override
Widget build(BuildContext context) {
_logger.finest('Build');
final accountService = getIt<AccountsService>();
final nss = getIt<NetworkStatusService>();
final timeline = TimelinePanel(timeline: currentTimeline);
return Scaffold(
appBar: AppBar(
leading: accountService.loggedIn
? Builder(builder: (context) {
return IconButton(
onPressed: () {
Scaffold.of(context).openDrawer();
},
icon: LoginAwareCachedNetworkImage(
imageUrl: accountService.currentProfile.avatar));
})
: null,
backgroundColor: Theme.of(context).canvasColor,
title: buildTimelineSelector(context),
),
body: Center(
child: Column(
children: [
StandardLinearProgressIndicator(nss.timelineLoadingStatus),
Expanded(
child: ResponsiveMaxWidth(child: timeline),
),
],
),
),
drawer: const StandardAppDrawer(),
bottomNavigationBar: AppBottomNavBar(
currentButton: NavBarButtons.timelines,
onHomeButtonReclick: () => timeline.scrollToTop(),
),
floatingActionButton: FloatingActionButton.small(
onPressed: () {
context.push('/post/new');
},
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,
))),
];
if (items.where((i) => i.value == currentTimeline).isEmpty) {
currentTimeline = TimelineIdentifiers.home();
}
return DropdownButton<TimelineIdentifiers?>(
value: currentTimeline,
items: items,
isExpanded: true,
onChanged: (value) {
setState(() {
if (value == null) {
return;
}
currentTimeline = value;
updateTimeline(manager);
});
});
}
}