import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; import 'package:logging/logging.dart'; import 'package:provider/provider.dart'; import 'package:relatica/controls/focus_mode_status_headline.dart'; import 'package:relatica/riverpod_controllers/focus_mode.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 ConsumerStatefulWidget { const HomeScreen({super.key}); @override ConsumerState createState() => _HomeScreenState(); } class _HomeScreenState extends ConsumerState { 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>() .activeEntry .andThenSuccess((m) => updateTimeline(m)); } @override Widget build(BuildContext context) { _logger.finest('Build'); final accountService = getIt(); final nss = getIt(); final focusMode = ref.watch(focusModeProvider); final timeline = TimelinePanel( timeline: focusMode.enabled ? TimelineIdentifiers.myPosts() : 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: focusMode.enabled ? AppBottomFocusModeStatus(disableTime: focusMode.disableTime) : buildTimelineSelector(context), ), body: Center( child: Column( children: [ StandardLinearProgressIndicator(nss.timelineLoadingStatus), Expanded( child: ResponsiveMaxWidth(child: timeline), ), ], ), ), drawer: const StandardAppDrawer(), bottomNavigationBar: focusMode.enabled ? null : 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>() .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( value: currentTimeline, items: items, isExpanded: true, onChanged: (value) { setState(() { if (value == null) { return; } currentTimeline = value; updateTimeline(manager); }); }); } }