Internal

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.

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!');
            }
          },
        ),
      ),
    );
  }
}

Copyright © 2024