Просмотр исходного кода

Add setting to disable notifications

vishnukvmd 2 лет назад
Родитель
Сommit
03d2a95501

+ 5 - 0
lib/generated/intl/messages_en.dart

@@ -826,6 +826,7 @@ class MessageLookup extends MessageLookupByLibrary {
             MessageLookupByLibrary.simpleMessage("No results found"),
         "nothingToSeeHere":
             MessageLookupByLibrary.simpleMessage("Nothing to see here! 👀"),
+        "notifications": MessageLookupByLibrary.simpleMessage("Notifications"),
         "ok": MessageLookupByLibrary.simpleMessage("Ok"),
         "onDevice": MessageLookupByLibrary.simpleMessage("On device"),
         "onEnte": MessageLookupByLibrary.simpleMessage(
@@ -1078,6 +1079,10 @@ class MessageLookup extends MessageLookupByLibrary {
         "sharedAlbumSectionDescription": MessageLookupByLibrary.simpleMessage(
             "Create shared and collaborative albums with other ente users, including users on free plans."),
         "sharedByMe": MessageLookupByLibrary.simpleMessage("Shared by me"),
+        "sharedPhotoNotifications":
+            MessageLookupByLibrary.simpleMessage("New shared photos"),
+        "sharedPhotoNotificationsExplanation": MessageLookupByLibrary.simpleMessage(
+            "Receive notifications when someone adds a photo to a shared album that you\'re a part of"),
         "sharedWith": m28,
         "sharedWithMe": MessageLookupByLibrary.simpleMessage("Shared with me"),
         "sharing": MessageLookupByLibrary.simpleMessage("Sharing..."),

+ 30 - 0
lib/generated/l10n.dart

@@ -3402,6 +3402,36 @@ class S {
     );
   }
 
+  /// `Notifications`
+  String get notifications {
+    return Intl.message(
+      'Notifications',
+      name: 'notifications',
+      desc: '',
+      args: [],
+    );
+  }
+
+  /// `New shared photos`
+  String get sharedPhotoNotifications {
+    return Intl.message(
+      'New shared photos',
+      name: 'sharedPhotoNotifications',
+      desc: '',
+      args: [],
+    );
+  }
+
+  /// `Receive notifications when someone adds a photo to a shared album that you're a part of`
+  String get sharedPhotoNotificationsExplanation {
+    return Intl.message(
+      'Receive notifications when someone adds a photo to a shared album that you\'re a part of',
+      name: 'sharedPhotoNotificationsExplanation',
+      desc: '',
+      args: [],
+    );
+  }
+
   /// `Advanced`
   String get advanced {
     return Intl.message(

+ 11 - 10
lib/l10n/intl_en.arb

@@ -490,6 +490,9 @@
   },
   "familyPlans": "Family plans",
   "referrals": "Referrals",
+  "notifications": "Notifications",
+  "sharedPhotoNotifications": "New shared photos",
+  "sharedPhotoNotificationsExplanation": "Receive notifications when someone adds a photo to a shared album that you're a part of",
   "advanced": "Advanced",
   "general": "General",
   "security": "Security",
@@ -641,7 +644,6 @@
     "description": "Button text for raising a support tickets in case of unhandled errors during backup",
     "type": "text"
   },
-
   "backupFailed": "Backup failed",
   "couldNotBackUpTryLater": "We could not backup your data.\nWe will retry later.",
   "enteCanEncryptAndPreserveFilesOnlyIfYouGrant": "ente can encrypt and preserve files only if you grant access to them",
@@ -753,7 +755,7 @@
   },
   "deleteAll": "Delete All",
   "renameAlbum": "Rename album",
-  "setCover" : "Set cover",
+  "setCover": "Set cover",
   "@setCover": {
     "description": "Text to set cover photo for an album"
   },
@@ -955,7 +957,7 @@
   "save": "Save",
   "centerPoint": "Center point",
   "pickCenterPoint": "Pick center point",
-  "useSelectedPhoto": "Use selected photo", 
+  "useSelectedPhoto": "Use selected photo",
   "edit": "Edit",
   "deleteLocation": "Delete location",
   "rotateLeft": "Rotate left",
@@ -982,13 +984,13 @@
   "@storageBreakupYou": {
     "description": "Label to indicate how much storage you are using when you are part of a family plan"
   },
-  "storageUsageInfo" : "{usedAmount} {usedStorageUnit} of {totalAmount} {totalStorageUnit} used",
-  "@storageUsageInfo" :{
+  "storageUsageInfo": "{usedAmount} {usedStorageUnit} of {totalAmount} {totalStorageUnit} used",
+  "@storageUsageInfo": {
     "description": "Example: 1.2 GB of 2 GB used or 100 GB or 2TB used"
   },
-  "freeStorageSpace" : "{freeAmount} {storageUnit} free",
+  "freeStorageSpace": "{freeAmount} {storageUnit} free",
   "appVersion": "Version: {versionValue}",
-  "verifyIDLabel" : "Verify",
+  "verifyIDLabel": "Verify",
   "fileInfoAddDescHint": "Add a description...",
   "editLocationTagTitle": "Edit location",
   "setLabel": "Set",
@@ -1056,8 +1058,7 @@
   "@map": {
     "description": "Label for the map view"
   },
-  "maps" : "Maps",
+  "maps": "Maps",
   "enableMaps": "Enable Maps",
-  "enableMapsDesc" : "This will show your photos on a world map.\n\nThis map is hosted by Open Street Map, and the exact locations of your photos are never shared.\n\nYou can disable this feature anytime from Settings."
+  "enableMapsDesc": "This will show your photos on a world map.\n\nThis map is hosted by Open Street Map, and the exact locations of your photos are never shared.\n\nYou can disable this feature anytime from Settings."
 }
-

+ 23 - 4
lib/services/notification_service.dart

@@ -8,6 +8,7 @@ class NotificationService {
       NotificationService._privateConstructor();
   static const String keyGrantedNotificationPermission =
       "notification_permission_granted";
+  static const String keyShouldShowNotifications = "notifications_enabled";
 
   NotificationService._privateConstructor();
 
@@ -25,7 +26,13 @@ class NotificationService {
       iOS: iosSettings,
     );
     await _flutterLocalNotificationsPlugin.initialize(initializationSettings);
-    if (Platform.isIOS && !_hasGrantedPermissions()) {
+    if (!hasGrantedPermissions()) {
+      await requestPermissions();
+    }
+  }
+
+  Future<void> requestPermissions() async {
+    if (Platform.isIOS) {
       final result = await _flutterLocalNotificationsPlugin
           .resolvePlatformSpecificImplementation<
               IOSFlutterLocalNotificationsPlugin>()
@@ -33,17 +40,29 @@ class NotificationService {
             sound: true,
             alert: true,
           );
-      if (result != null && result) {
-        _preferences.setBool(keyGrantedNotificationPermission, true);
+      if (result != null) {
+        _preferences.setBool(keyGrantedNotificationPermission, result);
       }
     }
   }
 
-  bool _hasGrantedPermissions() {
+  bool hasGrantedPermissions() {
+    if (Platform.isAndroid) {
+      return true;
+    }
     final result = _preferences.getBool(keyGrantedNotificationPermission);
     return result ?? false;
   }
 
+  bool shouldShowNotifications() {
+    final result = _preferences.getBool(keyShouldShowNotifications);
+    return result ?? true;
+  }
+
+  Future<void> setShouldShowNotifications(bool value) {
+    return _preferences.setBool(keyShouldShowNotifications, value);
+  }
+
   Future<void> showNotification(String title, String message) async {
     const AndroidNotificationDetails androidPlatformChannelSpecifics =
         AndroidNotificationDetails(

+ 20 - 0
lib/ui/settings/general_section_widget.dart

@@ -12,6 +12,7 @@ import "package:photos/ui/growth/referral_screen.dart";
 import 'package:photos/ui/settings/advanced_settings_screen.dart';
 import 'package:photos/ui/settings/common_settings.dart';
 import "package:photos/ui/settings/language_picker.dart";
+import "package:photos/ui/settings/notification_settings_screen.dart";
 import 'package:photos/utils/navigation_util.dart';
 
 class GeneralSectionWidget extends StatelessWidget {
@@ -82,6 +83,18 @@ class GeneralSectionWidget extends StatelessWidget {
           },
         ),
         sectionOptionSpacing,
+        MenuItemWidget(
+          captionedTextWidget: CaptionedTextWidget(
+            title: S.of(context).notifications,
+          ),
+          pressedColor: getEnteColorScheme(context).fillFaint,
+          trailingIcon: Icons.chevron_right_outlined,
+          trailingIconIsMuted: true,
+          onTap: () async {
+            _onNotificationsTapped(context);
+          },
+        ),
+        sectionOptionSpacing,
         MenuItemWidget(
           captionedTextWidget: CaptionedTextWidget(
             title: S.of(context).advanced,
@@ -104,6 +117,13 @@ class GeneralSectionWidget extends StatelessWidget {
     BillingService.instance.launchFamilyPortal(context, userDetails);
   }
 
+  void _onNotificationsTapped(BuildContext context) {
+    routeToPage(
+      context,
+      const NotificationSettingsScreen(),
+    );
+  }
+
   void _onAdvancedTapped(BuildContext context) {
     routeToPage(
       context,

+ 94 - 0
lib/ui/settings/notification_settings_screen.dart

@@ -0,0 +1,94 @@
+import 'package:flutter/material.dart';
+import "package:photos/generated/l10n.dart";
+import "package:photos/services/notification_service.dart";
+import 'package:photos/theme/ente_theme.dart';
+import 'package:photos/ui/components/buttons/icon_button_widget.dart';
+import 'package:photos/ui/components/captioned_text_widget.dart';
+import 'package:photos/ui/components/menu_item_widget/menu_item_widget.dart';
+import 'package:photos/ui/components/menu_section_description_widget.dart';
+import 'package:photos/ui/components/title_bar_title_widget.dart';
+import 'package:photos/ui/components/title_bar_widget.dart';
+import 'package:photos/ui/components/toggle_switch_widget.dart';
+
+class NotificationSettingsScreen extends StatelessWidget {
+  const NotificationSettingsScreen({super.key});
+
+  @override
+  Widget build(BuildContext context) {
+    final colorScheme = getEnteColorScheme(context);
+    return Scaffold(
+      body: CustomScrollView(
+        primary: false,
+        slivers: <Widget>[
+          TitleBarWidget(
+            flexibleSpaceTitle: TitleBarTitleWidget(
+              title: S.of(context).notifications,
+            ),
+            actionIcons: [
+              IconButtonWidget(
+                icon: Icons.close_outlined,
+                iconButtonType: IconButtonType.secondary,
+                onTap: () {
+                  Navigator.pop(context);
+                  Navigator.pop(context);
+                },
+              ),
+            ],
+          ),
+          SliverList(
+            delegate: SliverChildBuilderDelegate(
+              (context, index) {
+                return Padding(
+                  padding: const EdgeInsets.symmetric(horizontal: 16),
+                  child: Padding(
+                    padding: const EdgeInsets.symmetric(vertical: 20),
+                    child: Column(
+                      mainAxisSize: MainAxisSize.min,
+                      children: [
+                        Column(
+                          children: [
+                            MenuItemWidget(
+                              captionedTextWidget: CaptionedTextWidget(
+                                title: S.of(context).sharedPhotoNotifications,
+                              ),
+                              menuItemColor: colorScheme.fillFaint,
+                              trailingWidget: ToggleSwitchWidget(
+                                value: () =>
+                                    NotificationService.instance
+                                        .hasGrantedPermissions() &&
+                                    NotificationService.instance
+                                        .shouldShowNotifications(),
+                                onChanged: () async {
+                                  await NotificationService.instance
+                                      .requestPermissions();
+                                  await NotificationService.instance
+                                      .setShouldShowNotifications(
+                                    !NotificationService.instance
+                                        .shouldShowNotifications(),
+                                  );
+                                },
+                              ),
+                              singleBorderRadius: 8,
+                              alignCaptionedTextToLeft: true,
+                              isGestureDetectorDisabled: true,
+                            ),
+                            MenuSectionDescriptionWidget(
+                              content: S
+                                  .of(context)
+                                  .sharedPhotoNotificationsExplanation,
+                            )
+                          ],
+                        )
+                      ],
+                    ),
+                  ),
+                );
+              },
+              childCount: 1,
+            ),
+          ),
+        ],
+      ),
+    );
+  }
+}