From aa898441f25136b4c40171c8c6e0b8be1fbe02e6 Mon Sep 17 00:00:00 2001 From: jaap aarts Date: Wed, 12 Oct 2022 20:01:58 +0200 Subject: [PATCH 01/14] Add a safearea around all the screens --- lib/routes.dart | 63 +++-- lib/ui/screens/albums_screen.dart | 26 +- lib/ui/screens/calendar_screen.dart | 26 +- lib/ui/screens/event_admin_screen.dart | 40 +-- lib/ui/screens/event_screen.dart | 99 +++---- lib/ui/screens/food_admin_screen.dart | 38 +-- lib/ui/screens/food_screen.dart | 42 +-- lib/ui/screens/login_screen.dart | 94 +++---- lib/ui/screens/members_screen.dart | 26 +- lib/ui/screens/profile_screen.dart | 94 +++---- lib/ui/screens/registration_screen.dart | 328 ++++++++++++------------ lib/ui/screens/settings_screen.dart | 181 +++++++------ lib/ui/screens/welcome_screen.dart | 58 +++-- 13 files changed, 576 insertions(+), 539 deletions(-) diff --git a/lib/routes.dart b/lib/routes.dart index 8a86ea636..e84624fb4 100644 --- a/lib/routes.dart +++ b/lib/routes.dart @@ -50,31 +50,28 @@ final List routes = [ ), routes: [ GoRoute( - path: 'sales/order/:pk/pay', - name: 'sales-order-pay', - pageBuilder: (context, state) { - return CustomTransitionPage( - barrierColor: Colors.black54, - opaque: false, - transitionDuration: const Duration(milliseconds: 150), - transitionsBuilder: ( - context, - animation, - secondaryAnimation, - child, - ) { - return FadeTransition( - opacity: CurvedAnimation( - parent: animation, - curve: Curves.easeOut, - ), - child: child, - ); - }, - child: SalesOrderDialog(pk: state.params['pk']!), - ); - }, - ), + path: 'sales/order/:pk/pay', + name: 'sales-order-pay', + pageBuilder: (context, state) => CustomTransitionPage( + barrierColor: Colors.black54, + opaque: false, + transitionDuration: const Duration(milliseconds: 150), + transitionsBuilder: ( + context, + animation, + secondaryAnimation, + child, + ) { + return FadeTransition( + opacity: CurvedAnimation( + parent: animation, + curve: Curves.easeOut, + ), + child: child, + ); + }, + child: SalesOrderDialog(pk: state.params['pk']!), + )), ]), GoRoute( path: '/events', @@ -373,15 +370,13 @@ final List routes = [ GoRoute( path: '/pizzas', name: 'food', - pageBuilder: (context, state) { - return MaterialPage( - key: state.pageKey, - child: FoodScreen( - pk: (state.extra as Event?)?.foodEvent, - event: state.extra as Event?, - ), - ); - }, + pageBuilder: (context, state) => MaterialPage( + key: state.pageKey, + child: FoodScreen( + pk: (state.extra as Event?)?.foodEvent, + event: state.extra as Event?, + ), + ), routes: [ GoRoute( path: 'admin', diff --git a/lib/ui/screens/albums_screen.dart b/lib/ui/screens/albums_screen.dart index 9405f82d5..3fddeba0f 100644 --- a/lib/ui/screens/albums_screen.dart +++ b/lib/ui/screens/albums_screen.dart @@ -66,18 +66,20 @@ class _AlbumsScreenState extends State { onRefresh: () async { await _cubit.load(); }, - child: BlocBuilder( - builder: (context, listState) { - if (listState.hasException) { - return ErrorScrollView(listState.message!); - } else { - return AlbumListScrollView( - key: const PageStorageKey('albums'), - controller: _controller, - listState: listState, - ); - } - }, + child: SafeArea( + child: BlocBuilder( + builder: (context, listState) { + if (listState.hasException) { + return ErrorScrollView(listState.message!); + } else { + return AlbumListScrollView( + key: const PageStorageKey('albums'), + controller: _controller, + listState: listState, + ); + } + }, + ), ), ), ); diff --git a/lib/ui/screens/calendar_screen.dart b/lib/ui/screens/calendar_screen.dart index eec6f86a5..8f03608dd 100644 --- a/lib/ui/screens/calendar_screen.dart +++ b/lib/ui/screens/calendar_screen.dart @@ -73,18 +73,20 @@ class _CalendarScreenState extends State { onRefresh: () async { await _cubit.load(); }, - child: BlocBuilder( - builder: (context, calendarState) { - if (calendarState.hasException) { - return ErrorScrollView(calendarState.message!); - } else { - return CalendarScrollView( - key: const PageStorageKey('calendar'), - controller: _controller, - calendarState: calendarState, - ); - } - }, + child: SafeArea( + child: BlocBuilder( + builder: (context, calendarState) { + if (calendarState.hasException) { + return ErrorScrollView(calendarState.message!); + } else { + return CalendarScrollView( + key: const PageStorageKey('calendar'), + controller: _controller, + calendarState: calendarState, + ); + } + }, + ), ), ), ); diff --git a/lib/ui/screens/event_admin_screen.dart b/lib/ui/screens/event_admin_screen.dart index 9f8b3eff1..6caf8de8e 100644 --- a/lib/ui/screens/event_admin_screen.dart +++ b/lib/ui/screens/event_admin_screen.dart @@ -41,26 +41,28 @@ class _EventAdminScreenState extends State { context, ).loadRegistrations(); }, - child: BlocBuilder( - builder: (context, state) { - if (state.hasException) { - return ErrorScrollView(state.message!); - } else if (state.isLoading) { - return const Center(child: CircularProgressIndicator()); - } else { - return Scrollbar( - child: ListView.separated( - key: const PageStorageKey('event-admin'), - itemBuilder: (context, index) => _RegistrationTile( - registration: state.registrations[index], - requiresPayment: state.event!.paymentIsRequired, + child: SafeArea( + child: BlocBuilder( + builder: (context, state) { + if (state.hasException) { + return ErrorScrollView(state.message!); + } else if (state.isLoading) { + return const Center(child: CircularProgressIndicator()); + } else { + return Scrollbar( + child: ListView.separated( + key: const PageStorageKey('event-admin'), + itemBuilder: (context, index) => _RegistrationTile( + registration: state.registrations[index], + requiresPayment: state.event!.paymentIsRequired, + ), + separatorBuilder: (_, __) => const Divider(), + itemCount: state.registrations.length, ), - separatorBuilder: (_, __) => const Divider(), - itemCount: state.registrations.length, - ), - ); - } - }, + ); + } + }, + ), ), ), ); diff --git a/lib/ui/screens/event_screen.dart b/lib/ui/screens/event_screen.dart index b594ca7f1..1ca858a02 100644 --- a/lib/ui/screens/event_screen.dart +++ b/lib/ui/screens/event_screen.dart @@ -898,24 +898,23 @@ class _EventScreenState extends State { actions: [_makeShareEventButton(widget.pk)], ), body: RefreshIndicator( - onRefresh: () async { - // Await only the event info. - _registrationsCubit.load(); - await _eventCubit.load(); - }, - child: ErrorScrollView(state.message!), - ), + onRefresh: () async { + // Await only the event info. + _registrationsCubit.load(); + await _eventCubit.load(); + }, + child: SafeArea(child: ErrorScrollView(state.message!))), ); } else if (state.isLoading && widget.event == null && state.result == null) { return Scaffold( - appBar: ThaliaAppBar( - title: const Text('EVENT'), - actions: [_makeShareEventButton(widget.pk)], - ), - body: const Center(child: CircularProgressIndicator()), - ); + appBar: ThaliaAppBar( + title: const Text('EVENT'), + actions: [_makeShareEventButton(widget.pk)], + ), + body: const SafeArea( + child: Center(child: CircularProgressIndicator()))); } else { final event = (state.result ?? widget.event)!; return Scaffold( @@ -941,46 +940,48 @@ class _EventScreenState extends State { _registrationsCubit.load(); await _eventCubit.load(); }, - child: BlocBuilder( - bloc: _registrationsCubit, - builder: (context, listState) { - return Scrollbar( - controller: _controller, - child: CustomScrollView( + child: SafeArea( + child: BlocBuilder( + bloc: _registrationsCubit, + builder: (context, listState) { + return Scrollbar( controller: _controller, - key: const PageStorageKey('event'), - slivers: [ - SliverToBoxAdapter( - child: Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - _makeMap(event), - const Divider(height: 0), - _makeEventInfo(event), - const Divider(), - _makeDescription(event), - ], + child: CustomScrollView( + controller: _controller, + key: const PageStorageKey('event'), + slivers: [ + SliverToBoxAdapter( + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + _makeMap(event), + const Divider(height: 0), + _makeEventInfo(event), + const Divider(), + _makeDescription(event), + ], + ), ), - ), - if (event.registrationIsOptional || - event.registrationIsRequired) ...[ - const SliverToBoxAdapter(child: Divider()), - _makeRegistrationsHeader(listState), - _makeRegistrations(listState), - if (listState.isLoadingMore) - const SliverPadding( - padding: EdgeInsets.all(8), - sliver: SliverList( - delegate: SliverChildListDelegate.fixed([ - Center(child: CircularProgressIndicator()), - ]), + if (event.registrationIsOptional || + event.registrationIsRequired) ...[ + const SliverToBoxAdapter(child: Divider()), + _makeRegistrationsHeader(listState), + _makeRegistrations(listState), + if (listState.isLoadingMore) + const SliverPadding( + padding: EdgeInsets.all(8), + sliver: SliverList( + delegate: SliverChildListDelegate.fixed([ + Center(child: CircularProgressIndicator()), + ]), + ), ), - ), + ], ], - ], - ), - ); - }, + ), + ); + }, + ), ), ), ); diff --git a/lib/ui/screens/food_admin_screen.dart b/lib/ui/screens/food_admin_screen.dart index f0e72ff69..a1a45bfc9 100644 --- a/lib/ui/screens/food_admin_screen.dart +++ b/lib/ui/screens/food_admin_screen.dart @@ -60,24 +60,26 @@ class _FoodAdminScreenState extends State { onRefresh: () async { await BlocProvider.of(context).load(); }, - child: BlocBuilder( - builder: (context, state) { - if (state.hasException) { - return ErrorScrollView(state.message!); - } else if (state.isLoading) { - return const Center(child: CircularProgressIndicator()); - } else { - return Scrollbar( - child: ListView.separated( - key: const PageStorageKey('food-admin'), - itemBuilder: (context, index) => _OrderTile( - order: state.result![index], - ), - separatorBuilder: (_, __) => const Divider(), - itemCount: state.result!.length, - )); - } - }, + child: SafeArea( + child: BlocBuilder( + builder: (context, state) { + if (state.hasException) { + return ErrorScrollView(state.message!); + } else if (state.isLoading) { + return const Center(child: CircularProgressIndicator()); + } else { + return Scrollbar( + child: ListView.separated( + key: const PageStorageKey('food-admin'), + itemBuilder: (context, index) => _OrderTile( + order: state.result![index], + ), + separatorBuilder: (_, __) => const Divider(), + itemCount: state.result!.length, + )); + } + }, + ), ), ), ); diff --git a/lib/ui/screens/food_screen.dart b/lib/ui/screens/food_screen.dart index be545b88c..ca6f1b183 100644 --- a/lib/ui/screens/food_screen.dart +++ b/lib/ui/screens/food_screen.dart @@ -349,27 +349,29 @@ class _FoodScreenState extends State { ), body: RefreshIndicator( onRefresh: () => _foodCubit.load(), - child: ListView( - key: const PageStorageKey('food'), - controller: _controller, - physics: const AlwaysScrollableScrollPhysics(), - padding: const EdgeInsets.all(16), - children: [ - _makeEventInfo(foodEvent), - _makeOrderInfo(foodEvent), - const Divider(), - Card( - child: Column( - children: ListTile.divideTiles( - context: context, - tiles: [ - for (final product in products!) - _ProductTile(product) - ], - ).toList(), + child: SafeArea( + child: ListView( + key: const PageStorageKey('food'), + controller: _controller, + physics: const AlwaysScrollableScrollPhysics(), + padding: const EdgeInsets.all(16), + children: [ + _makeEventInfo(foodEvent), + _makeOrderInfo(foodEvent), + const Divider(), + Card( + child: Column( + children: ListTile.divideTiles( + context: context, + tiles: [ + for (final product in products!) + _ProductTile(product) + ], + ).toList(), + ), ), - ), - ], + ], + ), ), ), ); diff --git a/lib/ui/screens/login_screen.dart b/lib/ui/screens/login_screen.dart index efe7a202b..e095b71dc 100644 --- a/lib/ui/screens/login_screen.dart +++ b/lib/ui/screens/login_screen.dart @@ -29,59 +29,63 @@ class _LoginScreenState extends State { builder: (context, authState) { if (authState is LoadingAuthState) { return Scaffold( - backgroundColor: const Color(0xFFE62272), - body: Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - Center( - child: Image( - image: logo, - width: 260, - ), - ), - const SizedBox(height: 50), - const SizedBox( - height: 50, - child: Center( - child: CircularProgressIndicator( - valueColor: AlwaysStoppedAnimation(Colors.white), + backgroundColor: const Color(0xFFE62272), + body: SafeArea( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Center( + child: Image( + image: logo, + width: 260, + ), ), - ), + const SizedBox(height: 50), + const SizedBox( + height: 50, + child: Center( + child: CircularProgressIndicator( + valueColor: + AlwaysStoppedAnimation(Colors.white), + ), + ), + ), + ], ), - ], - ), - ); + )); } else { return Scaffold( backgroundColor: magenta, - body: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Center( - child: Image( - image: logo, - width: 260, + body: SafeArea( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Center( + child: Image( + image: logo, + width: 260, + ), ), - ), - const SizedBox(height: 50), - SizedBox( - height: 50, - child: ElevatedButton( - style: ElevatedButton.styleFrom( - backgroundColor: Colors.black87, - foregroundColor: Colors.white, + const SizedBox(height: 50), + SizedBox( + height: 50, + child: ElevatedButton( + style: ElevatedButton.styleFrom( + primary: Colors.black87, + onPrimary: Colors.white, + ), + onPressed: () { + BlocProvider.of( + context, + listen: false, + ).logIn(); + }, + child: const Text('LOGIN'), ), - onPressed: () { - BlocProvider.of( - context, - listen: false, - ).logIn(); - }, - child: const Text('LOGIN'), ), - ), - ], + ], + ), ), ); } diff --git a/lib/ui/screens/members_screen.dart b/lib/ui/screens/members_screen.dart index 867c1eb68..e05edbc84 100644 --- a/lib/ui/screens/members_screen.dart +++ b/lib/ui/screens/members_screen.dart @@ -66,18 +66,20 @@ class _MembersScreenState extends State { onRefresh: () async { await _cubit.load(); }, - child: BlocBuilder( - builder: (context, listState) { - if (listState.hasException) { - return ErrorScrollView(listState.message!); - } else { - return MemberListScrollView( - key: const PageStorageKey('members'), - controller: _controller, - listState: listState, - ); - } - }, + child: SafeArea( + child: BlocBuilder( + builder: (context, listState) { + if (listState.hasException) { + return ErrorScrollView(listState.message!); + } else { + return MemberListScrollView( + key: const PageStorageKey('members'), + controller: _controller, + listState: listState, + ); + } + }, + ), ), ), ); diff --git a/lib/ui/screens/profile_screen.dart b/lib/ui/screens/profile_screen.dart index 7bb5f8a79..428d811db 100644 --- a/lib/ui/screens/profile_screen.dart +++ b/lib/ui/screens/profile_screen.dart @@ -458,54 +458,56 @@ class _ProfileScreenState extends State { @override Widget build(BuildContext context) { return Scaffold( - body: BlocBuilder( - bloc: _memberCubit, - builder: (context, state) { - if (state.hasException) { - return CustomScrollView( - controller: _scrollController, - slivers: [ - _makeAppBar(), - SliverFillRemaining( - child: ErrorCenter(state.message!), - ), - ], - ); - } else if (state.isLoading && widget.member == null) { - return CustomScrollView( - controller: _scrollController, - slivers: [ - _makeAppBar(), - const SliverFillRemaining( - child: Center(child: CircularProgressIndicator()), - ), - ], - ); - } else { - return CustomScrollView( - key: const PageStorageKey('profile'), - controller: _scrollController, - slivers: [ - _makeAppBar((state.result ?? widget.member)!), - _makeFactsSliver((state.result ?? widget.member)!), - if (!state.isLoading) ...[ - if (state.result!.achievements.isNotEmpty) - _makeAchievementsSliver(state.result!), - if (state.result!.societies.isNotEmpty) - _makeSocietiesSliver(state.result!), - ] else ...[ - const SliverPadding( - padding: EdgeInsets.all(16), - sliver: SliverToBoxAdapter( - child: Center(child: CircularProgressIndicator()), - ), + body: SafeArea( + child: BlocBuilder( + bloc: _memberCubit, + builder: (context, state) { + if (state.hasException) { + return CustomScrollView( + controller: _scrollController, + slivers: [ + _makeAppBar(), + SliverFillRemaining( + child: ErrorCenter(state.message!), ), ], - const SliverToBoxAdapter(child: SizedBox(height: 32)) - ], - ); - } - }, + ); + } else if (state.isLoading && widget.member == null) { + return CustomScrollView( + controller: _scrollController, + slivers: [ + _makeAppBar(), + const SliverFillRemaining( + child: Center(child: CircularProgressIndicator()), + ), + ], + ); + } else { + return CustomScrollView( + key: const PageStorageKey('profile'), + controller: _scrollController, + slivers: [ + _makeAppBar((state.result ?? widget.member)!), + _makeFactsSliver((state.result ?? widget.member)!), + if (!state.isLoading) ...[ + if (state.result!.achievements.isNotEmpty) + _makeAchievementsSliver(state.result!), + if (state.result!.societies.isNotEmpty) + _makeSocietiesSliver(state.result!), + ] else ...[ + const SliverPadding( + padding: EdgeInsets.all(16), + sliver: SliverToBoxAdapter( + child: Center(child: CircularProgressIndicator()), + ), + ), + ], + const SliverToBoxAdapter(child: SizedBox(height: 32)) + ], + ); + } + }, + ), ), ); } diff --git a/lib/ui/screens/registration_screen.dart b/lib/ui/screens/registration_screen.dart index a68f81914..d8929a637 100644 --- a/lib/ui/screens/registration_screen.dart +++ b/lib/ui/screens/registration_screen.dart @@ -42,193 +42,195 @@ class _RegistrationScreenState extends State { @override Widget build(BuildContext context) { - return BlocBuilder( - bloc: _registrationFieldsCubit, - builder: (context, state) { - if (state.hasException) { - return Scaffold( - appBar: ThaliaAppBar( - title: const Text('REGISTRATION'), - leading: const CloseButton(), - ), - body: ErrorCenter(state.message!), - ); - } else if (state.isLoading) { + return SafeArea( + child: BlocBuilder( + bloc: _registrationFieldsCubit, + builder: (context, state) { + if (state.hasException) { + return Scaffold( + appBar: ThaliaAppBar( + title: const Text('REGISTRATION'), + leading: const CloseButton(), + ), + body: ErrorCenter(state.message!), + ); + } else if (state.isLoading) { + return Scaffold( + appBar: ThaliaAppBar( + title: const Text('REGISTRATION'), + leading: const CloseButton(), + ), + body: const Center(child: CircularProgressIndicator()), + ); + } else {} return Scaffold( appBar: ThaliaAppBar( title: const Text('REGISTRATION'), leading: const CloseButton(), ), - body: const Center(child: CircularProgressIndicator()), - ); - } else {} - return Scaffold( - appBar: ThaliaAppBar( - title: const Text('REGISTRATION'), - leading: const CloseButton(), - ), - body: SingleChildScrollView( - child: Form( - key: _formKey, - child: Column( - children: [ - ...state.result!.entries.map((entry) { - final field = entry.value; - if (field is TextRegistrationField) { - return Column( - children: [ - ListTile( - title: Text(field.label), - subtitle: field.description.isNotEmpty - ? Text(field.description) - : null, - ), - Padding( - padding: const EdgeInsets.only( - left: 16, - bottom: 16, - right: 16, + body: SingleChildScrollView( + child: Form( + key: _formKey, + child: Column( + children: [ + ...state.result!.entries.map((entry) { + final field = entry.value; + if (field is TextRegistrationField) { + return Column( + children: [ + ListTile( + title: Text(field.label), + subtitle: field.description.isNotEmpty + ? Text(field.description) + : null, ), - child: TextFormField( - initialValue: field.value, - minLines: 1, - maxLines: 5, - decoration: InputDecoration( - labelText: field.isRequired - ? '${field.label} *' - : field.label, - hintText: 'Lorem ipsum...', + Padding( + padding: const EdgeInsets.only( + left: 16, + bottom: 16, + right: 16, + ), + child: TextFormField( + initialValue: field.value, + minLines: 1, + maxLines: 5, + decoration: InputDecoration( + labelText: field.isRequired + ? '${field.label} *' + : field.label, + hintText: 'Lorem ipsum...', + ), + validator: (value) { + if (field.isRequired && + (value == null || value.isEmpty)) { + return 'Please fill in this field.'; + } + return null; + }, + onSaved: (newValue) => field.value = newValue, ), - validator: (value) { - if (field.isRequired && - (value == null || value.isEmpty)) { - return 'Please fill in this field.'; - } - return null; - }, - onSaved: (newValue) => field.value = newValue, ), - ), - ], - ); - } else if (field is IntegerRegistrationField) { - return Column( - children: [ - ListTile( - dense: field.description.isEmpty, + ], + ); + } else if (field is IntegerRegistrationField) { + return Column( + children: [ + ListTile( + dense: field.description.isEmpty, + title: Text(field.label), + subtitle: field.description.isNotEmpty + ? Text(field.description) + : null, + ), + Padding( + padding: const EdgeInsets.only( + left: 16, + right: 16, + bottom: 16, + ), + child: TextFormField( + keyboardType: TextInputType.number, + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly + ], + decoration: InputDecoration( + labelText: field.isRequired + ? '${field.label} *' + : field.label, + hintText: '123...', + ), + initialValue: field.value?.toString(), + validator: (value) { + if (field.isRequired && + (value == null || value.isEmpty)) { + return 'Please fill in this field.'; + } + return null; + }, + onSaved: (newValue) => + field.value = int.tryParse(newValue!), + ), + ), + ], + ); + } else if (field is CheckboxRegistrationField) { + return Padding( + padding: const EdgeInsets.only(bottom: 16), + child: _CheckboxFormField( + initialValue: field.value ?? false, + onSaved: (newValue) => field.value = newValue, title: Text(field.label), subtitle: field.description.isNotEmpty ? Text(field.description) : null, ), - Padding( - padding: const EdgeInsets.only( - left: 16, - right: 16, - bottom: 16, - ), - child: TextFormField( - keyboardType: TextInputType.number, - inputFormatters: [ - FilteringTextInputFormatter.digitsOnly - ], - decoration: InputDecoration( - labelText: field.isRequired - ? '${field.label} *' - : field.label, - hintText: '123...', - ), - initialValue: field.value?.toString(), - validator: (value) { - if (field.isRequired && - (value == null || value.isEmpty)) { - return 'Please fill in this field.'; - } - return null; - }, - onSaved: (newValue) => - field.value = int.tryParse(newValue!), - ), + ); + } else { + return const SizedBox(height: 0); + } + }), + Padding( + padding: const EdgeInsets.all(16), + child: Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + TextButton.icon( + onPressed: () { + _formKey.currentState!.reset(); + }, + icon: const Icon(Icons.restore_page_outlined), + label: const Text('RESTORE'), ), - ], - ); - } else if (field is CheckboxRegistrationField) { - return Padding( - padding: const EdgeInsets.only(bottom: 16), - child: _CheckboxFormField( - initialValue: field.value ?? false, - onSaved: (newValue) => field.value = newValue, - title: Text(field.label), - subtitle: field.description.isNotEmpty - ? Text(field.description) - : null, - ), - ); - } else { - return const SizedBox(height: 0); - } - }), - Padding( - padding: const EdgeInsets.all(16), - child: Row( - mainAxisAlignment: MainAxisAlignment.end, - children: [ - TextButton.icon( - onPressed: () { - _formKey.currentState!.reset(); - }, - icon: const Icon(Icons.restore_page_outlined), - label: const Text('RESTORE'), - ), - const SizedBox(width: 16), - ElevatedButton.icon( - onPressed: () async { - if (_formKey.currentState!.validate()) { - _formKey.currentState!.save(); + const SizedBox(width: 16), + ElevatedButton.icon( + onPressed: () async { + if (_formKey.currentState!.validate()) { + _formKey.currentState!.save(); - final messenger = ScaffoldMessenger.of(context); + final messenger = ScaffoldMessenger.of(context); - try { - await _registrationFieldsCubit.update( - eventPk: widget.eventPk, - registrationPk: widget.registrationPk, - fields: state.result!, - ); + try { + await _registrationFieldsCubit.update( + eventPk: widget.eventPk, + registrationPk: widget.registrationPk, + fields: state.result!, + ); - if (mounted) Navigator.of(context).pop(); + if (mounted) Navigator.of(context).pop(); - messenger.showSnackBar( - const SnackBar( - behavior: SnackBarBehavior.floating, - content: Text( - 'Your registration has been updated.', + messenger.showSnackBar( + const SnackBar( + behavior: SnackBarBehavior.floating, + content: Text( + 'Your registration has been updated.', + ), ), - ), - ); - } on ApiException { - messenger.showSnackBar( - const SnackBar( - behavior: SnackBarBehavior.floating, - content: Text( - 'Could not update your registration.', + ); + } on ApiException { + messenger.showSnackBar( + const SnackBar( + behavior: SnackBarBehavior.floating, + content: Text( + 'Could not update your registration.', + ), ), - ), - ); + ); + } } - } - }, - icon: const Icon(Icons.check), - label: const Text('SUBMIT'), - ), - ], + }, + icon: const Icon(Icons.check), + label: const Text('SUBMIT'), + ), + ], + ), ), - ), - ], + ], + ), ), ), - ), - ); - }, + ); + }, + ), ); } } diff --git a/lib/ui/screens/settings_screen.dart b/lib/ui/screens/settings_screen.dart index d51264637..b221739c0 100644 --- a/lib/ui/screens/settings_screen.dart +++ b/lib/ui/screens/settings_screen.dart @@ -14,107 +14,126 @@ class SettingsScreen extends StatelessWidget { return Scaffold( appBar: ThaliaAppBar(title: const Text('SETTINGS')), drawer: MenuDrawer(), - body: BlocBuilder( - builder: (context, state) { - if (state.hasException) { - return RefreshIndicator( - onRefresh: () => BlocProvider.of(context).load(), - child: ListView( + body: SafeArea( + child: BlocBuilder( + builder: (context, state) { + if (state.hasException) { + return RefreshIndicator( + onRefresh: () => BlocProvider.of(context).load(), + child: ListView( + padding: const EdgeInsets.all(16), + children: [ + Text('THEME', style: textTheme.caption), + const _ThemeModeCard(), + const SizedBox(height: 8), + Text('NOTIFICATIONS', style: textTheme.caption), + Center(child: Text(state.message!)), + const SizedBox(height: 8), + Text('ABOUT', style: textTheme.caption), + const _AboutCard(), + ], + ), + ); + } else if (state.isLoading && state.categories == null) { + return ListView( padding: const EdgeInsets.all(16), children: [ Text('THEME', style: textTheme.caption), const _ThemeModeCard(), const SizedBox(height: 8), Text('NOTIFICATIONS', style: textTheme.caption), - Center(child: Text(state.message!)), + const Padding( + padding: EdgeInsets.symmetric(vertical: 16), + child: Center(child: CircularProgressIndicator()), + ), const SizedBox(height: 8), Text('ABOUT', style: textTheme.caption), const _AboutCard(), const SizedBox(height: 8), const _LogOutButton(), ], - ), - ); - } else if (state.isLoading && state.categories == null) { - return ListView( - padding: const EdgeInsets.all(16), - children: [ - Text('THEME', style: textTheme.caption), - const _ThemeModeCard(), - const SizedBox(height: 8), - Text('NOTIFICATIONS', style: textTheme.caption), - const Padding( - padding: EdgeInsets.symmetric(vertical: 16), - child: Center(child: CircularProgressIndicator()), - ), - const SizedBox(height: 8), - Text('ABOUT', style: textTheme.caption), - const _AboutCard(), - const SizedBox(height: 8), - const _LogOutButton(), - ], - ); - } else { - return ListView( - padding: const EdgeInsets.all(16), - children: [ - Text('THEME', style: textTheme.caption), - const _ThemeModeCard(), - const SizedBox(height: 8), - Text('NOTIFICATIONS', style: textTheme.caption), - if (!state.hasPermissions!) ...[ + ); + } else if (state.isLoading && state.categories == null) { + return ListView( + padding: const EdgeInsets.all(16), + children: [ + Text('THEME', style: textTheme.caption), + const _ThemeModeCard(), + const SizedBox(height: 8), + Text('NOTIFICATIONS', style: textTheme.caption), + const Padding( + padding: EdgeInsets.symmetric(vertical: 16), + child: Center(child: CircularProgressIndicator()), + ), + const SizedBox(height: 8), + Text('ABOUT', style: textTheme.caption), + const _AboutCard(), + const SizedBox(height: 8), + const _LogOutButton(), + ], + ); + } else { + return ListView( + padding: const EdgeInsets.all(16), + children: [ + Text('THEME', style: textTheme.caption), + const _ThemeModeCard(), + const SizedBox(height: 8), + Text('NOTIFICATIONS', style: textTheme.caption), + if (!state.hasPermissions!) ...[ + Card( + margin: const EdgeInsets.symmetric(vertical: 8), + child: Padding( + padding: const EdgeInsets.all(4), + child: Row( + children: [ + const Padding( + padding: EdgeInsets.all(12), + child: Icon(Icons.notifications_off_outlined), + ), + Expanded( + child: Text( + 'Notifications are disabled. Enable ' + 'them in your device settings.', + style: textTheme.bodyText2!.copyWith( + color: textTheme.caption!.color, + ), + ), + ), + ], + ), + ), + ), + ], Card( margin: const EdgeInsets.symmetric(vertical: 8), - child: Padding( - padding: const EdgeInsets.all(4), - child: Row( - children: [ - const Padding( - padding: EdgeInsets.all(12), - child: Icon(Icons.notifications_off_outlined), - ), - Expanded( - child: Text( - 'Notifications are disabled. Enable ' - 'them in your device settings.', - style: textTheme.bodyText2!.copyWith( - color: textTheme.caption!.color, + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: ListTile.divideTiles( + context: context, + tiles: [ + for (final category in state.categories!) + _NotificationSettingTile( + category: category, + enabled: state.device!.receiveCategory.contains( + category.key, ), ), - ), ], - ), + ).toList(), ), ), + const SizedBox(height: 8), + Text('ABOUT', style: textTheme.caption), + const _AboutCard(), + const SizedBox(height: 8), + const _LogOutButton(), ], - Card( - margin: const EdgeInsets.symmetric(vertical: 8), - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: ListTile.divideTiles( - context: context, - tiles: [ - for (final category in state.categories!) - _NotificationSettingTile( - category: category, - enabled: state.device!.receiveCategory.contains( - category.key, - ), - ), - ], - ).toList(), - ), - ), - const SizedBox(height: 8), - Text('ABOUT', style: textTheme.caption), - const _AboutCard(), - const SizedBox(height: 8), - const _LogOutButton(), - ], - ); - } - }, + ); + } + }, + ), ), ); } diff --git a/lib/ui/screens/welcome_screen.dart b/lib/ui/screens/welcome_screen.dart index 9f83342db..1a6fa52e1 100644 --- a/lib/ui/screens/welcome_screen.dart +++ b/lib/ui/screens/welcome_screen.dart @@ -165,34 +165,36 @@ class _WelcomeScreenState extends State { return Scaffold( appBar: ThaliaAppBar(title: const Text('WELCOME')), drawer: MenuDrawer(), - body: RefreshIndicator( - onRefresh: () => BlocProvider.of(context).load(), - child: BlocBuilder( - builder: (context, state) { - if (state.hasException) { - return ErrorScrollView(state.message!); - } else if (!state.hasResults) { - return const Center(child: CircularProgressIndicator()); - } else { - return Scrollbar( - child: ListView( - key: const PageStorageKey('welcome'), - physics: const AlwaysScrollableScrollPhysics(), - children: [ - _makeSlides(state.slides!), - if (state.slides!.isNotEmpty) const Divider(height: 0), - _makeArticles(state.articles!), - if (state.articles!.isNotEmpty) - const Divider(indent: 16, endIndent: 16, height: 8), - _makeUpcomingEvents(state.upcomingEvents!), - TextButton( - onPressed: () => context.goNamed('calendar'), - child: const Text('SHOW THE ENTIRE AGENDA'), - ), - ], - )); - } - }, + body: SafeArea( + child: RefreshIndicator( + onRefresh: () => BlocProvider.of(context).load(), + child: BlocBuilder( + builder: (context, state) { + if (state.hasException) { + return ErrorScrollView(state.message!); + } else if (!state.hasResults) { + return const Center(child: CircularProgressIndicator()); + } else { + return Scrollbar( + child: ListView( + key: const PageStorageKey('welcome'), + physics: const AlwaysScrollableScrollPhysics(), + children: [ + _makeSlides(state.slides!), + if (state.slides!.isNotEmpty) const Divider(height: 0), + _makeArticles(state.articles!), + if (state.articles!.isNotEmpty) + const Divider(indent: 16, endIndent: 16, height: 8), + _makeUpcomingEvents(state.upcomingEvents!), + TextButton( + onPressed: () => context.goNamed('calendar'), + child: const Text('SHOW THE ENTIRE AGENDA'), + ), + ], + )); + } + }, + ), ), ), ); From 72718310dd143f33d92f6edb74fcd4283f904682 Mon Sep 17 00:00:00 2001 From: jaap aarts Date: Fri, 2 Dec 2022 15:03:52 +0100 Subject: [PATCH 02/14] Redo the safearea for all screens This fixes lists not scrolling under the safearea, and works around issues with CustomScrollView --- lib/ui/screens/albums_screen.dart | 26 +- lib/ui/screens/event_admin_screen.dart | 40 ++- lib/ui/screens/event_screen.dart | 30 ++- lib/ui/screens/food_admin_screen.dart | 39 ++- lib/ui/screens/food_screen.dart | 42 ++- lib/ui/screens/group_screen.dart | 76 +++--- lib/ui/screens/groups_screen.dart | 58 +++-- lib/ui/screens/members_screen.dart | 11 +- lib/ui/screens/profile_screen.dart | 50 ++-- lib/ui/screens/registration_screen.dart | 327 ++++++++++++------------ lib/ui/screens/settings_screen.dart | 202 ++++++++------- lib/ui/screens/welcome_screen.dart | 48 ++-- 12 files changed, 500 insertions(+), 449 deletions(-) diff --git a/lib/ui/screens/albums_screen.dart b/lib/ui/screens/albums_screen.dart index 3fddeba0f..9405f82d5 100644 --- a/lib/ui/screens/albums_screen.dart +++ b/lib/ui/screens/albums_screen.dart @@ -66,20 +66,18 @@ class _AlbumsScreenState extends State { onRefresh: () async { await _cubit.load(); }, - child: SafeArea( - child: BlocBuilder( - builder: (context, listState) { - if (listState.hasException) { - return ErrorScrollView(listState.message!); - } else { - return AlbumListScrollView( - key: const PageStorageKey('albums'), - controller: _controller, - listState: listState, - ); - } - }, - ), + child: BlocBuilder( + builder: (context, listState) { + if (listState.hasException) { + return ErrorScrollView(listState.message!); + } else { + return AlbumListScrollView( + key: const PageStorageKey('albums'), + controller: _controller, + listState: listState, + ); + } + }, ), ), ); diff --git a/lib/ui/screens/event_admin_screen.dart b/lib/ui/screens/event_admin_screen.dart index 6caf8de8e..9f8b3eff1 100644 --- a/lib/ui/screens/event_admin_screen.dart +++ b/lib/ui/screens/event_admin_screen.dart @@ -41,28 +41,26 @@ class _EventAdminScreenState extends State { context, ).loadRegistrations(); }, - child: SafeArea( - child: BlocBuilder( - builder: (context, state) { - if (state.hasException) { - return ErrorScrollView(state.message!); - } else if (state.isLoading) { - return const Center(child: CircularProgressIndicator()); - } else { - return Scrollbar( - child: ListView.separated( - key: const PageStorageKey('event-admin'), - itemBuilder: (context, index) => _RegistrationTile( - registration: state.registrations[index], - requiresPayment: state.event!.paymentIsRequired, - ), - separatorBuilder: (_, __) => const Divider(), - itemCount: state.registrations.length, + child: BlocBuilder( + builder: (context, state) { + if (state.hasException) { + return ErrorScrollView(state.message!); + } else if (state.isLoading) { + return const Center(child: CircularProgressIndicator()); + } else { + return Scrollbar( + child: ListView.separated( + key: const PageStorageKey('event-admin'), + itemBuilder: (context, index) => _RegistrationTile( + registration: state.registrations[index], + requiresPayment: state.event!.paymentIsRequired, ), - ); - } - }, - ), + separatorBuilder: (_, __) => const Divider(), + itemCount: state.registrations.length, + ), + ); + } + }, ), ), ); diff --git a/lib/ui/screens/event_screen.dart b/lib/ui/screens/event_screen.dart index 1ca858a02..e9c0baf7a 100644 --- a/lib/ui/screens/event_screen.dart +++ b/lib/ui/screens/event_screen.dart @@ -1,6 +1,7 @@ import 'package:add_2_calendar/add_2_calendar.dart' as add2calendar; import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/rendering.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_widget_from_html_core/flutter_widget_from_html_core.dart'; import 'package:go_router/go_router.dart'; @@ -903,7 +904,7 @@ class _EventScreenState extends State { _registrationsCubit.load(); await _eventCubit.load(); }, - child: SafeArea(child: ErrorScrollView(state.message!))), + child: ErrorScrollView(state.message!)), ); } else if (state.isLoading && widget.event == null && @@ -913,8 +914,7 @@ class _EventScreenState extends State { title: const Text('EVENT'), actions: [_makeShareEventButton(widget.pk)], ), - body: const SafeArea( - child: Center(child: CircularProgressIndicator()))); + body: const Center(child: CircularProgressIndicator())); } else { final event = (state.result ?? widget.event)!; return Scaffold( @@ -940,16 +940,20 @@ class _EventScreenState extends State { _registrationsCubit.load(); await _eventCubit.load(); }, - child: SafeArea( - child: BlocBuilder( - bloc: _registrationsCubit, - builder: (context, listState) { - return Scrollbar( - controller: _controller, + child: BlocBuilder( + bloc: _registrationsCubit, + builder: (context, listState) { + return Scrollbar( + controller: _controller, + child: SafeArea( + top: false, + bottom: false, child: CustomScrollView( controller: _controller, key: const PageStorageKey('event'), slivers: [ + const SliverSafeArea( + bottom: false, sliver: SliverToBoxAdapter()), SliverToBoxAdapter( child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, @@ -977,11 +981,13 @@ class _EventScreenState extends State { ), ), ], + const SliverSafeArea( + top: false, sliver: SliverToBoxAdapter()), ], ), - ); - }, - ), + ), + ); + }, ), ), ); diff --git a/lib/ui/screens/food_admin_screen.dart b/lib/ui/screens/food_admin_screen.dart index a1a45bfc9..646e7fba8 100644 --- a/lib/ui/screens/food_admin_screen.dart +++ b/lib/ui/screens/food_admin_screen.dart @@ -60,26 +60,24 @@ class _FoodAdminScreenState extends State { onRefresh: () async { await BlocProvider.of(context).load(); }, - child: SafeArea( - child: BlocBuilder( - builder: (context, state) { - if (state.hasException) { - return ErrorScrollView(state.message!); - } else if (state.isLoading) { - return const Center(child: CircularProgressIndicator()); - } else { - return Scrollbar( - child: ListView.separated( - key: const PageStorageKey('food-admin'), - itemBuilder: (context, index) => _OrderTile( - order: state.result![index], - ), - separatorBuilder: (_, __) => const Divider(), - itemCount: state.result!.length, - )); - } - }, - ), + child: BlocBuilder( + builder: (context, state) { + if (state.hasException) { + return ErrorScrollView(state.message!); + } else if (state.isLoading) { + return const Center(child: CircularProgressIndicator()); + } else { + return Scrollbar( + child: ListView.separated( + key: const PageStorageKey('food-admin'), + itemBuilder: (context, index) => _OrderTile( + order: state.result![index], + ), + separatorBuilder: (_, __) => const Divider(), + itemCount: state.result!.length, + )); + } + }, ), ), ); @@ -89,6 +87,7 @@ class _FoodAdminScreenState extends State { } } +//TODO: This does not carry any state? class _OrderTile extends StatefulWidget { final AdminFoodOrder order; diff --git a/lib/ui/screens/food_screen.dart b/lib/ui/screens/food_screen.dart index ca6f1b183..be545b88c 100644 --- a/lib/ui/screens/food_screen.dart +++ b/lib/ui/screens/food_screen.dart @@ -349,29 +349,27 @@ class _FoodScreenState extends State { ), body: RefreshIndicator( onRefresh: () => _foodCubit.load(), - child: SafeArea( - child: ListView( - key: const PageStorageKey('food'), - controller: _controller, - physics: const AlwaysScrollableScrollPhysics(), - padding: const EdgeInsets.all(16), - children: [ - _makeEventInfo(foodEvent), - _makeOrderInfo(foodEvent), - const Divider(), - Card( - child: Column( - children: ListTile.divideTiles( - context: context, - tiles: [ - for (final product in products!) - _ProductTile(product) - ], - ).toList(), - ), + child: ListView( + key: const PageStorageKey('food'), + controller: _controller, + physics: const AlwaysScrollableScrollPhysics(), + padding: const EdgeInsets.all(16), + children: [ + _makeEventInfo(foodEvent), + _makeOrderInfo(foodEvent), + const Divider(), + Card( + child: Column( + children: ListTile.divideTiles( + context: context, + tiles: [ + for (final product in products!) + _ProductTile(product) + ], + ).toList(), ), - ], - ), + ), + ], ), ), ); diff --git a/lib/ui/screens/group_screen.dart b/lib/ui/screens/group_screen.dart index 2b2630bde..77bc315cd 100644 --- a/lib/ui/screens/group_screen.dart +++ b/lib/ui/screens/group_screen.dart @@ -94,22 +94,30 @@ class _Page extends StatelessWidget { body: RefreshIndicator( onRefresh: () => cubit.load(), child: Scrollbar( - child: CustomScrollView( - key: const PageStorageKey('group'), - slivers: [ - SliverToBoxAdapter( - child: Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - _GroupImage(group: group), - const Divider(height: 0), - _GroupInfo(group: group) - ], + child: SafeArea( + top: false, + bottom: false, + child: CustomScrollView( + key: const PageStorageKey('group'), + slivers: [ + const SliverSafeArea( + bottom: false, sliver: SliverToBoxAdapter()), + SliverToBoxAdapter( + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + _GroupImage(group: group), + const Divider(height: 0), + _GroupInfo(group: group) + ], + ), ), - ), - _MembersHeader(group: group), - const _MembersGrid(members: null), - ], + _MembersHeader(group: group), + const _MembersGrid(members: null), + const SliverSafeArea( + top: false, sliver: SliverToBoxAdapter()), + ], + ), ), ), ), @@ -121,22 +129,30 @@ class _Page extends StatelessWidget { body: RefreshIndicator( onRefresh: () => cubit.load(), child: Scrollbar( - child: CustomScrollView( - key: const PageStorageKey('group'), - slivers: [ - SliverToBoxAdapter( - child: Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - _GroupImage(group: group), - const Divider(height: 0), - _GroupInfo(group: group) - ], + child: SafeArea( + top: false, + bottom: false, + child: CustomScrollView( + key: const PageStorageKey('group'), + slivers: [ + const SliverSafeArea( + bottom: false, sliver: SliverToBoxAdapter()), + SliverToBoxAdapter( + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + _GroupImage(group: group), + const Divider(height: 0), + _GroupInfo(group: group) + ], + ), ), - ), - _MembersHeader(group: group), - _MembersGrid(members: group.members), - ], + _MembersHeader(group: group), + _MembersGrid(members: group.members), + const SliverSafeArea( + top: false, sliver: SliverToBoxAdapter()), + ], + ), ), ), ), diff --git a/lib/ui/screens/groups_screen.dart b/lib/ui/screens/groups_screen.dart index 7b192f932..72a13d942 100644 --- a/lib/ui/screens/groups_screen.dart +++ b/lib/ui/screens/groups_screen.dart @@ -138,36 +138,42 @@ class GroupListScrollView extends StatelessWidget { @override Widget build(BuildContext context) { return Scrollbar( - child: CustomScrollView( - physics: const RangeMaintainingScrollPhysics( - parent: AlwaysScrollableScrollPhysics(), - ), - slivers: [ - if (activeBoard != null) - SliverToBoxAdapter( - child: Padding( - padding: const EdgeInsets.all(8), - child: AspectRatio( - aspectRatio: 3 / 2, - child: GroupTile(group: activeBoard!), + child: SafeArea( + top: false, + bottom: false, + child: CustomScrollView( + physics: const RangeMaintainingScrollPhysics( + parent: AlwaysScrollableScrollPhysics(), + ), + slivers: [ + const SliverSafeArea(bottom: false, sliver: SliverToBoxAdapter()), + if (activeBoard != null) + SliverToBoxAdapter( + child: Padding( + padding: const EdgeInsets.all(8), + child: AspectRatio( + aspectRatio: 3 / 2, + child: GroupTile(group: activeBoard!), + ), ), ), - ), - SliverPadding( - padding: const EdgeInsets.all(8), - sliver: SliverGrid( - gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: 3, - mainAxisSpacing: 8, - crossAxisSpacing: 8, - ), - delegate: SliverChildBuilderDelegate( - (context, index) => GroupTile(group: groups[index]), - childCount: groups.length, + SliverPadding( + padding: const EdgeInsets.all(8), + sliver: SliverGrid( + gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 3, + mainAxisSpacing: 8, + crossAxisSpacing: 8, + ), + delegate: SliverChildBuilderDelegate( + (context, index) => GroupTile(group: groups[index]), + childCount: groups.length, + ), ), ), - ), - ], + const SliverSafeArea(top: false, sliver: SliverToBoxAdapter()), + ], + ), ), ); } diff --git a/lib/ui/screens/members_screen.dart b/lib/ui/screens/members_screen.dart index e05edbc84..03811941a 100644 --- a/lib/ui/screens/members_screen.dart +++ b/lib/ui/screens/members_screen.dart @@ -195,13 +195,17 @@ class MemberListScrollView extends StatelessWidget { @override Widget build(BuildContext context) { return Scrollbar( - controller: controller, + controller: controller, + child: SafeArea( + top: false, + bottom: false, child: CustomScrollView( controller: controller, physics: const RangeMaintainingScrollPhysics( parent: AlwaysScrollableScrollPhysics(), ), slivers: [ + const SliverSafeArea(bottom: false, sliver: SliverToBoxAdapter()), SliverPadding( padding: const EdgeInsets.all(8), sliver: SliverGrid( @@ -229,7 +233,10 @@ class MemberListScrollView extends StatelessWidget { ]), ), ), + const SliverSafeArea(top: false, sliver: SliverToBoxAdapter()), ], - )); + ), + ), + ); } } diff --git a/lib/ui/screens/profile_screen.dart b/lib/ui/screens/profile_screen.dart index 428d811db..38cad2bdf 100644 --- a/lib/ui/screens/profile_screen.dart +++ b/lib/ui/screens/profile_screen.dart @@ -458,12 +458,14 @@ class _ProfileScreenState extends State { @override Widget build(BuildContext context) { return Scaffold( - body: SafeArea( - child: BlocBuilder( - bloc: _memberCubit, - builder: (context, state) { - if (state.hasException) { - return CustomScrollView( + body: BlocBuilder( + bloc: _memberCubit, + builder: (context, state) { + if (state.hasException) { + return SafeArea( + top: false, + bottom: false, + child: CustomScrollView( controller: _scrollController, slivers: [ _makeAppBar(), @@ -471,9 +473,13 @@ class _ProfileScreenState extends State { child: ErrorCenter(state.message!), ), ], - ); - } else if (state.isLoading && widget.member == null) { - return CustomScrollView( + ), + ); + } else if (state.isLoading && widget.member == null) { + return SafeArea( + top: false, + bottom: false, + child: CustomScrollView( controller: _scrollController, slivers: [ _makeAppBar(), @@ -481,12 +487,18 @@ class _ProfileScreenState extends State { child: Center(child: CircularProgressIndicator()), ), ], - ); - } else { - return CustomScrollView( + ), + ); + } else { + return SafeArea( + top: false, + bottom: false, + child: CustomScrollView( key: const PageStorageKey('profile'), controller: _scrollController, slivers: [ + const SliverSafeArea( + bottom: false, sliver: SliverToBoxAdapter()), _makeAppBar((state.result ?? widget.member)!), _makeFactsSliver((state.result ?? widget.member)!), if (!state.isLoading) ...[ @@ -502,12 +514,16 @@ class _ProfileScreenState extends State { ), ), ], - const SliverToBoxAdapter(child: SizedBox(height: 32)) + const SliverToBoxAdapter( + child: + SizedBox(height: 32)), // Im pretty sure this can go? + const SliverSafeArea( + top: false, sliver: SliverToBoxAdapter()), ], - ); - } - }, - ), + ), + ); + } + }, ), ); } diff --git a/lib/ui/screens/registration_screen.dart b/lib/ui/screens/registration_screen.dart index d8929a637..df071147f 100644 --- a/lib/ui/screens/registration_screen.dart +++ b/lib/ui/screens/registration_screen.dart @@ -42,195 +42,198 @@ class _RegistrationScreenState extends State { @override Widget build(BuildContext context) { - return SafeArea( - child: BlocBuilder( - bloc: _registrationFieldsCubit, - builder: (context, state) { - if (state.hasException) { - return Scaffold( - appBar: ThaliaAppBar( - title: const Text('REGISTRATION'), - leading: const CloseButton(), - ), - body: ErrorCenter(state.message!), - ); - } else if (state.isLoading) { - return Scaffold( - appBar: ThaliaAppBar( - title: const Text('REGISTRATION'), - leading: const CloseButton(), - ), - body: const Center(child: CircularProgressIndicator()), - ); - } else {} + return BlocBuilder( + bloc: _registrationFieldsCubit, + builder: (context, state) { + if (state.hasException) { + return Scaffold( + appBar: ThaliaAppBar( + title: const Text('REGISTRATION'), + leading: const CloseButton(), + ), + body: ErrorCenter(state.message!), + ); + } else if (state.isLoading) { + return Scaffold( + appBar: ThaliaAppBar( + title: const Text('REGISTRATION'), + leading: const CloseButton(), + ), + body: const Center(child: CircularProgressIndicator()), + ); + } else { return Scaffold( appBar: ThaliaAppBar( title: const Text('REGISTRATION'), leading: const CloseButton(), ), body: SingleChildScrollView( - child: Form( - key: _formKey, - child: Column( - children: [ - ...state.result!.entries.map((entry) { - final field = entry.value; - if (field is TextRegistrationField) { - return Column( - children: [ - ListTile( - title: Text(field.label), - subtitle: field.description.isNotEmpty - ? Text(field.description) - : null, - ), - Padding( - padding: const EdgeInsets.only( - left: 16, - bottom: 16, - right: 16, + child: SafeArea( + child: Form( + key: _formKey, + child: Column( + children: [ + ...state.result!.entries.map((entry) { + final field = entry.value; + if (field is TextRegistrationField) { + return Column( + children: [ + ListTile( + title: Text(field.label), + subtitle: field.description.isNotEmpty + ? Text(field.description) + : null, ), - child: TextFormField( - initialValue: field.value, - minLines: 1, - maxLines: 5, - decoration: InputDecoration( - labelText: field.isRequired - ? '${field.label} *' - : field.label, - hintText: 'Lorem ipsum...', + Padding( + padding: const EdgeInsets.only( + left: 16, + bottom: 16, + right: 16, + ), + child: TextFormField( + initialValue: field.value, + minLines: 1, + maxLines: 5, + decoration: InputDecoration( + labelText: field.isRequired + ? '${field.label} *' + : field.label, + hintText: 'Lorem ipsum...', + ), + validator: (value) { + if (field.isRequired && + (value == null || value.isEmpty)) { + return 'Please fill in this field.'; + } + return null; + }, + onSaved: (newValue) => field.value = newValue, ), - validator: (value) { - if (field.isRequired && - (value == null || value.isEmpty)) { - return 'Please fill in this field.'; - } - return null; - }, - onSaved: (newValue) => field.value = newValue, ), - ), - ], - ); - } else if (field is IntegerRegistrationField) { - return Column( - children: [ - ListTile( - dense: field.description.isEmpty, + ], + ); + } else if (field is IntegerRegistrationField) { + return Column( + children: [ + ListTile( + dense: field.description.isEmpty, + title: Text(field.label), + subtitle: field.description.isNotEmpty + ? Text(field.description) + : null, + ), + Padding( + padding: const EdgeInsets.only( + left: 16, + right: 16, + bottom: 16, + ), + child: TextFormField( + keyboardType: TextInputType.number, + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly + ], + decoration: InputDecoration( + labelText: field.isRequired + ? '${field.label} *' + : field.label, + hintText: '123...', + ), + initialValue: field.value?.toString(), + validator: (value) { + if (field.isRequired && + (value == null || value.isEmpty)) { + return 'Please fill in this field.'; + } + return null; + }, + onSaved: (newValue) => + field.value = int.tryParse(newValue!), + ), + ), + ], + ); + } else if (field is CheckboxRegistrationField) { + return Padding( + padding: const EdgeInsets.only(bottom: 16), + child: _CheckboxFormField( + initialValue: field.value ?? false, + onSaved: (newValue) => field.value = newValue, title: Text(field.label), subtitle: field.description.isNotEmpty ? Text(field.description) : null, ), - Padding( - padding: const EdgeInsets.only( - left: 16, - right: 16, - bottom: 16, - ), - child: TextFormField( - keyboardType: TextInputType.number, - inputFormatters: [ - FilteringTextInputFormatter.digitsOnly - ], - decoration: InputDecoration( - labelText: field.isRequired - ? '${field.label} *' - : field.label, - hintText: '123...', - ), - initialValue: field.value?.toString(), - validator: (value) { - if (field.isRequired && - (value == null || value.isEmpty)) { - return 'Please fill in this field.'; - } - return null; - }, - onSaved: (newValue) => - field.value = int.tryParse(newValue!), - ), + ); + } else { + return const SizedBox(height: 0); + } + }), + Padding( + padding: const EdgeInsets.all(16), + child: Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + TextButton.icon( + onPressed: () { + _formKey.currentState!.reset(); + }, + icon: const Icon(Icons.restore_page_outlined), + label: const Text('RESTORE'), ), - ], - ); - } else if (field is CheckboxRegistrationField) { - return Padding( - padding: const EdgeInsets.only(bottom: 16), - child: _CheckboxFormField( - initialValue: field.value ?? false, - onSaved: (newValue) => field.value = newValue, - title: Text(field.label), - subtitle: field.description.isNotEmpty - ? Text(field.description) - : null, - ), - ); - } else { - return const SizedBox(height: 0); - } - }), - Padding( - padding: const EdgeInsets.all(16), - child: Row( - mainAxisAlignment: MainAxisAlignment.end, - children: [ - TextButton.icon( - onPressed: () { - _formKey.currentState!.reset(); - }, - icon: const Icon(Icons.restore_page_outlined), - label: const Text('RESTORE'), - ), - const SizedBox(width: 16), - ElevatedButton.icon( - onPressed: () async { - if (_formKey.currentState!.validate()) { - _formKey.currentState!.save(); + const SizedBox(width: 16), + ElevatedButton.icon( + onPressed: () async { + if (_formKey.currentState!.validate()) { + _formKey.currentState!.save(); - final messenger = ScaffoldMessenger.of(context); + final messenger = + ScaffoldMessenger.of(context); - try { - await _registrationFieldsCubit.update( - eventPk: widget.eventPk, - registrationPk: widget.registrationPk, - fields: state.result!, - ); + try { + await _registrationFieldsCubit.update( + eventPk: widget.eventPk, + registrationPk: widget.registrationPk, + fields: state.result!, + ); - if (mounted) Navigator.of(context).pop(); + if (mounted) Navigator.of(context).pop(); - messenger.showSnackBar( - const SnackBar( - behavior: SnackBarBehavior.floating, - content: Text( - 'Your registration has been updated.', + messenger.showSnackBar( + const SnackBar( + behavior: SnackBarBehavior.floating, + content: Text( + 'Your registration has been updated.', + ), ), - ), - ); - } on ApiException { - messenger.showSnackBar( - const SnackBar( - behavior: SnackBarBehavior.floating, - content: Text( - 'Could not update your registration.', + ); + } on ApiException { + messenger.showSnackBar( + const SnackBar( + behavior: SnackBarBehavior.floating, + content: Text( + 'Could not update your registration.', + ), ), - ), - ); + ); + } } - } - }, - icon: const Icon(Icons.check), - label: const Text('SUBMIT'), - ), - ], + }, + icon: const Icon(Icons.check), + label: const Text('SUBMIT'), + ), + ], + ), ), - ), - ], + ], + ), ), ), ), ); - }, - ), + } + ; + }, ); } } diff --git a/lib/ui/screens/settings_screen.dart b/lib/ui/screens/settings_screen.dart index b221739c0..f00db749c 100644 --- a/lib/ui/screens/settings_screen.dart +++ b/lib/ui/screens/settings_screen.dart @@ -14,126 +14,124 @@ class SettingsScreen extends StatelessWidget { return Scaffold( appBar: ThaliaAppBar(title: const Text('SETTINGS')), drawer: MenuDrawer(), - body: SafeArea( - child: BlocBuilder( - builder: (context, state) { - if (state.hasException) { - return RefreshIndicator( - onRefresh: () => BlocProvider.of(context).load(), - child: ListView( - padding: const EdgeInsets.all(16), - children: [ - Text('THEME', style: textTheme.caption), - const _ThemeModeCard(), - const SizedBox(height: 8), - Text('NOTIFICATIONS', style: textTheme.caption), - Center(child: Text(state.message!)), - const SizedBox(height: 8), - Text('ABOUT', style: textTheme.caption), - const _AboutCard(), - ], - ), - ); - } else if (state.isLoading && state.categories == null) { - return ListView( + body: BlocBuilder( + builder: (context, state) { + if (state.hasException) { + return RefreshIndicator( + onRefresh: () => BlocProvider.of(context).load(), + child: ListView( padding: const EdgeInsets.all(16), children: [ Text('THEME', style: textTheme.caption), const _ThemeModeCard(), const SizedBox(height: 8), Text('NOTIFICATIONS', style: textTheme.caption), - const Padding( - padding: EdgeInsets.symmetric(vertical: 16), - child: Center(child: CircularProgressIndicator()), - ), + Center(child: Text(state.message!)), const SizedBox(height: 8), Text('ABOUT', style: textTheme.caption), const _AboutCard(), - const SizedBox(height: 8), - const _LogOutButton(), ], - ); - } else if (state.isLoading && state.categories == null) { - return ListView( - padding: const EdgeInsets.all(16), - children: [ - Text('THEME', style: textTheme.caption), - const _ThemeModeCard(), - const SizedBox(height: 8), - Text('NOTIFICATIONS', style: textTheme.caption), - const Padding( - padding: EdgeInsets.symmetric(vertical: 16), - child: Center(child: CircularProgressIndicator()), - ), - const SizedBox(height: 8), - Text('ABOUT', style: textTheme.caption), - const _AboutCard(), - const SizedBox(height: 8), - const _LogOutButton(), - ], - ); - } else { - return ListView( - padding: const EdgeInsets.all(16), - children: [ - Text('THEME', style: textTheme.caption), - const _ThemeModeCard(), - const SizedBox(height: 8), - Text('NOTIFICATIONS', style: textTheme.caption), - if (!state.hasPermissions!) ...[ - Card( - margin: const EdgeInsets.symmetric(vertical: 8), - child: Padding( - padding: const EdgeInsets.all(4), - child: Row( - children: [ - const Padding( - padding: EdgeInsets.all(12), - child: Icon(Icons.notifications_off_outlined), - ), - Expanded( - child: Text( - 'Notifications are disabled. Enable ' - 'them in your device settings.', - style: textTheme.bodyText2!.copyWith( - color: textTheme.caption!.color, - ), - ), - ), - ], - ), - ), - ), - ], + ), + ); + } else if (state.isLoading && state.categories == null) { + return ListView( + padding: const EdgeInsets.all(16), + children: [ + Text('THEME', style: textTheme.caption), + const _ThemeModeCard(), + const SizedBox(height: 8), + Text('NOTIFICATIONS', style: textTheme.caption), + const Padding( + padding: EdgeInsets.symmetric(vertical: 16), + child: Center(child: CircularProgressIndicator()), + ), + const SizedBox(height: 8), + Text('ABOUT', style: textTheme.caption), + const _AboutCard(), + const SizedBox(height: 8), + const _LogOutButton(), + ], + ); + } else if (state.isLoading && state.categories == null) { + return ListView( + padding: const EdgeInsets.all(16), + children: [ + Text('THEME', style: textTheme.caption), + const _ThemeModeCard(), + const SizedBox(height: 8), + Text('NOTIFICATIONS', style: textTheme.caption), + const Padding( + padding: EdgeInsets.symmetric(vertical: 16), + child: Center(child: CircularProgressIndicator()), + ), + const SizedBox(height: 8), + Text('ABOUT', style: textTheme.caption), + const _AboutCard(), + const SizedBox(height: 8), + const _LogOutButton(), + ], + ); + } else { + return ListView( + padding: const EdgeInsets.all(16), + children: [ + Text('THEME', style: textTheme.caption), + const _ThemeModeCard(), + const SizedBox(height: 8), + Text('NOTIFICATIONS', style: textTheme.caption), + if (!state.hasPermissions!) ...[ Card( margin: const EdgeInsets.symmetric(vertical: 8), - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: ListTile.divideTiles( - context: context, - tiles: [ - for (final category in state.categories!) - _NotificationSettingTile( - category: category, - enabled: state.device!.receiveCategory.contains( - category.key, + child: Padding( + padding: const EdgeInsets.all(4), + child: Row( + children: [ + const Padding( + padding: EdgeInsets.all(12), + child: Icon(Icons.notifications_off_outlined), + ), + Expanded( + child: Text( + 'Notifications are disabled. Enable ' + 'them in your device settings.', + style: textTheme.bodyText2!.copyWith( + color: textTheme.caption!.color, ), ), + ), ], - ).toList(), + ), ), ), - const SizedBox(height: 8), - Text('ABOUT', style: textTheme.caption), - const _AboutCard(), - const SizedBox(height: 8), - const _LogOutButton(), ], - ); - } - }, - ), + Card( + margin: const EdgeInsets.symmetric(vertical: 8), + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: ListTile.divideTiles( + context: context, + tiles: [ + for (final category in state.categories!) + _NotificationSettingTile( + category: category, + enabled: state.device!.receiveCategory.contains( + category.key, + ), + ), + ], + ).toList(), + ), + ), + const SizedBox(height: 8), + Text('ABOUT', style: textTheme.caption), + const _AboutCard(), + const SizedBox(height: 8), + const _LogOutButton(), + ], + ); + } + }, ), ); } diff --git a/lib/ui/screens/welcome_screen.dart b/lib/ui/screens/welcome_screen.dart index 1a6fa52e1..a161d6cc6 100644 --- a/lib/ui/screens/welcome_screen.dart +++ b/lib/ui/screens/welcome_screen.dart @@ -162,11 +162,14 @@ class _WelcomeScreenState extends State { @override Widget build(BuildContext context) { - return Scaffold( - appBar: ThaliaAppBar(title: const Text('WELCOME')), - drawer: MenuDrawer(), - body: SafeArea( - child: RefreshIndicator( + var mq = MediaQuery.of(context); + mq = mq.copyWith(padding: mq.padding.copyWith(bottom: 0)); + return MediaQuery( + data: mq, + child: Scaffold( + appBar: ThaliaAppBar(title: const Text('WELCOME')), + drawer: MenuDrawer(), + body: RefreshIndicator( onRefresh: () => BlocProvider.of(context).load(), child: BlocBuilder( builder: (context, state) { @@ -176,22 +179,25 @@ class _WelcomeScreenState extends State { return const Center(child: CircularProgressIndicator()); } else { return Scrollbar( - child: ListView( - key: const PageStorageKey('welcome'), - physics: const AlwaysScrollableScrollPhysics(), - children: [ - _makeSlides(state.slides!), - if (state.slides!.isNotEmpty) const Divider(height: 0), - _makeArticles(state.articles!), - if (state.articles!.isNotEmpty) - const Divider(indent: 16, endIndent: 16, height: 8), - _makeUpcomingEvents(state.upcomingEvents!), - TextButton( - onPressed: () => context.goNamed('calendar'), - child: const Text('SHOW THE ENTIRE AGENDA'), - ), - ], - )); + // child: SafeArea( + child: ListView( + key: const PageStorageKey('welcome'), + physics: const AlwaysScrollableScrollPhysics(), + children: [ + _makeSlides(state.slides!), + if (state.slides!.isNotEmpty) const Divider(height: 0), + _makeArticles(state.articles!), + if (state.articles!.isNotEmpty) + const Divider(indent: 16, endIndent: 16, height: 8), + _makeUpcomingEvents(state.upcomingEvents!), + TextButton( + onPressed: () => context.goNamed('calendar'), + child: const Text('SHOW THE ENTIRE AGENDA'), + ), + ], + // ), + ), + ); } }, ), From a85baa2295ec51f9f1dbbc53ce95d612c548ff80 Mon Sep 17 00:00:00 2001 From: jaap aarts Date: Fri, 2 Dec 2022 15:13:33 +0100 Subject: [PATCH 03/14] Fix linting --- lib/ui/screens/login_screen.dart | 4 ++-- lib/ui/screens/registration_screen.dart | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/ui/screens/login_screen.dart b/lib/ui/screens/login_screen.dart index e095b71dc..dfab53680 100644 --- a/lib/ui/screens/login_screen.dart +++ b/lib/ui/screens/login_screen.dart @@ -72,8 +72,8 @@ class _LoginScreenState extends State { height: 50, child: ElevatedButton( style: ElevatedButton.styleFrom( - primary: Colors.black87, - onPrimary: Colors.white, + backgroundColor: Colors.black87, + foregroundColor: Colors.white, ), onPressed: () { BlocProvider.of( diff --git a/lib/ui/screens/registration_screen.dart b/lib/ui/screens/registration_screen.dart index df071147f..b61a8ab80 100644 --- a/lib/ui/screens/registration_screen.dart +++ b/lib/ui/screens/registration_screen.dart @@ -232,7 +232,6 @@ class _RegistrationScreenState extends State { ), ); } - ; }, ); } From 218212c72c3279220a90e3f8f3f4882089fa9d5d Mon Sep 17 00:00:00 2001 From: jaap aarts Date: Fri, 2 Dec 2022 15:16:01 +0100 Subject: [PATCH 04/14] more fixes --- lib/ui/screens/event_screen.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/ui/screens/event_screen.dart b/lib/ui/screens/event_screen.dart index e9c0baf7a..7ac90a380 100644 --- a/lib/ui/screens/event_screen.dart +++ b/lib/ui/screens/event_screen.dart @@ -1,7 +1,6 @@ import 'package:add_2_calendar/add_2_calendar.dart' as add2calendar; import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; -import 'package:flutter/rendering.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_widget_from_html_core/flutter_widget_from_html_core.dart'; import 'package:go_router/go_router.dart'; From f12fd0548064188c19eae4832100800ad9f5c2a6 Mon Sep 17 00:00:00 2001 From: jaap aarts Date: Fri, 2 Dec 2022 19:17:38 +0100 Subject: [PATCH 05/14] Fix issue after rebase --- lib/ui/screens/settings_screen.dart | 21 ++------------------- 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/lib/ui/screens/settings_screen.dart b/lib/ui/screens/settings_screen.dart index f00db749c..d51264637 100644 --- a/lib/ui/screens/settings_screen.dart +++ b/lib/ui/screens/settings_screen.dart @@ -30,6 +30,8 @@ class SettingsScreen extends StatelessWidget { const SizedBox(height: 8), Text('ABOUT', style: textTheme.caption), const _AboutCard(), + const SizedBox(height: 8), + const _LogOutButton(), ], ), ); @@ -52,25 +54,6 @@ class SettingsScreen extends StatelessWidget { const _LogOutButton(), ], ); - } else if (state.isLoading && state.categories == null) { - return ListView( - padding: const EdgeInsets.all(16), - children: [ - Text('THEME', style: textTheme.caption), - const _ThemeModeCard(), - const SizedBox(height: 8), - Text('NOTIFICATIONS', style: textTheme.caption), - const Padding( - padding: EdgeInsets.symmetric(vertical: 16), - child: Center(child: CircularProgressIndicator()), - ), - const SizedBox(height: 8), - Text('ABOUT', style: textTheme.caption), - const _AboutCard(), - const SizedBox(height: 8), - const _LogOutButton(), - ], - ); } else { return ListView( padding: const EdgeInsets.all(16), From 1aaaab2000c9b50ccea379a62d3cd1cd8ecf238c Mon Sep 17 00:00:00 2001 From: jaap aarts Date: Fri, 2 Dec 2022 19:18:54 +0100 Subject: [PATCH 06/14] Fix some debugging leftovers --- lib/ui/screens/registration_screen.dart | 300 ++++++++++++------------ lib/ui/screens/welcome_screen.dart | 72 +++--- 2 files changed, 182 insertions(+), 190 deletions(-) diff --git a/lib/ui/screens/registration_screen.dart b/lib/ui/screens/registration_screen.dart index b61a8ab80..f8ec62c1e 100644 --- a/lib/ui/screens/registration_screen.dart +++ b/lib/ui/screens/registration_screen.dart @@ -61,177 +61,175 @@ class _RegistrationScreenState extends State { ), body: const Center(child: CircularProgressIndicator()), ); - } else { - return Scaffold( - appBar: ThaliaAppBar( - title: const Text('REGISTRATION'), - leading: const CloseButton(), - ), - body: SingleChildScrollView( - child: SafeArea( - child: Form( - key: _formKey, - child: Column( - children: [ - ...state.result!.entries.map((entry) { - final field = entry.value; - if (field is TextRegistrationField) { - return Column( - children: [ - ListTile( - title: Text(field.label), - subtitle: field.description.isNotEmpty - ? Text(field.description) - : null, - ), - Padding( - padding: const EdgeInsets.only( - left: 16, - bottom: 16, - right: 16, - ), - child: TextFormField( - initialValue: field.value, - minLines: 1, - maxLines: 5, - decoration: InputDecoration( - labelText: field.isRequired - ? '${field.label} *' - : field.label, - hintText: 'Lorem ipsum...', - ), - validator: (value) { - if (field.isRequired && - (value == null || value.isEmpty)) { - return 'Please fill in this field.'; - } - return null; - }, - onSaved: (newValue) => field.value = newValue, - ), - ), - ], - ); - } else if (field is IntegerRegistrationField) { - return Column( - children: [ - ListTile( - dense: field.description.isEmpty, - title: Text(field.label), - subtitle: field.description.isNotEmpty - ? Text(field.description) - : null, + } + return Scaffold( + appBar: ThaliaAppBar( + title: const Text('REGISTRATION'), + leading: const CloseButton(), + ), + body: SingleChildScrollView( + child: SafeArea( + child: Form( + key: _formKey, + child: Column( + children: [ + ...state.result!.entries.map((entry) { + final field = entry.value; + if (field is TextRegistrationField) { + return Column( + children: [ + ListTile( + title: Text(field.label), + subtitle: field.description.isNotEmpty + ? Text(field.description) + : null, + ), + Padding( + padding: const EdgeInsets.only( + left: 16, + bottom: 16, + right: 16, ), - Padding( - padding: const EdgeInsets.only( - left: 16, - right: 16, - bottom: 16, - ), - child: TextFormField( - keyboardType: TextInputType.number, - inputFormatters: [ - FilteringTextInputFormatter.digitsOnly - ], - decoration: InputDecoration( - labelText: field.isRequired - ? '${field.label} *' - : field.label, - hintText: '123...', - ), - initialValue: field.value?.toString(), - validator: (value) { - if (field.isRequired && - (value == null || value.isEmpty)) { - return 'Please fill in this field.'; - } - return null; - }, - onSaved: (newValue) => - field.value = int.tryParse(newValue!), + child: TextFormField( + initialValue: field.value, + minLines: 1, + maxLines: 5, + decoration: InputDecoration( + labelText: field.isRequired + ? '${field.label} *' + : field.label, + hintText: 'Lorem ipsum...', ), + validator: (value) { + if (field.isRequired && + (value == null || value.isEmpty)) { + return 'Please fill in this field.'; + } + return null; + }, + onSaved: (newValue) => field.value = newValue, ), - ], - ); - } else if (field is CheckboxRegistrationField) { - return Padding( - padding: const EdgeInsets.only(bottom: 16), - child: _CheckboxFormField( - initialValue: field.value ?? false, - onSaved: (newValue) => field.value = newValue, + ), + ], + ); + } else if (field is IntegerRegistrationField) { + return Column( + children: [ + ListTile( + dense: field.description.isEmpty, title: Text(field.label), subtitle: field.description.isNotEmpty ? Text(field.description) : null, ), - ); - } else { - return const SizedBox(height: 0); - } - }), - Padding( - padding: const EdgeInsets.all(16), - child: Row( - mainAxisAlignment: MainAxisAlignment.end, - children: [ - TextButton.icon( - onPressed: () { - _formKey.currentState!.reset(); - }, - icon: const Icon(Icons.restore_page_outlined), - label: const Text('RESTORE'), + Padding( + padding: const EdgeInsets.only( + left: 16, + right: 16, + bottom: 16, + ), + child: TextFormField( + keyboardType: TextInputType.number, + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly + ], + decoration: InputDecoration( + labelText: field.isRequired + ? '${field.label} *' + : field.label, + hintText: '123...', + ), + initialValue: field.value?.toString(), + validator: (value) { + if (field.isRequired && + (value == null || value.isEmpty)) { + return 'Please fill in this field.'; + } + return null; + }, + onSaved: (newValue) => + field.value = int.tryParse(newValue!), + ), ), - const SizedBox(width: 16), - ElevatedButton.icon( - onPressed: () async { - if (_formKey.currentState!.validate()) { - _formKey.currentState!.save(); + ], + ); + } else if (field is CheckboxRegistrationField) { + return Padding( + padding: const EdgeInsets.only(bottom: 16), + child: _CheckboxFormField( + initialValue: field.value ?? false, + onSaved: (newValue) => field.value = newValue, + title: Text(field.label), + subtitle: field.description.isNotEmpty + ? Text(field.description) + : null, + ), + ); + } else { + return const SizedBox(height: 0); + } + }), + Padding( + padding: const EdgeInsets.all(16), + child: Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + TextButton.icon( + onPressed: () { + _formKey.currentState!.reset(); + }, + icon: const Icon(Icons.restore_page_outlined), + label: const Text('RESTORE'), + ), + const SizedBox(width: 16), + ElevatedButton.icon( + onPressed: () async { + if (_formKey.currentState!.validate()) { + _formKey.currentState!.save(); - final messenger = - ScaffoldMessenger.of(context); + final messenger = ScaffoldMessenger.of(context); - try { - await _registrationFieldsCubit.update( - eventPk: widget.eventPk, - registrationPk: widget.registrationPk, - fields: state.result!, - ); + try { + await _registrationFieldsCubit.update( + eventPk: widget.eventPk, + registrationPk: widget.registrationPk, + fields: state.result!, + ); - if (mounted) Navigator.of(context).pop(); + if (mounted) Navigator.of(context).pop(); - messenger.showSnackBar( - const SnackBar( - behavior: SnackBarBehavior.floating, - content: Text( - 'Your registration has been updated.', - ), + messenger.showSnackBar( + const SnackBar( + behavior: SnackBarBehavior.floating, + content: Text( + 'Your registration has been updated.', ), - ); - } on ApiException { - messenger.showSnackBar( - const SnackBar( - behavior: SnackBarBehavior.floating, - content: Text( - 'Could not update your registration.', - ), + ), + ); + } on ApiException { + messenger.showSnackBar( + const SnackBar( + behavior: SnackBarBehavior.floating, + content: Text( + 'Could not update your registration.', ), - ); - } + ), + ); } - }, - icon: const Icon(Icons.check), - label: const Text('SUBMIT'), - ), - ], - ), + } + }, + icon: const Icon(Icons.check), + label: const Text('SUBMIT'), + ), + ], ), - ], - ), + ), + ], ), ), ), - ); - } + ), + ); }, ); } diff --git a/lib/ui/screens/welcome_screen.dart b/lib/ui/screens/welcome_screen.dart index a161d6cc6..6afd58cde 100644 --- a/lib/ui/screens/welcome_screen.dart +++ b/lib/ui/screens/welcome_screen.dart @@ -162,45 +162,39 @@ class _WelcomeScreenState extends State { @override Widget build(BuildContext context) { - var mq = MediaQuery.of(context); - mq = mq.copyWith(padding: mq.padding.copyWith(bottom: 0)); - return MediaQuery( - data: mq, - child: Scaffold( - appBar: ThaliaAppBar(title: const Text('WELCOME')), - drawer: MenuDrawer(), - body: RefreshIndicator( - onRefresh: () => BlocProvider.of(context).load(), - child: BlocBuilder( - builder: (context, state) { - if (state.hasException) { - return ErrorScrollView(state.message!); - } else if (!state.hasResults) { - return const Center(child: CircularProgressIndicator()); - } else { - return Scrollbar( - // child: SafeArea( - child: ListView( - key: const PageStorageKey('welcome'), - physics: const AlwaysScrollableScrollPhysics(), - children: [ - _makeSlides(state.slides!), - if (state.slides!.isNotEmpty) const Divider(height: 0), - _makeArticles(state.articles!), - if (state.articles!.isNotEmpty) - const Divider(indent: 16, endIndent: 16, height: 8), - _makeUpcomingEvents(state.upcomingEvents!), - TextButton( - onPressed: () => context.goNamed('calendar'), - child: const Text('SHOW THE ENTIRE AGENDA'), - ), - ], - // ), - ), - ); - } - }, - ), + return Scaffold( + appBar: ThaliaAppBar(title: const Text('WELCOME')), + drawer: MenuDrawer(), + body: RefreshIndicator( + onRefresh: () => BlocProvider.of(context).load(), + child: BlocBuilder( + builder: (context, state) { + if (state.hasException) { + return ErrorScrollView(state.message!); + } else if (!state.hasResults) { + return const Center(child: CircularProgressIndicator()); + } else { + return Scrollbar( + // child: SafeArea( + child: ListView( + key: const PageStorageKey('welcome'), + physics: const AlwaysScrollableScrollPhysics(), + children: [ + _makeSlides(state.slides!), + if (state.slides!.isNotEmpty) const Divider(height: 0), + _makeArticles(state.articles!), + if (state.articles!.isNotEmpty) + const Divider(indent: 16, endIndent: 16, height: 8), + _makeUpcomingEvents(state.upcomingEvents!), + TextButton( + onPressed: () => context.goNamed('calendar'), + child: const Text('SHOW THE ENTIRE AGENDA'), + ), + ], + ), + ); + } + }, ), ), ); From 9f387009e970a01b4bd7b68b56fba01cab336a52 Mon Sep 17 00:00:00 2001 From: jaap aarts Date: Wed, 7 Dec 2022 20:31:43 +0100 Subject: [PATCH 07/14] `custom widget for safearea in custom scrollviews --- lib/tosti/tosti_shift_screen.dart | 4 +- lib/ui/screens/albums_screen.dart | 3 +- lib/ui/screens/calendar_screen.dart | 30 +++---- lib/ui/screens/event_screen.dart | 67 +++++++--------- lib/ui/screens/group_screen.dart | 77 ++++++++---------- lib/ui/screens/groups_screen.dart | 59 +++++++------- lib/ui/screens/members_screen.dart | 93 ++++++++++------------ lib/ui/screens/profile_screen.dart | 91 +++++++++------------ lib/ui/screens/welcome_screen.dart | 1 - lib/ui/widgets/safe_custom_scrollview.dart | 41 ++++++++++ 10 files changed, 230 insertions(+), 236 deletions(-) create mode 100644 lib/ui/widgets/safe_custom_scrollview.dart diff --git a/lib/tosti/tosti_shift_screen.dart b/lib/tosti/tosti_shift_screen.dart index 2a2028a12..bcbadbcd3 100644 --- a/lib/tosti/tosti_shift_screen.dart +++ b/lib/tosti/tosti_shift_screen.dart @@ -7,6 +7,8 @@ import 'package:reaxit/tosti/models.dart'; import 'package:reaxit/tosti/tosti_api_repository.dart'; import 'package:reaxit/ui/widgets.dart'; +import '../ui/widgets/safe_custom_scrollview.dart'; + class TostiShiftScreen extends StatelessWidget { const TostiShiftScreen({required this.id, required this.api}); @@ -173,7 +175,7 @@ class TostiShiftScreen extends StatelessWidget { return RefreshIndicator( onRefresh: () => cubit.load(id), - child: CustomScrollView( + child: SafeCustomScrollView( slivers: [header, orderList], ), ); diff --git a/lib/ui/screens/albums_screen.dart b/lib/ui/screens/albums_screen.dart index 9405f82d5..4d9aa9214 100644 --- a/lib/ui/screens/albums_screen.dart +++ b/lib/ui/screens/albums_screen.dart @@ -4,6 +4,7 @@ import 'package:google_fonts/google_fonts.dart'; import 'package:reaxit/blocs.dart'; import 'package:reaxit/api/api_repository.dart'; import 'package:reaxit/ui/widgets.dart'; +import 'package:reaxit/ui/widgets/safe_custom_scrollview.dart'; class AlbumsScreen extends StatefulWidget { @override @@ -194,7 +195,7 @@ class AlbumListScrollView extends StatelessWidget { Widget build(BuildContext context) { return Scrollbar( controller: controller, - child: CustomScrollView( + child: SafeCustomScrollView( controller: controller, physics: const RangeMaintainingScrollPhysics( parent: AlwaysScrollableScrollPhysics(), diff --git a/lib/ui/screens/calendar_screen.dart b/lib/ui/screens/calendar_screen.dart index 8f03608dd..c2c59450a 100644 --- a/lib/ui/screens/calendar_screen.dart +++ b/lib/ui/screens/calendar_screen.dart @@ -9,6 +9,7 @@ import 'package:reaxit/blocs.dart'; import 'package:reaxit/models.dart'; import 'package:reaxit/ui/theme.dart'; import 'package:reaxit/ui/widgets.dart'; +import 'package:reaxit/ui/widgets/safe_custom_scrollview.dart'; import 'package:sticky_headers/sticky_headers/widget.dart'; import 'package:url_launcher/url_launcher.dart'; @@ -73,20 +74,18 @@ class _CalendarScreenState extends State { onRefresh: () async { await _cubit.load(); }, - child: SafeArea( - child: BlocBuilder( - builder: (context, calendarState) { - if (calendarState.hasException) { - return ErrorScrollView(calendarState.message!); - } else { - return CalendarScrollView( - key: const PageStorageKey('calendar'), - controller: _controller, - calendarState: calendarState, - ); - } - }, - ), + child: BlocBuilder( + builder: (context, calendarState) { + if (calendarState.hasException) { + return ErrorScrollView(calendarState.message!); + } else { + return CalendarScrollView( + key: const PageStorageKey('calendar'), + controller: _controller, + calendarState: calendarState, + ); + } + }, ), ), ); @@ -236,13 +235,14 @@ class CalendarScrollView extends StatelessWidget { return Scrollbar( controller: controller, - child: CustomScrollView( + child: SafeCustomScrollView( controller: controller, physics: const RangeMaintainingScrollPhysics( parent: AlwaysScrollableScrollPhysics(), ), slivers: [ SliverPadding( + // should this padding be here? padding: const EdgeInsets.all(12), sliver: SliverList( delegate: SliverChildBuilderDelegate( diff --git a/lib/ui/screens/event_screen.dart b/lib/ui/screens/event_screen.dart index 7ac90a380..1a1cffacf 100644 --- a/lib/ui/screens/event_screen.dart +++ b/lib/ui/screens/event_screen.dart @@ -11,6 +11,7 @@ import 'package:reaxit/blocs.dart'; import 'package:reaxit/models.dart'; import 'package:reaxit/routes.dart'; import 'package:reaxit/ui/widgets.dart'; +import 'package:reaxit/ui/widgets/safe_custom_scrollview.dart'; import 'package:share_plus/share_plus.dart'; import 'package:url_launcher/url_launcher.dart'; import 'package:reaxit/config.dart' as config; @@ -944,46 +945,38 @@ class _EventScreenState extends State { builder: (context, listState) { return Scrollbar( controller: _controller, - child: SafeArea( - top: false, - bottom: false, - child: CustomScrollView( - controller: _controller, - key: const PageStorageKey('event'), - slivers: [ - const SliverSafeArea( - bottom: false, sliver: SliverToBoxAdapter()), - SliverToBoxAdapter( - child: Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - _makeMap(event), - const Divider(height: 0), - _makeEventInfo(event), - const Divider(), - _makeDescription(event), - ], - ), + child: SafeCustomScrollView( + controller: _controller, + key: const PageStorageKey('event'), + slivers: [ + SliverToBoxAdapter( + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + _makeMap(event), + const Divider(height: 0), + _makeEventInfo(event), + const Divider(), + _makeDescription(event), + ], ), - if (event.registrationIsOptional || - event.registrationIsRequired) ...[ - const SliverToBoxAdapter(child: Divider()), - _makeRegistrationsHeader(listState), - _makeRegistrations(listState), - if (listState.isLoadingMore) - const SliverPadding( - padding: EdgeInsets.all(8), - sliver: SliverList( - delegate: SliverChildListDelegate.fixed([ - Center(child: CircularProgressIndicator()), - ]), - ), + ), + if (event.registrationIsOptional || + event.registrationIsRequired) ...[ + const SliverToBoxAdapter(child: Divider()), + _makeRegistrationsHeader(listState), + _makeRegistrations(listState), + if (listState.isLoadingMore) + const SliverPadding( + padding: EdgeInsets.all(8), + sliver: SliverList( + delegate: SliverChildListDelegate.fixed([ + Center(child: CircularProgressIndicator()), + ]), ), - ], - const SliverSafeArea( - top: false, sliver: SliverToBoxAdapter()), + ), ], - ), + ], ), ); }, diff --git a/lib/ui/screens/group_screen.dart b/lib/ui/screens/group_screen.dart index 77bc315cd..bc8e92f90 100644 --- a/lib/ui/screens/group_screen.dart +++ b/lib/ui/screens/group_screen.dart @@ -7,6 +7,7 @@ import 'package:reaxit/blocs.dart'; import 'package:reaxit/models.dart'; import 'package:reaxit/routes.dart'; import 'package:reaxit/ui/widgets.dart'; +import 'package:reaxit/ui/widgets/safe_custom_scrollview.dart'; import 'package:url_launcher/url_launcher.dart'; class GroupScreen extends StatelessWidget { @@ -94,30 +95,22 @@ class _Page extends StatelessWidget { body: RefreshIndicator( onRefresh: () => cubit.load(), child: Scrollbar( - child: SafeArea( - top: false, - bottom: false, - child: CustomScrollView( - key: const PageStorageKey('group'), - slivers: [ - const SliverSafeArea( - bottom: false, sliver: SliverToBoxAdapter()), - SliverToBoxAdapter( - child: Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - _GroupImage(group: group), - const Divider(height: 0), - _GroupInfo(group: group) - ], - ), + child: SafeCustomScrollView( + key: const PageStorageKey('group'), + slivers: [ + SliverToBoxAdapter( + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + _GroupImage(group: group), + const Divider(height: 0), + _GroupInfo(group: group) + ], ), - _MembersHeader(group: group), - const _MembersGrid(members: null), - const SliverSafeArea( - top: false, sliver: SliverToBoxAdapter()), - ], - ), + ), + _MembersHeader(group: group), + const _MembersGrid(members: null), + ], ), ), ), @@ -129,30 +122,22 @@ class _Page extends StatelessWidget { body: RefreshIndicator( onRefresh: () => cubit.load(), child: Scrollbar( - child: SafeArea( - top: false, - bottom: false, - child: CustomScrollView( - key: const PageStorageKey('group'), - slivers: [ - const SliverSafeArea( - bottom: false, sliver: SliverToBoxAdapter()), - SliverToBoxAdapter( - child: Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - _GroupImage(group: group), - const Divider(height: 0), - _GroupInfo(group: group) - ], - ), + child: SafeCustomScrollView( + key: const PageStorageKey('group'), + slivers: [ + SliverToBoxAdapter( + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + _GroupImage(group: group), + const Divider(height: 0), + _GroupInfo(group: group) + ], ), - _MembersHeader(group: group), - _MembersGrid(members: group.members), - const SliverSafeArea( - top: false, sliver: SliverToBoxAdapter()), - ], - ), + ), + _MembersHeader(group: group), + _MembersGrid(members: group.members), + ], ), ), ), diff --git a/lib/ui/screens/groups_screen.dart b/lib/ui/screens/groups_screen.dart index 72a13d942..c70d46e36 100644 --- a/lib/ui/screens/groups_screen.dart +++ b/lib/ui/screens/groups_screen.dart @@ -4,6 +4,7 @@ import 'package:reaxit/blocs/groups_cubit.dart'; import 'package:reaxit/models/group.dart'; import 'package:reaxit/ui/widgets.dart'; import 'package:collection/collection.dart'; +import 'package:reaxit/ui/widgets/safe_custom_scrollview.dart'; class GroupsScreen extends StatefulWidget { final MemberGroupType? currentScreen; @@ -138,42 +139,36 @@ class GroupListScrollView extends StatelessWidget { @override Widget build(BuildContext context) { return Scrollbar( - child: SafeArea( - top: false, - bottom: false, - child: CustomScrollView( - physics: const RangeMaintainingScrollPhysics( - parent: AlwaysScrollableScrollPhysics(), - ), - slivers: [ - const SliverSafeArea(bottom: false, sliver: SliverToBoxAdapter()), - if (activeBoard != null) - SliverToBoxAdapter( - child: Padding( - padding: const EdgeInsets.all(8), - child: AspectRatio( - aspectRatio: 3 / 2, - child: GroupTile(group: activeBoard!), - ), + child: SafeCustomScrollView( + physics: const RangeMaintainingScrollPhysics( + parent: AlwaysScrollableScrollPhysics(), + ), + slivers: [ + if (activeBoard != null) + SliverToBoxAdapter( + child: Padding( + padding: const EdgeInsets.all(8), + child: AspectRatio( + aspectRatio: 3 / 2, + child: GroupTile(group: activeBoard!), ), ), - SliverPadding( - padding: const EdgeInsets.all(8), - sliver: SliverGrid( - gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: 3, - mainAxisSpacing: 8, - crossAxisSpacing: 8, - ), - delegate: SliverChildBuilderDelegate( - (context, index) => GroupTile(group: groups[index]), - childCount: groups.length, - ), + ), + SliverPadding( + padding: const EdgeInsets.all(8), + sliver: SliverGrid( + gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 3, + mainAxisSpacing: 8, + crossAxisSpacing: 8, + ), + delegate: SliverChildBuilderDelegate( + (context, index) => GroupTile(group: groups[index]), + childCount: groups.length, ), ), - const SliverSafeArea(top: false, sliver: SliverToBoxAdapter()), - ], - ), + ), + ], ), ); } diff --git a/lib/ui/screens/members_screen.dart b/lib/ui/screens/members_screen.dart index 03811941a..23f447312 100644 --- a/lib/ui/screens/members_screen.dart +++ b/lib/ui/screens/members_screen.dart @@ -4,6 +4,7 @@ import 'package:google_fonts/google_fonts.dart'; import 'package:reaxit/api/api_repository.dart'; import 'package:reaxit/blocs.dart'; import 'package:reaxit/ui/widgets.dart'; +import 'package:reaxit/ui/widgets/safe_custom_scrollview.dart'; class MembersScreen extends StatefulWidget { @override @@ -66,20 +67,18 @@ class _MembersScreenState extends State { onRefresh: () async { await _cubit.load(); }, - child: SafeArea( - child: BlocBuilder( - builder: (context, listState) { - if (listState.hasException) { - return ErrorScrollView(listState.message!); - } else { - return MemberListScrollView( - key: const PageStorageKey('members'), - controller: _controller, - listState: listState, - ); - } - }, - ), + child: BlocBuilder( + builder: (context, listState) { + if (listState.hasException) { + return ErrorScrollView(listState.message!); + } else { + return MemberListScrollView( + key: const PageStorageKey('members'), + controller: _controller, + listState: listState, + ); + } + }, ), ), ); @@ -196,46 +195,40 @@ class MemberListScrollView extends StatelessWidget { Widget build(BuildContext context) { return Scrollbar( controller: controller, - child: SafeArea( - top: false, - bottom: false, - child: CustomScrollView( - controller: controller, - physics: const RangeMaintainingScrollPhysics( - parent: AlwaysScrollableScrollPhysics(), - ), - slivers: [ - const SliverSafeArea(bottom: false, sliver: SliverToBoxAdapter()), - SliverPadding( - padding: const EdgeInsets.all(8), - sliver: SliverGrid( - gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: 3, - mainAxisSpacing: 8, - crossAxisSpacing: 8, - ), - delegate: SliverChildBuilderDelegate( - (context, index) => MemberTile( - member: listState.results[index], - ), - childCount: listState.results.length, + child: SafeCustomScrollView( + controller: controller, + physics: const RangeMaintainingScrollPhysics( + parent: AlwaysScrollableScrollPhysics(), + ), + slivers: [ + SliverPadding( + padding: const EdgeInsets.all(8), + sliver: SliverGrid( + gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 3, + mainAxisSpacing: 8, + crossAxisSpacing: 8, + ), + delegate: SliverChildBuilderDelegate( + (context, index) => MemberTile( + member: listState.results[index], ), + childCount: listState.results.length, ), ), - if (listState.isLoadingMore) - const SliverPadding( - padding: EdgeInsets.all(8), - sliver: SliverList( - delegate: SliverChildListDelegate.fixed([ - Center( - child: CircularProgressIndicator(), - ) - ]), - ), + ), + if (listState.isLoadingMore) + const SliverPadding( + padding: EdgeInsets.all(8), + sliver: SliverList( + delegate: SliverChildListDelegate.fixed([ + Center( + child: CircularProgressIndicator(), + ) + ]), ), - const SliverSafeArea(top: false, sliver: SliverToBoxAdapter()), - ], - ), + ), + ], ), ); } diff --git a/lib/ui/screens/profile_screen.dart b/lib/ui/screens/profile_screen.dart index 38cad2bdf..022b7bbdc 100644 --- a/lib/ui/screens/profile_screen.dart +++ b/lib/ui/screens/profile_screen.dart @@ -12,6 +12,7 @@ import 'package:reaxit/api/exceptions.dart'; import 'package:reaxit/blocs.dart'; import 'package:reaxit/models.dart'; import 'package:reaxit/ui/widgets.dart'; +import 'package:reaxit/ui/widgets/safe_custom_scrollview.dart'; import 'package:url_launcher/url_launcher.dart'; /// Screen that loads and shows a the profile of the member with `pk`. @@ -462,65 +463,49 @@ class _ProfileScreenState extends State { bloc: _memberCubit, builder: (context, state) { if (state.hasException) { - return SafeArea( - top: false, - bottom: false, - child: CustomScrollView( - controller: _scrollController, - slivers: [ - _makeAppBar(), - SliverFillRemaining( - child: ErrorCenter(state.message!), - ), - ], - ), + return SafeCustomScrollView( + controller: _scrollController, + slivers: [ + _makeAppBar(), + SliverFillRemaining( + child: ErrorCenter(state.message!), + ), + ], ); } else if (state.isLoading && widget.member == null) { - return SafeArea( - top: false, - bottom: false, - child: CustomScrollView( - controller: _scrollController, - slivers: [ - _makeAppBar(), - const SliverFillRemaining( - child: Center(child: CircularProgressIndicator()), - ), - ], - ), + return SafeCustomScrollView( + controller: _scrollController, + slivers: [ + _makeAppBar(), + const SliverFillRemaining( + child: Center(child: CircularProgressIndicator()), + ), + ], ); } else { - return SafeArea( - top: false, - bottom: false, - child: CustomScrollView( - key: const PageStorageKey('profile'), - controller: _scrollController, - slivers: [ - const SliverSafeArea( - bottom: false, sliver: SliverToBoxAdapter()), - _makeAppBar((state.result ?? widget.member)!), - _makeFactsSliver((state.result ?? widget.member)!), - if (!state.isLoading) ...[ - if (state.result!.achievements.isNotEmpty) - _makeAchievementsSliver(state.result!), - if (state.result!.societies.isNotEmpty) - _makeSocietiesSliver(state.result!), - ] else ...[ - const SliverPadding( - padding: EdgeInsets.all(16), - sliver: SliverToBoxAdapter( - child: Center(child: CircularProgressIndicator()), - ), + // should this be a CustomScrollview? This would add padding _around_ the the appbar not in + return CustomScrollView( + key: const PageStorageKey('profile'), + controller: _scrollController, + slivers: [ + _makeAppBar((state.result ?? widget.member)!), + _makeFactsSliver((state.result ?? widget.member)!), + if (!state.isLoading) ...[ + if (state.result!.achievements.isNotEmpty) + _makeAchievementsSliver(state.result!), + if (state.result!.societies.isNotEmpty) + _makeSocietiesSliver(state.result!), + ] else ...[ + const SliverPadding( + padding: EdgeInsets.all(16), + sliver: SliverToBoxAdapter( + child: Center(child: CircularProgressIndicator()), ), - ], - const SliverToBoxAdapter( - child: - SizedBox(height: 32)), // Im pretty sure this can go? - const SliverSafeArea( - top: false, sliver: SliverToBoxAdapter()), + ), ], - ), + const SliverToBoxAdapter( + child: SizedBox(height: 32)), // Im pretty sure this can go? + ], ); } }, diff --git a/lib/ui/screens/welcome_screen.dart b/lib/ui/screens/welcome_screen.dart index 6afd58cde..1229c2f9c 100644 --- a/lib/ui/screens/welcome_screen.dart +++ b/lib/ui/screens/welcome_screen.dart @@ -175,7 +175,6 @@ class _WelcomeScreenState extends State { return const Center(child: CircularProgressIndicator()); } else { return Scrollbar( - // child: SafeArea( child: ListView( key: const PageStorageKey('welcome'), physics: const AlwaysScrollableScrollPhysics(), diff --git a/lib/ui/widgets/safe_custom_scrollview.dart b/lib/ui/widgets/safe_custom_scrollview.dart new file mode 100644 index 000000000..3b64c9790 --- /dev/null +++ b/lib/ui/widgets/safe_custom_scrollview.dart @@ -0,0 +1,41 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/widgets.dart'; + +class SafeCustomScrollView extends StatelessWidget { + final List slivers; + final ScrollController? controller; + final ScrollPhysics? physics; + + const SafeCustomScrollView( + {required this.slivers, this.controller, this.physics, super.key}); + + @override + Widget build(BuildContext context) { + final MediaQueryData mediaquery = MediaQuery.of(context); + EdgeInsets padding = mediaquery.padding; + + return SafeArea( + top: false, + bottom: false, + child: MediaQuery.removePadding( + context: context, + removeLeft: true, + removeTop: true, + removeRight: true, + removeBottom: true, + child: Padding( + padding: EdgeInsets.only(left: padding.left, right: padding.right), + child: CustomScrollView( + controller: controller, + physics: physics, + slivers: [ + SliverPadding(padding: EdgeInsets.only(top: padding.top)), + ...slivers, + SliverPadding(padding: EdgeInsets.only(bottom: padding.bottom)), + ], + ), + ), + ), + ); + } +} From 7ca3ac759f8c27b5c574ff3a0a7fa7e6686ee6b5 Mon Sep 17 00:00:00 2001 From: jaap aarts Date: Wed, 7 Dec 2022 20:48:55 +0100 Subject: [PATCH 08/14] Add appbar support to safe widget --- lib/ui/screens/profile_screen.dart | 13 ++++++------- lib/ui/widgets/safe_custom_scrollview.dart | 11 +++++++++-- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/lib/ui/screens/profile_screen.dart b/lib/ui/screens/profile_screen.dart index 022b7bbdc..13b2b899d 100644 --- a/lib/ui/screens/profile_screen.dart +++ b/lib/ui/screens/profile_screen.dart @@ -465,8 +465,8 @@ class _ProfileScreenState extends State { if (state.hasException) { return SafeCustomScrollView( controller: _scrollController, + sliverappbar: _makeAppBar(), slivers: [ - _makeAppBar(), SliverFillRemaining( child: ErrorCenter(state.message!), ), @@ -475,20 +475,19 @@ class _ProfileScreenState extends State { } else if (state.isLoading && widget.member == null) { return SafeCustomScrollView( controller: _scrollController, - slivers: [ - _makeAppBar(), - const SliverFillRemaining( + sliverappbar: _makeAppBar(), + slivers: const [ + SliverFillRemaining( child: Center(child: CircularProgressIndicator()), ), ], ); } else { - // should this be a CustomScrollview? This would add padding _around_ the the appbar not in - return CustomScrollView( + return SafeCustomScrollView( key: const PageStorageKey('profile'), controller: _scrollController, + sliverappbar: _makeAppBar((state.result ?? widget.member)!), slivers: [ - _makeAppBar((state.result ?? widget.member)!), _makeFactsSliver((state.result ?? widget.member)!), if (!state.isLoading) ...[ if (state.result!.achievements.isNotEmpty) diff --git a/lib/ui/widgets/safe_custom_scrollview.dart b/lib/ui/widgets/safe_custom_scrollview.dart index 3b64c9790..f40886547 100644 --- a/lib/ui/widgets/safe_custom_scrollview.dart +++ b/lib/ui/widgets/safe_custom_scrollview.dart @@ -5,9 +5,15 @@ class SafeCustomScrollView extends StatelessWidget { final List slivers; final ScrollController? controller; final ScrollPhysics? physics; + final Widget? sliverappbar; - const SafeCustomScrollView( - {required this.slivers, this.controller, this.physics, super.key}); + const SafeCustomScrollView({ + required this.slivers, + this.controller, + this.physics, + this.sliverappbar, + super.key, + }); @override Widget build(BuildContext context) { @@ -29,6 +35,7 @@ class SafeCustomScrollView extends StatelessWidget { controller: controller, physics: physics, slivers: [ + if (sliverappbar != null) sliverappbar!, SliverPadding(padding: EdgeInsets.only(top: padding.top)), ...slivers, SliverPadding(padding: EdgeInsets.only(bottom: padding.bottom)), From 209858526265096d0851f0b6fd648de95411170d Mon Sep 17 00:00:00 2001 From: jaap aarts Date: Wed, 7 Dec 2022 20:55:50 +0100 Subject: [PATCH 09/14] Alternate method of doing an appbar --- lib/ui/screens/profile_screen.dart | 13 +++++++---- lib/ui/widgets/safe_custom_scrollview.dart | 27 ++++++++++++++-------- 2 files changed, 26 insertions(+), 14 deletions(-) diff --git a/lib/ui/screens/profile_screen.dart b/lib/ui/screens/profile_screen.dart index 13b2b899d..5c19e02df 100644 --- a/lib/ui/screens/profile_screen.dart +++ b/lib/ui/screens/profile_screen.dart @@ -465,8 +465,9 @@ class _ProfileScreenState extends State { if (state.hasException) { return SafeCustomScrollView( controller: _scrollController, - sliverappbar: _makeAppBar(), + top: false, slivers: [ + _makeAppBar(), SliverFillRemaining( child: ErrorCenter(state.message!), ), @@ -475,9 +476,10 @@ class _ProfileScreenState extends State { } else if (state.isLoading && widget.member == null) { return SafeCustomScrollView( controller: _scrollController, - sliverappbar: _makeAppBar(), - slivers: const [ - SliverFillRemaining( + top: false, + slivers: [ + _makeAppBar(), + const SliverFillRemaining( child: Center(child: CircularProgressIndicator()), ), ], @@ -486,8 +488,9 @@ class _ProfileScreenState extends State { return SafeCustomScrollView( key: const PageStorageKey('profile'), controller: _scrollController, - sliverappbar: _makeAppBar((state.result ?? widget.member)!), + top: false, slivers: [ + _makeAppBar((state.result ?? widget.member)!), _makeFactsSliver((state.result ?? widget.member)!), if (!state.isLoading) ...[ if (state.result!.achievements.isNotEmpty) diff --git a/lib/ui/widgets/safe_custom_scrollview.dart b/lib/ui/widgets/safe_custom_scrollview.dart index f40886547..9e2c45f16 100644 --- a/lib/ui/widgets/safe_custom_scrollview.dart +++ b/lib/ui/widgets/safe_custom_scrollview.dart @@ -5,13 +5,19 @@ class SafeCustomScrollView extends StatelessWidget { final List slivers; final ScrollController? controller; final ScrollPhysics? physics; - final Widget? sliverappbar; + final bool top; + final bool right; + final bool bottom; + final bool left; const SafeCustomScrollView({ required this.slivers, this.controller, this.physics, - this.sliverappbar, + this.top = true, + this.right = true, + this.bottom = true, + this.left = true, super.key, }); @@ -23,22 +29,25 @@ class SafeCustomScrollView extends StatelessWidget { return SafeArea( top: false, bottom: false, + left: left, + right: right, child: MediaQuery.removePadding( context: context, - removeLeft: true, - removeTop: true, - removeRight: true, - removeBottom: true, + removeLeft: left, + removeTop: top, + removeRight: right, + removeBottom: bottom, child: Padding( padding: EdgeInsets.only(left: padding.left, right: padding.right), child: CustomScrollView( controller: controller, physics: physics, slivers: [ - if (sliverappbar != null) sliverappbar!, - SliverPadding(padding: EdgeInsets.only(top: padding.top)), + if (top) + SliverPadding(padding: EdgeInsets.only(top: padding.top)), ...slivers, - SliverPadding(padding: EdgeInsets.only(bottom: padding.bottom)), + if (bottom) + SliverPadding(padding: EdgeInsets.only(bottom: padding.bottom)), ], ), ), From 6fa7a88ca44c656f8b1ee41994d7df5461c4035a Mon Sep 17 00:00:00 2001 From: jaap aarts Date: Wed, 21 Dec 2022 20:15:43 +0100 Subject: [PATCH 10/14] Use a padding field in the SaveCustomScrollview --- lib/ui/screens/albums_screen.dart | 25 ++++--- lib/ui/screens/calendar_screen.dart | 76 ++++++++++------------ lib/ui/screens/groups_screen.dart | 23 +++---- lib/ui/screens/members_screen.dart | 25 ++++--- lib/ui/widgets/safe_custom_scrollview.dart | 11 +++- 5 files changed, 76 insertions(+), 84 deletions(-) diff --git a/lib/ui/screens/albums_screen.dart b/lib/ui/screens/albums_screen.dart index 4d9aa9214..a918b22a3 100644 --- a/lib/ui/screens/albums_screen.dart +++ b/lib/ui/screens/albums_screen.dart @@ -201,25 +201,22 @@ class AlbumListScrollView extends StatelessWidget { parent: AlwaysScrollableScrollPhysics(), ), slivers: [ - SliverPadding( - padding: const EdgeInsets.all(8), - sliver: SliverGrid( - gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: 3, - mainAxisSpacing: 8, - crossAxisSpacing: 8, - ), - delegate: SliverChildBuilderDelegate( - (context, index) => AlbumTile( - album: listState.results[index], - ), - childCount: listState.results.length, + SliverGrid( + gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 3, + mainAxisSpacing: 8, + crossAxisSpacing: 8, + ), + delegate: SliverChildBuilderDelegate( + (context, index) => AlbumTile( + album: listState.results[index], ), + childCount: listState.results.length, ), ), if (listState.isLoadingMore) const SliverPadding( - padding: EdgeInsets.all(8), + padding: EdgeInsets.only(top: 8), sliver: SliverList( delegate: SliverChildListDelegate.fixed([ Center( diff --git a/lib/ui/screens/calendar_screen.dart b/lib/ui/screens/calendar_screen.dart index c2c59450a..8e28cd495 100644 --- a/lib/ui/screens/calendar_screen.dart +++ b/lib/ui/screens/calendar_screen.dart @@ -240,50 +240,44 @@ class CalendarScrollView extends StatelessWidget { physics: const RangeMaintainingScrollPhysics( parent: AlwaysScrollableScrollPhysics(), ), + padding: const EdgeInsets.symmetric(vertical: 8), slivers: [ - SliverPadding( - // should this padding be here? - padding: const EdgeInsets.all(12), - sliver: SliverList( - delegate: SliverChildBuilderDelegate( - (context, index) { - final month = months[index]; - final events = monthGroupedEvents[month]!; - - final dayGroupedEvents = _groupByDay(events); - final days = dayGroupedEvents.keys.toList(); - - return StickyHeader( - header: SizedBox( - width: double.infinity, - child: Material( - child: Padding( - padding: const EdgeInsets.symmetric(vertical: 8), - child: Text( - month.year == DateTime.now().year - ? monthFormatter - .format(month.toLocal()) - .toUpperCase() - : monthYearFormatter - .format(month.toLocal()) - .toUpperCase(), - style: Theme.of(context).textTheme.subtitle1, - ), - ), + SliverList( + delegate: SliverChildBuilderDelegate( + (context, index) { + final month = months[index]; + final events = monthGroupedEvents[month]!; + + final dayGroupedEvents = _groupByDay(events); + final days = dayGroupedEvents.keys.toList(); + + return StickyHeader( + header: SizedBox( + width: double.infinity, + child: Material( + child: Text( + month.year == DateTime.now().year + ? monthFormatter + .format(month.toLocal()) + .toUpperCase() + : monthYearFormatter + .format(month.toLocal()) + .toUpperCase(), + style: Theme.of(context).textTheme.subtitle1, ), ), - content: Column( - mainAxisSize: MainAxisSize.min, - children: [ - const SizedBox(height: 8), - for (final day in days) - _DayCard(day: day, events: dayGroupedEvents[day]!), - ], - ), - ); - }, - childCount: monthGroupedEvents.length, - ), + ), + content: Column( + mainAxisSize: MainAxisSize.min, + children: [ + const SizedBox(height: 8), + for (final day in days) + _DayCard(day: day, events: dayGroupedEvents[day]!), + ], + ), + ); + }, + childCount: monthGroupedEvents.length, ), ), if (calendarState.isLoadingMore) diff --git a/lib/ui/screens/groups_screen.dart b/lib/ui/screens/groups_screen.dart index c70d46e36..eb26254d9 100644 --- a/lib/ui/screens/groups_screen.dart +++ b/lib/ui/screens/groups_screen.dart @@ -147,25 +147,22 @@ class GroupListScrollView extends StatelessWidget { if (activeBoard != null) SliverToBoxAdapter( child: Padding( - padding: const EdgeInsets.all(8), + padding: const EdgeInsets.only(bottom: 8), child: AspectRatio( aspectRatio: 3 / 2, child: GroupTile(group: activeBoard!), ), ), ), - SliverPadding( - padding: const EdgeInsets.all(8), - sliver: SliverGrid( - gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: 3, - mainAxisSpacing: 8, - crossAxisSpacing: 8, - ), - delegate: SliverChildBuilderDelegate( - (context, index) => GroupTile(group: groups[index]), - childCount: groups.length, - ), + SliverGrid( + gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 3, + mainAxisSpacing: 8, + crossAxisSpacing: 8, + ), + delegate: SliverChildBuilderDelegate( + (context, index) => GroupTile(group: groups[index]), + childCount: groups.length, ), ), ], diff --git a/lib/ui/screens/members_screen.dart b/lib/ui/screens/members_screen.dart index 23f447312..8c218e531 100644 --- a/lib/ui/screens/members_screen.dart +++ b/lib/ui/screens/members_screen.dart @@ -201,25 +201,22 @@ class MemberListScrollView extends StatelessWidget { parent: AlwaysScrollableScrollPhysics(), ), slivers: [ - SliverPadding( - padding: const EdgeInsets.all(8), - sliver: SliverGrid( - gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: 3, - mainAxisSpacing: 8, - crossAxisSpacing: 8, - ), - delegate: SliverChildBuilderDelegate( - (context, index) => MemberTile( - member: listState.results[index], - ), - childCount: listState.results.length, + SliverGrid( + gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 3, + mainAxisSpacing: 8, + crossAxisSpacing: 8, + ), + delegate: SliverChildBuilderDelegate( + (context, index) => MemberTile( + member: listState.results[index], ), + childCount: listState.results.length, ), ), if (listState.isLoadingMore) const SliverPadding( - padding: EdgeInsets.all(8), + padding: EdgeInsets.only(top: 8), sliver: SliverList( delegate: SliverChildListDelegate.fixed([ Center( diff --git a/lib/ui/widgets/safe_custom_scrollview.dart b/lib/ui/widgets/safe_custom_scrollview.dart index 9e2c45f16..ee82579ce 100644 --- a/lib/ui/widgets/safe_custom_scrollview.dart +++ b/lib/ui/widgets/safe_custom_scrollview.dart @@ -1,3 +1,5 @@ +import 'dart:math'; + import 'package:flutter/cupertino.dart'; import 'package:flutter/widgets.dart'; @@ -9,6 +11,7 @@ class SafeCustomScrollView extends StatelessWidget { final bool right; final bool bottom; final bool left; + final EdgeInsets padding; const SafeCustomScrollView({ required this.slivers, @@ -18,14 +21,18 @@ class SafeCustomScrollView extends StatelessWidget { this.right = true, this.bottom = true, this.left = true, + this.padding = const EdgeInsets.all(8), super.key, }); @override Widget build(BuildContext context) { final MediaQueryData mediaquery = MediaQuery.of(context); - EdgeInsets padding = mediaquery.padding; - + EdgeInsets padding = EdgeInsets.fromLTRB( + max(mediaquery.padding.left, this.padding.left), + max(mediaquery.padding.top, this.padding.top), + max(mediaquery.padding.right, this.padding.right), + max(mediaquery.padding.bottom, this.padding.bottom)); return SafeArea( top: false, bottom: false, From a60e7da1fc7b5e8a96cb5a5cb383aa6ff72daec5 Mon Sep 17 00:00:00 2001 From: jaap aarts Date: Wed, 21 Dec 2022 20:18:25 +0100 Subject: [PATCH 11/14] Fix imports --- lib/tosti/tosti_shift_screen.dart | 2 -- lib/ui/screens/calendar_screen.dart | 1 - lib/ui/screens/event_screen.dart | 1 - lib/ui/screens/group_screen.dart | 1 - lib/ui/screens/groups_screen.dart | 1 - lib/ui/screens/members_screen.dart | 1 - lib/ui/screens/profile_screen.dart | 1 - lib/ui/widgets.dart | 1 + 8 files changed, 1 insertion(+), 8 deletions(-) diff --git a/lib/tosti/tosti_shift_screen.dart b/lib/tosti/tosti_shift_screen.dart index bcbadbcd3..f7b87c0ad 100644 --- a/lib/tosti/tosti_shift_screen.dart +++ b/lib/tosti/tosti_shift_screen.dart @@ -7,8 +7,6 @@ import 'package:reaxit/tosti/models.dart'; import 'package:reaxit/tosti/tosti_api_repository.dart'; import 'package:reaxit/ui/widgets.dart'; -import '../ui/widgets/safe_custom_scrollview.dart'; - class TostiShiftScreen extends StatelessWidget { const TostiShiftScreen({required this.id, required this.api}); diff --git a/lib/ui/screens/calendar_screen.dart b/lib/ui/screens/calendar_screen.dart index 8e28cd495..e8a760baa 100644 --- a/lib/ui/screens/calendar_screen.dart +++ b/lib/ui/screens/calendar_screen.dart @@ -9,7 +9,6 @@ import 'package:reaxit/blocs.dart'; import 'package:reaxit/models.dart'; import 'package:reaxit/ui/theme.dart'; import 'package:reaxit/ui/widgets.dart'; -import 'package:reaxit/ui/widgets/safe_custom_scrollview.dart'; import 'package:sticky_headers/sticky_headers/widget.dart'; import 'package:url_launcher/url_launcher.dart'; diff --git a/lib/ui/screens/event_screen.dart b/lib/ui/screens/event_screen.dart index 1a1cffacf..0d69fcabe 100644 --- a/lib/ui/screens/event_screen.dart +++ b/lib/ui/screens/event_screen.dart @@ -11,7 +11,6 @@ import 'package:reaxit/blocs.dart'; import 'package:reaxit/models.dart'; import 'package:reaxit/routes.dart'; import 'package:reaxit/ui/widgets.dart'; -import 'package:reaxit/ui/widgets/safe_custom_scrollview.dart'; import 'package:share_plus/share_plus.dart'; import 'package:url_launcher/url_launcher.dart'; import 'package:reaxit/config.dart' as config; diff --git a/lib/ui/screens/group_screen.dart b/lib/ui/screens/group_screen.dart index bc8e92f90..848f4ba37 100644 --- a/lib/ui/screens/group_screen.dart +++ b/lib/ui/screens/group_screen.dart @@ -7,7 +7,6 @@ import 'package:reaxit/blocs.dart'; import 'package:reaxit/models.dart'; import 'package:reaxit/routes.dart'; import 'package:reaxit/ui/widgets.dart'; -import 'package:reaxit/ui/widgets/safe_custom_scrollview.dart'; import 'package:url_launcher/url_launcher.dart'; class GroupScreen extends StatelessWidget { diff --git a/lib/ui/screens/groups_screen.dart b/lib/ui/screens/groups_screen.dart index eb26254d9..d209de4fa 100644 --- a/lib/ui/screens/groups_screen.dart +++ b/lib/ui/screens/groups_screen.dart @@ -4,7 +4,6 @@ import 'package:reaxit/blocs/groups_cubit.dart'; import 'package:reaxit/models/group.dart'; import 'package:reaxit/ui/widgets.dart'; import 'package:collection/collection.dart'; -import 'package:reaxit/ui/widgets/safe_custom_scrollview.dart'; class GroupsScreen extends StatefulWidget { final MemberGroupType? currentScreen; diff --git a/lib/ui/screens/members_screen.dart b/lib/ui/screens/members_screen.dart index 8c218e531..223657a87 100644 --- a/lib/ui/screens/members_screen.dart +++ b/lib/ui/screens/members_screen.dart @@ -4,7 +4,6 @@ import 'package:google_fonts/google_fonts.dart'; import 'package:reaxit/api/api_repository.dart'; import 'package:reaxit/blocs.dart'; import 'package:reaxit/ui/widgets.dart'; -import 'package:reaxit/ui/widgets/safe_custom_scrollview.dart'; class MembersScreen extends StatefulWidget { @override diff --git a/lib/ui/screens/profile_screen.dart b/lib/ui/screens/profile_screen.dart index 5c19e02df..f9bc5d565 100644 --- a/lib/ui/screens/profile_screen.dart +++ b/lib/ui/screens/profile_screen.dart @@ -12,7 +12,6 @@ import 'package:reaxit/api/exceptions.dart'; import 'package:reaxit/blocs.dart'; import 'package:reaxit/models.dart'; import 'package:reaxit/ui/widgets.dart'; -import 'package:reaxit/ui/widgets/safe_custom_scrollview.dart'; import 'package:url_launcher/url_launcher.dart'; /// Screen that loads and shows a the profile of the member with `pk`. diff --git a/lib/ui/widgets.dart b/lib/ui/widgets.dart index e3ffbc54d..3d460c33b 100644 --- a/lib/ui/widgets.dart +++ b/lib/ui/widgets.dart @@ -12,3 +12,4 @@ export 'widgets/push_notification_overlay.dart'; export 'widgets/sales_order_dialog.dart'; export 'widgets/tpay_button.dart'; export 'widgets/group_tile.dart'; +export 'widgets/safe_custom_scrollview.dart'; From 83f9f205378c0f2a18468fc80739f2ca74f0f2ab Mon Sep 17 00:00:00 2001 From: jaap aarts Date: Wed, 21 Dec 2022 20:24:51 +0100 Subject: [PATCH 12/14] Fix another lint --- lib/ui/screens/albums_screen.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/ui/screens/albums_screen.dart b/lib/ui/screens/albums_screen.dart index a918b22a3..68a09b740 100644 --- a/lib/ui/screens/albums_screen.dart +++ b/lib/ui/screens/albums_screen.dart @@ -4,7 +4,6 @@ import 'package:google_fonts/google_fonts.dart'; import 'package:reaxit/blocs.dart'; import 'package:reaxit/api/api_repository.dart'; import 'package:reaxit/ui/widgets.dart'; -import 'package:reaxit/ui/widgets/safe_custom_scrollview.dart'; class AlbumsScreen extends StatefulWidget { @override From ed5fc9e6dcadfa6b588a01af9efc2ab43af62f52 Mon Sep 17 00:00:00 2001 From: jaap aarts Date: Wed, 15 Feb 2023 20:49:49 +0100 Subject: [PATCH 13/14] Fix small problem --- lib/ui/screens/calendar_screen.dart | 43 ++++++++++++++--------------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/lib/ui/screens/calendar_screen.dart b/lib/ui/screens/calendar_screen.dart index 521841e26..3d29242f6 100644 --- a/lib/ui/screens/calendar_screen.dart +++ b/lib/ui/screens/calendar_screen.dart @@ -244,28 +244,27 @@ class CalendarScrollView extends StatelessWidget { SliverList( delegate: SliverChildBuilderDelegate( (context, index) { - final month = months[index]; - final events = monthGroupedEvents[month]!; - - final dayGroupedEvents = _groupByDay(events); - final days = dayGroupedEvents.keys.toList(); - - return StickyHeader( - header: SizedBox( - width: double.infinity, - child: Material( - child: Padding( - padding: const EdgeInsets.symmetric(vertical: 8), - child: Text( - month.year == DateTime.now().year - ? monthFormatter - .format(month.toLocal()) - .toUpperCase() - : monthYearFormatter - .format(month.toLocal()) - .toUpperCase(), - style: Theme.of(context).textTheme.titleMedium, - ), + final month = months[index]; + final events = monthGroupedEvents[month]!; + + final dayGroupedEvents = _groupByDay(events); + final days = dayGroupedEvents.keys.toList(); + + return StickyHeader( + header: SizedBox( + width: double.infinity, + child: Material( + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 8), + child: Text( + month.year == DateTime.now().year + ? monthFormatter + .format(month.toLocal()) + .toUpperCase() + : monthYearFormatter + .format(month.toLocal()) + .toUpperCase(), + style: Theme.of(context).textTheme.titleMedium, ), ), ), From 31189616570e357d5e1b8101aefbe82f6e47f654 Mon Sep 17 00:00:00 2001 From: jaap aarts Date: Wed, 15 Feb 2023 20:51:43 +0100 Subject: [PATCH 14/14] Add padding in calendar --- lib/ui/screens/calendar_screen.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ui/screens/calendar_screen.dart b/lib/ui/screens/calendar_screen.dart index 3d29242f6..871b761d6 100644 --- a/lib/ui/screens/calendar_screen.dart +++ b/lib/ui/screens/calendar_screen.dart @@ -239,7 +239,7 @@ class CalendarScrollView extends StatelessWidget { physics: const RangeMaintainingScrollPhysics( parent: AlwaysScrollableScrollPhysics(), ), - padding: const EdgeInsets.symmetric(vertical: 8), + padding: const EdgeInsets.all(8), slivers: [ SliverList( delegate: SliverChildBuilderDelegate(