Skip to content

Commit

Permalink
feat: allow to easily override setting entries
Browse files Browse the repository at this point in the history
  • Loading branch information
robert-virkus committed Feb 4, 2024
1 parent 038d3a5 commit 1b6fdf4
Show file tree
Hide file tree
Showing 18 changed files with 394 additions and 236 deletions.
2 changes: 1 addition & 1 deletion lib/account/provider.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions lib/enough_mail_app.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
export 'account/account.dart';
export 'contact/contact.dart';
export 'localization/app_localizations.g.dart';
export 'localization/extension.dart';
export 'logger.dart';
export 'main.dart';
export 'routes/provider.dart';
export 'routes/routes.dart';
export 'settings/settings.dart';
export 'util/localized_dialog_helper.dart';
2 changes: 2 additions & 0 deletions lib/hoster/service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ class MailHoster {
height: 50,
fit: BoxFit.contain,
errorBuilder: (context, error, stacktrace) => Container(),
package: 'enough_mail_app',
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 8),
Expand Down Expand Up @@ -237,6 +238,7 @@ class GmailMailHoster extends MailHoster {
height: 50,
fit: BoxFit.contain,
errorBuilder: (context, error, stacktrace) => Container(),
package: 'enough_mail_app',
),
Padding(
padding: const EdgeInsets.only(left: 8, right: 16),
Expand Down
10 changes: 5 additions & 5 deletions lib/mail/provider.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion lib/routes/provider.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions lib/screens/welcome_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ class WelcomeScreen extends StatelessWidget {
'assets/images/maily.png',
height: 200,
fit: BoxFit.cover,
package: 'enough_mail_app',
),
decoration: PageDecoration(pageColor: Colors.green[700]),
footer: _buildFooter(context, localizations),
Expand All @@ -65,6 +66,7 @@ class WelcomeScreen extends StatelessWidget {
'assets/images/mailboxes.png',
height: 200,
fit: BoxFit.cover,
package: 'enough_mail_app',
),
decoration: const PageDecoration(pageColor: Color(0xff543226)),
footer: _buildFooter(context, localizations),
Expand All @@ -76,6 +78,7 @@ class WelcomeScreen extends StatelessWidget {
'assets/images/swipe_press.png',
height: 200,
fit: BoxFit.cover,
package: 'enough_mail_app',
),
decoration: const PageDecoration(pageColor: Color(0xff761711)),
footer: _buildFooter(context, localizations),
Expand All @@ -87,6 +90,7 @@ class WelcomeScreen extends StatelessWidget {
'assets/images/drawing.jpg',
height: 200,
fit: BoxFit.cover,
package: 'enough_mail_app',
),
footer: _buildFooter(context, localizations),
),
Expand Down
3 changes: 3 additions & 0 deletions lib/settings/home/home.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export 'model.dart';
export 'provider.dart';
export 'screen.dart';
86 changes: 86 additions & 0 deletions lib/settings/home/model.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import 'package:flutter/widgets.dart';

/// Standard setting entries
enum UiSettingsType {
divider,
security,
accounts,
swipe,
signature,
defaultSender,
design,
language,
folders,
readReceipts,
reply,
feedback,
about,
welcome,
development,
}

/// A UI element for the settings screen
class UiSettingsElement {
/// Creates a new [UiSettingsElement]
const UiSettingsElement({
required this.title,
required this.onTap,
this.type,
this.subtitle,
this.icon,
});

/// Creates a new [UiSettingsElement] as a divider
UiSettingsElement.divider()
: this(
title: '',
onTap: null,
type: UiSettingsType.divider,
);

/// The title of the element
final String title;

/// The standard type of the element
final UiSettingsType? type;

/// The subtitle of the element
final String? subtitle;

/// The icon of the element
final IconData? icon;

/// The action when the element is tapped
final VoidCallback? onTap;

/// Is this element a divider?
bool get isDivider => type == UiSettingsType.divider;
}

/// Eases custom elements
extension UiSettingsElementsExtension on List<UiSettingsElement> {
/// Inserts an element after the element with the given type
void insertAfter(UiSettingsType type, UiSettingsElement element) {
final index = indexWhere((e) => e.type == type);
if (index == -1) {
add(element);
} else {
insert(index + 1, element);
}
}

/// Inserts an element before the element with the given type
void insertBefore(UiSettingsType type, UiSettingsElement element) {
final index = indexWhere((e) => e.type == type);
if (index == -1) {
insert(0, element);
} else {
insert(index, element);
}
}

/// Removes the element with the given type
void removeType(UiSettingsType type) {
removeWhere((e) => e.type == type);
}
}
95 changes: 95 additions & 0 deletions lib/settings/home/provider.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import 'package:flutter/widgets.dart';
import 'package:go_router/go_router.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';

import '../../localization/extension.dart';
import '../../routes/routes.dart';
import '../../util/localized_dialog_helper.dart';
import 'model.dart';

part 'provider.g.dart';

@Riverpod(keepAlive: true)
class SettingsUiElements extends _$SettingsUiElements {
@override
void build() {}

/// Generates the shown setting entries
List<UiSettingsElement> generate(
BuildContext context,
) =>
buildStandardElements(context);

static List<UiSettingsElement> buildStandardElements(BuildContext context) {
final text = context.text;

return [
UiSettingsElement(
type: UiSettingsType.security,
title: text.securitySettingsTitle,
onTap: () => context.pushNamed(Routes.settingsSecurity),
),
UiSettingsElement(
type: UiSettingsType.accounts,
title: text.settingsActionAccounts,
onTap: () => context.pushNamed(Routes.settingsAccounts),
),
UiSettingsElement(
type: UiSettingsType.swipe,
title: text.swipeSettingTitle,
onTap: () => context.pushNamed(Routes.settingsSwipe),
),
UiSettingsElement(
type: UiSettingsType.signature,
title: text.signatureSettingsTitle,
onTap: () => context.pushNamed(Routes.settingsSignature),
),
UiSettingsElement(
type: UiSettingsType.defaultSender,
title: text.defaultSenderSettingsTitle,
onTap: () => context.pushNamed(Routes.settingsDefaultSender),
),
UiSettingsElement(
type: UiSettingsType.design,
title: text.settingsActionDesign,
onTap: () => context.pushNamed(Routes.settingsDesign),
),
UiSettingsElement(
type: UiSettingsType.language,
title: text.languageSettingTitle,
onTap: () => context.pushNamed(Routes.settingsLanguage),
),
UiSettingsElement(
type: UiSettingsType.folders,
title: text.settingsFolders,
onTap: () => context.pushNamed(Routes.settingsFolders),
),
UiSettingsElement(
type: UiSettingsType.readReceipts,
title: text.settingsReadReceipts,
onTap: () => context.pushNamed(Routes.settingsReadReceipts),
),
UiSettingsElement(
type: UiSettingsType.reply,
title: text.replySettingsTitle,
onTap: () => context.pushNamed(Routes.settingsReplyFormat),
),
UiSettingsElement.divider(),
UiSettingsElement(
type: UiSettingsType.feedback,
title: text.settingsActionFeedback,
onTap: () => context.pushNamed(Routes.settingsFeedback),
),
UiSettingsElement(
type: UiSettingsType.about,
title: text.drawerEntryAbout,
onTap: () => LocalizedDialogHelper.showAbout(context),
),
UiSettingsElement(
type: UiSettingsType.welcome,
title: text.settingsActionWelcome,
onTap: () => context.pushNamed(Routes.welcome),
),
];
}
}
27 changes: 27 additions & 0 deletions lib/settings/home/provider.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

51 changes: 51 additions & 0 deletions lib/settings/home/screen.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import 'package:enough_platform_widgets/enough_platform_widgets.dart';
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';

import '../../localization/extension.dart';
import '../../screens/base.dart';
import 'model.dart';
import 'provider.dart';

/// Allows to personalize the app settings
class SettingsScreen extends ConsumerWidget {
/// Creates a new [SettingsScreen]
const SettingsScreen({super.key});

@override
Widget build(BuildContext context, WidgetRef ref) {
final uiSettingElementsNotifier = ref.watch(
settingsUiElementsProvider.notifier,
);
final settingEntries = uiSettingElementsNotifier.generate(context);
final localizations = context.text;

Widget buildEntry(UiSettingsElement entry) {
if (entry.isDivider) return const Divider();
final subtitle = entry.subtitle;
final icon = entry.icon;

return PlatformListTile(
title: Text(entry.title),
subtitle: subtitle != null ? Text(subtitle) : null,
leading: icon != null ? Icon(icon) : null,
onTap: entry.onTap,
);
}

return BasePage(
title: localizations.settingsTitle,
content: SingleChildScrollView(
child: SafeArea(
child: Padding(
padding: const EdgeInsets.all(8),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: settingEntries.map(buildEntry).toList(),
),
),
),
),
);
}
}
1 change: 1 addition & 0 deletions lib/settings/settings.dart
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export 'home/home.dart';
export 'model.dart';
export 'provider.dart';
Loading

0 comments on commit 1b6fdf4

Please sign in to comment.