1
0
mirror of https://gitlab.com/comunic/comunicmobile synced 2024-11-22 12:59:21 +00:00
comunicmobile/lib/ui/routes/push_notifications_route.dart
2021-04-17 08:54:36 +02:00

200 lines
7.0 KiB
Dart

import 'package:comunic/helpers/firebase_messaging_helper.dart';
import 'package:comunic/helpers/independent_push_notifications_helper.dart';
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 (!PushNotificationsHelper.arePushNotificationsAvailable) 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(
textStyle: TextStyle(color: Colors.white),
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, color: Colors.white),
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 our own self-hosted notifications service. This option is much more privacy-friendly, but it will drain your battery."),
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 service. 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 {
String firebaseToken = "";
if (currStatus == await PushNotificationsHelper.getLocalStatus()) {
Navigator.of(context).pop();
return;
}
switch (currStatus) {
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(currStatus,
firebaseToken: firebaseToken);
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,
fillColor: MaterialStateProperty.all(Colors.white),
),
title: Text(title, style: TextStyle(color: Colors.white)),
subtitle: Text(description, style: TextStyle(color: Colors.white)),
contentPadding: EdgeInsets.all(0),
onTap: () => onChanged(option),
),
);
}