1 changed files with 120 additions and 0 deletions
@ -0,0 +1,120 @@
|
||||
import 'dart:async'; |
||||
|
||||
import 'package:flutter/material.dart'; |
||||
import 'package:meta/meta.dart'; |
||||
import 'package:neon/neon.dart'; |
||||
import 'package:neon/src/widgets/app_bar.dart'; |
||||
import 'package:neon/src/widgets/drawer_destination.dart'; |
||||
import 'package:provider/provider.dart'; |
||||
|
||||
@internal |
||||
class NeonTabBar extends StatelessWidget { |
||||
const NeonTabBar({ |
||||
super.key, |
||||
}); |
||||
|
||||
@override |
||||
Widget build(final BuildContext context) { |
||||
final theme = Theme.of(context); |
||||
final accountsBloc = Provider.of<AccountsBloc>(context, listen: false); |
||||
final appsBloc = accountsBloc.activeAppsBloc; |
||||
|
||||
final tabbar = ResultBuilder.behaviorSubject( |
||||
stream: appsBloc.appImplementations, |
||||
builder: (final context, final snapshot) { |
||||
if (!snapshot.hasData) { |
||||
return const SizedBox.shrink(); |
||||
} |
||||
|
||||
return _NeonTabBar( |
||||
apps: snapshot.requireData, |
||||
); |
||||
}, |
||||
); |
||||
|
||||
return DecoratedBox( |
||||
decoration: BoxDecoration( |
||||
border: Border( |
||||
bottom: BorderSide( |
||||
color: theme.dividerColor, |
||||
), |
||||
), |
||||
), |
||||
child: Row( |
||||
children: [ |
||||
Expanded( |
||||
child: tabbar, |
||||
), |
||||
const NotificationIconButton(), |
||||
const AccountSwitcherButton(), |
||||
], |
||||
), |
||||
); |
||||
} |
||||
} |
||||
|
||||
class _NeonTabBar extends StatefulWidget { |
||||
const _NeonTabBar({ |
||||
required this.apps, |
||||
}); |
||||
|
||||
final Iterable<AppImplementation> apps; |
||||
|
||||
@override |
||||
State<_NeonTabBar> createState() => __NeonTabBarState(); |
||||
} |
||||
|
||||
class __NeonTabBarState extends State<_NeonTabBar> with SingleTickerProviderStateMixin { |
||||
late TabController _tabController; |
||||
late AccountsBloc _accountsBloc; |
||||
late AppsBloc _appsBloc; |
||||
late List<AppImplementation> _apps; |
||||
|
||||
@override |
||||
void initState() { |
||||
super.initState(); |
||||
|
||||
_accountsBloc = Provider.of<AccountsBloc>(context, listen: false); |
||||
_appsBloc = _accountsBloc.activeAppsBloc; |
||||
|
||||
_apps = widget.apps.toList(); |
||||
final initialIndex = _apps.indexWhere((final app) => app.id == _appsBloc.activeApp.valueOrNull?.id); |
||||
|
||||
_tabController = TabController( |
||||
initialIndex: initialIndex, |
||||
vsync: this, |
||||
length: widget.apps.length, |
||||
); |
||||
} |
||||
|
||||
@override |
||||
void dispose() { |
||||
_tabController.dispose(); |
||||
super.dispose(); |
||||
} |
||||
|
||||
void onAppChange(final int index) { |
||||
_tabController.animateTo(index); |
||||
|
||||
unawaited(_appsBloc.setActiveApp(_apps[index].id)); |
||||
} |
||||
|
||||
@override |
||||
Widget build(final BuildContext context) { |
||||
final appDestinations = _apps.map( |
||||
(final app) => TabExtension.fromNeonDestination( |
||||
app.destination(context), |
||||
), |
||||
); |
||||
|
||||
final drawer = TabBar( |
||||
controller: _tabController, |
||||
tabs: appDestinations.toList(), |
||||
onTap: onAppChange, |
||||
isScrollable: true, |
||||
dividerColor: Colors.transparent, |
||||
); |
||||
|
||||
return drawer; |
||||
} |
||||
} |
Loading…
Reference in new issue