Browse Source

neon: let apps provide a NavigationDestination

pull/387/head
Nikolas Rimikis 1 year ago
parent
commit
b4ae60b1e5
No known key found for this signature in database
GPG Key ID: 85ED1DE9786A4FF2
  1. 12
      packages/neon/neon/lib/src/utils/app_implementation.dart
  2. 137
      packages/neon/neon/lib/src/widgets/drawer_destination.dart

12
packages/neon/neon/lib/src/utils/app_implementation.dart

@ -41,6 +41,18 @@ abstract class AppImplementation<T extends Bloc, R extends NextcloudAppSpecificO
Widget get page; Widget get page;
NeonNavigationDestination destination(final BuildContext context) {
final accountsBloc = Provider.of<AccountsBloc>(context, listen: false);
final account = accountsBloc.activeAccount.value!;
final bloc = getBloc(account);
return NeonNavigationDestination(
label: name(context),
icon: buildIcon,
notificationCount: getUnreadCounter(bloc),
);
}
Widget buildIcon({ Widget buildIcon({
final Size size = const Size.square(32), final Size size = const Size.square(32),
final Color? color, final Color? color,

137
packages/neon/neon/lib/src/widgets/drawer_destination.dart

@ -0,0 +1,137 @@
import 'package:flutter/material.dart';
import 'package:neon/neon.dart';
import 'package:rxdart/subjects.dart';
typedef DestinationIconBuilder = Widget Function({Size size, Color color});
class NeonNavigationDestination {
const NeonNavigationDestination({
required this.label,
required this.icon,
this.selectedIcon,
this.notificationCount,
});
final String label;
final DestinationIconBuilder icon;
final Widget? selectedIcon;
final BehaviorSubject<int>? notificationCount;
}
extension NavigationDestinationExtension on NavigationDestination {
static NavigationDestination fromNeonDestination(final NeonNavigationDestination neonDestination) =>
NavigationDestination(
label: neonDestination.label,
icon: neonDestination.icon(),
selectedIcon: neonDestination.selectedIcon,
);
}
extension NavigationRailDestinationExtension on NavigationRailDestination {
static NavigationRailDestination fromNeonDestination(final NeonNavigationDestination neonDestination) {
final iconWIdget = StreamBuilder(
stream: neonDestination.notificationCount,
initialData: 0,
builder: (final context, final snapshot) {
final colorScheme = Theme.of(context).colorScheme;
final color = snapshot.data! > 0 ? colorScheme.primary : colorScheme.onBackground;
const size = Size.square(kAvatarSize * 2 / 3);
final icon = Container(
margin: const EdgeInsets.all(5),
child: neonDestination.icon(size: size, color: color),
);
if (snapshot.data! <= 0) {
return icon;
}
final notificationIdicator = Builder(
builder: (final context) {
final style = TextStyle(
color: Theme.of(context).colorScheme.primary,
fontWeight: FontWeight.bold,
);
return Text(
snapshot.data!.toString(),
style: style,
);
},
);
return Stack(
alignment: Alignment.bottomRight,
children: [
icon,
notificationIdicator,
],
);
},
);
return NavigationRailDestination(
label: Text(neonDestination.label),
icon: iconWIdget,
selectedIcon: neonDestination.selectedIcon,
);
}
}
extension NavigationDrawerDestinationExtension on NavigationDrawerDestination {
static NavigationDrawerDestination fromNeonDestination(final NeonNavigationDestination neonDestination) {
final labelWidget = StreamBuilder(
stream: neonDestination.notificationCount,
initialData: 0,
builder: (final context, final snapshot) {
final label = Text(neonDestination.label);
if (snapshot.data! <= 0) {
return label;
}
final notificationIdicator = Padding(
padding: const EdgeInsets.only(left: 12, right: 24),
child: Builder(
builder: (final context) {
final style = TextStyle(
color: Theme.of(context).colorScheme.primary,
fontWeight: FontWeight.bold,
fontSize: 14,
);
return Text(
snapshot.data!.toString(),
style: style,
);
},
),
);
return Expanded(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
label,
notificationIdicator,
],
),
);
},
);
return NavigationDrawerDestination(
label: labelWidget,
icon: neonDestination.icon(),
selectedIcon: neonDestination.selectedIcon,
);
}
}
extension TabExtension on Tab {
static Tab fromNeonDestination(final NeonNavigationDestination neonDestination) => Tab(
text: neonDestination.label,
icon: neonDestination.icon(),
);
}
Loading…
Cancel
Save