浏览代码

Merge pull request #609 from ente-io/redesign-with-components

Redesign with components
Neeraj Gupta 2 年之前
父节点
当前提交
1f6a08d71a

+ 1 - 1
lib/theme/text_style.dart

@@ -43,7 +43,7 @@ const TextStyle large = TextStyle(
 );
 );
 const TextStyle body = TextStyle(
 const TextStyle body = TextStyle(
   fontSize: 16,
   fontSize: 16,
-  height: 19.4 / 16.0,
+  height: 20 / 16.0,
   fontWeight: _regularWeight,
   fontWeight: _regularWeight,
   fontFamily: _fontFamily,
   fontFamily: _fontFamily,
 );
 );

+ 138 - 0
lib/ui/backup_settings_screen.dart

@@ -0,0 +1,138 @@
+import 'dart:io';
+
+import 'package:flutter/material.dart';
+import 'package:photos/core/configuration.dart';
+import 'package:photos/theme/ente_theme.dart';
+import 'package:photos/ui/components/captioned_text_widget.dart';
+import 'package:photos/ui/components/icon_button_widget.dart';
+import 'package:photos/ui/components/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 BackupSettingsScreen extends StatelessWidget {
+  const BackupSettingsScreen({super.key});
+
+  @override
+  Widget build(BuildContext context) {
+    final colorScheme = getEnteColorScheme(context);
+    return Scaffold(
+      body: CustomScrollView(
+        primary: false,
+        slivers: <Widget>[
+          TitleBarWidget(
+            flexibleSpaceTitle: const TitleBarTitleWidget(
+              title: "Backup settings",
+            ),
+            actionIcons: [
+              IconButtonWidget(
+                icon: Icons.close_outlined,
+                isSecondary: true,
+                onTap: () {
+                  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: const CaptionedTextWidget(
+                                title: "Backup over mobile data",
+                              ),
+                              menuItemColor: colorScheme.fillFaint,
+                              trailingSwitch: ToggleSwitchWidget(
+                                value: () {
+                                  return Configuration.instance
+                                      .shouldBackupOverMobileData();
+                                },
+                                onChanged: () async {
+                                  await Configuration.instance
+                                      .setBackupOverMobileData(
+                                    !Configuration.instance
+                                        .shouldBackupOverMobileData(),
+                                  );
+                                },
+                              ),
+                              borderRadius: 8,
+                              alignCaptionedTextToLeft: true,
+                              isBottomBorderRadiusRemoved: true,
+                              isGestureDetectorDisabled: true,
+                            ),
+                            const SizedBox(height: 1),
+                            MenuItemWidget(
+                              captionedTextWidget: const CaptionedTextWidget(
+                                title: "Backup videos",
+                              ),
+                              menuItemColor: colorScheme.fillFaint,
+                              trailingSwitch: ToggleSwitchWidget(
+                                value: () =>
+                                    Configuration.instance.shouldBackupVideos(),
+                                onChanged: () => Configuration.instance
+                                    .setShouldBackupVideos(
+                                  !Configuration.instance.shouldBackupVideos(),
+                                ),
+                              ),
+                              borderRadius: 8,
+                              alignCaptionedTextToLeft: true,
+                              isTopBorderRadiusRemoved: true,
+                              isGestureDetectorDisabled: true,
+                            ),
+                          ],
+                        ),
+                        const SizedBox(height: 24),
+                        Platform.isIOS
+                            ? Column(
+                                children: [
+                                  MenuItemWidget(
+                                    captionedTextWidget:
+                                        const CaptionedTextWidget(
+                                      title: "Disable auto lock",
+                                    ),
+                                    menuItemColor: colorScheme.fillFaint,
+                                    trailingSwitch: ToggleSwitchWidget(
+                                      value: () => Configuration.instance
+                                          .shouldKeepDeviceAwake(),
+                                      onChanged: () {
+                                        return Configuration.instance
+                                            .setShouldKeepDeviceAwake(
+                                          !Configuration.instance
+                                              .shouldKeepDeviceAwake(),
+                                        );
+                                      },
+                                    ),
+                                    borderRadius: 8,
+                                    alignCaptionedTextToLeft: true,
+                                    isGestureDetectorDisabled: true,
+                                  ),
+                                  const MenuSectionDescriptionWidget(
+                                    content:
+                                        "Disable the device screen lock when ente is in the foreground and there is a backup in progress. This is normally not needed, but may help big uploads and initial imports of large libraries complete faster.",
+                                  )
+                                ],
+                              )
+                            : const SizedBox.shrink(),
+                      ],
+                    ),
+                  ),
+                );
+              },
+              childCount: 1,
+            ),
+          ),
+        ],
+      ),
+    );
+  }
+}

+ 5 - 7
lib/ui/components/home_header_widget.dart

@@ -3,6 +3,7 @@ import 'dart:ui';
 import 'package:flutter/material.dart';
 import 'package:flutter/material.dart';
 import 'package:photos/core/event_bus.dart';
 import 'package:photos/core/event_bus.dart';
 import 'package:photos/events/opened_settings_event.dart';
 import 'package:photos/events/opened_settings_event.dart';
+import 'package:photos/ui/components/icon_button_widget.dart';
 import 'package:photos/ui/viewer/search/search_widget.dart';
 import 'package:photos/ui/viewer/search/search_widget.dart';
 
 
 class HomeHeaderWidget extends StatefulWidget {
 class HomeHeaderWidget extends StatefulWidget {
@@ -23,16 +24,13 @@ class _HomeHeaderWidgetState extends State<HomeHeaderWidget> {
       child: Row(
       child: Row(
         mainAxisAlignment: MainAxisAlignment.spaceBetween,
         mainAxisAlignment: MainAxisAlignment.spaceBetween,
         children: [
         children: [
-          IconButton(
-            visualDensity: const VisualDensity(horizontal: -2, vertical: -2),
-            onPressed: () {
+          IconButtonWidget(
+            isPrimary: true,
+            icon: Icons.menu_outlined,
+            onTap: () {
               Scaffold.of(context).openDrawer();
               Scaffold.of(context).openDrawer();
               Bus.instance.fire(OpenedSettingsEvent());
               Bus.instance.fire(OpenedSettingsEvent());
             },
             },
-            splashColor: Colors.transparent,
-            icon: const Icon(
-              Icons.menu_outlined,
-            ),
           ),
           ),
           AnimatedSwitcher(
           AnimatedSwitcher(
             duration: const Duration(milliseconds: 250),
             duration: const Duration(milliseconds: 250),

+ 102 - 0
lib/ui/components/icon_button_widget.dart

@@ -0,0 +1,102 @@
+import 'package:flutter/material.dart';
+import 'package:photos/theme/colors.dart';
+import 'package:photos/theme/ente_theme.dart';
+
+class IconButtonWidget extends StatefulWidget {
+  final bool isPrimary;
+  final bool isSecondary;
+  final bool isRounded;
+  final IconData icon;
+  final bool disableGestureDetector;
+  final VoidCallback? onTap;
+  final Color? defaultColor;
+  final Color? pressedColor;
+  final Color? iconColor;
+  const IconButtonWidget({
+    required this.icon,
+    this.isPrimary = false,
+    this.isSecondary = false,
+    this.isRounded = false,
+    this.disableGestureDetector = false,
+    this.onTap,
+    this.defaultColor,
+    this.pressedColor,
+    this.iconColor,
+    super.key,
+  });
+
+  @override
+  State<IconButtonWidget> createState() => _IconButtonWidgetState();
+}
+
+class _IconButtonWidgetState extends State<IconButtonWidget> {
+  Color? iconStateColor;
+  @override
+  void didChangeDependencies() {
+    setState(() {
+      iconStateColor = null;
+    });
+    super.didChangeDependencies();
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    if (!widget.isPrimary && !widget.isRounded && !widget.isSecondary) {
+      return const SizedBox.shrink();
+    }
+    final colorTheme = getEnteColorScheme(context);
+    iconStateColor ??
+        (iconStateColor = widget.defaultColor ??
+            (widget.isRounded ? colorTheme.fillFaint : null));
+    return widget.disableGestureDetector
+        ? _iconButton(colorTheme)
+        : GestureDetector(
+            onTapDown: _onTapDown,
+            onTapUp: _onTapUp,
+            onTapCancel: _onTapCancel,
+            onTap: widget.onTap,
+            child: _iconButton(colorTheme),
+          );
+  }
+
+  Widget _iconButton(EnteColorScheme colorTheme) {
+    return AnimatedContainer(
+      duration: const Duration(milliseconds: 20),
+      padding: const EdgeInsets.all(8),
+      decoration: BoxDecoration(
+        borderRadius: BorderRadius.circular(20),
+        color: iconStateColor,
+      ),
+      child: Icon(
+        widget.icon,
+        color: widget.iconColor ??
+            (widget.isSecondary
+                ? colorTheme.strokeMuted
+                : colorTheme.strokeBase),
+        size: 24,
+      ),
+    );
+  }
+
+  _onTapDown(details) {
+    final colorTheme = getEnteColorScheme(context);
+    setState(() {
+      iconStateColor = widget.pressedColor ??
+          (widget.isRounded ? colorTheme.fillMuted : colorTheme.fillFaint);
+    });
+  }
+
+  _onTapUp(details) {
+    Future.delayed(const Duration(milliseconds: 100), () {
+      setState(() {
+        iconStateColor = null;
+      });
+    });
+  }
+
+  _onTapCancel() {
+    setState(() {
+      iconStateColor = null;
+    });
+  }
+}

+ 16 - 5
lib/ui/components/menu_item_widget.dart

@@ -19,6 +19,10 @@ class MenuItemWidget extends StatefulWidget {
   final double borderRadius;
   final double borderRadius;
   final Color? pressedColor;
   final Color? pressedColor;
   final ExpandableController? expandableController;
   final ExpandableController? expandableController;
+  final bool isBottomBorderRadiusRemoved;
+  final bool isTopBorderRadiusRemoved;
+  //disable gesture detector if not used
+  final bool isGestureDetectorDisabled;
   const MenuItemWidget({
   const MenuItemWidget({
     required this.captionedTextWidget,
     required this.captionedTextWidget,
     this.isExpandable = false,
     this.isExpandable = false,
@@ -34,6 +38,9 @@ class MenuItemWidget extends StatefulWidget {
     this.borderRadius = 4.0,
     this.borderRadius = 4.0,
     this.pressedColor,
     this.pressedColor,
     this.expandableController,
     this.expandableController,
+    this.isBottomBorderRadiusRemoved = false,
+    this.isTopBorderRadiusRemoved = false,
+    this.isGestureDetectorDisabled = false,
     Key? key,
     Key? key,
   }) : super(key: key);
   }) : super(key: key);
 
 
@@ -70,7 +77,7 @@ class _MenuItemWidgetState extends State<MenuItemWidget> {
 
 
   @override
   @override
   Widget build(BuildContext context) {
   Widget build(BuildContext context) {
-    return widget.isExpandable
+    return widget.isExpandable || widget.isGestureDetectorDisabled
         ? menuItemWidget(context)
         ? menuItemWidget(context)
         : GestureDetector(
         : GestureDetector(
             onTap: widget.onTap,
             onTap: widget.onTap,
@@ -86,7 +93,11 @@ class _MenuItemWidgetState extends State<MenuItemWidget> {
     final enteColorScheme = Theme.of(context).colorScheme.enteTheme.colorScheme;
     final enteColorScheme = Theme.of(context).colorScheme.enteTheme.colorScheme;
     final borderRadius = Radius.circular(widget.borderRadius);
     final borderRadius = Radius.circular(widget.borderRadius);
     final isExpanded = widget.expandableController?.value;
     final isExpanded = widget.expandableController?.value;
-    final bottomBorderRadius = isExpanded != null && isExpanded
+    final bottomBorderRadius =
+        (isExpanded != null && isExpanded) || widget.isBottomBorderRadiusRemoved
+            ? const Radius.circular(0)
+            : borderRadius;
+    final topBorderRadius = widget.isTopBorderRadiusRemoved
         ? const Radius.circular(0)
         ? const Radius.circular(0)
         : borderRadius;
         : borderRadius;
     return AnimatedContainer(
     return AnimatedContainer(
@@ -95,8 +106,8 @@ class _MenuItemWidgetState extends State<MenuItemWidget> {
       padding: const EdgeInsets.symmetric(horizontal: 12),
       padding: const EdgeInsets.symmetric(horizontal: 12),
       decoration: BoxDecoration(
       decoration: BoxDecoration(
         borderRadius: BorderRadius.only(
         borderRadius: BorderRadius.only(
-          topLeft: borderRadius,
-          topRight: borderRadius,
+          topLeft: topBorderRadius,
+          topRight: topBorderRadius,
           bottomLeft: bottomBorderRadius,
           bottomLeft: bottomBorderRadius,
           bottomRight: bottomBorderRadius,
           bottomRight: bottomBorderRadius,
         ),
         ),
@@ -155,7 +166,7 @@ class _MenuItemWidgetState extends State<MenuItemWidget> {
 
 
   void _onTapDown(details) {
   void _onTapDown(details) {
     setState(() {
     setState(() {
-      menuItemColor = widget.pressedColor;
+      menuItemColor = widget.pressedColor ?? widget.menuItemColor;
     });
     });
   }
   }
 
 

+ 20 - 0
lib/ui/components/menu_section_description_widget.dart

@@ -0,0 +1,20 @@
+import 'package:flutter/material.dart';
+import 'package:photos/theme/ente_theme.dart';
+
+class MenuSectionDescriptionWidget extends StatelessWidget {
+  final String content;
+  const MenuSectionDescriptionWidget({required this.content, super.key});
+
+  @override
+  Widget build(BuildContext context) {
+    return Padding(
+      padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 6),
+      child: Text(
+        content,
+        style: getEnteTextTheme(context)
+            .mini
+            .copyWith(color: getEnteColorScheme(context).textMuted),
+      ),
+    );
+  }
+}

+ 9 - 17
lib/ui/components/notification_warning_widget.dart

@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
 import 'package:photos/ente_theme_data.dart';
 import 'package:photos/ente_theme_data.dart';
 import 'package:photos/theme/colors.dart';
 import 'package:photos/theme/colors.dart';
 import 'package:photos/theme/text_style.dart';
 import 'package:photos/theme/text_style.dart';
+import 'package:photos/ui/components/icon_button_widget.dart';
 
 
 class NotificationWarningWidget extends StatelessWidget {
 class NotificationWarningWidget extends StatelessWidget {
   final IconData warningIcon;
   final IconData warningIcon;
@@ -51,23 +52,14 @@ class NotificationWarningWidget extends StatelessWidget {
                     ),
                     ),
                   ),
                   ),
                   const SizedBox(width: 12),
                   const SizedBox(width: 12),
-                  ClipOval(
-                    child: Material(
-                      color: fillFaintDark,
-                      child: InkWell(
-                        splashColor: Colors.red, // Splash color
-                        onTap: onTap,
-                        child: SizedBox(
-                          width: 40,
-                          height: 40,
-                          child: Icon(
-                            actionIcon,
-                            color: Colors.white,
-                          ),
-                        ),
-                      ),
-                    ),
-                  ),
+                  IconButtonWidget(
+                    icon: actionIcon,
+                    isRounded: true,
+                    iconColor: strokeBaseDark,
+                    defaultColor: fillFaintDark,
+                    pressedColor: fillMutedDark,
+                    onTap: onTap,
+                  )
                 ],
                 ],
               ),
               ),
             ),
             ),

+ 55 - 0
lib/ui/components/title_bar_title_widget.dart

@@ -0,0 +1,55 @@
+import 'package:flutter/material.dart';
+import 'package:photos/theme/ente_theme.dart';
+
+class TitleBarTitleWidget extends StatelessWidget {
+  final String? title;
+  final bool isTitleH2;
+  final IconData? icon;
+  const TitleBarTitleWidget({
+    this.title,
+    this.isTitleH2 = false,
+    this.icon,
+    super.key,
+  });
+
+  @override
+  Widget build(BuildContext context) {
+    final textTheme = getEnteTextTheme(context);
+    final colorTheme = getEnteColorScheme(context);
+    if (title != null) {
+      if (icon != null) {
+        return Row(
+          mainAxisSize: MainAxisSize.min,
+          crossAxisAlignment: CrossAxisAlignment.center,
+          children: <Widget>[
+            Text(
+              title!,
+              style: textTheme.h3Bold,
+              overflow: TextOverflow.ellipsis,
+              maxLines: 1,
+            ),
+            const SizedBox(width: 8),
+            Icon(icon, size: 20, color: colorTheme.strokeMuted),
+          ],
+        );
+      }
+      if (isTitleH2) {
+        return Text(
+          title!,
+          style: textTheme.h2Bold,
+          overflow: TextOverflow.ellipsis,
+          maxLines: 1,
+        );
+      } else {
+        return Text(
+          title!,
+          style: textTheme.h3Bold,
+          overflow: TextOverflow.ellipsis,
+          maxLines: 1,
+        );
+      }
+    }
+
+    return const SizedBox.shrink();
+  }
+}

+ 146 - 0
lib/ui/components/title_bar_widget.dart

@@ -0,0 +1,146 @@
+import 'package:flutter/material.dart';
+import 'package:photos/theme/ente_theme.dart';
+import 'package:photos/ui/components/icon_button_widget.dart';
+
+class TitleBarWidget extends StatelessWidget {
+  final String? title;
+  final String? caption;
+  final Widget? flexibleSpaceTitle;
+  final String? flexibleSpaceCaption;
+  final List<Widget>? actionIcons;
+  final bool isTitleH2WithoutLeading;
+  final bool isFlexibleSpaceDisabled;
+  const TitleBarWidget({
+    this.title,
+    this.caption,
+    this.flexibleSpaceTitle,
+    this.flexibleSpaceCaption,
+    this.actionIcons,
+    this.isTitleH2WithoutLeading = false,
+    this.isFlexibleSpaceDisabled = false,
+    super.key,
+  });
+
+  @override
+  Widget build(BuildContext context) {
+    const toolbarHeight = 48.0;
+    final textTheme = getEnteTextTheme(context);
+    final colorTheme = getEnteColorScheme(context);
+    return SliverAppBar(
+      toolbarHeight: toolbarHeight,
+      leadingWidth: 48,
+      automaticallyImplyLeading: false,
+      pinned: true,
+      expandedHeight: 102,
+      centerTitle: false,
+      titleSpacing: 0,
+      title: Padding(
+        padding: EdgeInsets.only(left: isTitleH2WithoutLeading ? 16 : 0),
+        child: Column(
+          crossAxisAlignment: CrossAxisAlignment.start,
+          mainAxisAlignment: MainAxisAlignment.start,
+          children: [
+            title == null
+                ? const SizedBox.shrink()
+                : Text(
+                    title!,
+                    style: isTitleH2WithoutLeading
+                        ? textTheme.h2Bold
+                        : textTheme.largeBold,
+                  ),
+            caption == null || isTitleH2WithoutLeading
+                ? const SizedBox.shrink()
+                : Text(
+                    caption!,
+                    style: textTheme.mini.copyWith(color: colorTheme.textMuted),
+                  )
+          ],
+        ),
+      ),
+      actions: [
+        Padding(
+          padding: const EdgeInsets.fromLTRB(4, 4, 12, 4),
+          child: Row(
+            children: _actionsWithPaddingInBetween(),
+          ),
+        ),
+      ],
+      leading: isTitleH2WithoutLeading
+          ? null
+          : Padding(
+              padding: const EdgeInsets.all(4),
+              child: IconButtonWidget(
+                icon: Icons.arrow_back_outlined,
+                isPrimary: true,
+                onTap: () {
+                  Navigator.pop(context);
+                },
+              ),
+            ),
+      flexibleSpace: isFlexibleSpaceDisabled
+          ? null
+          : FlexibleSpaceBar(
+              background: SafeArea(
+                child: Column(
+                  crossAxisAlignment: CrossAxisAlignment.start,
+                  mainAxisSize: MainAxisSize.min,
+                  children: <Widget>[
+                    const SizedBox(height: toolbarHeight),
+                    Padding(
+                      padding: const EdgeInsets.symmetric(
+                        vertical: 4,
+                        horizontal: 16,
+                      ),
+                      child: Column(
+                        crossAxisAlignment: CrossAxisAlignment.start,
+                        children: [
+                          flexibleSpaceTitle == null
+                              ? const SizedBox.shrink()
+                              : flexibleSpaceTitle!,
+                          flexibleSpaceCaption == null
+                              ? const SizedBox.shrink()
+                              : Text(
+                                  flexibleSpaceCaption!,
+                                  style: textTheme.small.copyWith(
+                                    color: colorTheme.textMuted,
+                                  ),
+                                  overflow: TextOverflow.ellipsis,
+                                  maxLines: 1,
+                                )
+                        ],
+                      ),
+                    ),
+                  ],
+                ),
+              ),
+            ),
+    );
+  }
+
+  _actionsWithPaddingInBetween() {
+    if (actionIcons == null) {
+      return <Widget>[const SizedBox.shrink()];
+    }
+    final actions = <Widget>[];
+    bool addWhiteSpace = false;
+    final length = actionIcons!.length;
+    int index = 0;
+    if (length == 0) {
+      return <Widget>[const SizedBox.shrink()];
+    }
+    if (length == 1) {
+      return actionIcons;
+    }
+    while (index < length) {
+      if (!addWhiteSpace) {
+        actions.add(actionIcons![index]);
+        index++;
+        addWhiteSpace = true;
+      } else {
+        actions.add(const SizedBox(width: 4));
+        addWhiteSpace = false;
+      }
+    }
+    return actions;
+  }
+}

+ 8 - 4
lib/ui/components/toggle_switch_widget.dart

@@ -1,10 +1,11 @@
 import 'package:flutter/material.dart';
 import 'package:flutter/material.dart';
 import 'package:photos/ente_theme_data.dart';
 import 'package:photos/ente_theme_data.dart';
 
 
-typedef OnChangedCallBack = void Function(bool);
+typedef OnChangedCallBack = Future<void> Function();
+typedef ValueCallBack = bool Function();
 
 
 class ToggleSwitchWidget extends StatefulWidget {
 class ToggleSwitchWidget extends StatefulWidget {
-  final bool value;
+  final ValueCallBack value;
   final OnChangedCallBack onChanged;
   final OnChangedCallBack onChanged;
   const ToggleSwitchWidget({
   const ToggleSwitchWidget({
     required this.value,
     required this.value,
@@ -30,8 +31,11 @@ class _ToggleSwitchWidgetState extends State<ToggleSwitchWidget> {
             activeColor: enteColorScheme.primary400,
             activeColor: enteColorScheme.primary400,
             inactiveTrackColor: enteColorScheme.fillMuted,
             inactiveTrackColor: enteColorScheme.fillMuted,
             materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
             materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
-            value: widget.value,
-            onChanged: widget.onChanged,
+            value: widget.value.call(),
+            onChanged: (value) async {
+              await widget.onChanged.call();
+              setState(() {});
+            },
           ),
           ),
         ),
         ),
       ),
       ),

+ 12 - 53
lib/ui/settings/backup_section_widget.dart

@@ -3,7 +3,6 @@
 import 'dart:io';
 import 'dart:io';
 
 
 import 'package:flutter/material.dart';
 import 'package:flutter/material.dart';
-import 'package:photos/core/configuration.dart';
 import 'package:photos/ente_theme_data.dart';
 import 'package:photos/ente_theme_data.dart';
 import 'package:photos/models/backup_status.dart';
 import 'package:photos/models/backup_status.dart';
 import 'package:photos/models/duplicate_files.dart';
 import 'package:photos/models/duplicate_files.dart';
@@ -11,11 +10,10 @@ import 'package:photos/services/deduplication_service.dart';
 import 'package:photos/services/sync_service.dart';
 import 'package:photos/services/sync_service.dart';
 import 'package:photos/theme/ente_theme.dart';
 import 'package:photos/theme/ente_theme.dart';
 import 'package:photos/ui/backup_folder_selection_page.dart';
 import 'package:photos/ui/backup_folder_selection_page.dart';
-import 'package:photos/ui/common/dialogs.dart';
+import 'package:photos/ui/backup_settings_screen.dart';
 import 'package:photos/ui/components/captioned_text_widget.dart';
 import 'package:photos/ui/components/captioned_text_widget.dart';
 import 'package:photos/ui/components/expandable_menu_item_widget.dart';
 import 'package:photos/ui/components/expandable_menu_item_widget.dart';
 import 'package:photos/ui/components/menu_item_widget.dart';
 import 'package:photos/ui/components/menu_item_widget.dart';
-import 'package:photos/ui/components/toggle_switch_widget.dart';
 import 'package:photos/ui/settings/common_settings.dart';
 import 'package:photos/ui/settings/common_settings.dart';
 import 'package:photos/ui/tools/deduplicate_page.dart';
 import 'package:photos/ui/tools/deduplicate_page.dart';
 import 'package:photos/ui/tools/free_space_page.dart';
 import 'package:photos/ui/tools/free_space_page.dart';
@@ -64,60 +62,21 @@ class BackupSectionWidgetState extends State<BackupSectionWidget> {
       sectionOptionSpacing,
       sectionOptionSpacing,
       MenuItemWidget(
       MenuItemWidget(
         captionedTextWidget: const CaptionedTextWidget(
         captionedTextWidget: const CaptionedTextWidget(
-          title: "Backup over mobile data",
-        ),
-        trailingSwitch: ToggleSwitchWidget(
-          value: Configuration.instance.shouldBackupOverMobileData(),
-          onChanged: (value) async {
-            Configuration.instance.setBackupOverMobileData(value);
-            setState(() {});
-          },
-        ),
-      ),
-      sectionOptionSpacing,
-      MenuItemWidget(
-        captionedTextWidget: const CaptionedTextWidget(
-          title: "Backup videos",
-        ),
-        trailingSwitch: ToggleSwitchWidget(
-          value: Configuration.instance.shouldBackupVideos(),
-          onChanged: (value) async {
-            Configuration.instance.setShouldBackupVideos(value);
-            setState(() {});
-          },
+          title: "Backup settings",
         ),
         ),
+        pressedColor: getEnteColorScheme(context).fillFaint,
+        trailingIcon: Icons.chevron_right_outlined,
+        trailingIconIsMuted: true,
+        onTap: () {
+          routeToPage(
+            context,
+            const BackupSettingsScreen(),
+          );
+        },
       ),
       ),
       sectionOptionSpacing,
       sectionOptionSpacing,
     ];
     ];
-    if (Platform.isIOS) {
-      sectionOptions.addAll([
-        MenuItemWidget(
-          captionedTextWidget: const CaptionedTextWidget(
-            title: "Disable auto lock",
-          ),
-          trailingSwitch: ToggleSwitchWidget(
-            value: Configuration.instance.shouldKeepDeviceAwake(),
-            onChanged: (value) async {
-              if (value) {
-                final choice = await showChoiceDialog(
-                  context,
-                  "Disable automatic screen lock when ente is running?",
-                  "This will ensure faster uploads by ensuring your device does not sleep when uploads are in progress.",
-                  firstAction: "No",
-                  secondAction: "Yes",
-                );
-                if (choice != DialogUserChoice.secondChoice) {
-                  return;
-                }
-              }
-              await Configuration.instance.setShouldKeepDeviceAwake(value);
-              setState(() {});
-            },
-          ),
-        ),
-        sectionOptionSpacing,
-      ]);
-    }
+
     sectionOptions.addAll(
     sectionOptions.addAll(
       [
       [
         MenuItemWidget(
         MenuItemWidget(

+ 79 - 85
lib/ui/settings/security_section_widget.dart

@@ -73,8 +73,8 @@ class _SecuritySectionWidgetState extends State<SecuritySectionWidget> {
                 ),
                 ),
                 trailingSwitch: snapshot.hasData
                 trailingSwitch: snapshot.hasData
                     ? ToggleSwitchWidget(
                     ? ToggleSwitchWidget(
-                        value: snapshot.data,
-                        onChanged: (value) async {
+                        value: () => snapshot.data,
+                        onChanged: () async {
                           final hasAuthenticated =
                           final hasAuthenticated =
                               await LocalAuthenticationService.instance
                               await LocalAuthenticationService.instance
                                   .requestLocalAuthentication(
                                   .requestLocalAuthentication(
@@ -82,7 +82,7 @@ class _SecuritySectionWidgetState extends State<SecuritySectionWidget> {
                             "Please authenticate to configure two-factor authentication",
                             "Please authenticate to configure two-factor authentication",
                           );
                           );
                           if (hasAuthenticated) {
                           if (hasAuthenticated) {
-                            if (value) {
+                            if (!snapshot.data) {
                               UserService.instance.setupTwoFactor(context);
                               UserService.instance.setupTwoFactor(context);
                             } else {
                             } else {
                               _disableTwoFactor();
                               _disableTwoFactor();
@@ -106,18 +106,15 @@ class _SecuritySectionWidgetState extends State<SecuritySectionWidget> {
           title: "Lockscreen",
           title: "Lockscreen",
         ),
         ),
         trailingSwitch: ToggleSwitchWidget(
         trailingSwitch: ToggleSwitchWidget(
-          value: _config.shouldShowLockScreen(),
-          onChanged: (value) async {
-            final hasAuthenticated = await LocalAuthenticationService.instance
+          value: () => _config.shouldShowLockScreen(),
+          onChanged: () async {
+            await LocalAuthenticationService.instance
                 .requestLocalAuthForLockScreen(
                 .requestLocalAuthForLockScreen(
               context,
               context,
-              value,
+              !_config.shouldShowLockScreen(),
               "Please authenticate to change lockscreen setting",
               "Please authenticate to change lockscreen setting",
               "To enable lockscreen, please setup device passcode or screen lock in your system settings.",
               "To enable lockscreen, please setup device passcode or screen lock in your system settings.",
             );
             );
-            if (hasAuthenticated) {
-              setState(() {});
-            }
           },
           },
         ),
         ),
       ),
       ),
@@ -131,81 +128,8 @@ class _SecuritySectionWidgetState extends State<SecuritySectionWidget> {
               title: "Hide from recents",
               title: "Hide from recents",
             ),
             ),
             trailingSwitch: ToggleSwitchWidget(
             trailingSwitch: ToggleSwitchWidget(
-              value: _config.shouldHideFromRecents(),
-              onChanged: (value) async {
-                if (value) {
-                  final AlertDialog alert = AlertDialog(
-                    title: const Text("Hide from recents?"),
-                    content: SingleChildScrollView(
-                      child: Column(
-                        mainAxisAlignment: MainAxisAlignment.start,
-                        crossAxisAlignment: CrossAxisAlignment.start,
-                        children: const [
-                          Text(
-                            "Hiding from the task switcher will prevent you from taking screenshots in this app.",
-                            style: TextStyle(
-                              height: 1.5,
-                            ),
-                          ),
-                          Padding(padding: EdgeInsets.all(8)),
-                          Text(
-                            "Are you sure?",
-                            style: TextStyle(
-                              height: 1.5,
-                            ),
-                          ),
-                        ],
-                      ),
-                    ),
-                    actions: [
-                      TextButton(
-                        child: Text(
-                          "No",
-                          style: TextStyle(
-                            color:
-                                Theme.of(context).colorScheme.defaultTextColor,
-                          ),
-                        ),
-                        onPressed: () {
-                          Navigator.of(context, rootNavigator: true)
-                              .pop('dialog');
-                        },
-                      ),
-                      TextButton(
-                        child: Text(
-                          "Yes",
-                          style: TextStyle(
-                            color:
-                                Theme.of(context).colorScheme.defaultTextColor,
-                          ),
-                        ),
-                        onPressed: () async {
-                          Navigator.of(context, rootNavigator: true)
-                              .pop('dialog');
-                          await _config.setShouldHideFromRecents(true);
-                          await FlutterWindowManager.addFlags(
-                            FlutterWindowManager.FLAG_SECURE,
-                          );
-                          setState(() {});
-                        },
-                      ),
-                    ],
-                  );
-
-                  showDialog(
-                    context: context,
-                    builder: (BuildContext context) {
-                      return alert;
-                    },
-                  );
-                } else {
-                  await _config.setShouldHideFromRecents(false);
-                  await FlutterWindowManager.clearFlags(
-                    FlutterWindowManager.FLAG_SECURE,
-                  );
-                  setState(() {});
-                }
-              },
+              value: () => _config.shouldHideFromRecents(),
+              onChanged: _hideFromRecentsOnChanged,
             ),
             ),
           ),
           ),
           sectionOptionSpacing,
           sectionOptionSpacing,
@@ -284,4 +208,74 @@ class _SecuritySectionWidgetState extends State<SecuritySectionWidget> {
       },
       },
     );
     );
   }
   }
+
+  Future<void> _hideFromRecentsOnChanged() async {
+    if (!_config.shouldHideFromRecents()) {
+      final AlertDialog alert = AlertDialog(
+        title: const Text("Hide from recents?"),
+        content: SingleChildScrollView(
+          child: Column(
+            mainAxisAlignment: MainAxisAlignment.start,
+            crossAxisAlignment: CrossAxisAlignment.start,
+            children: const [
+              Text(
+                "Hiding from the task switcher will prevent you from taking screenshots in this app.",
+                style: TextStyle(
+                  height: 1.5,
+                ),
+              ),
+              Padding(padding: EdgeInsets.all(8)),
+              Text(
+                "Are you sure?",
+                style: TextStyle(
+                  height: 1.5,
+                ),
+              ),
+            ],
+          ),
+        ),
+        actions: [
+          TextButton(
+            child: Text(
+              "No",
+              style: TextStyle(
+                color: Theme.of(context).colorScheme.defaultTextColor,
+              ),
+            ),
+            onPressed: () {
+              Navigator.of(context, rootNavigator: true).pop('dialog');
+            },
+          ),
+          TextButton(
+            child: Text(
+              "Yes",
+              style: TextStyle(
+                color: Theme.of(context).colorScheme.defaultTextColor,
+              ),
+            ),
+            onPressed: () async {
+              Navigator.of(context, rootNavigator: true).pop('dialog');
+              await _config.setShouldHideFromRecents(true);
+              await FlutterWindowManager.addFlags(
+                FlutterWindowManager.FLAG_SECURE,
+              );
+              setState(() {});
+            },
+          ),
+        ],
+      );
+
+      showDialog(
+        context: context,
+        builder: (BuildContext context) {
+          return alert;
+        },
+      );
+    } else {
+      await _config.setShouldHideFromRecents(false);
+      await FlutterWindowManager.clearFlags(
+        FlutterWindowManager.FLAG_SECURE,
+      );
+    }
+  }
 }
 }