Notification UI Elements
InternalNotificationsBadge
Description
The InternalNotificationsBadge widget is a predefined UI element that displays a badge indicating the number of pending internal notifications. It can be used to provide a visual representation of the notification count and allow users to access the internal notifications page.
Usage
To use the InternalNotificationsBadge widget, simply place it in your widget tree. The widget will automatically update its appearance based on the number of pending notifications.
Example: on homepage app bar
AppBar(
actions: const [
InternalNotificationsBadge()
],
)
InternalNotificationsView
Description
The InternalNotificationsView widget is a predefined UI page that displays a list of internal notifications. It provides a visual representation of each notification and allows users to interact with them.
Usage
To navigate to the InternalNotificationsView page, use the InternalNotificationsView.route() method to obtain the route. You can then push the route onto the navigation stack using Navigator.push.
Generally you don't need to push this/ configure this manually as this is handle by InternalNotificationsBadge widget.
- Please note that this documentation assumes the existence of the InternalNotificationsService and its related dependencies (notification.dart, env.dart, and constants.dart).
- Make sure to import the necessary dependencies and customize the code according to your specific implementation.
Source Code
import 'package:flutter/material.dart';
import './notification.dart';
import '../../../env.dart';
import '../../../helpers/constants.dart';
class InternalNotificationsBadge extends StatefulWidget {
const InternalNotificationsBadge({Key? key}) : super(key: key);
@override
State<InternalNotificationsBadge> createState() => _InternalNotificationsBadgeState();
}
class _InternalNotificationsBadgeState extends State<InternalNotificationsBadge> {
final EnvironmentConfig _environmentConfig = EnvironmentConfig.getEnvConfig();
@override
Widget build(BuildContext context) {
return _environmentConfig.internalNotificationsServiceType ==
InternalNotificationsServiceType.none
? emptyWidget
: StreamBuilder(
initialData: 0,
stream: InternalNotifications.pendingNotificationsCountStream,
builder: (context, snapshot) {
if (snapshot.hasData) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: GestureDetector(
onTap: () => Navigator.push(context, InternalNotificationsView.route()),
child: Center(
child: Badge(
isLabelVisible: snapshot.data != 0,
label: Text(snapshot.data.toString()),
child: const Icon(Icons.notifications_none_rounded),
),
),
),
);
} else {
return emptyWidget;
}
},
);
}
}
class InternalNotificationsView extends StatefulWidget {
static const String routePath = '/notifications';
static Route<void> route() {
return MaterialPageRoute(
settings: const RouteSettings(name: routePath),
builder: (_) => const InternalNotificationsView(),
);
}
const InternalNotificationsView({Key? key}) : super(key: key);
@override
State<InternalNotificationsView> createState() => _InternalNotificationsViewState();
}
class _InternalNotificationsViewState extends State<InternalNotificationsView> {
final double _borderRadius = defaultMargin / 1.5;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Padding(
padding: allPadding16,
child: StreamBuilder(
initialData: InternalNotifications.notifications,
stream: InternalNotifications.notificationsStream,
builder: (context, snapshot) {
if (snapshot.hasData) {
return ListView.builder(
reverse: true,
shrinkWrap: true,
itemCount: snapshot.data!.length,
itemBuilder: (context, index) => Padding(
padding: bottomPadding8,
child: GestureDetector(
onTap: () {
if (snapshot.data![index].payload != null &&
snapshot.data![index].payload['path'] != null) {
Navigator.pushNamed(
context,
snapshot.data![index].payload['path'],
arguments: <String, dynamic>{
'data': snapshot.data![index].payload['data'],
'auth': snapshot.data![index].payload['auth'],
},
);
}
},
child: Card(
elevation: 5,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(_borderRadius),
),
child: Column(
children: [
if (snapshot.data![index].imageUrl != null)
ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(_borderRadius),
topRight: Radius.circular(_borderRadius),
),
child: AspectRatio(
aspectRatio: 16 / 9,
child: Image.network(
snapshot.data![index].imageUrl!,
fit: BoxFit.cover,
),
),
),
ListTile(
title: snapshot.data![index].heading == null
? Text(snapshot.data![index].content)
: Text(snapshot.data![index].heading!),
subtitle: snapshot.data![index].heading != null
? Text(snapshot.data![index].content)
: null,
),
],
),
),
),
),
);
} else {
return const Text('Come back later!');
}
},
),
),
);
}
}