import 'package:comunic/helpers/firebase_messaging_helper.dart'; import 'package:comunic/helpers/independent_push_notifications_helper.dart'; import 'package:comunic/helpers/preferences_helper.dart'; import 'package:comunic/helpers/server_config_helper.dart'; import 'package:comunic/models/api_request.dart'; import 'package:comunic/utils/flutter_utils.dart'; import 'package:flutter/material.dart'; /// Push notifications helper /// /// @author Pierre Hubert enum PushNotificationsStatus { UNDEFINED, DISABLED, FIREBASE, INDEPENDENT } const _PushNotificationsAPIMap = { "undefined": PushNotificationsStatus.UNDEFINED, "disabled": PushNotificationsStatus.DISABLED, "firebase": PushNotificationsStatus.FIREBASE, "independent": PushNotificationsStatus.INDEPENDENT }; class PushNotificationsHelper { /// Get cached status of push notifications static Future getLocalStatus() async { final pref = await PreferencesHelper.getInstance(); if (!pref.containsKey(PreferencesKeyList.PUSH_NOTIFICATIONS_STATUS)) return PushNotificationsStatus.UNDEFINED; return _PushNotificationsAPIMap[ pref.getString(PreferencesKeyList.PUSH_NOTIFICATIONS_STATUS)!]; } /// Refresh local status with information from server /// /// Throws in case of failure static Future refreshLocalStatus() async { final response = await APIRequest.withLogin("push_notifications/status") .execWithThrowGetObject(); var status = _PushNotificationsAPIMap[response["status"]]; if (status == null) status = PushNotificationsStatus.UNDEFINED; if (status == PushNotificationsStatus.INDEPENDENT) { // Invoke plugin to apply new WebSocket URL await IndependentPushNotificationsHelper.configure( response["independent_push_url"]); } await (await PreferencesHelper.getInstance()).setString( PreferencesKeyList.PUSH_NOTIFICATIONS_STATUS, response["status"]); } /// Clear local push notifications status static Future clearLocalStatus() async { await (await PreferencesHelper.getInstance()) .removeKey(PreferencesKeyList.PUSH_NOTIFICATIONS_STATUS); // Stop local refresh notification refresh IndependentPushNotificationsHelper.disable(); } /// Configure push notifications static Future configure( BuildContext context, PushNotificationsStatus? newStatus) async { String? firebaseToken = ""; switch (newStatus) { case PushNotificationsStatus.DISABLED: break; case PushNotificationsStatus.FIREBASE: await FirebaseMessagingHelper.preConfigure(); firebaseToken = await FirebaseMessagingHelper.getToken(); break; case PushNotificationsStatus.INDEPENDENT: if (await IndependentPushNotificationsHelper.needPreConfiguration()) await IndependentPushNotificationsHelper.preConfigure(context); break; default: throw new Exception("Unknown status!"); } await PushNotificationsHelper.clearLocalStatus(); await PushNotificationsHelper.setNewStatus(newStatus, firebaseToken: firebaseToken); await PushNotificationsHelper.refreshLocalStatus(); } /// Set new push notification status on the server static Future setNewStatus( PushNotificationsStatus? newStatus, { String? firebaseToken = "", }) async => await APIRequest.withLogin("push_notifications/configure") .addString( "status", _PushNotificationsAPIMap.entries .firstWhere((e) => e.value == newStatus) .key) .addString("firebase_token", firebaseToken) .execWithThrow(); /// Is true if possible if push notifications are configurable static bool get arePushNotificationsAvailable => srvConfig!.notificationsPolicy.hasFirebase || (isAndroid && srvConfig!.notificationsPolicy.hasIndependent); }