From 7f79e18b9425e954c61dd17ba7b0cab29c68a5bb Mon Sep 17 00:00:00 2001 From: Jorge Pabon Date: Fri, 11 Aug 2023 10:44:57 +0800 Subject: [PATCH] Refactoring: use of AppTextThemeExtension --- lib/app/mixins/repo_actions_mixin.dart | 10 +- .../accept_eq_values_terms_privacy_page.dart | 21 +- lib/app/pages/add_repository_page.dart | 22 +- lib/app/pages/onboarding_page.dart | 14 +- lib/app/pages/peer_list.dart | 10 +- lib/app/pages/repo_qr_page.dart | 46 ++- lib/app/pages/repository_security_page.dart | 37 ++- lib/app/utils/dialogs.dart | 76 ++--- lib/app/utils/themes/app_typography.dart | 2 +- .../widgets/animated/file_icon_animated.dart | 13 +- .../widgets/bars/folder_navigation_bar.dart | 13 +- lib/app/widgets/bars/sort_contents_bar.dart | 54 ++-- lib/app/widgets/dialogs/actions_dialog.dart | 90 +++--- lib/app/widgets/dialogs/info_bubble.dart | 157 +++++------ .../modal_file_detail_bottom_sheet.dart | 262 ++++++++---------- .../modal_folder_detail_bottom_sheet.dart | 199 ++++++------- .../modal_repo_list_actions_bottom_sheet.dart | 68 +++-- .../modal_repo_settings_bottom_sheet.dart | 235 ++++++---------- .../modal_repository_creation_dialog.dart | 25 +- .../modal_share_repository_bottom_sheet.dart | 33 +-- lib/app/widgets/eq_terms_privacy.dart | 57 ++-- lib/app/widgets/eq_values.dart | 59 ++-- .../inputs/password_validation_input.dart | 15 +- lib/app/widgets/items/entry_action_item.dart | 8 +- lib/app/widgets/items/file_description.dart | 67 ++--- lib/app/widgets/items/folder_description.dart | 13 +- .../selectors/access_mode_selector.dart | 94 +++---- lib/app/widgets/settings/about_section.dart | 12 +- lib/app/widgets/settings/logs_section.dart | 6 +- lib/app/widgets/settings/network_section.dart | 4 +- .../widgets/settings/repository_section.dart | 4 +- .../widgets/settings/repository_selector.dart | 117 ++++---- .../widgets/settings/settings_container.dart | 71 ++--- 33 files changed, 834 insertions(+), 1080 deletions(-) diff --git a/lib/app/mixins/repo_actions_mixin.dart b/lib/app/mixins/repo_actions_mixin.dart index 1587a6c5f..bc14ab7c3 100644 --- a/lib/app/mixins/repo_actions_mixin.dart +++ b/lib/app/mixins/repo_actions_mixin.dart @@ -540,15 +540,15 @@ mixin RepositoryActionsMixin on AppLogger { context: context, title: S.current.titleSaveChanges, body: [ - Text(message) + Text(message, style: context.theme.appTextStyle.bodyMedium) ], actions: [ TextButton( - child: Text(positiveButtonText), - onPressed: () => Navigator.of(context).pop(true)), + child: Text(S.current.actionCancel.toUpperCase()), + onPressed: () => Navigator.of(context).pop(false)), TextButton( - child: Text(S.current.actionCancel), - onPressed: () => Navigator.of(context).pop(false)) + child: Text(positiveButtonText.toUpperCase()), + onPressed: () => Navigator.of(context).pop(true)) ]); return saveChanges; diff --git a/lib/app/pages/accept_eq_values_terms_privacy_page.dart b/lib/app/pages/accept_eq_values_terms_privacy_page.dart index e23290f10..9ed2c0bd8 100644 --- a/lib/app/pages/accept_eq_values_terms_privacy_page.dart +++ b/lib/app/pages/accept_eq_values_terms_privacy_page.dart @@ -21,21 +21,6 @@ class AcceptEqualitieValuesTermsPrivacyPage extends StatefulWidget { class _AcceptEqualitieValuesTermsPrivacyPageState extends State { - TextStyle? introTextStyle; - TextStyle? bodyTextStyle; - TextStyle? byTextStyle; - - @override - void didChangeDependencies() { - super.didChangeDependencies(); - - introTextStyle = Theme.of(context).textTheme.titleMedium; - bodyTextStyle = Theme.of(context).textTheme.bodyMedium; - byTextStyle = TextStyle( - fontSize: (bodyTextStyle?.fontSize ?? 10.0) * 0.8, - color: Colors.black54); - } - @override Widget build(BuildContext context) => Scaffold( appBar: PlatformValues.isMobileDevice @@ -66,14 +51,16 @@ class _AcceptEqualitieValuesTermsPrivacyPageState width: MediaQuery.of(context).size.width * 0.6), Padding( padding: EdgeInsets.only(bottom: 10.0), - child: Text(S.current.messageBy, style: byTextStyle)), + child: Text(S.current.messageBy, + style: context.theme.appTextStyle.bodyMicro + .copyWith(color: Colors.black54))), Image.asset(Constants.eQLogo, width: MediaQuery.of(context).size.width * 0.2) ]); Widget _introTextSpan() => RichText( textAlign: TextAlign.start, - text: TextSpan(style: bodyTextStyle, children: [ + text: TextSpan(style: context.theme.appTextStyle.bodyMedium, children: [ Fields.boldTextSpan(S.current.titleAppTitle), TextSpan(text: ' ${S.current.messageEqualitieValues}') ])); diff --git a/lib/app/pages/add_repository_page.dart b/lib/app/pages/add_repository_page.dart index 50c32e010..f4f954a7a 100644 --- a/lib/app/pages/add_repository_page.dart +++ b/lib/app/pages/add_repository_page.dart @@ -24,28 +24,17 @@ class _AddRepositoryPageState extends State with AppLogger { final _isDesktop = PlatformValues.isDesktopDevice; - TextStyle? titleStyle; - TextStyle? bodyStyle; - TextStyle? bodySmallStyle; - @override Widget build(BuildContext context) { final noReposImageHeight = MediaQuery.of(context).size.height * 0.2; - titleStyle = Theme.of(context).textTheme.titleLarge; - bodyStyle = Theme.of(context).textTheme.bodyMedium; - bodySmallStyle = Theme.of(context) - .textTheme - .bodySmall - ?.copyWith(fontWeight: FontWeight.w700); - return Scaffold( appBar: AppBar( title: Text(S.current.titleAddRepoToken), elevation: 0.0, backgroundColor: Colors.transparent, foregroundColor: Colors.black87, - titleTextStyle: titleStyle), + titleTextStyle: context.theme.appTextStyle.titleMedium), body: Form( key: formKey, autovalidateMode: AutovalidateMode.disabled, @@ -70,15 +59,15 @@ class _AddRepositoryPageState extends State with AppLogger { crossAxisAlignment: WrapCrossAlignment.center, children: [ Row(children: [ - Fields.constrainedText(S.current.messageAddRepoQR, - flex: 0, style: bodyStyle) + Fields.constrainedText(S.current.messageAddRepoQR, flex: 0) ]), if (_isDesktop) Row(children: [ Fields.constrainedText( '(${S.current.messageAvailableOnMobile})', flex: 0, - style: bodySmallStyle) + style: context.theme.appTextStyle.bodySmall + .copyWith(fontWeight: FontWeight.w700)) ]) ]), Dimensions.spacingVerticalDouble, @@ -143,7 +132,8 @@ class _AddRepositoryPageState extends State with AppLogger { thickness: 1.0, endIndent: 20.0, color: Colors.black26)), Text( S.current.messageOr.toUpperCase(), - style: const TextStyle(fontWeight: FontWeight.w500), + style: context.theme.appTextStyle.bodySmall + .copyWith(fontWeight: FontWeight.bold), ), const Expanded( child: Divider( diff --git a/lib/app/pages/onboarding_page.dart b/lib/app/pages/onboarding_page.dart index e790258b5..29f520978 100644 --- a/lib/app/pages/onboarding_page.dart +++ b/lib/app/pages/onboarding_page.dart @@ -30,20 +30,10 @@ class _OnboardingPageState extends State { @override Widget build(BuildContext context) { - final titleFontSize = Theme.of(context).textTheme.titleLarge?.fontSize; - final titleFontWeight = Theme.of(context).textTheme.titleLarge?.fontWeight; - final titleStyle = - TextStyle(fontSize: titleFontSize, fontWeight: titleFontWeight); - - final bodyFontSize = Theme.of(context).textTheme.bodyMedium?.fontSize; - final bodyFontWeight = Theme.of(context).textTheme.bodyMedium?.fontWeight; - final bodyStyle = - TextStyle(fontSize: bodyFontSize, fontWeight: bodyFontWeight); - final pageDecoration = PageDecoration( - titleTextStyle: titleStyle, + titleTextStyle: context.theme.appTextStyle.titleLarge, bodyAlignment: Alignment.center, - bodyTextStyle: bodyStyle, + bodyTextStyle: context.theme.appTextStyle.bodyMedium, bodyPadding: EdgeInsets.fromLTRB(16.0, 0.0, 16.0, 16.0), imagePadding: EdgeInsets.zero); diff --git a/lib/app/pages/peer_list.dart b/lib/app/pages/peer_list.dart index 0ca0a7f5b..e58d037a3 100644 --- a/lib/app/pages/peer_list.dart +++ b/lib/app/pages/peer_list.dart @@ -13,13 +13,7 @@ class PeerList extends StatelessWidget { @override Widget build(BuildContext context) { - final microFontSize = - (Theme.of(context).textTheme.bodySmall?.fontSize ?? 0) * 0.8; - - bodyMicroStyle = Theme.of(context) - .textTheme - .bodySmall - ?.copyWith(fontSize: microFontSize); + bodyMicroStyle = context.theme.appTextStyle.bodyMicro; return Scaffold( appBar: AppBar(title: Text(S.current.labelPeers)), @@ -47,7 +41,7 @@ class PeerList extends StatelessWidget { ); TableRow _buildHeaderRow(BuildContext context) { - final style = Theme.of(context).textTheme.titleSmall; + final style = context.theme.appTextStyle.titleSmall; return TableRow(children: [ _buildCell(Text('IP', style: style)), diff --git a/lib/app/pages/repo_qr_page.dart b/lib/app/pages/repo_qr_page.dart index 4eefa9db5..e40cc4115 100644 --- a/lib/app/pages/repo_qr_page.dart +++ b/lib/app/pages/repo_qr_page.dart @@ -16,32 +16,20 @@ class RepositoryQRPage extends StatefulWidget { } class _RepositoryQRPageState extends State { - TextStyle? titleStyle; - TextStyle? bodyStyle; - @override - Widget build(BuildContext context) { - titleStyle = - Theme.of(context).textTheme.titleLarge?.copyWith(color: Colors.white); - bodyStyle = - Theme.of(context).textTheme.bodyMedium?.copyWith(color: Colors.white); - - return Scaffold( - appBar: AppBar( - leading: Fields.actionIcon( - const Icon(Icons.close, color: Colors.white), - onPressed: () => Navigator.of(context).pop()), - elevation: 0.0, - backgroundColor: Colors.transparent), - backgroundColor: Theme.of(context).primaryColorDark, - body: Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - _getQRCodeImage(widget.shareLink), - _buildShareMessage() - ]))); - } + Widget build(BuildContext context) => Scaffold( + appBar: AppBar( + leading: Fields.actionIcon( + const Icon(Icons.close, color: Colors.white), + onPressed: () => Navigator.of(context).pop()), + elevation: 0.0, + backgroundColor: Colors.transparent), + backgroundColor: Theme.of(context).primaryColorDark, + body: Center( + child: Column(mainAxisAlignment: MainAxisAlignment.center, children: [ + _getQRCodeImage(widget.shareLink), + _buildShareMessage() + ]))); Widget _getQRCodeImage(String tokenLink) { double qrCodeSize = 0.0; @@ -70,10 +58,14 @@ class _RepositoryQRPageState extends State { padding: Dimensions.paddingTop40, child: Column(children: [ Text(S.current.messageShareWithWR, - textAlign: TextAlign.center, style: titleStyle), + textAlign: TextAlign.center, + style: context.theme.appTextStyle.titleLarge + .copyWith(color: Colors.white)), Dimensions.spacingVertical, Text(S.current.messageScanQROrShare, - textAlign: TextAlign.center, style: bodyStyle) + textAlign: TextAlign.center, + style: context.theme.appTextStyle.bodyMedium + .copyWith(color: Colors.white)) ])); } } diff --git a/lib/app/pages/repository_security_page.dart b/lib/app/pages/repository_security_page.dart index e1c318028..de5fc026f 100644 --- a/lib/app/pages/repository_security_page.dart +++ b/lib/app/pages/repository_security_page.dart @@ -43,8 +43,6 @@ class _RepositorySecurityState extends State final FocusNode _passwordAction = FocusNode(debugLabel: 'password_input'); - TextStyle? bodyStyle; - @override void initState() { security = SecurityCubit.create( @@ -58,27 +56,23 @@ class _RepositorySecurityState extends State } @override - Widget build(BuildContext context) { - bodyStyle = Theme.of(context).textTheme.bodyMedium; - - return Scaffold( - appBar: AppBar(title: Text(S.current.titleSecurity), elevation: 0.0), - body: SingleChildScrollView( - child: Container( - child: BlocBuilder( - bloc: security, - builder: (context, state) => Column(children: [ - _pasword(state), - Divider(height: 30.0), - _biometrics(state) - ]))))); - } + Widget build(BuildContext context) => Scaffold( + appBar: AppBar(title: Text(S.current.titleSecurity), elevation: 0.0), + body: SingleChildScrollView( + child: Container( + child: BlocBuilder( + bloc: security, + builder: (context, state) => Column(children: [ + _pasword(state), + Divider(height: 30.0), + _biometrics(state) + ]))))); Widget _pasword(SecurityState state) { return Container( padding: Dimensions.paddingDialog, child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text(state.passwordModeTitle, style: bodyStyle), + Text(state.passwordModeTitle), Dimensions.spacingVerticalDouble, PasswordValidation( passwordMode: state.passwordMode, @@ -99,8 +93,8 @@ class _RepositorySecurityState extends State TextButton( focusNode: _passwordAction, child: Text(S.current.actionRemoveLocalPassword, - style: - bodyStyle?.copyWith(color: Constants.dangerColor)), + style: context.theme.appTextStyle.bodyMedium + .copyWith(color: Constants.dangerColor)), onPressed: () async { final positiveButtonText = S.current.actionRemove; final confirmationMessage = @@ -118,6 +112,7 @@ class _RepositorySecurityState extends State f: _removePassword()); }) ]), + Dimensions.spacingVertical, Row(mainAxisAlignment: MainAxisAlignment.center, children: [ Fields.inPageButton( onPressed: () async { @@ -191,7 +186,7 @@ class _RepositorySecurityState extends State secondary: Icon(Icons.fingerprint_rounded, color: Colors.black), title: Text(S.current.messageUnlockUsingBiometrics, - style: bodyStyle), + style: context.theme.appTextStyle.bodyMedium), onChanged: (useBiometrics) async { final positiveButtonText = S.current.actionAccept; String confirmationMessage = useBiometrics diff --git a/lib/app/utils/dialogs.dart b/lib/app/utils/dialogs.dart index 25635238e..c228b3005 100644 --- a/lib/app/utils/dialogs.dart +++ b/lib/app/utils/dialogs.dart @@ -126,21 +126,21 @@ abstract class Dialogs { static Future deleteFileAlertDialog(RepoCubit repo, String path, BuildContext context, String fileName, String parent) async { - final bodyStyle = Theme.of(context).textTheme.bodyMedium; + final bodyStyle = context.theme.appTextStyle.bodyMedium + .copyWith(fontWeight: FontWeight.bold); + return showDialog( context: context, barrierDismissible: false, builder: (BuildContext context) => ActionsDialog( title: S.current.titleDeleteFile, body: ListBody(children: [ - Text(fileName, - style: bodyStyle?.copyWith(fontWeight: FontWeight.bold)), + Text(fileName, style: bodyStyle), Row(children: [ - Text(Strings.atSymbol, - style: bodyStyle?.copyWith(fontWeight: FontWeight.bold)), - Text(parent) + Text(Strings.atSymbol, style: bodyStyle), + Text(parent, style: bodyStyle) ]), - const SizedBox(height: 30.0), + const SizedBox(height: 20.0), Text(S.current.messageConfirmFileDeletion), Fields.dialogActions(context, buttons: [ NegativeButton( @@ -161,35 +161,35 @@ abstract class Dialogs { ]))); } - static Future deleteFolderAlertDialog( - BuildContext context, RepoCubit repo, String path, bool recursive) async { - final bodyStyle = Theme.of(context).textTheme.bodyMedium; - return showDialog( - context: context, - barrierDismissible: false, - builder: (BuildContext context) => ActionsDialog( - title: S.current.titleDeleteFolder, - body: ListBody(children: [ - Text(path, - style: bodyStyle?.copyWith(fontWeight: FontWeight.bold)), - const SizedBox(height: 30.0), - Text(S.current.messageConfirmFolderDeletion), - Fields.dialogActions(context, buttons: [ - NegativeButton( - text: S.current.actionCancel, - onPressed: () => - Navigator.of(context, rootNavigator: true).pop(), - buttonsAspectRatio: - Dimensions.aspectRatioModalDialogButton), - PositiveButton( - text: S.current.actionDelete, - isDangerButton: true, - onPressed: () async { - await repo.deleteFolder(path, recursive); - Navigator.of(context).pop(path); - }, - buttonsAspectRatio: Dimensions.aspectRatioModalDialogButton) - ]) - ]))); - } + static Future deleteFolderAlertDialog(BuildContext context, + RepoCubit repo, String path, bool recursive) async => + showDialog( + context: context, + barrierDismissible: false, + builder: (BuildContext context) => ActionsDialog( + title: S.current.titleDeleteFolder, + body: ListBody(children: [ + Text(path, + style: context.theme.appTextStyle.bodyMedium + .copyWith(fontWeight: FontWeight.bold)), + const SizedBox(height: 20.0), + Text(S.current.messageConfirmFolderDeletion), + Fields.dialogActions(context, buttons: [ + NegativeButton( + text: S.current.actionCancel, + onPressed: () => + Navigator.of(context, rootNavigator: true).pop(), + buttonsAspectRatio: + Dimensions.aspectRatioModalDialogButton), + PositiveButton( + text: S.current.actionDelete, + isDangerButton: true, + onPressed: () async { + await repo.deleteFolder(path, recursive); + Navigator.of(context).pop(path); + }, + buttonsAspectRatio: + Dimensions.aspectRatioModalDialogButton) + ]) + ]))); } diff --git a/lib/app/utils/themes/app_typography.dart b/lib/app/utils/themes/app_typography.dart index 08a2c7ca2..bc8c2ce7e 100644 --- a/lib/app/utils/themes/app_typography.dart +++ b/lib/app/utils/themes/app_typography.dart @@ -23,7 +23,7 @@ abstract class AppTypography { static const bodyMicro = TextStyle( color: Color(0x8a000000), fontSize: 10.0, - fontWeight: FontWeight.w500, + fontWeight: FontWeight.w400, textBaseline: TextBaseline.alphabetic, decoration: TextDecoration.none); diff --git a/lib/app/widgets/animated/file_icon_animated.dart b/lib/app/widgets/animated/file_icon_animated.dart index 9b16b07db..268e9d3ed 100644 --- a/lib/app/widgets/animated/file_icon_animated.dart +++ b/lib/app/widgets/animated/file_icon_animated.dart @@ -10,18 +10,8 @@ class FileIconAnimated extends StatelessWidget with AppLogger { final Job? _downloadJob; - TextStyle? bodyMicroStyle; - @override Widget build(BuildContext context) { - final microFontSize = - (Theme.of(context).textTheme.bodySmall?.fontSize ?? 0.0) * 0.8; - - bodyMicroStyle = Theme.of(context) - .textTheme - .bodySmall - ?.copyWith(fontSize: microFontSize); - return GestureDetector( child: _getWidgetForState(context), onTap: () => onFileIconTap(context)); @@ -55,7 +45,8 @@ class FileIconAnimated extends StatelessWidget with AppLogger { animateFromLastPercent: true, percent: ratio, progressColor: Theme.of(context).colorScheme.secondary, - center: Text('$percentage%', style: bodyMicroStyle)); + center: Text('$percentage%', + style: context.theme.appTextStyle.bodyMicro)); }); // TODO: This code used to show a different icon once the download finished. diff --git a/lib/app/widgets/bars/folder_navigation_bar.dart b/lib/app/widgets/bars/folder_navigation_bar.dart index 32e20ac01..3e9059fb2 100644 --- a/lib/app/widgets/bars/folder_navigation_bar.dart +++ b/lib/app/widgets/bars/folder_navigation_bar.dart @@ -6,16 +6,12 @@ import '../../cubits/cubits.dart'; class FolderNavigationBar extends StatelessWidget { final RepoCubit _repo; - FolderNavigationBar(this._repo); - - TextStyle? titleStyle; + const FolderNavigationBar(this._repo); @override Widget build(BuildContext context) { - titleStyle = Theme.of(context).textTheme.titleMedium; - final path = _repo.state.currentFolder.path; - final route = _currentLocationBar(path, context); + final route = _currentLocationBar(context, path, context); return Container( padding: const EdgeInsets.all(10.0), @@ -31,7 +27,8 @@ class FolderNavigationBar extends StatelessWidget { ])); } - Widget _currentLocationBar(String path, BuildContext ctx) { + Widget _currentLocationBar( + BuildContext context, String path, BuildContext ctx) { final current = getBasename(path); String separator = Strings.root; @@ -45,7 +42,7 @@ class FolderNavigationBar extends StatelessWidget { child: Text(current, softWrap: false, overflow: TextOverflow.ellipsis, - style: titleStyle))) + style: context.theme.appTextStyle.titleMedium))) ]); } diff --git a/lib/app/widgets/bars/sort_contents_bar.dart b/lib/app/widgets/bars/sort_contents_bar.dart index ead283156..111739691 100644 --- a/lib/app/widgets/bars/sort_contents_bar.dart +++ b/lib/app/widgets/bars/sort_contents_bar.dart @@ -19,33 +19,33 @@ class SortContentsBar extends StatefulWidget { class _SortContentsBarState extends State { @override - Widget build(BuildContext context) { - final bodyStyle = Theme.of(context).textTheme.bodySmall; - - return BlocBuilder( - bloc: widget.sortListCubit, - builder: (context, state) => widget.reposCubit.showList - ? SizedBox.shrink() - : Container( - alignment: Alignment.centerLeft, - padding: Dimensions.paddingActionBox, - decoration: const BoxDecoration( - borderRadius: BorderRadius.all( - Radius.circular(Dimensions.radiusSmall))), - child: GestureDetector( - child: Padding( - padding: Dimensions.paddingItem, - child: Row(children: [ - Fields.constrainedText(state.sortBy.name.capitalize(), - flex: 0, style: bodyStyle), - Dimensions.spacingHorizontalHalf, - Fields.actionIcon(_getDirectionArrow(state.direction), - color: Colors.black, - onPressed: () => _updateSortDirection(state)) - ])), - onTap: () async => await _showSortByDialog()), - )); - } + Widget build(BuildContext context) => + BlocBuilder( + bloc: widget.sortListCubit, + builder: (context, state) => widget.reposCubit.showList + ? SizedBox.shrink() + : Container( + alignment: Alignment.centerLeft, + padding: Dimensions.paddingActionBox, + decoration: const BoxDecoration( + borderRadius: BorderRadius.all( + Radius.circular(Dimensions.radiusSmall))), + child: GestureDetector( + child: Padding( + padding: Dimensions.paddingItem, + child: Row(children: [ + Fields.constrainedText( + state.sortBy.name.capitalize(), + flex: 0, + style: context.theme.appTextStyle.bodySmall), + Dimensions.spacingHorizontalHalf, + Fields.actionIcon( + _getDirectionArrow(state.direction), + color: Colors.black, + onPressed: () => _updateSortDirection(state)) + ])), + onTap: () async => await _showSortByDialog()), + )); Icon _getDirectionArrow(SortDirection direction) { return direction == SortDirection.asc diff --git a/lib/app/widgets/dialogs/actions_dialog.dart b/lib/app/widgets/dialogs/actions_dialog.dart index bbf389eef..82cb8c1c0 100644 --- a/lib/app/widgets/dialogs/actions_dialog.dart +++ b/lib/app/widgets/dialogs/actions_dialog.dart @@ -19,52 +19,50 @@ class ActionsDialog extends StatefulWidget { class _ActionsDialogState extends State { @override - Widget build(BuildContext context) { - final titleStyle = Theme.of(context).textTheme.titleMedium; - - return Dialog( - child: Stack( - children: [ - Container( - width: Platform.isAndroid - ? null - : Dimensions.sizeModalDialogWidthDesktop, - padding: Dimensions.paddingDialog, - decoration: BoxDecoration( - shape: BoxShape.rectangle, - color: Colors.white, - borderRadius: BorderRadius.circular(Dimensions.radiusSmall), - boxShadow: const [ - BoxShadow( - color: Colors.black, - offset: Offset(0, 10), - blurRadius: Dimensions.radiusBig / 2), - ]), - child: LayoutBuilder( - builder: - (BuildContext context, BoxConstraints viewportConstraints) { - return SingleChildScrollView( - reverse: true, - child: ConstrainedBox( - constraints: - BoxConstraints(minHeight: viewportConstraints.minHeight), - child: Column( - mainAxisSize: MainAxisSize.min, - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Fields.constrainedText(widget.title, - flex: 0, style: titleStyle, maxLines: 2), - Dimensions.spacingVertical, - widget.body!, - ], + Widget build(BuildContext context) => Dialog( + child: Stack( + children: [ + Container( + width: Platform.isAndroid + ? null + : Dimensions.sizeModalDialogWidthDesktop, + padding: Dimensions.paddingDialog, + decoration: BoxDecoration( + shape: BoxShape.rectangle, + color: Colors.white, + borderRadius: BorderRadius.circular(Dimensions.radiusSmall), + boxShadow: const [ + BoxShadow( + color: Colors.black, + offset: Offset(0, 10), + blurRadius: Dimensions.radiusBig / 2), + ]), + child: LayoutBuilder( + builder: + (BuildContext context, BoxConstraints viewportConstraints) { + return SingleChildScrollView( + reverse: true, + child: ConstrainedBox( + constraints: BoxConstraints( + minHeight: viewportConstraints.minHeight), + child: Column( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Fields.constrainedText(widget.title, + flex: 0, + style: context.theme.appTextStyle.titleMedium, + maxLines: 2), + Dimensions.spacingVertical, + widget.body!, + ], + ), ), - ), - ); - }, + ); + }, + ), ), - ), - ], - )); - } + ], + )); } diff --git a/lib/app/widgets/dialogs/info_bubble.dart b/lib/app/widgets/dialogs/info_bubble.dart index b7e44fa8f..1820366e6 100644 --- a/lib/app/widgets/dialogs/info_bubble.dart +++ b/lib/app/widgets/dialogs/info_bubble.dart @@ -185,90 +185,85 @@ class _InfoBubbleDialogState extends State<_InfoBubbleDialog> { } @override - Widget build(BuildContext context) { - final titleStyle = Theme.of(context).textTheme.bodySmall; - final bodySmallStyle = Theme.of(context).textTheme.bodySmall; - - return Stack( - children: [ - AnimatedPositioned( - duration: animationDuration, - left: leftPosition, - right: rightPosition, - top: topPosition != null - ? topPosition! // + animationTopHeight - : null, - bottom: bottomPosition != null - ? bottomPosition! // + animationBottomHeight - : null, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - // if (!showBubbleAboveWidget) - // Padding( - // padding: EdgeInsets.only(left: bubbleTipLeftPadding), - // child: CustomPaint( - // painter: TrianglePainter( - // strokeColor: widget.bgColor, - // strokeWidth: 10, - // paintingStyle: PaintingStyle.fill, - // ), - // child: SizedBox( - // height: widget.bubbleTipHeight, - // width: widget.bubbleTipWidth, - // ), - // ), - // ), - Material( - color: Colors.transparent, - child: Container( - padding: const EdgeInsets.all(12), - width: widget.bubbleWidth, - decoration: BoxDecoration( - color: widget.bgColor, - borderRadius: BorderRadius.circular(8)), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.min, - children: [ - Text(widget.title, - style: titleStyle?.copyWith( - fontWeight: FontWeight.w600)), - const SizedBox(height: 12), - RichText( - textAlign: TextAlign.start, - text: TextSpan( - style: bodySmallStyle?.copyWith( - color: Colors.black87), - children: widget.description)), - ], + Widget build(BuildContext context) => Stack( + children: [ + AnimatedPositioned( + duration: animationDuration, + left: leftPosition, + right: rightPosition, + top: topPosition != null + ? topPosition! // + animationTopHeight + : null, + bottom: bottomPosition != null + ? bottomPosition! // + animationBottomHeight + : null, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // if (!showBubbleAboveWidget) + // Padding( + // padding: EdgeInsets.only(left: bubbleTipLeftPadding), + // child: CustomPaint( + // painter: TrianglePainter( + // strokeColor: widget.bgColor, + // strokeWidth: 10, + // paintingStyle: PaintingStyle.fill, + // ), + // child: SizedBox( + // height: widget.bubbleTipHeight, + // width: widget.bubbleTipWidth, + // ), + // ), + // ), + Material( + color: Colors.transparent, + child: Container( + padding: const EdgeInsets.all(12), + width: widget.bubbleWidth, + decoration: BoxDecoration( + color: widget.bgColor, + borderRadius: BorderRadius.circular(8)), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Text(widget.title, + style: context.theme.appTextStyle.bodySmall + .copyWith(fontWeight: FontWeight.w500)), + const SizedBox(height: 12), + RichText( + textAlign: TextAlign.start, + text: TextSpan( + style: context.theme.appTextStyle.bodySmall + .copyWith(color: Colors.black87), + children: widget.description)), + ], + ), ), ), - ), - // if (showBubbleAboveWidget) - // Padding( - // padding: EdgeInsets.only(left: bubbleTipLeftPadding), - // child: RotatedBox( - // quarterTurns: 2, - // child: CustomPaint( - // painter: TrianglePainter( - // strokeColor: widget.bgColor, - // strokeWidth: 10, - // paintingStyle: PaintingStyle.fill, - // ), - // child: SizedBox( - // height: widget.bubbleTipHeight, - // width: widget.bubbleTipWidth, - // ), - // ), - // ), - // ), - ], + // if (showBubbleAboveWidget) + // Padding( + // padding: EdgeInsets.only(left: bubbleTipLeftPadding), + // child: RotatedBox( + // quarterTurns: 2, + // child: CustomPaint( + // painter: TrianglePainter( + // strokeColor: widget.bgColor, + // strokeWidth: 10, + // paintingStyle: PaintingStyle.fill, + // ), + // child: SizedBox( + // height: widget.bubbleTipHeight, + // width: widget.bubbleTipWidth, + // ), + // ), + // ), + // ), + ], + ), ), - ), - ], - ); - } + ], + ); @override void dispose() { diff --git a/lib/app/widgets/dialogs/modal_file_detail_bottom_sheet.dart b/lib/app/widgets/dialogs/modal_file_detail_bottom_sheet.dart index 86d47f1fe..0bd73beff 100644 --- a/lib/app/widgets/dialogs/modal_file_detail_bottom_sheet.dart +++ b/lib/app/widgets/dialogs/modal_file_detail_bottom_sheet.dart @@ -33,166 +33,146 @@ class FileDetail extends StatefulWidget { class _FileDetailState extends State { @override - Widget build(BuildContext context) { - final sheetTitleStyle = Theme.of(context) - .textTheme - .bodyLarge - ?.copyWith(fontWeight: FontWeight.w400); - - final bodyLargeStyle = Theme.of(context).textTheme.bodyLarge; - final bodyStyle = Theme.of(context).textTheme.bodyMedium; - - return SingleChildScrollView( - child: Container( - padding: Dimensions.paddingBottomSheet, - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - Fields.bottomSheetHandle(context), - Fields.bottomSheetTitle(S.current.titleFileDetails, - style: sheetTitleStyle), - EntryActionItem( - iconData: Icons.download, - title: S.current.iconDownload, - titleTextStyle: bodyStyle, - dense: true, - onTap: () async { - Navigator.of(context, rootNavigator: false).pop(); - - await showDialog( - context: context, - barrierDismissible: false, - builder: (BuildContext context) { - return ActionsDialog( - title: S.current.titleDownloadToDevice, - body: - SaveToDevice(data: widget.data, cubit: widget.cubit), - ); - }, - ); - }, - enabledValidation: () => widget.isActionAvailableValidator( - widget.cubit.state.accessMode, EntryAction.download), - disabledMessage: S.current.messageActionNotAvailable, - disabledMessageDuration: - Constants.notAvailableActionMessageDuration, - ), - if (io.Platform.isAndroid) + Widget build(BuildContext context) => SingleChildScrollView( + child: Container( + padding: Dimensions.paddingBottomSheet, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Fields.bottomSheetHandle(context), + Fields.bottomSheetTitle(S.current.titleFileDetails, + style: context.theme.appTextStyle.titleMedium), EntryActionItem( - iconData: Icons.preview_rounded, - title: S.current.iconPreview, - titleTextStyle: bodyStyle, + iconData: Icons.download, + title: S.current.iconDownload, dense: true, - onTap: () async => await NativeChannels.previewOuiSyncFile( - F.authority, - widget.data.path, - widget.data.size ?? 0, - ), + onTap: () async { + Navigator.of(context, rootNavigator: false).pop(); + + await showDialog( + context: context, + barrierDismissible: false, + builder: (BuildContext context) { + return ActionsDialog( + title: S.current.titleDownloadToDevice, + body: SaveToDevice( + data: widget.data, cubit: widget.cubit), + ); + }, + ); + }, enabledValidation: () => widget.isActionAvailableValidator( - widget.cubit.state.accessMode, EntryAction.preview), + widget.cubit.state.accessMode, EntryAction.download), disabledMessage: S.current.messageActionNotAvailable, disabledMessageDuration: Constants.notAvailableActionMessageDuration, ), - if (io.Platform.isAndroid) + if (io.Platform.isAndroid) + EntryActionItem( + iconData: Icons.preview_rounded, + title: S.current.iconPreview, + dense: true, + onTap: () async => await NativeChannels.previewOuiSyncFile( + F.authority, + widget.data.path, + widget.data.size ?? 0, + ), + enabledValidation: () => widget.isActionAvailableValidator( + widget.cubit.state.accessMode, EntryAction.preview), + disabledMessage: S.current.messageActionNotAvailable, + disabledMessageDuration: + Constants.notAvailableActionMessageDuration, + ), + if (io.Platform.isAndroid) + EntryActionItem( + iconData: Icons.share_rounded, + title: S.current.iconShare, + dense: true, + onTap: () async => await NativeChannels.shareOuiSyncFile( + F.authority, + widget.data.path, + widget.data.size ?? 0, + ), + enabledValidation: () => widget.isActionAvailableValidator( + widget.cubit.state.accessMode, EntryAction.share), + disabledMessage: S.current.messageActionNotAvailable, + disabledMessageDuration: + Constants.notAvailableActionMessageDuration, + ), EntryActionItem( - iconData: Icons.share_rounded, - title: S.current.iconShare, - titleTextStyle: bodyStyle, + iconData: Icons.edit, + title: S.current.iconRename, dense: true, - onTap: () async => await NativeChannels.shareOuiSyncFile( - F.authority, - widget.data.path, - widget.data.size ?? 0, - ), + onTap: () async => _showRenameDialog(widget.data), enabledValidation: () => widget.isActionAvailableValidator( - widget.cubit.state.accessMode, EntryAction.share), + widget.cubit.state.accessMode, EntryAction.rename), disabledMessage: S.current.messageActionNotAvailable, disabledMessageDuration: Constants.notAvailableActionMessageDuration, ), - EntryActionItem( - iconData: Icons.edit, - title: S.current.iconRename, - titleTextStyle: bodyStyle, - dense: true, - onTap: () async => _showRenameDialog(widget.data), - enabledValidation: () => widget.isActionAvailableValidator( - widget.cubit.state.accessMode, EntryAction.rename), - disabledMessage: S.current.messageActionNotAvailable, - disabledMessageDuration: - Constants.notAvailableActionMessageDuration, - ), - EntryActionItem( - iconData: Icons.drive_file_move_outlined, - title: S.current.iconMove, - titleTextStyle: bodyStyle, - dense: true, - onTap: () async => _showMoveEntryBottomSheet( - widget.data.path, - EntryType.file, - widget.onMoveEntry, - widget.onUpdateBottomSheet, - ), - enabledValidation: () => widget.isActionAvailableValidator( - widget.cubit.state.accessMode, EntryAction.move), - disabledMessage: S.current.messageActionNotAvailable, - disabledMessageDuration: - Constants.notAvailableActionMessageDuration, - ), - EntryActionItem( - iconData: Icons.delete, - title: S.current.iconDelete, - titleTextStyle: bodyStyle, - isDanger: true, + EntryActionItem( + iconData: Icons.drive_file_move_outlined, + title: S.current.iconMove, dense: true, - onTap: () async { - final fileName = getBasename(widget.data.path); - final parent = getDirname(widget.data.path); - - final deletedFileName = await Dialogs.deleteFileAlertDialog( - widget.cubit, - widget.data.path, - context, - fileName, - parent); - - if (deletedFileName != null && deletedFileName.isNotEmpty) { - Navigator.of(context).pop(); - } - }, + onTap: () async => _showMoveEntryBottomSheet( + widget.data.path, + EntryType.file, + widget.onMoveEntry, + widget.onUpdateBottomSheet, + ), enabledValidation: () => widget.isActionAvailableValidator( - widget.cubit.state.accessMode, EntryAction.delete), + widget.cubit.state.accessMode, EntryAction.move), disabledMessage: S.current.messageActionNotAvailable, disabledMessageDuration: - Constants.notAvailableActionMessageDuration), - const Divider( - height: 10.0, thickness: 2.0, indent: 20.0, endIndent: 20.0), - Fields.iconLabel( - icon: Icons.info_rounded, - text: S.current.iconInformation, - style: bodyLargeStyle), - Fields.autosizedLabeledText( - label: S.current.labelName, - text: widget.data.name, - textStyle: bodyStyle), - Fields.labeledText( - label: S.current.labelLocation, - text: widget.data.path - .replaceAll(widget.data.name, '') - .trimRight(), - textStyle: bodyStyle), - Fields.labeledText( - label: S.current.labelSize, - text: formatSize(widget.data.size ?? 0), - textStyle: bodyStyle), - ], + Constants.notAvailableActionMessageDuration, + ), + EntryActionItem( + iconData: Icons.delete, + title: S.current.iconDelete, + isDanger: true, + dense: true, + onTap: () async { + final fileName = getBasename(widget.data.path); + final parent = getDirname(widget.data.path); + + final deletedFileName = await Dialogs.deleteFileAlertDialog( + widget.cubit, + widget.data.path, + context, + fileName, + parent); + + if (deletedFileName != null && deletedFileName.isNotEmpty) { + Navigator.of(context).pop(); + } + }, + enabledValidation: () => widget.isActionAvailableValidator( + widget.cubit.state.accessMode, EntryAction.delete), + disabledMessage: S.current.messageActionNotAvailable, + disabledMessageDuration: + Constants.notAvailableActionMessageDuration), + const Divider( + height: 10.0, thickness: 2.0, indent: 20.0, endIndent: 20.0), + Fields.iconLabel( + icon: Icons.info_rounded, + text: S.current.iconInformation, + style: context.theme.appTextStyle.titleMedium), + Fields.autosizedLabeledText( + label: S.current.labelName, text: widget.data.name), + Fields.labeledText( + label: S.current.labelLocation, + text: widget.data.path + .replaceAll(widget.data.name, '') + .trimRight()), + Fields.labeledText( + label: S.current.labelSize, + text: formatSize(widget.data.size ?? 0)), + ], + ), ), - ), - ); - } + ); _showMoveEntryBottomSheet( String path, diff --git a/lib/app/widgets/dialogs/modal_folder_detail_bottom_sheet.dart b/lib/app/widgets/dialogs/modal_folder_detail_bottom_sheet.dart index 1a24e5504..8836bc82c 100644 --- a/lib/app/widgets/dialogs/modal_folder_detail_bottom_sheet.dart +++ b/lib/app/widgets/dialogs/modal_folder_detail_bottom_sheet.dart @@ -30,112 +30,97 @@ class FolderDetail extends StatefulWidget { class _FolderDetailState extends State with AppLogger { @override - Widget build(BuildContext context) { - final sheetTitleStyle = Theme.of(context) - .textTheme - .bodyLarge - ?.copyWith(fontWeight: FontWeight.w400); - - final bodyLargeStyle = Theme.of(context).textTheme.bodyLarge; - final bodyStyle = Theme.of(context).textTheme.bodyMedium; - - return Container( - padding: Dimensions.paddingBottomSheet, - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - Fields.bottomSheetHandle(context), - Fields.bottomSheetTitle(S.current.titleFolderDetails, - style: sheetTitleStyle), - EntryActionItem( - iconData: Icons.edit, - title: S.current.iconRename, - titleTextStyle: bodyStyle, - dense: true, - onTap: () async => _showRenameDialog(widget.data), - enabledValidation: () => widget.isActionAvailableValidator( - widget.cubit.state.accessMode, EntryAction.rename), - disabledMessage: S.current.messageActionNotAvailable, - disabledMessageDuration: - Constants.notAvailableActionMessageDuration), - EntryActionItem( - iconData: Icons.drive_file_move_outlined, - title: S.current.iconMove, - titleTextStyle: bodyStyle, - dense: true, - onTap: () async => _showMoveEntryBottomSheet( - widget.data.path, - EntryType.directory, - widget.onMoveEntry, - widget.onUpdateBottomSheet), - enabledValidation: () => widget.isActionAvailableValidator( - widget.cubit.state.accessMode, EntryAction.move), - disabledMessage: S.current.messageActionNotAvailable, - disabledMessageDuration: - Constants.notAvailableActionMessageDuration), - EntryActionItem( - iconData: Icons.delete, - title: S.current.iconDelete, - titleTextStyle: bodyStyle, - isDanger: true, - dense: true, - onTap: () async { - final repo = widget.cubit; - final path = widget.data.path; - - final recursiveDeletion = - await deleteFolderWithContentsValidation( - context, repo, path); - - if (recursiveDeletion == null) { - // The item is not a folder or, most likely, the user canceled - return; - } - - final deletedFolderName = await Dialogs.deleteFolderAlertDialog( - widget.context, - widget.cubit, + Widget build(BuildContext context) => Container( + padding: Dimensions.paddingBottomSheet, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Fields.bottomSheetHandle(context), + Fields.bottomSheetTitle(S.current.titleFolderDetails, + style: context.theme.appTextStyle.titleMedium), + EntryActionItem( + iconData: Icons.edit, + title: S.current.iconRename, + dense: true, + onTap: () async => _showRenameDialog(widget.data), + enabledValidation: () => widget.isActionAvailableValidator( + widget.cubit.state.accessMode, EntryAction.rename), + disabledMessage: S.current.messageActionNotAvailable, + disabledMessageDuration: + Constants.notAvailableActionMessageDuration), + EntryActionItem( + iconData: Icons.drive_file_move_outlined, + title: S.current.iconMove, + dense: true, + onTap: () async => _showMoveEntryBottomSheet( widget.data.path, - recursiveDeletion); - - if (deletedFolderName != null && deletedFolderName.isNotEmpty) { - Navigator.of(context).pop(deletedFolderName); - showSnackBar(context, - message: - S.current.messageFolderDeleted(widget.data.name)); - } - }, - enabledValidation: () => widget.isActionAvailableValidator( - widget.cubit.state.accessMode, EntryAction.delete), - disabledMessage: S.current.messageActionNotAvailable, - disabledMessageDuration: - Constants.notAvailableActionMessageDuration), - const Divider( - height: 10.0, thickness: 2.0, indent: 20.0, endIndent: 20.0), - Fields.iconLabel( - icon: Icons.info_rounded, - text: S.current.iconInformation, - iconSize: Dimensions.sizeIconBig, - textAlign: TextAlign.start, - style: bodyLargeStyle), - Fields.autosizedLabeledText( - label: S.current.labelName, - text: widget.data.name, - textAlign: TextAlign.start, - textMaxLines: 2, - textStyle: bodyStyle), - Fields.labeledText( - label: S.current.labelLocation, - text: - widget.data.path.replaceAll(widget.data.name, '').trimRight(), - textAlign: TextAlign.start, - textStyle: bodyStyle), - ], - ), - ); - } + EntryType.directory, + widget.onMoveEntry, + widget.onUpdateBottomSheet), + enabledValidation: () => widget.isActionAvailableValidator( + widget.cubit.state.accessMode, EntryAction.move), + disabledMessage: S.current.messageActionNotAvailable, + disabledMessageDuration: + Constants.notAvailableActionMessageDuration), + EntryActionItem( + iconData: Icons.delete, + title: S.current.iconDelete, + isDanger: true, + dense: true, + onTap: () async { + final repo = widget.cubit; + final path = widget.data.path; + + final recursiveDeletion = + await deleteFolderWithContentsValidation( + context, repo, path); + + if (recursiveDeletion == null) { + // The item is not a folder or, most likely, the user canceled + return; + } + + final deletedFolderName = + await Dialogs.deleteFolderAlertDialog(widget.context, + widget.cubit, widget.data.path, recursiveDeletion); + + if (deletedFolderName != null && + deletedFolderName.isNotEmpty) { + Navigator.of(context).pop(deletedFolderName); + showSnackBar(context, + message: + S.current.messageFolderDeleted(widget.data.name)); + } + }, + enabledValidation: () => widget.isActionAvailableValidator( + widget.cubit.state.accessMode, EntryAction.delete), + disabledMessage: S.current.messageActionNotAvailable, + disabledMessageDuration: + Constants.notAvailableActionMessageDuration), + const Divider( + height: 10.0, thickness: 2.0, indent: 20.0, endIndent: 20.0), + Fields.iconLabel( + icon: Icons.info_rounded, + text: S.current.iconInformation, + iconSize: Dimensions.sizeIconBig, + textAlign: TextAlign.start, + style: context.theme.appTextStyle.titleMedium), + Fields.autosizedLabeledText( + label: S.current.labelName, + text: widget.data.name, + textAlign: TextAlign.start, + textMaxLines: 2), + Fields.labeledText( + label: S.current.labelLocation, + text: widget.data.path + .replaceAll(widget.data.name, '') + .trimRight(), + textAlign: TextAlign.start) + ], + ), + ); Future deleteFolderWithContentsValidation( BuildContext context, RepoCubit repo, String path) async { @@ -156,14 +141,12 @@ class _FolderDetailState extends State with AppLogger { } if (directory.isNotEmpty) { - final bodyStyle = Theme.of(context).textTheme.bodyMedium; - recursive = await Dialogs.alertDialogWithActions( context: context, title: S.current.titleDeleteNotEmptyFolder, body: [ Text(S.current.messageConfirmNotEmptyFolderDeletion, - style: bodyStyle) + style: context.theme.appTextStyle.bodyMedium) ], actions: [ Fields.dialogActions(context, buttons: [ diff --git a/lib/app/widgets/dialogs/modal_repo_list_actions_bottom_sheet.dart b/lib/app/widgets/dialogs/modal_repo_list_actions_bottom_sheet.dart index 7b3d351dc..15fc8624b 100644 --- a/lib/app/widgets/dialogs/modal_repo_list_actions_bottom_sheet.dart +++ b/lib/app/widgets/dialogs/modal_repo_list_actions_bottom_sheet.dart @@ -17,47 +17,41 @@ class RepoListActions extends StatelessWidget with AppLogger { final Future Function() onNewRepositoryPressed; final Future Function() onImportRepositoryPressed; - TextStyle? bodySmallStyle; - @override - Widget build(BuildContext context) { - bodySmallStyle = Theme.of(context).textTheme.bodySmall; - - return Column( - mainAxisAlignment: MainAxisAlignment.center, - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - Fields.bottomSheetHandle(context), - Row(mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ - _buildAction( - name: S.current.actionNewRepo, - icon: Icons.archive_outlined, - action: () async { - final newRepoName = await onNewRepositoryPressed.call(); + Widget build(BuildContext context) => Column( + mainAxisAlignment: MainAxisAlignment.center, + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Fields.bottomSheetHandle(context), + Row(mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ + _buildAction( + name: S.current.actionNewRepo, + icon: Icons.archive_outlined, + action: () async { + final newRepoName = await onNewRepositoryPressed.call(); - if (newRepoName == null) { - return; - } + if (newRepoName == null) { + return; + } - Navigator.of(context).pop(); - }), - _buildAction( - name: S.current.actionImportRepo, - icon: Icons.unarchive_outlined, - action: () async { - final importedRepoName = - await onImportRepositoryPressed.call(); + Navigator.of(context).pop(); + }), + _buildAction( + name: S.current.actionImportRepo, + icon: Icons.unarchive_outlined, + action: () async { + final importedRepoName = + await onImportRepositoryPressed.call(); - if (importedRepoName == null) { - return; - } + if (importedRepoName == null) { + return; + } - Navigator.of(context).pop(); - }) - ]), - ]); - } + Navigator.of(context).pop(); + }) + ]), + ]); Widget _buildAction({name, icon, action}) => Padding( padding: Dimensions.paddingBottomSheetActions, @@ -67,6 +61,6 @@ class RepoListActions extends StatelessWidget with AppLogger { child: Column(children: [ Icon(icon, size: Dimensions.sizeIconBig), Dimensions.spacingVertical, - Text(name, style: bodySmallStyle) + Text(name) ]))); } diff --git a/lib/app/widgets/dialogs/modal_repo_settings_bottom_sheet.dart b/lib/app/widgets/dialogs/modal_repo_settings_bottom_sheet.dart index 66208d285..50ffe3199 100644 --- a/lib/app/widgets/dialogs/modal_repo_settings_bottom_sheet.dart +++ b/lib/app/widgets/dialogs/modal_repo_settings_bottom_sheet.dart @@ -8,6 +8,7 @@ import '../../cubits/cubits.dart'; import '../../mixins/mixins.dart'; import '../../models/models.dart'; import '../../utils/utils.dart'; +import '../widgets.dart'; class RepositorySettings extends StatefulWidget { const RepositorySettings( @@ -35,151 +36,95 @@ class RepositorySettings extends StatefulWidget { class _RepositorySettingsState extends State with AppLogger, RepositoryActionsMixin { @override - Widget build(BuildContext context) { - final sheetTitleStyle = Theme.of(context) - .textTheme - .bodyLarge - ?.copyWith(fontWeight: FontWeight.w400); - - final settingStyle = - Theme.of(context).textTheme.bodyMedium?.copyWith(color: Colors.black87); - - return BlocBuilder( - bloc: widget.cubit, - builder: (context, state) => SingleChildScrollView( - child: Container( - padding: Dimensions.paddingBottomSheet, - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - Fields.bottomSheetHandle(context), - Fields.bottomSheetTitle(widget.cubit.name, - style: sheetTitleStyle), - Row(children: [ - Expanded( - child: SwitchListTile.adaptive( - title: Text(S.current.labelBitTorrentDHT, - style: settingStyle), - secondary: const Icon( - Icons.hub, - size: Dimensions.sizeIconMicro, - color: Colors.black87, - ), - contentPadding: EdgeInsets.zero, - dense: true, - visualDensity: VisualDensity(horizontal: -4.0), - value: state.isDhtEnabled, - onChanged: (value) => widget.cubit.setDhtEnabled(value), - )), - ]), - Row(children: [ - Expanded( - child: SwitchListTile.adaptive( - title: Text(S.current.messagePeerExchange, - style: settingStyle), - secondary: const Icon( - Icons.group_add, - size: Dimensions.sizeIconMicro, - color: Colors.black87, - ), - contentPadding: EdgeInsets.zero, - dense: true, - visualDensity: VisualDensity(horizontal: -4.0), - value: state.isPexEnabled, - onChanged: (value) => widget.cubit.setPexEnabled(value), - )) - ]), - Row( - children: [ - Expanded( - child: Fields.actionListTile(S.current.actionRename, - textOverflow: TextOverflow.ellipsis, - textSoftWrap: false, - style: settingStyle, - onTap: () async => await renameRepository( - widget.context, - repository: widget.cubit, - rename: widget.renameRepository, - popDialog: () => - Navigator.of(context).pop()), - icon: Icons.edit, - iconSize: Dimensions.sizeIconMicro, - iconColor: Colors.black87, - dense: true, - visualDensity: VisualDensity.compact)), - ], - ), - Row( - mainAxisSize: MainAxisSize.max, - children: [ - Expanded( - child: Fields.actionListTile(S.current.actionShare, - textOverflow: TextOverflow.ellipsis, - textSoftWrap: false, - style: settingStyle, onTap: () async { - Navigator.of(context).pop(); - await shareRepository(context, - repository: widget.cubit); - }, - icon: Icons.share, - iconSize: Dimensions.sizeIconMicro, - iconColor: Colors.black87, - dense: true, - visualDensity: VisualDensity.compact)), - ], - ), - Row( - mainAxisSize: MainAxisSize.max, - children: [ + Widget build(BuildContext context) => BlocBuilder( + bloc: widget.cubit, + builder: (context, state) => SingleChildScrollView( + child: Container( + padding: Dimensions.paddingBottomSheet, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Fields.bottomSheetHandle(context), + Fields.bottomSheetTitle(widget.cubit.name, + style: context.theme.appTextStyle.titleMedium), + Row(children: [ Expanded( - child: Fields.actionListTile( - S.current.titleSecurity, - textOverflow: TextOverflow.ellipsis, - textSoftWrap: false, - style: settingStyle, - onTap: () async => - await navigateToRepositorySecurity( - context, - repository: widget.cubit, - checkForBiometrics: - widget.checkForBiometrics, - popDialog: () => - Navigator.of(context).pop(), - ), - icon: Icons.password, - iconSize: Dimensions.sizeIconMicro, - iconColor: Colors.black87, - dense: true, - visualDensity: VisualDensity.compact)), - ], - ), - Row( - mainAxisSize: MainAxisSize.max, - children: [ + child: SwitchListTile.adaptive( + title: Text(S.current.labelBitTorrentDHT, + style: context.theme.appTextStyle.bodyMedium), + secondary: const Icon( + Icons.hub, + size: Dimensions.sizeIconMicro, + color: Colors.black87, + ), + contentPadding: EdgeInsets.zero, + dense: true, + visualDensity: VisualDensity(horizontal: -4.0), + value: state.isDhtEnabled, + onChanged: (value) => + widget.cubit.setDhtEnabled(value), + )), + ]), + Row(children: [ Expanded( - child: Fields.actionListTile(S.current.actionDelete, - textOverflow: TextOverflow.ellipsis, - textSoftWrap: false, - style: settingStyle, - onTap: () async => await deleteRepository( - context, - repositoryName: widget.cubit.name, - repositoryMetaInfo: widget.cubit.metaInfo, - getAuthenticationMode: - widget.getAuthenticationMode, - delete: widget.deleteRepository, - popDialog: () => - Navigator.of(context).pop()), - icon: Icons.delete, - iconSize: Dimensions.sizeIconMicro, - iconColor: Constants.dangerColor, - dense: true, - visualDensity: VisualDensity.compact)), - ], - ) - ]))), - ); - } + child: SwitchListTile.adaptive( + title: Text(S.current.messagePeerExchange, + style: context.theme.appTextStyle.bodyMedium), + secondary: const Icon( + Icons.group_add, + size: Dimensions.sizeIconMicro, + color: Colors.black87, + ), + contentPadding: EdgeInsets.zero, + dense: true, + visualDensity: VisualDensity(horizontal: -4.0), + value: state.isPexEnabled, + onChanged: (value) => + widget.cubit.setPexEnabled(value), + )) + ]), + EntryActionItem( + iconData: Icons.edit, + title: S.current.actionRename, + dense: true, + onTap: () async => await renameRepository( + widget.context, + repository: widget.cubit, + rename: widget.renameRepository, + popDialog: () => Navigator.of(context).pop())), + EntryActionItem( + iconData: Icons.share, + title: S.current.actionShare, + dense: true, + onTap: () async { + Navigator.of(context).pop(); + await shareRepository(context, + repository: widget.cubit); + }), + EntryActionItem( + iconData: Icons.password, + title: S.current.titleSecurity, + dense: true, + onTap: () async => await navigateToRepositorySecurity( + context, + repository: widget.cubit, + checkForBiometrics: widget.checkForBiometrics, + popDialog: () => Navigator.of(context).pop(), + )), + EntryActionItem( + iconData: Icons.delete, + title: S.current.actionDelete, + dense: true, + isDanger: true, + onTap: () async => await deleteRepository(context, + repositoryName: widget.cubit.name, + repositoryMetaInfo: widget.cubit.metaInfo, + getAuthenticationMode: + widget.getAuthenticationMode, + delete: widget.deleteRepository, + popDialog: () => Navigator.of(context).pop())) + ]))), + ); } diff --git a/lib/app/widgets/dialogs/modal_repository_creation_dialog.dart b/lib/app/widgets/dialogs/modal_repository_creation_dialog.dart index 44bbac144..38c67d283 100644 --- a/lib/app/widgets/dialogs/modal_repository_creation_dialog.dart +++ b/lib/app/widgets/dialogs/modal_repository_creation_dialog.dart @@ -176,18 +176,14 @@ class _RepositoryCreationState extends State @override Widget build(BuildContext context) { - _linkStyle = Theme.of(context) - .textTheme - .bodySmall - ?.copyWith(fontWeight: FontWeight.w500); + _linkStyle = context.theme.appTextStyle.bodySmall + .copyWith(fontWeight: FontWeight.w500); - _labelStyle = Theme.of(context) - .textTheme - .labelMedium - ?.copyWith(color: Constants.inputLabelForeColor); + _labelStyle = context.theme.appTextStyle.labelMedium + .copyWith(color: Constants.inputLabelForeColor); _messageSmall = - Theme.of(context).textTheme.bodySmall?.copyWith(color: Colors.black54); + context.theme.appTextStyle.bodySmall.copyWith(color: Colors.black54); return WillPopScope( onWillPop: () async { @@ -231,7 +227,8 @@ class _RepositoryCreationState extends State if (!_isBlindReplica) ..._passwordSection(), if (_isBiometricsAvailable && !_isBlindReplica && _addPassword) _useBiometricsSwitch(), - _manualPasswordWarning(), + Dimensions.spacingVertical, + _manualPasswordWarning(context), Fields.dialogActions(context, buttons: _actions(context)), ]); @@ -414,7 +411,8 @@ class _RepositoryCreationState extends State child: SwitchListTile.adaptive( value: _secureWithBiometrics, title: Text(S.current.messageSecureUsingBiometrics, - textAlign: TextAlign.end), + textAlign: TextAlign.end, + style: context.theme.appTextStyle.bodyMedium), onChanged: (enableBiometrics) { setState(() { _secureWithBiometrics = enableBiometrics; @@ -427,10 +425,11 @@ class _RepositoryCreationState extends State contentPadding: EdgeInsets.zero, visualDensity: VisualDensity.compact)); - Widget _manualPasswordWarning() => Visibility( + Widget _manualPasswordWarning(BuildContext context) => Visibility( visible: _showSavePasswordWarning && _addPassword, child: Fields.autosizeText(S.current.messageRememberSavePasswordAlert, - style: TextStyle(color: Colors.red), + style: + context.theme.appTextStyle.bodyMedium.copyWith(color: Colors.red), maxLines: 10, softWrap: true, textOverflow: TextOverflow.ellipsis)); diff --git a/lib/app/widgets/dialogs/modal_share_repository_bottom_sheet.dart b/lib/app/widgets/dialogs/modal_share_repository_bottom_sheet.dart index 4fd955b3d..70f85e18c 100644 --- a/lib/app/widgets/dialogs/modal_share_repository_bottom_sheet.dart +++ b/lib/app/widgets/dialogs/modal_share_repository_bottom_sheet.dart @@ -37,25 +37,11 @@ class _ShareRepositoryState extends State with AppLogger { final scrollController = ScrollController(); TextStyle? labelStyle; - TextStyle? descriptionStyle; @override Widget build(BuildContext context) { - final microFontSize = - (Theme.of(context).textTheme.labelMedium?.fontSize ?? 0.0) * 0.8; - - labelStyle = Theme.of(context).textTheme.labelMedium?.copyWith( - fontSize: microFontSize, color: Constants.inputLabelForeColor); - - descriptionStyle = Theme.of(context) - .textTheme - .bodyMedium - ?.copyWith(fontSize: microFontSize, color: Colors.black54); - - final sheetTitleStyle = Theme.of(context) - .textTheme - .bodyLarge - ?.copyWith(fontWeight: FontWeight.w400); + labelStyle = context.theme.appTextStyle.bodyMicro + .copyWith(color: Constants.inputLabelForeColor); // On certain resolutions (higer) the constrain set on this dialog when called // causes the content to scroll, giving the appearance of a smaller padding @@ -82,7 +68,7 @@ class _ShareRepositoryState extends State with AppLogger { children: [ Fields.bottomSheetHandle(context), Fields.bottomSheetTitle(widget.repository.name, - style: sheetTitleStyle), + style: context.theme.appTextStyle.titleMedium), Dimensions.spacingVertical, AccessModeSelector( currentAccessMode: widget.repository.state.accessMode, @@ -134,7 +120,11 @@ class _ShareRepositoryState extends State with AppLogger { child: Row( children: [ Fields.constrainedText(_tokenDescription(accessMode), - flex: 0, style: descriptionStyle), + style: context.theme.appTextStyle.bodyMicro + .copyWith(color: Colors.black54), + softWrap: true, + maxLines: 2, + textOverflow: TextOverflow.ellipsis), ], ), ); @@ -169,14 +159,13 @@ class _ShareRepositoryState extends State with AppLogger { mainAxisSize: MainAxisSize.min, children: [ Fields.constrainedText(_displayToken ?? Constants.ouisyncUrl, - flex: 0, - style: Theme.of(context).textTheme.bodyMedium?.copyWith( + style: TextStyle().copyWith( color: _shareToken != null ? Colors.black : Colors.black54), softWrap: true, - maxLines: 2, - textOverflow: TextOverflow.fade), + maxLines: 1, + textOverflow: TextOverflow.ellipsis), ], ), ), diff --git a/lib/app/widgets/eq_terms_privacy.dart b/lib/app/widgets/eq_terms_privacy.dart index bf258c740..9298c144d 100644 --- a/lib/app/widgets/eq_terms_privacy.dart +++ b/lib/app/widgets/eq_terms_privacy.dart @@ -25,28 +25,29 @@ class EqTermsAndPrivacy extends StatelessWidget { } Widget _temsAndPrivacyTextBlock(BuildContext context) { - final titleTextStyle = Theme.of(context).textTheme.titleLarge; - final subtitleTextStyle = Theme.of(context).textTheme.titleMedium; - final bodyTextStyle = Theme.of(context).textTheme.bodyMedium; + final titleFontSize = context.theme.appTextStyle.titleLarge.fontSize; + final subtitleFontSize = context.theme.appTextStyle.titleMedium.fontSize; return Column(crossAxisAlignment: CrossAxisAlignment.stretch, children: [ RichText( textAlign: TextAlign.start, - text: TextSpan(style: titleTextStyle, children: [ - Fields.boldTextSpan('\n${S.current.titleTermsPrivacy}\n') - ])), + text: TextSpan( + style: context.theme.appTextStyle.titleLarge, + children: [ + Fields.boldTextSpan('\n${S.current.titleTermsPrivacy}\n') + ])), RichText( text: TextSpan( - style: bodyTextStyle, + style: context.theme.appTextStyle.bodyMedium, children: [ Fields.boldTextSpan('${S.current.titleOverview}\n\n', - fontSize: titleTextStyle?.fontSize), + fontSize: titleFontSize), TextSpan(text: '${S.current.messageTermsPrivacyP1}.\n\n'), TextSpan(text: '${S.current.messageTermsPrivacyP2}.\n\n'), Fields.boldTextSpan('${S.current.titleTermsOfUse}\n\n', - fontSize: titleTextStyle?.fontSize), + fontSize: titleFontSize), TextSpan(text: '${S.current.messageTermsPrivacyP3}\n\n'), - Fields.boldTextSpan('· ', fontSize: subtitleTextStyle?.fontSize), + Fields.boldTextSpan('· ', fontSize: subtitleFontSize), TextSpan(text: S.current.messageTerms1_1), Fields.linkTextSpan( context, S.current.messageCanadaPrivacyAct, _launchCPA), @@ -54,62 +55,62 @@ class EqTermsAndPrivacy extends StatelessWidget { Fields.linkTextSpan( context, S.current.messagePIPEDA, _launchPIPEDA), TextSpan(text: ' ${S.current.messageTerms1_2},\n\n'), - Fields.boldTextSpan('· ', fontSize: subtitleTextStyle?.fontSize), + Fields.boldTextSpan('· ', fontSize: subtitleFontSize), TextSpan(text: '${S.current.messageTerms2};\n\n'), - Fields.boldTextSpan('· ', fontSize: subtitleTextStyle?.fontSize), + Fields.boldTextSpan('· ', fontSize: subtitleFontSize), TextSpan(text: '${S.current.messageTerms3};\n\n'), - Fields.boldTextSpan('· ', fontSize: subtitleTextStyle?.fontSize), + Fields.boldTextSpan('· ', fontSize: subtitleFontSize), TextSpan(text: '${S.current.messageTerms4};\n\n'), - Fields.boldTextSpan('· ', fontSize: subtitleTextStyle?.fontSize), + Fields.boldTextSpan('· ', fontSize: subtitleFontSize), TextSpan(text: '${S.current.messageTerms5}.\n\n'), Fields.boldTextSpan('${S.current.titlePrivacyNotice}\n\n', - fontSize: titleTextStyle?.fontSize), + fontSize: titleFontSize), TextSpan(text: '${S.current.messagePrivacyIntro}.\n\n'), Fields.boldTextSpan('${S.current.titleDataCollection}\n\n', - fontSize: subtitleTextStyle?.fontSize), + fontSize: subtitleFontSize), TextSpan(text: '${S.current.messageDataCollectionP1}.\n\n'), TextSpan(text: '${S.current.messageDataCollectionP2}.\n\n'), Fields.boldTextSpan('${S.current.titleDataSharing}\n\n', - fontSize: subtitleTextStyle?.fontSize), + fontSize: subtitleFontSize), TextSpan(text: '${S.current.messageDataSharingP1}.\n\n'), Fields.boldTextSpan('${S.current.titleSecurityPractices}\n\n', - fontSize: subtitleTextStyle?.fontSize), + fontSize: subtitleFontSize), TextSpan(text: '${S.current.messageSecurityPracticesP1}.\n\n'), TextSpan(text: '${S.current.messageSecurityPracticesP2}.\n\n'), TextSpan(text: '${S.current.messageSecurityPracticesP3}.\n\n'), TextSpan(text: '${S.current.messageSecurityPracticesP4}.\n\n'), Fields.boldTextSpan('${S.current.titleDeletionDataServer}\n\n', - fontSize: subtitleTextStyle?.fontSize), + fontSize: subtitleFontSize), TextSpan(text: '${S.current.messageDeletionDataServerP1}.\n\n'), Fields.italicTextSpan('${S.current.messageNote}: '), Fields.italicTextSpan( '${S.current.messageDeletionDataServerNote}.\n\n'), Fields.boldTextSpan('${S.current.titleLogData}\n\n', - fontSize: titleTextStyle?.fontSize), + fontSize: titleFontSize), TextSpan(text: '${S.current.messageLogDataP1}.\n\n'), TextSpan(text: '${S.current.messageLogDataP2}\n\n'), - Fields.boldTextSpan('· ', fontSize: subtitleTextStyle?.fontSize), + Fields.boldTextSpan('· ', fontSize: subtitleFontSize), TextSpan(text: '${S.current.messageLogData1};\n\n'), - Fields.boldTextSpan('· ', fontSize: subtitleTextStyle?.fontSize), + Fields.boldTextSpan('· ', fontSize: subtitleFontSize), TextSpan(text: '${S.current.messageLogData2};\n\n'), - Fields.boldTextSpan('· ', fontSize: subtitleTextStyle?.fontSize), + Fields.boldTextSpan('· ', fontSize: subtitleFontSize), TextSpan(text: '${S.current.messageLogData3}.\n\n'), TextSpan(text: '${S.current.messageLogDataP3}.\n\n'), Fields.boldTextSpan('${S.current.titleCookies}\n\n', - fontSize: titleTextStyle?.fontSize), + fontSize: titleFontSize), TextSpan(text: '${S.current.messageCookiesP1}.\n\n'), Fields.boldTextSpan('${S.current.titleLinksOtherSites}\n\n', - fontSize: titleTextStyle?.fontSize), + fontSize: titleFontSize), TextSpan(text: '${S.current.messageLinksOtherSitesP1}.\n\n'), Fields.boldTextSpan('${S.current.titleChildrensPrivacy}\n\n', - fontSize: titleTextStyle?.fontSize), + fontSize: titleFontSize), TextSpan(text: '${S.current.messageChildrensPolicyP1}.\n\n'), Fields.boldTextSpan('${S.current.titleChangesToTerms}\n\n', - fontSize: titleTextStyle?.fontSize), + fontSize: titleFontSize), TextSpan(text: '${S.current.messageChangesToTermsP1}.\n\n'), TextSpan(text: '${S.current.messageChangesToTermsP2}.\n\n'), Fields.boldTextSpan('${S.current.titleContactUs}\n\n', - fontSize: titleTextStyle?.fontSize), + fontSize: titleFontSize), TextSpan(text: '${S.current.messageContatUsP1} '), Fields.linkTextSpan(context, Constants.supportEmail, _mailTo), TextSpan(text: '.'), diff --git a/lib/app/widgets/eq_values.dart b/lib/app/widgets/eq_values.dart index 56039920a..81fcadf5f 100644 --- a/lib/app/widgets/eq_values.dart +++ b/lib/app/widgets/eq_values.dart @@ -7,42 +7,37 @@ class EqValues extends StatelessWidget { const EqValues({super.key}); @override - Widget build(BuildContext context) { - final primaryColor = Theme.of(context).primaryColor; - final headerTextStyle = Theme.of(context) - .textTheme - .titleSmall - ?.copyWith(color: primaryColor, fontStyle: FontStyle.italic); - - return Theme( - data: Theme.of(context).copyWith(dividerColor: Colors.transparent), - child: ExpansionTile( - childrenPadding: EdgeInsets.only(bottom: 10.0), - title: Text(S.current.messageTapForValues, - textAlign: TextAlign.end, style: headerTextStyle), - children: [_valuesTextBlock(context)])); - } + Widget build(BuildContext context) => Theme( + data: Theme.of(context).copyWith(dividerColor: Colors.transparent), + child: ExpansionTile( + childrenPadding: EdgeInsets.only(bottom: 10.0), + title: Text(S.current.messageTapForValues, + textAlign: TextAlign.end, + style: context.theme.appTextStyle.titleSmall.copyWith( + color: context.theme.primaryColor, + fontStyle: FontStyle.italic)), + children: [_valuesTextBlock(context)])); Widget _valuesTextBlock(BuildContext context) { - final titleTextStyle = Theme.of(context).textTheme.titleLarge; - final subtitleTextStyle = Theme.of(context).textTheme.titleMedium; - final quoteTextStyle = Theme.of(context).textTheme.bodyLarge; - final bodyTextStyle = Theme.of(context).textTheme.bodyMedium; + final titleFontSize = context.theme.appTextStyle.titleLarge.fontSize; + final subtitleFontSize = context.theme.appTextStyle.titleMedium.fontSize; return Column(crossAxisAlignment: CrossAxisAlignment.stretch, children: [ RichText( textAlign: TextAlign.start, - text: TextSpan(style: titleTextStyle, children: [ - Fields.boldTextSpan('\n${S.current.titleEqualitiesValues}\n') - ])), + text: TextSpan( + style: context.theme.appTextStyle.titleLarge, + children: [ + Fields.boldTextSpan('\n${S.current.titleEqualitiesValues}\n') + ])), RichText( textAlign: TextAlign.end, text: Fields.quoteTextSpan('${S.current.messageQuoteMainIsFree}\n\n', '${S.current.messageRousseau}\n\n', - fontSize: quoteTextStyle?.fontSize)), + fontSize: context.theme.appTextStyle.bodyLarge.fontSize)), RichText( text: TextSpan( - style: bodyTextStyle, + style: context.theme.appTextStyle.bodyMedium, children: [ TextSpan(text: S.current.messageEqValuesP1), Fields.linkTextSpan( @@ -52,32 +47,32 @@ class EqValues extends StatelessWidget { TextSpan(text: '${S.current.messageEqValuesP2}.\n\n'), TextSpan(text: '${S.current.messageEqValuesP3}.\n\n'), Fields.boldTextSpan('${S.current.titleOurMission}\n\n', - fontSize: titleTextStyle?.fontSize), + fontSize: titleFontSize), TextSpan(text: '${S.current.messageEqValuesP4}.\n\n'), TextSpan(text: '${S.current.messageEqValuesP5}.\n\n'), Fields.boldTextSpan('${S.current.titleWeAreEq}\n\n', - fontSize: titleTextStyle?.fontSize), + fontSize: titleFontSize), TextSpan(text: '${S.current.messageEqValuesP6}.\n\n'), Fields.boldTextSpan('${S.current.titleOurPrinciples}\n\n', - fontSize: titleTextStyle?.fontSize), + fontSize: titleFontSize), TextSpan(text: '${S.current.messageEqValuesP7}.\n\n'), Fields.boldTextSpan('· ${S.current.titlePrivacy}\n\n', - fontSize: subtitleTextStyle?.fontSize), + fontSize: subtitleFontSize), TextSpan(text: S.current.messageEqValuesP8), Fields.linkTextSpan(context, '${S.current.messageDeclarationDOS}.\n\n', _launchDfDOS), Fields.boldTextSpan('· ${S.current.titleDigitalSecurity}\n\n', - fontSize: subtitleTextStyle?.fontSize), + fontSize: subtitleFontSize), TextSpan(text: '${S.current.messageEqValuesP9}.\n\n'), Fields.boldTextSpan('· ${S.current.titleOpennessTransparency}\n\n', - fontSize: subtitleTextStyle?.fontSize), + fontSize: subtitleFontSize), TextSpan(text: '${S.current.messageEqValuesP10}\n\n'), Fields.boldTextSpan( '· ${S.current.titleFreedomExpresionAccessInfo}\n\n', - fontSize: subtitleTextStyle?.fontSize), + fontSize: subtitleFontSize), TextSpan(text: '${S.current.messageEqValuesP11}.\n\n'), Fields.boldTextSpan('· ${S.current.titleJustLegalSociety}\n\n', - fontSize: subtitleTextStyle?.fontSize), + fontSize: subtitleFontSize), TextSpan( text: '${S.current.messageEqValuesP12}.\n\n' '${S.current.messageEqValuesP13}.\n\n' diff --git a/lib/app/widgets/inputs/password_validation_input.dart b/lib/app/widgets/inputs/password_validation_input.dart index 8e1a85bf8..4e200e7a1 100644 --- a/lib/app/widgets/inputs/password_validation_input.dart +++ b/lib/app/widgets/inputs/password_validation_input.dart @@ -40,8 +40,6 @@ class _PasswordValidationState extends State String? _passwordStrength; Color? _passwordStrengthColorValue; - TextStyle? bodySmallStyle; - @override void initState() { widget.passwordController.addListener( @@ -51,11 +49,7 @@ class _PasswordValidationState extends State } @override - Widget build(BuildContext context) { - bodySmallStyle = Theme.of(context).textTheme.bodySmall; - - return _passwordInputs(); - } + Widget build(BuildContext context) => _passwordInputs(); double _inputOpacity() => widget.passwordMode != PasswordMode.bio ? 1 : 0.5; @@ -105,11 +99,12 @@ class _PasswordValidationState extends State Dimensions.spacingVertical, Row(children: [ Text('${S.current.messagePasswordStrength}:', - style: bodySmallStyle?.copyWith(color: Colors.black54)), + style: context.theme.appTextStyle.bodySmall + .copyWith(color: Colors.black54)), Dimensions.spacingHorizontalHalf, Text(_passwordStrength ?? '', - style: - bodySmallStyle?.copyWith(color: _passwordStrengthColorValue)) + style: context.theme.appTextStyle.bodySmall + .copyWith(color: _passwordStrengthColorValue)) ]), Dimensions.spacingVertical, FlutterPasswordStrength( diff --git a/lib/app/widgets/items/entry_action_item.dart b/lib/app/widgets/items/entry_action_item.dart index a0fc9165a..4ba0d926a 100644 --- a/lib/app/widgets/items/entry_action_item.dart +++ b/lib/app/widgets/items/entry_action_item.dart @@ -15,14 +15,14 @@ class EntryActionItem extends StatefulWidget { this.disabledMessage, this.disabledMessageDuration = 0, this.contentPadding = EdgeInsets.zero, - this.dense, - this.visualDensity, + this.dense = true, + this.visualDensity = VisualDensity.compact, this.minLeadingWidth = 20.0, this.textAlign = TextAlign.start, this.textOverflow = TextOverflow.ellipsis, this.textSoftWrap = true, - required this.titleTextStyle, - this.subtitleTextStyle, + this.titleTextStyle = AppTypography.bodyMedium, + this.subtitleTextStyle = AppTypography.bodySmall, this.isDanger = false, Key? key, }) : super(key: key); diff --git a/lib/app/widgets/items/file_description.dart b/lib/app/widgets/items/file_description.dart index d9d050e6a..4005e8f31 100644 --- a/lib/app/widgets/items/file_description.dart +++ b/lib/app/widgets/items/file_description.dart @@ -7,7 +7,7 @@ import '../../models/models.dart'; import '../../utils/utils.dart'; class FileDescription extends StatelessWidget with AppLogger { - FileDescription( + const FileDescription( this.repo, this.fileData, this._uploadJob, @@ -17,27 +17,18 @@ class FileDescription extends StatelessWidget with AppLogger { final FileItem fileData; final Job? _uploadJob; - late Color primaryColor; - - TextStyle? bodyStyle; - TextStyle? bodySmallStyle; - @override - Widget build(BuildContext context) { - primaryColor = Theme.of(context).primaryColor; - - bodyStyle = Theme.of(context).textTheme.bodyMedium; - bodySmallStyle = Theme.of(context).textTheme.bodySmall; - - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Fields.autosizeText(fileData.name, style: bodyStyle), - Dimensions.spacingVerticalHalf, - _buildDetails(context), - ], - ); - } + Widget build(BuildContext context) => Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Fields.autosizeText(fileData.name, + minFontSize: context.theme.appTextStyle.bodyMicro.fontSize, + maxFontSize: context.theme.appTextStyle.bodyMedium.fontSize, + maxLines: 1), + Dimensions.spacingVerticalHalf, + _buildDetails(context), + ], + ); Widget _buildDetails(BuildContext context) { final uploadJob = _uploadJob; @@ -79,12 +70,12 @@ class FileDescription extends StatelessWidget with AppLogger { children: [ _buildSizeWidget(context, formatSize(state.soFar), false), Dimensions.spacingVerticalHalf, - _buildUploadProgress(job), + _buildUploadProgress(context, job), ], ), ); - Widget _buildUploadProgress(Job job) => Row( + Widget _buildUploadProgress(BuildContext context, Job job) => Row( textBaseline: TextBaseline.alphabetic, children: [ Expanded( @@ -94,28 +85,20 @@ class FileDescription extends StatelessWidget with AppLogger { onPressed: () { job.cancel(); }, - child: Text( - S.current.actionCancelCapital, - style: bodySmallStyle?.copyWith(color: primaryColor), - )), + child: Text(S.current.actionCancelCapital, + style: context.theme.appTextStyle.bodyMicro + .copyWith(color: context.theme.primaryColor))), ], ); Widget _buildSizeWidget(BuildContext context, String? text, bool loading) => - Row( - children: [ - if (text != null) - Fields.constrainedText( - text, + Row(children: [ + if (text != null) + Fields.constrainedText(text, flex: 0, - style: bodySmallStyle?.copyWith(fontWeight: FontWeight.w400), - softWrap: true, - ), - if (loading) - Icon( - Icons.hourglass_top, - color: Colors.black.withAlpha(128), - ), - ], - ); + style: context.theme.appTextStyle.bodyMicro, + softWrap: true), + if (loading) + Icon(Icons.hourglass_top, color: Colors.black.withAlpha(128)) + ]); } diff --git a/lib/app/widgets/items/folder_description.dart b/lib/app/widgets/items/folder_description.dart index b3bae3d9f..07ede1503 100644 --- a/lib/app/widgets/items/folder_description.dart +++ b/lib/app/widgets/items/folder_description.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:ouisync_app/app/utils/utils.dart'; import '../../models/models.dart'; @@ -10,12 +11,8 @@ class FolderDescription extends StatelessWidget { final BaseItem folderData; @override - Widget build(BuildContext context) { - final bodyStyle = Theme.of(context).textTheme.bodyMedium; - - return Text( - folderData.name, - style: bodyStyle?.copyWith(fontWeight: FontWeight.w500), - ); - } + Widget build(BuildContext context) => Fields.autosizeText(folderData.name, + minFontSize: context.theme.appTextStyle.bodyMicro.fontSize, + maxFontSize: context.theme.appTextStyle.bodyMedium.fontSize, + maxLines: 2); } diff --git a/lib/app/widgets/selectors/access_mode_selector.dart b/lib/app/widgets/selectors/access_mode_selector.dart index a7568a087..aa996f35b 100644 --- a/lib/app/widgets/selectors/access_mode_selector.dart +++ b/lib/app/widgets/selectors/access_mode_selector.dart @@ -44,65 +44,47 @@ class _AccessModeSelectorState extends State ); } - Widget _buildModeSelector() { - final microFontSize = - (Theme.of(context).textTheme.bodySmall?.fontSize ?? 0.0) * 0.8; - - final microBodyStyle = Theme.of(context).textTheme.bodySmall?.copyWith( - fontSize: microFontSize, color: Constants.inputLabelForeColor); - - return Column( - children: [ + Widget _buildModeSelector() => Column(children: [ Padding( - padding: Dimensions.paddingItem, - child: Row( - children: [ + padding: Dimensions.paddingItem, + child: Row(children: [ Fields.constrainedText(S.current.labelSetPermission, - style: microBodyStyle), - ], - ), - ), + style: context.theme.appTextStyle.bodyMicro + .copyWith(color: Constants.inputLabelForeColor)) + ])), Row( - mainAxisAlignment: MainAxisAlignment.center, - children: _buildAccessModeOptions(), - ) - ], - ); - } - - List _buildAccessModeOptions() { - final bodyStyle = Theme.of(context).textTheme.bodyMedium; - - return AccessMode.values - .map((mode) => Expanded( - child: Row( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Radio( - value: mode, - groupValue: _selectedMode, - toggleable: true, - onChanged: (current) async { - loggy.app('Access mode: $current'); - - if (!widget.availableAccessMode.contains(mode)) { - final message = S.current.messageAccessModeDisabled( - widget.currentAccessMode.name); - widget.onDisabledMessage(message); - return; - } - - setState(() => _selectedMode = current); - await widget.onChanged(current); - }), - Text( - mode.name, - textAlign: TextAlign.start, - style: bodyStyle?.copyWith(color: _getModeStateColor(mode)), - ) - ]))) - .toList(); - } + mainAxisAlignment: MainAxisAlignment.center, + children: _buildAccessModeOptions()) + ]); + + List _buildAccessModeOptions() => AccessMode.values + .map((mode) => Expanded( + child: + Row(crossAxisAlignment: CrossAxisAlignment.center, children: [ + Radio( + value: mode, + groupValue: _selectedMode, + toggleable: true, + onChanged: (current) async { + loggy.app('Access mode: $current'); + + if (!widget.availableAccessMode.contains(mode)) { + final message = S.current.messageAccessModeDisabled( + widget.currentAccessMode.name); + widget.onDisabledMessage(message); + return; + } + + setState(() => _selectedMode = current); + await widget.onChanged(current); + }), + Text( + mode.name, + textAlign: TextAlign.start, + style: TextStyle().copyWith(color: _getModeStateColor(mode)), + ) + ]))) + .toList(); Color _getModeStateColor(AccessMode accessMode) { if (widget.availableAccessMode.contains(accessMode)) { diff --git a/lib/app/widgets/settings/about_section.dart b/lib/app/widgets/settings/about_section.dart index 50ec7fede..bc4248a5d 100644 --- a/lib/app/widgets/settings/about_section.dart +++ b/lib/app/widgets/settings/about_section.dart @@ -28,12 +28,10 @@ class AboutSection extends SettingsSection with AppLogger { late final ValueNotifier _launchAtStartup; TextStyle? bodyStyle; - TextStyle? subtitleStyle; @override List buildTiles(BuildContext context) { - bodyStyle = Theme.of(context).textTheme.bodyMedium; - subtitleStyle = Theme.of(context).textTheme.bodySmall; + bodyStyle = context.theme.appTextStyle.bodyMedium; return [ if (PlatformValues.isDesktopDevice) @@ -49,7 +47,8 @@ class AboutSection extends SettingsSection with AppLogger { leading: Icon(Icons.question_answer_rounded), trailing: PlatformValues.isDesktopDevice ? _externalNavigationIcon : null, - value: Text(S.current.messageFAQ, style: subtitleStyle), + value: Text(S.current.messageFAQ, + style: context.theme.appTextStyle.bodySmall), onTap: () => unawaited( _openUrl(context, S.current.titleFAQShort, Constants.faqUrl))), NavigationTile( @@ -203,8 +202,9 @@ class AboutSection extends SettingsSection with AppLogger { future: _cubits.repositories.session.thisRuntimeId, builder: (context, snapshot) { final runtimeId = snapshot.data ?? ''; - final runtimeIdWidget = - Text(runtimeId, overflow: TextOverflow.ellipsis, style: bodyStyle); + final runtimeIdWidget = Text(runtimeId, + overflow: TextOverflow.ellipsis, + style: context.theme.appTextStyle.bodySmall); if (Platform.isIOS) { return Expanded( diff --git a/lib/app/widgets/settings/logs_section.dart b/lib/app/widgets/settings/logs_section.dart index 299f9fe47..90469bc6a 100644 --- a/lib/app/widgets/settings/logs_section.dart +++ b/lib/app/widgets/settings/logs_section.dart @@ -15,10 +15,8 @@ import 'package:url_launcher/url_launcher.dart'; import '../../../generated/l10n.dart'; import '../../cubits/cubits.dart'; import '../../pages/log_view_page.dart'; -import '../../utils/constants.dart'; -import '../../utils/dump.dart'; -import '../../utils/log.dart'; import '../../utils/platform/platform.dart'; +import '../../utils/utils.dart'; import 'settings_section.dart'; import 'settings_tile.dart'; @@ -34,7 +32,7 @@ class LogsSection extends SettingsSection with AppLogger { @override List buildTiles(BuildContext context) { - bodyStyle = Theme.of(context).textTheme.bodyMedium; + bodyStyle = context.theme.appTextStyle.bodyMedium; final mountCubit = _cubits.mount; diff --git a/lib/app/widgets/settings/network_section.dart b/lib/app/widgets/settings/network_section.dart index 675cc44a0..4d5bf8ae0 100644 --- a/lib/app/widgets/settings/network_section.dart +++ b/lib/app/widgets/settings/network_section.dart @@ -20,8 +20,8 @@ class NetworkSection extends SettingsSection { @override List buildTiles(BuildContext context) { - bodyStyle = Theme.of(context).textTheme.bodyMedium; - subtitleStyle = Theme.of(context).textTheme.bodySmall; + bodyStyle = context.theme.appTextStyle.bodyMedium; + subtitleStyle = context.theme.appTextStyle.bodySmall; return [ _buildConnectivityTypeTile(context), diff --git a/lib/app/widgets/settings/repository_section.dart b/lib/app/widgets/settings/repository_section.dart index 61a67ada7..243140272 100644 --- a/lib/app/widgets/settings/repository_section.dart +++ b/lib/app/widgets/settings/repository_section.dart @@ -30,7 +30,7 @@ class RepositorySection extends SettingsSection @override List buildTiles(BuildContext context) { - bodyStyle = Theme.of(context).textTheme.bodyMedium; + bodyStyle = context.theme.appTextStyle.bodyMedium; final currentRepo = _cubits.repositories.currentRepo; @@ -162,7 +162,7 @@ class _SecurityTileState extends State @override Widget build(BuildContext context) { - bodyStyle = Theme.of(context).textTheme.bodyMedium; + bodyStyle = context.theme.appTextStyle.bodyMedium; return BlocBuilder( bloc: _security, diff --git a/lib/app/widgets/settings/repository_selector.dart b/lib/app/widgets/settings/repository_selector.dart index b98cc14fb..d1f167645 100644 --- a/lib/app/widgets/settings/repository_selector.dart +++ b/lib/app/widgets/settings/repository_selector.dart @@ -12,65 +12,60 @@ class RepositorySelector extends StatelessWidget with AppLogger { const RepositorySelector(this.repos); @override - Widget build(BuildContext context) { - final bodyStyle = Theme.of(context).textTheme.labelMedium; - - final labelStyle = Theme.of(context) - .textTheme - .labelSmall - ?.copyWith(color: Constants.inputLabelForeColor); - - return Container( - constraints: PlatformValues.isDesktopDevice - ? BoxConstraints( - maxWidth: PlatformValues.getFormFactorMaxWidth(context) * 0.7) - : null, - padding: Dimensions.paddingActionBox, - decoration: const BoxDecoration( - borderRadius: - BorderRadius.all(Radius.circular(Dimensions.radiusSmall)), - color: Constants.inputBackgroundColor), - child: DropdownButton( - isExpanded: true, - value: repos.currentRepo, - underline: const SizedBox(), - selectedItemBuilder: (context) => repos - .repositoryNames() - .map((String repoName) => Padding( - padding: Dimensions.paddingItem, - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row(children: [ - Fields.idLabel(S.current.labelSelectRepository, - style: labelStyle) - ]), - Row(children: [ - Fields.constrainedText(repoName, style: bodyStyle) - ]) - ]))) - .toList(), - items: repos.repos - .map((RepoEntry repo) => DropdownMenuItem( - value: repo, - child: Row( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisSize: MainAxisSize.max, - children: [ - Icon(repo == repos.currentRepo ? Icons.check : null, - size: Dimensions.sizeIconSmall, - color: Theme.of(context).primaryColor), - Dimensions.spacingHorizontalDouble, - Fields.constrainedText(repo.name, style: bodyStyle) - ]))) - .toList(), - onChanged: (repo) async { - loggy.app('Selected repository: ${repo?.name}'); - await repos.setCurrentByName(repo?.name); - }, - ), - ); - } + Widget build(BuildContext context) => Container( + constraints: PlatformValues.isDesktopDevice + ? BoxConstraints( + maxWidth: PlatformValues.getFormFactorMaxWidth(context) * 0.7) + : null, + padding: Dimensions.paddingActionBox, + decoration: const BoxDecoration( + borderRadius: + BorderRadius.all(Radius.circular(Dimensions.radiusSmall)), + color: Constants.inputBackgroundColor), + child: DropdownButton( + isExpanded: true, + value: repos.currentRepo, + underline: const SizedBox(), + selectedItemBuilder: (context) => repos + .repositoryNames() + .map((String repoName) => Padding( + padding: Dimensions.paddingItem, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row(children: [ + Fields.idLabel(S.current.labelSelectRepository, + style: context.theme.appTextStyle.bodyMicro + .copyWith( + color: Constants.inputLabelForeColor)) + ]), + Row(children: [ + Fields.constrainedText(repoName, + style: context.theme.appTextStyle.labelMedium) + ]) + ]))) + .toList(), + items: repos.repos + .map((RepoEntry repo) => DropdownMenuItem( + value: repo, + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisSize: MainAxisSize.max, + children: [ + Icon(repo == repos.currentRepo ? Icons.check : null, + size: Dimensions.sizeIconSmall, + color: Theme.of(context).primaryColor), + Dimensions.spacingHorizontalDouble, + Fields.constrainedText(repo.name, + style: context.theme.appTextStyle.labelMedium) + ]))) + .toList(), + onChanged: (repo) async { + loggy.app('Selected repository: ${repo?.name}'); + await repos.setCurrentByName(repo?.name); + }, + ), + ); } diff --git a/lib/app/widgets/settings/settings_container.dart b/lib/app/widgets/settings/settings_container.dart index 7282db009..80ffad8ff 100644 --- a/lib/app/widgets/settings/settings_container.dart +++ b/lib/app/widgets/settings/settings_container.dart @@ -3,9 +3,8 @@ import 'package:flutter/material.dart'; import 'package:settings_ui/settings_ui.dart' as s; import '../../cubits/cubits.dart'; -import '../../utils/constants.dart'; -import '../../utils/fields.dart'; import '../../utils/platform/platform.dart'; +import '../../utils/utils.dart'; import 'about_section.dart'; import 'logs_section.dart'; import 'network_section.dart'; @@ -36,29 +35,24 @@ class SettingsContainer extends StatelessWidget { } class SettingsContainerMobile extends StatelessWidget { - SettingsContainerMobile(this.sections); + const SettingsContainerMobile(this.sections); final List sections; - TextStyle? bodyStyle; - @override - Widget build(BuildContext context) { - bodyStyle = Theme.of(context).textTheme.bodyMedium; - - return s.SettingsList( - platform: s.PlatformUtils.detectPlatform(context), - sections: sections - .map((section) => s.SettingsSection( - title: Text(section.title, style: bodyStyle), - tiles: section - .buildTiles(context) - .map((tile) => (tile is s.AbstractSettingsTile) - ? tile - : s.CustomSettingsTile(child: tile)) - .toList())) - .toList()); - } + Widget build(BuildContext context) => s.SettingsList( + platform: s.PlatformUtils.detectPlatform(context), + sections: sections + .map((section) => s.SettingsSection( + title: Text(section.title, + style: context.theme.appTextStyle.titleMedium), + tiles: section + .buildTiles(context) + .map((tile) => (tile is s.AbstractSettingsTile) + ? tile + : s.CustomSettingsTile(child: tile)) + .toList())) + .toList()); } class SettingsContainerDesktop extends StatefulWidget { @@ -103,7 +97,7 @@ class _SettingsContainerDesktopState extends State { } class SettingsSectionTitleDesktop extends StatelessWidget { - SettingsSectionTitleDesktop({ + const SettingsSectionTitleDesktop({ required this.section, required this.onTap, this.selected = false, @@ -113,26 +107,20 @@ class SettingsSectionTitleDesktop extends StatelessWidget { final bool selected; final VoidCallback? onTap; - TextStyle? bodyStyle; - @override - Widget build(BuildContext context) { - bodyStyle = Theme.of(context).textTheme.bodyMedium; - - return ListTile( - title: Row(children: [ - // Need to put the badge in a row because wrapping the Text in Badge - // will make the text centered. Maybe there's a better solution - // though. - Text(section.title, style: _getStyle()), - _maybeBadge(section) - ]), - selected: selected, - onTap: onTap, - ); - } + Widget build(BuildContext context) => ListTile( + title: Row(children: [ + // Need to put the badge in a row because wrapping the Text in Badge + // will make the text centered. Maybe there's a better solution + // though. + Text(section.title, style: _getStyle(context)), + _maybeBadge(section) + ]), + selected: selected, + onTap: onTap, + ); - TextStyle? _getStyle() { + TextStyle? _getStyle(BuildContext context) { Color? color = Colors.black54; FontWeight fontWeight = FontWeight.normal; @@ -141,7 +129,8 @@ class SettingsSectionTitleDesktop extends StatelessWidget { fontWeight = FontWeight.w500; } - return bodyStyle?.copyWith(color: color, fontWeight: fontWeight); + return context.theme.appTextStyle.bodyMedium + .copyWith(color: color, fontWeight: fontWeight); } Widget _maybeBadge(SettingsSection section) {