mirror of
				https://gitlab.com/comunic/comunicmobile
				synced 2025-11-03 11:44:18 +00:00 
			
		
		
		
	Start to integrate push notifications
This commit is contained in:
		
							
								
								
									
										188
									
								
								lib/ui/routes/push_notifications_route.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										188
									
								
								lib/ui/routes/push_notifications_route.dart
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,188 @@
 | 
			
		||||
import 'package:comunic/helpers/push_notifications_helper.dart';
 | 
			
		||||
import 'package:comunic/helpers/server_config_helper.dart';
 | 
			
		||||
import 'package:comunic/models/config.dart';
 | 
			
		||||
import 'package:comunic/ui/widgets/async_screen_widget.dart';
 | 
			
		||||
import 'package:comunic/utils/flutter_utils.dart';
 | 
			
		||||
import 'package:comunic/utils/intl_utils.dart';
 | 
			
		||||
import 'package:comunic/utils/log_utils.dart';
 | 
			
		||||
import 'package:comunic/utils/ui_utils.dart';
 | 
			
		||||
import 'package:flutter/material.dart';
 | 
			
		||||
 | 
			
		||||
/// Push notifications configuration route
 | 
			
		||||
///
 | 
			
		||||
/// @author Pierre Hubert
 | 
			
		||||
 | 
			
		||||
Future<void> showInitialPushNotificationsConfiguration(
 | 
			
		||||
    BuildContext context) async {
 | 
			
		||||
  // Check if no notifications service are available
 | 
			
		||||
  if (!srvConfig.notificationsPolicy.hasIndependent &&
 | 
			
		||||
      (!isAndroid || !srvConfig.notificationsPolicy.hasFirebase)) return;
 | 
			
		||||
 | 
			
		||||
  await Navigator.of(context).push(
 | 
			
		||||
      MaterialPageRoute(builder: (c) => PushNotificationsConfigurationRoute()));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class PushNotificationsConfigurationRoute extends StatefulWidget {
 | 
			
		||||
  @override
 | 
			
		||||
  _PushNotificationsConfigurationRouteState createState() =>
 | 
			
		||||
      _PushNotificationsConfigurationRouteState();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class _PushNotificationsConfigurationRouteState
 | 
			
		||||
    extends State<PushNotificationsConfigurationRoute> {
 | 
			
		||||
  PushNotificationsStatus currStatus;
 | 
			
		||||
 | 
			
		||||
  bool get canSubmit =>
 | 
			
		||||
      (currStatus ?? PushNotificationsStatus.UNDEFINED) !=
 | 
			
		||||
      PushNotificationsStatus.UNDEFINED;
 | 
			
		||||
 | 
			
		||||
  Future<void> _refresh() async {
 | 
			
		||||
    await PushNotificationsHelper.refreshLocalStatus();
 | 
			
		||||
    currStatus = await PushNotificationsHelper.getLocalStatus();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  Widget build(BuildContext context) {
 | 
			
		||||
    return Material(
 | 
			
		||||
        color: config().splashBackgroundColor,
 | 
			
		||||
        child: Center(
 | 
			
		||||
          child: Padding(
 | 
			
		||||
            padding: const EdgeInsets.all(8.0),
 | 
			
		||||
            child: AsyncScreenWidget(
 | 
			
		||||
              onReload: _refresh,
 | 
			
		||||
              onBuild: _buildForm,
 | 
			
		||||
              errorMessage: tr("Failed to load push notifications settings!"),
 | 
			
		||||
            ),
 | 
			
		||||
          ),
 | 
			
		||||
        ));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Widget _buildForm() => ConstrainedBox(
 | 
			
		||||
        constraints: BoxConstraints(maxWidth: 300),
 | 
			
		||||
        child: Column(
 | 
			
		||||
          mainAxisAlignment: MainAxisAlignment.center,
 | 
			
		||||
          children: [
 | 
			
		||||
            Spacer(),
 | 
			
		||||
            Icon(Icons.notifications_none),
 | 
			
		||||
            Spacer(),
 | 
			
		||||
            Text(
 | 
			
		||||
              tr("Comunic can now send you notifications to your device when the application is closed if you want."),
 | 
			
		||||
              textAlign: TextAlign.center,
 | 
			
		||||
            ),
 | 
			
		||||
            Spacer(),
 | 
			
		||||
            _NotificationOption(
 | 
			
		||||
              title: tr("Use Google services"),
 | 
			
		||||
              description: tr(
 | 
			
		||||
                  "Use the Google Play services to send you notifications. This option is less privacy-friendly, but it will work on most phones and will save your battery life."),
 | 
			
		||||
              option: PushNotificationsStatus.FIREBASE,
 | 
			
		||||
              current: currStatus,
 | 
			
		||||
              available: srvConfig.notificationsPolicy.hasFirebase,
 | 
			
		||||
              onChanged: (s) => setState(() => currStatus = s),
 | 
			
		||||
            ),
 | 
			
		||||
            _NotificationOption(
 | 
			
		||||
              title: tr("Use independent notifications service"),
 | 
			
		||||
              description: tr(
 | 
			
		||||
                  "Configure Comunic to use your own self-hosted notifications service. This option is much more privacy-friendly, but it will drain your battery life."),
 | 
			
		||||
              option: PushNotificationsStatus.INDEPENDENT,
 | 
			
		||||
              current: currStatus,
 | 
			
		||||
              available:
 | 
			
		||||
                  srvConfig.notificationsPolicy.hasIndependent && isAndroid,
 | 
			
		||||
              onChanged: (s) => setState(() => currStatus = s),
 | 
			
		||||
            ),
 | 
			
		||||
            _NotificationOption(
 | 
			
		||||
              title: tr("Do not send notification"),
 | 
			
		||||
              description: tr(
 | 
			
		||||
                  "Disable notifications services. You will always be able to change it from application settings."),
 | 
			
		||||
              option: PushNotificationsStatus.DISABLED,
 | 
			
		||||
              current: currStatus,
 | 
			
		||||
              available: true,
 | 
			
		||||
              onChanged: (s) => setState(() => currStatus = s),
 | 
			
		||||
            ),
 | 
			
		||||
            Spacer(),
 | 
			
		||||
            OutlinedButton(
 | 
			
		||||
                onPressed: canSubmit ? _submit : null,
 | 
			
		||||
                child: Text(tr("Configure").toUpperCase()),
 | 
			
		||||
                style: OutlinedButton.styleFrom(primary: Colors.white)),
 | 
			
		||||
            Spacer(),
 | 
			
		||||
          ],
 | 
			
		||||
        ),
 | 
			
		||||
      );
 | 
			
		||||
 | 
			
		||||
  Future<void> _submit() async {
 | 
			
		||||
    try {
 | 
			
		||||
      switch (currStatus) {
 | 
			
		||||
        case PushNotificationsStatus.DISABLED:
 | 
			
		||||
          break;
 | 
			
		||||
 | 
			
		||||
        case PushNotificationsStatus.FIREBASE:
 | 
			
		||||
          // TODO: Handle this case.
 | 
			
		||||
          throw new Exception("Firebase not supported yet!");
 | 
			
		||||
          break;
 | 
			
		||||
        case PushNotificationsStatus.INDEPENDENT:
 | 
			
		||||
          // TODO: Handle this case.
 | 
			
		||||
          throw new Exception("Independent not supported yet!");
 | 
			
		||||
          break;
 | 
			
		||||
 | 
			
		||||
        default:
 | 
			
		||||
          throw new Exception("Unknown status!");
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      await PushNotificationsHelper.clearLocalStatus();
 | 
			
		||||
      await PushNotificationsHelper.setNewStatus(currStatus);
 | 
			
		||||
      await PushNotificationsHelper.refreshLocalStatus();
 | 
			
		||||
 | 
			
		||||
      Navigator.of(context).pop();
 | 
			
		||||
    } catch (e, s) {
 | 
			
		||||
      logError(e, s);
 | 
			
		||||
      showAlert(
 | 
			
		||||
          context: context,
 | 
			
		||||
          message: tr("Failed to configure push notifications!"));
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class _NotificationOption extends StatelessWidget {
 | 
			
		||||
  final String title;
 | 
			
		||||
  final String description;
 | 
			
		||||
  final PushNotificationsStatus option;
 | 
			
		||||
  final PushNotificationsStatus current;
 | 
			
		||||
  final bool available;
 | 
			
		||||
  final Function(PushNotificationsStatus) onChanged;
 | 
			
		||||
 | 
			
		||||
  const _NotificationOption({
 | 
			
		||||
    Key key,
 | 
			
		||||
    @required this.title,
 | 
			
		||||
    @required this.description,
 | 
			
		||||
    @required this.option,
 | 
			
		||||
    @required this.current,
 | 
			
		||||
    @required this.available,
 | 
			
		||||
    @required this.onChanged,
 | 
			
		||||
  })  : assert(title != null),
 | 
			
		||||
        assert(description != null),
 | 
			
		||||
        assert(option != null),
 | 
			
		||||
        assert(current != null),
 | 
			
		||||
        assert(available != null),
 | 
			
		||||
        assert(onChanged != null),
 | 
			
		||||
        super(key: key);
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  Widget build(BuildContext context) => !available
 | 
			
		||||
      ? Container()
 | 
			
		||||
      : Theme(
 | 
			
		||||
          data: Theme.of(context).copyWith(
 | 
			
		||||
            splashColor: Colors.transparent,
 | 
			
		||||
            highlightColor: Colors.transparent,
 | 
			
		||||
          ),
 | 
			
		||||
          child: ListTile(
 | 
			
		||||
            leading: Radio(
 | 
			
		||||
              value: option,
 | 
			
		||||
              groupValue: current,
 | 
			
		||||
              onChanged: onChanged,
 | 
			
		||||
            ),
 | 
			
		||||
            title: Text(title),
 | 
			
		||||
            subtitle: Text(description),
 | 
			
		||||
            contentPadding: EdgeInsets.all(0),
 | 
			
		||||
            onTap: () => onChanged(option),
 | 
			
		||||
          ),
 | 
			
		||||
        );
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user