From 3c38d6a88f13cbc4a87e8d01df2a5cb21a1d134d Mon Sep 17 00:00:00 2001 From: problematicconsumer Date: Fri, 12 Jan 2024 22:45:52 +0330 Subject: [PATCH] Fix bugs --- ios/Runner/Handlers/MethodHandler.swift | 2 +- .../profile/details/profile_details_page.dart | 269 +++++++++--------- .../overview/profiles_overview_page.dart | 128 +++++---- 3 files changed, 202 insertions(+), 197 deletions(-) diff --git a/ios/Runner/Handlers/MethodHandler.swift b/ios/Runner/Handlers/MethodHandler.swift index 9620128e..61337dd7 100644 --- a/ios/Runner/Handlers/MethodHandler.swift +++ b/ios/Runner/Handlers/MethodHandler.swift @@ -48,7 +48,7 @@ public class MethodHandler: NSObject, FlutterPlugin { result(FlutterError(code: String(error.code), message: error.description, details: nil)) return } - result(true) + result("") case "change_config_options": guard let options = call.arguments as? String else { result(FlutterError(code: "INVALID_ARGS", message: nil, details: nil)) diff --git a/lib/features/profile/details/profile_details_page.dart b/lib/features/profile/details/profile_details_page.dart index 4c55d4ed..642b24cc 100644 --- a/lib/features/profile/details/profile_details_page.dart +++ b/lib/features/profile/details/profile_details_page.dart @@ -86,158 +86,161 @@ class ProfileDetailsPage extends HookConsumerWidget with PresLogger { return Stack( children: [ Scaffold( - body: CustomScrollView( - slivers: [ - SliverAppBar( - title: Text(t.profile.detailsPageTitle), - pinned: true, - actions: [ - if (state.isEditing) - PopupMenuButton( - itemBuilder: (context) { - return [ - if (state.profile case RemoteProfileEntity()) + body: SafeArea( + child: CustomScrollView( + slivers: [ + SliverAppBar( + title: Text(t.profile.detailsPageTitle), + pinned: true, + actions: [ + if (state.isEditing) + PopupMenuButton( + itemBuilder: (context) { + return [ + if (state.profile case RemoteProfileEntity()) + PopupMenuItem( + child: Text(t.profile.update.buttonTxt), + onTap: () async { + await notifier.updateProfile(); + }, + ), PopupMenuItem( - child: Text(t.profile.update.buttonTxt), + child: Text(t.profile.delete.buttonTxt), onTap: () async { - await notifier.updateProfile(); + final deleteConfirmed = + await showConfirmationDialog( + context, + title: t.profile.delete.buttonTxt, + message: t.profile.delete.confirmationMsg, + ); + if (deleteConfirmed) { + await notifier.delete(); + } }, ), - PopupMenuItem( - child: Text(t.profile.delete.buttonTxt), - onTap: () async { - final deleteConfirmed = - await showConfirmationDialog( - context, - title: t.profile.delete.buttonTxt, - message: t.profile.delete.confirmationMsg, - ); - if (deleteConfirmed) { - await notifier.delete(); - } - }, - ), - ]; - }, - ), - ], - ), - Form( - autovalidateMode: state.showErrorMessages - ? AutovalidateMode.always - : AutovalidateMode.disabled, - child: SliverList.list( - children: [ - Padding( - padding: const EdgeInsets.symmetric( - horizontal: 16, - vertical: 8, + ]; + }, ), - child: CustomTextFormField( - initialValue: state.profile.name, - onChanged: (value) => - notifier.setField(name: value), - validator: (value) => (value?.isEmpty ?? true) - ? t.profile.detailsForm.emptyNameMsg - : null, - label: t.profile.detailsForm.nameLabel, - hint: t.profile.detailsForm.nameHint, - ), - ), - if (state.profile - case RemoteProfileEntity( - :final url, - :final options - )) ...[ + ], + ), + Form( + autovalidateMode: state.showErrorMessages + ? AutovalidateMode.always + : AutovalidateMode.disabled, + child: SliverList.list( + children: [ Padding( padding: const EdgeInsets.symmetric( horizontal: 16, vertical: 8, ), child: CustomTextFormField( - initialValue: url, + initialValue: state.profile.name, onChanged: (value) => - notifier.setField(url: value), - validator: (value) => - (value != null && !isUrl(value)) - ? t.profile.detailsForm.invalidUrlMsg - : null, - label: t.profile.detailsForm.urlLabel, - hint: t.profile.detailsForm.urlHint, + notifier.setField(name: value), + validator: (value) => (value?.isEmpty ?? true) + ? t.profile.detailsForm.emptyNameMsg + : null, + label: t.profile.detailsForm.nameLabel, + hint: t.profile.detailsForm.nameHint, ), ), - ListTile( - title: Text(t.profile.detailsForm.updateInterval), - subtitle: Text( - options?.updateInterval.toApproximateTime( - isRelativeToNow: false, - ) ?? - t.general.toggle.disabled, + if (state.profile + case RemoteProfileEntity( + :final url, + :final options + )) ...[ + Padding( + padding: const EdgeInsets.symmetric( + horizontal: 16, + vertical: 8, + ), + child: CustomTextFormField( + initialValue: url, + onChanged: (value) => + notifier.setField(url: value), + validator: (value) => + (value != null && !isUrl(value)) + ? t.profile.detailsForm.invalidUrlMsg + : null, + label: t.profile.detailsForm.urlLabel, + hint: t.profile.detailsForm.urlHint, + ), ), - leading: const Icon(Icons.update), - onTap: () async { - final intervalInHours = await SettingsInputDialog( - title: t.profile.detailsForm - .updateIntervalDialogTitle, - initialValue: options?.updateInterval.inHours, - optionalAction: ( - t.general.state.disable, - () => - notifier.setField(updateInterval: none()), - ), - validator: isPort, - mapTo: int.tryParse, - digitsOnly: true, - ).show(context); - if (intervalInHours == null) return; - notifier.setField( - updateInterval: optionOf(intervalInHours), - ); - }, - ), - ], - if (state.isEditing) - ListTile( - title: Text(t.profile.detailsForm.lastUpdate), - subtitle: Text(state.profile.lastUpdate.format()), - dense: true, - ), - ], - ), - ), - SliverFillRemaining( - hasScrollBody: false, - child: Padding( - padding: const EdgeInsets.symmetric( - horizontal: 16, - vertical: 16, - ), - child: Column( - mainAxisAlignment: MainAxisAlignment.end, - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - OverflowBar( - spacing: 12, - overflowAlignment: OverflowBarAlignment.end, - children: [ - OutlinedButton( - onPressed: context.pop, - child: Text( - MaterialLocalizations.of(context) - .cancelButtonLabel, - ), + ListTile( + title: Text(t.profile.detailsForm.updateInterval), + subtitle: Text( + options?.updateInterval.toApproximateTime( + isRelativeToNow: false, + ) ?? + t.general.toggle.disabled, ), - FilledButton( - onPressed: notifier.save, - child: Text(t.profile.save.buttonText), - ), - ], - ), + leading: const Icon(Icons.update), + onTap: () async { + final intervalInHours = + await SettingsInputDialog( + title: t.profile.detailsForm + .updateIntervalDialogTitle, + initialValue: options?.updateInterval.inHours, + optionalAction: ( + t.general.state.disable, + () => notifier.setField( + updateInterval: none()), + ), + validator: isPort, + mapTo: int.tryParse, + digitsOnly: true, + ).show(context); + if (intervalInHours == null) return; + notifier.setField( + updateInterval: optionOf(intervalInHours), + ); + }, + ), + ], + if (state.isEditing) + ListTile( + title: Text(t.profile.detailsForm.lastUpdate), + subtitle: Text(state.profile.lastUpdate.format()), + dense: true, + ), ], ), ), - ), - ], + SliverFillRemaining( + hasScrollBody: false, + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: 16, + vertical: 16, + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.end, + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + OverflowBar( + spacing: 12, + overflowAlignment: OverflowBarAlignment.end, + children: [ + OutlinedButton( + onPressed: context.pop, + child: Text( + MaterialLocalizations.of(context) + .cancelButtonLabel, + ), + ), + FilledButton( + onPressed: notifier.save, + child: Text(t.profile.save.buttonText), + ), + ], + ), + ], + ), + ), + ), + ], + ), ), ), if (showLoadingOverlay) diff --git a/lib/features/profile/overview/profiles_overview_page.dart b/lib/features/profile/overview/profiles_overview_page.dart index 07231312..1d0dac0d 100644 --- a/lib/features/profile/overview/profiles_overview_page.dart +++ b/lib/features/profile/overview/profiles_overview_page.dart @@ -43,73 +43,75 @@ class ProfilesOverviewModal extends HookConsumerWidget { }, ); - return Stack( - children: [ - CustomScrollView( - controller: scrollController, - slivers: [ - switch (asyncProfiles) { - AsyncData(value: final profiles) => SliverList.builder( - itemBuilder: (context, index) { - final profile = profiles[index]; - return ProfileTile(profile: profile); - }, - itemCount: profiles.length, + return SafeArea( + child: Stack( + children: [ + CustomScrollView( + controller: scrollController, + slivers: [ + switch (asyncProfiles) { + AsyncData(value: final profiles) => SliverList.builder( + itemBuilder: (context, index) { + final profile = profiles[index]; + return ProfileTile(profile: profile); + }, + itemCount: profiles.length, + ), + AsyncError(:final error) => SliverErrorBodyPlaceholder( + t.presentShortError(error), + ), + AsyncLoading() => const SliverLoadingBodyPlaceholder(), + _ => const SliverToBoxAdapter(), + }, + const SliverGap(48), + ], + ), + Positioned.fill( + child: Align( + alignment: Alignment.bottomCenter, + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 8), + child: Wrap( + alignment: WrapAlignment.center, + spacing: 8, + children: [ + FilledButton.icon( + onPressed: () { + const AddProfileRoute().push(context); + }, + icon: const Icon(Icons.add), + label: Text(t.profile.add.shortBtnTxt), + ), + FilledButton.icon( + onPressed: () { + showDialog( + context: context, + builder: (context) { + return const ProfilesSortModal(); + }, + ); + }, + icon: const Icon(Icons.sort), + label: Text(t.general.sort), + ), + FilledButton.icon( + onPressed: () async { + await ref + .read( + foregroundProfilesUpdateNotifierProvider.notifier, + ) + .trigger(); + }, + icon: const Icon(Icons.update), + label: Text(t.profile.update.updateSubscriptions), + ), + ], ), - AsyncError(:final error) => SliverErrorBodyPlaceholder( - t.presentShortError(error), - ), - AsyncLoading() => const SliverLoadingBodyPlaceholder(), - _ => const SliverToBoxAdapter(), - }, - const SliverGap(48), - ], - ), - Positioned.fill( - child: Align( - alignment: Alignment.bottomCenter, - child: Padding( - padding: const EdgeInsets.symmetric(vertical: 8), - child: Wrap( - alignment: WrapAlignment.center, - spacing: 8, - children: [ - FilledButton.icon( - onPressed: () { - const AddProfileRoute().push(context); - }, - icon: const Icon(Icons.add), - label: Text(t.profile.add.shortBtnTxt), - ), - FilledButton.icon( - onPressed: () { - showDialog( - context: context, - builder: (context) { - return const ProfilesSortModal(); - }, - ); - }, - icon: const Icon(Icons.sort), - label: Text(t.general.sort), - ), - FilledButton.icon( - onPressed: () async { - await ref - .read( - foregroundProfilesUpdateNotifierProvider.notifier, - ) - .trigger(); - }, - icon: const Icon(Icons.update), - label: Text(t.profile.update.updateSubscriptions), - ), - ], ), ), ), - ), - ], + ], + ), ); } }