diff --git a/fastlane/metadata/android/de-DE/changelogs/default.txt b/fastlane/metadata/android/de-DE/changelogs/default.txt index 6e148f7..1aa1b15 100644 --- a/fastlane/metadata/android/de-DE/changelogs/default.txt +++ b/fastlane/metadata/android/de-DE/changelogs/default.txt @@ -1 +1 @@ -Wir haben einige Fehler behoben und die App verbessert. +Schaltflächen und Inhalte werden nicht mehr von der Systemleiste am unteren Bildschirmrand verdeckt. Dazu kleinere Verbesserungen an der Oberfläche. diff --git a/fastlane/metadata/android/en-GB/changelogs/default.txt b/fastlane/metadata/android/en-GB/changelogs/default.txt index 0ae099f..660188e 100644 --- a/fastlane/metadata/android/en-GB/changelogs/default.txt +++ b/fastlane/metadata/android/en-GB/changelogs/default.txt @@ -1 +1 @@ -We fixed a few bugs and polished the app. +Buttons and content are no longer hidden behind the system bar at the bottom of the screen. Plus a few smaller layout fixes. diff --git a/fastlane/metadata/android/es-ES/changelogs/default.txt b/fastlane/metadata/android/es-ES/changelogs/default.txt index edfc6e4..eab7414 100644 --- a/fastlane/metadata/android/es-ES/changelogs/default.txt +++ b/fastlane/metadata/android/es-ES/changelogs/default.txt @@ -1 +1 @@ -Hemos corregido algunos errores y pulido la aplicación. +Los botones y el contenido ya no quedan ocultos tras la barra del sistema en la parte inferior de la pantalla. Además, pequeñas mejoras en la interfaz. diff --git a/fastlane/metadata/android/fr-FR/changelogs/default.txt b/fastlane/metadata/android/fr-FR/changelogs/default.txt index 210ee33..7422027 100644 --- a/fastlane/metadata/android/fr-FR/changelogs/default.txt +++ b/fastlane/metadata/android/fr-FR/changelogs/default.txt @@ -1 +1 @@ -Nous avons corrigé quelques bugs et peaufiné l’application. +Les boutons et le contenu ne sont plus masqués par la barre système en bas de l’écran. Et quelques petites améliorations de l’interface. diff --git a/fastlane/metadata/android/it-IT/changelogs/default.txt b/fastlane/metadata/android/it-IT/changelogs/default.txt index aee1120..d246f74 100644 --- a/fastlane/metadata/android/it-IT/changelogs/default.txt +++ b/fastlane/metadata/android/it-IT/changelogs/default.txt @@ -1 +1 @@ -Abbiamo corretto alcuni errori e migliorato l’app. +I pulsanti e i contenuti non sono più nascosti dalla barra di sistema nella parte inferiore dello schermo. Inoltre, piccoli miglioramenti all’interfaccia. diff --git a/fastlane/metadata/ios/de-DE/release_notes.txt b/fastlane/metadata/ios/de-DE/release_notes.txt index 6e148f7..1aa1b15 100644 --- a/fastlane/metadata/ios/de-DE/release_notes.txt +++ b/fastlane/metadata/ios/de-DE/release_notes.txt @@ -1 +1 @@ -Wir haben einige Fehler behoben und die App verbessert. +Schaltflächen und Inhalte werden nicht mehr von der Systemleiste am unteren Bildschirmrand verdeckt. Dazu kleinere Verbesserungen an der Oberfläche. diff --git a/fastlane/metadata/ios/en-GB/release_notes.txt b/fastlane/metadata/ios/en-GB/release_notes.txt index 0ae099f..660188e 100644 --- a/fastlane/metadata/ios/en-GB/release_notes.txt +++ b/fastlane/metadata/ios/en-GB/release_notes.txt @@ -1 +1 @@ -We fixed a few bugs and polished the app. +Buttons and content are no longer hidden behind the system bar at the bottom of the screen. Plus a few smaller layout fixes. diff --git a/fastlane/metadata/ios/es-ES/release_notes.txt b/fastlane/metadata/ios/es-ES/release_notes.txt index edfc6e4..eab7414 100644 --- a/fastlane/metadata/ios/es-ES/release_notes.txt +++ b/fastlane/metadata/ios/es-ES/release_notes.txt @@ -1 +1 @@ -Hemos corregido algunos errores y pulido la aplicación. +Los botones y el contenido ya no quedan ocultos tras la barra del sistema en la parte inferior de la pantalla. Además, pequeñas mejoras en la interfaz. diff --git a/fastlane/metadata/ios/fr-FR/release_notes.txt b/fastlane/metadata/ios/fr-FR/release_notes.txt index 210ee33..7422027 100644 --- a/fastlane/metadata/ios/fr-FR/release_notes.txt +++ b/fastlane/metadata/ios/fr-FR/release_notes.txt @@ -1 +1 @@ -Nous avons corrigé quelques bugs et peaufiné l’application. +Les boutons et le contenu ne sont plus masqués par la barre système en bas de l’écran. Et quelques petites améliorations de l’interface. diff --git a/fastlane/metadata/ios/it/release_notes.txt b/fastlane/metadata/ios/it/release_notes.txt index aee1120..d246f74 100644 --- a/fastlane/metadata/ios/it/release_notes.txt +++ b/fastlane/metadata/ios/it/release_notes.txt @@ -1 +1 @@ -Abbiamo corretto alcuni errori e migliorato l’app. +I pulsanti e i contenuti non sono più nascosti dalla barra di sistema nella parte inferiore dello schermo. Inoltre, piccoli miglioramenti all’interfaccia. diff --git a/lib/presentation/screens/auth.dart b/lib/presentation/screens/auth.dart index 581c703..c8b4e4a 100644 --- a/lib/presentation/screens/auth.dart +++ b/lib/presentation/screens/auth.dart @@ -29,32 +29,35 @@ class AuthScreen extends StatelessWidget { // TODO(borgoat): this shouldn't be needed: fix the navigation stack instead automaticallyImplyLeading: false, ), - body: SingleChildScrollView( - padding: const EdgeInsets.symmetric(horizontal: 16), - child: Column( - children: [ - SupaEmailAuth( - redirectTo: _getRedirectUrl(), - // The Redux auth listener (main.dart) also reacts to sign-in, but upstream - // supabase_auth_ui requires these callbacks; navigate home to match - // SupaSocialsAuth.onSuccess below. - onSignInComplete: (response) => HomeScreenRoute().go(context), - // Email confirmation is disabled, so sign-up yields a session immediately. - // TODO: if confirmations get enabled, show a "check your email" state instead. - onSignUpComplete: (response) => HomeScreenRoute().go(context), - ), - Divider(height: 64), - SupaSocialsAuth( - socialProviders: [OAuthProvider.apple, OAuthProvider.google], - nativeGoogleAuthConfig: NativeGoogleAuthConfig( - webClientId: config.socialAuthWebClientId, - iosClientId: config.socialAuthIosClientId, + body: SafeArea( + top: false, + child: SingleChildScrollView( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: Column( + children: [ + SupaEmailAuth( + redirectTo: _getRedirectUrl(), + // The Redux auth listener (main.dart) also reacts to sign-in, but upstream + // supabase_auth_ui requires these callbacks; navigate home to match + // SupaSocialsAuth.onSuccess below. + onSignInComplete: (response) => HomeScreenRoute().go(context), + // Email confirmation is disabled, so sign-up yields a session immediately. + // TODO: if confirmations get enabled, show a "check your email" state instead. + onSignUpComplete: (response) => HomeScreenRoute().go(context), ), - enableNativeAppleAuth: true, - redirectUrl: _getRedirectUrl(), - onSuccess: (session) => HomeScreenRoute().go(context), - ), - ], + Divider(height: 64), + SupaSocialsAuth( + socialProviders: [OAuthProvider.apple, OAuthProvider.google], + nativeGoogleAuthConfig: NativeGoogleAuthConfig( + webClientId: config.socialAuthWebClientId, + iosClientId: config.socialAuthIosClientId, + ), + enableNativeAppleAuth: true, + redirectUrl: _getRedirectUrl(), + onSuccess: (session) => HomeScreenRoute().go(context), + ), + ], + ), ), ), ); diff --git a/lib/presentation/screens/group_member_details.dart b/lib/presentation/screens/group_member_details.dart index 5b149d1..3b5cbc6 100644 --- a/lib/presentation/screens/group_member_details.dart +++ b/lib/presentation/screens/group_member_details.dart @@ -112,7 +112,7 @@ class GroupMemberDetailsScreen extends StatelessWidget { ListTile( leading: const Icon(Icons.group_remove_outlined), title: Text(l10n.groupRemoveMember), - splashColor: theme.colorScheme.error.withOpacity(0.3), + splashColor: theme.colorScheme.error.withValues(alpha: 0.3), iconColor: theme.colorScheme.error, textColor: theme.colorScheme.error, onTap: () => _confirmRemoveMember(context, member!), @@ -121,7 +121,7 @@ class GroupMemberDetailsScreen extends StatelessWidget { ListTile( leading: const Icon(Icons.waving_hand), title: Text(l10n.groupLeave), - splashColor: theme.colorScheme.error.withOpacity(0.3), + splashColor: theme.colorScheme.error.withValues(alpha: 0.3), iconColor: theme.colorScheme.error, textColor: theme.colorScheme.error, onTap: () => _confirmRemoveMember(context, member!), diff --git a/lib/presentation/screens/group_schedule_details.dart b/lib/presentation/screens/group_schedule_details.dart index fc0ae7f..c7fe374 100644 --- a/lib/presentation/screens/group_schedule_details.dart +++ b/lib/presentation/screens/group_schedule_details.dart @@ -143,6 +143,13 @@ class GroupScheduleDetailsScreen extends StatelessWidget { }, ), ], + // CustomScrollView slivers don't apply the bottom view inset + // automatically (unlike ListView), so pad past the system nav bar. + SliverPadding( + padding: EdgeInsets.only( + bottom: MediaQuery.paddingOf(context).bottom, + ), + ), ], ), ); diff --git a/lib/presentation/screens/locale.dart b/lib/presentation/screens/locale.dart index bc6bfa0..b638b6a 100644 --- a/lib/presentation/screens/locale.dart +++ b/lib/presentation/screens/locale.dart @@ -26,26 +26,26 @@ class LocaleScreen extends StatelessWidget { final l10n = AppLocalizations.of(context)!; final radioButtons = AppLocalizations.supportedLocales.map( - (l) => RadioListTile.adaptive( + (l) => RadioListTile.adaptive( title: Text(localeNames[l.languageCode] ?? l.languageCode), - groupValue: selectedLocale, value: l, - onChanged: (l) => onLocaleChanged(l!), ), ); return Scaffold( appBar: AppBar(title: Text(l10n.language)), - body: Column( - children: [ - RadioListTile.adaptive( - title: Text(l10n.systemLanguage), - groupValue: selectedLocale, - value: null, - onChanged: (l) => onLocaleChanged(null), - ), - ...radioButtons, - ], + body: RadioGroup( + groupValue: selectedLocale, + onChanged: onLocaleChanged, + child: ListView( + children: [ + RadioListTile.adaptive( + title: Text(l10n.systemLanguage), + value: null, + ), + ...radioButtons, + ], + ), ), ); } diff --git a/lib/presentation/screens/profile.dart b/lib/presentation/screens/profile.dart index 2504229..92c86ab 100644 --- a/lib/presentation/screens/profile.dart +++ b/lib/presentation/screens/profile.dart @@ -63,77 +63,80 @@ class _ProfileScreenState extends State { ), ], ), - body: Form( - key: _formKey, - autovalidateMode: AutovalidateMode.onUserInteraction, - onChanged: () { - setState(() { - if (_formKey.currentState!.validate()) { - _enableSaveButton = true; - } else { - _enableSaveButton = false; - } - }); - }, - child: Column( - children: [ - Expanded( - child: SingleChildScrollView( - padding: const EdgeInsets.all(16), - child: Column( - children: [ - ImageFormField( - controller: _imageController, - initialImage: widget.profile?.picture != null - ? NetworkImage(widget.profile!.picture!) - : null, - radius: 64, - icon: Icons.person, - ), - TextFormField( - focusNode: _nameFocusNode, - controller: _nameController, - decoration: InputDecoration( - labelText: l10n.enterYourName, + body: SafeArea( + top: false, + child: Form( + key: _formKey, + autovalidateMode: AutovalidateMode.onUserInteraction, + onChanged: () { + setState(() { + if (_formKey.currentState!.validate()) { + _enableSaveButton = true; + } else { + _enableSaveButton = false; + } + }); + }, + child: Column( + children: [ + Expanded( + child: SingleChildScrollView( + padding: const EdgeInsets.all(16), + child: Column( + children: [ + ImageFormField( + controller: _imageController, + initialImage: widget.profile?.picture != null + ? NetworkImage(widget.profile!.picture!) + : null, + radius: 64, + icon: Icons.person, ), - validator: (value) { - if (value == null || value.isEmpty) { - return l10n.enterYourNamePlease; - } - return null; - }, - ), - // TODO(borgoat): options to link additional auth providers - ], + TextFormField( + focusNode: _nameFocusNode, + controller: _nameController, + decoration: InputDecoration( + labelText: l10n.enterYourName, + ), + validator: (value) { + if (value == null || value.isEmpty) { + return l10n.enterYourNamePlease; + } + return null; + }, + ), + // TODO(borgoat): options to link additional auth providers + ], + ), ), ), - ), - Padding( - padding: const EdgeInsets.all(16), - child: FilledButton( - onPressed: _enableSaveButton - ? () { - if (_formKey.currentState!.validate()) { - setState(() { - _enableSaveButton = false; - }); - _formKey.currentState!.save(); - _nameFocusNode.unfocus(); - widget.onSave(( - _nameController.text.trim(), - _imageController.value, - )); + Padding( + padding: const EdgeInsets.all(16), + child: FilledButton( + onPressed: _enableSaveButton + ? () { + if (_formKey.currentState!.validate()) { + setState(() { + _enableSaveButton = false; + }); + _formKey.currentState!.save(); + _nameFocusNode.unfocus(); + widget.onSave(( + _nameController.text.trim(), + _imageController.value, + )); - if (!(widget.userNavigated ?? false)) { - Navigator.of(context).pop(context); + if (!(widget.userNavigated ?? false)) { + Navigator.of(context).pop(context); + } } } - } - : null, - child: Text(l10n.save), + : null, + child: Text(l10n.save), + ), ), - ), - ], + ], + ), ), ), ); diff --git a/lib/presentation/screens/schedule_create.dart b/lib/presentation/screens/schedule_create.dart index 506dd2b..50ccce8 100644 --- a/lib/presentation/screens/schedule_create.dart +++ b/lib/presentation/screens/schedule_create.dart @@ -21,15 +21,18 @@ class _ScheduleCreateScreenState extends State { return Scaffold( appBar: AppBar(title: Text(l10n.createNewEvent)), - body: SingleChildScrollView( - padding: const EdgeInsets.all(16.0), - child: ScheduleForm( - onChanged: (schedule) { - setState(() { - _showSaveButton = true; - }); - _schedule = schedule; - }, + body: SafeArea( + top: false, + child: SingleChildScrollView( + padding: const EdgeInsets.all(16.0), + child: ScheduleForm( + onChanged: (schedule) { + setState(() { + _showSaveButton = true; + }); + _schedule = schedule; + }, + ), ), ), floatingActionButton: _showSaveButton diff --git a/lib/presentation/widgets/default_rule_action_sheet.dart b/lib/presentation/widgets/default_rule_action_sheet.dart index 27462bb..eb0dea0 100644 --- a/lib/presentation/widgets/default_rule_action_sheet.dart +++ b/lib/presentation/widgets/default_rule_action_sheet.dart @@ -38,12 +38,15 @@ class DefaultRuleActionSheet extends StatelessWidget { ), ]; - return Wrap( - children: [ - _buildActionSheetHeader(context), - ...actions, - _buildExplanationWidget(context), - ], + return SafeArea( + top: false, + child: Wrap( + children: [ + _buildActionSheetHeader(context), + ...actions, + _buildExplanationWidget(context), + ], + ), ); } diff --git a/lib/presentation/widgets/delete_profile_tile.dart b/lib/presentation/widgets/delete_profile_tile.dart index 4ef659f..9106b2f 100644 --- a/lib/presentation/widgets/delete_profile_tile.dart +++ b/lib/presentation/widgets/delete_profile_tile.dart @@ -19,9 +19,9 @@ class DeleteProfileTile extends StatelessWidget { leading: const Icon(Icons.delete), // Show in red to indicate danger. iconColor: theme.colorScheme.error, - splashColor: theme.colorScheme.error.withOpacity(0.2), - hoverColor: theme.colorScheme.error.withOpacity(0.1), - focusColor: theme.colorScheme.error.withOpacity(0.1), + splashColor: theme.colorScheme.error.withValues(alpha: 0.2), + hoverColor: theme.colorScheme.error.withValues(alpha: 0.1), + focusColor: theme.colorScheme.error.withValues(alpha: 0.1), textColor: theme.colorScheme.error, onTap: () => _confirmDelete(context), ); diff --git a/lib/presentation/widgets/group_events.dart b/lib/presentation/widgets/group_events.dart index 24f82be..03d77ca 100644 --- a/lib/presentation/widgets/group_events.dart +++ b/lib/presentation/widgets/group_events.dart @@ -68,16 +68,19 @@ class GroupEvents extends StatelessWidget { ), ); - return Padding( - padding: const EdgeInsets.symmetric(vertical: 16.0), - child: Column( - children: [ - Expanded(child: topWidget), - FilledButton( - onPressed: () => _createNewEvent(context), - child: Text(l10n.createNewEvent), - ), - ], + return SafeArea( + top: false, + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 16.0), + child: Column( + children: [ + Expanded(child: topWidget), + FilledButton( + onPressed: () => _createNewEvent(context), + child: Text(l10n.createNewEvent), + ), + ], + ), ), ); } diff --git a/lib/presentation/widgets/group_form.dart b/lib/presentation/widgets/group_form.dart index fa184cd..7d074f6 100644 --- a/lib/presentation/widgets/group_form.dart +++ b/lib/presentation/widgets/group_form.dart @@ -49,83 +49,88 @@ class _GroupFormState extends State { return Form( key: _formKey, - child: Column( - children: [ - Expanded( - child: SingleChildScrollView( - padding: const EdgeInsets.all(16), - child: Column( - children: [ - ListenableBuilder( - listenable: _nameController, - builder: (context, child) => ImageFormField( - radius: 64, - icon: Icons.group, - color: colorScheme.secondary, - controller: _imageController, - initialImage: widget.group?.picture != null - ? NetworkImage(widget.group!.picture!) - : null, + child: SafeArea( + top: false, + child: Column( + children: [ + Expanded( + child: SingleChildScrollView( + padding: const EdgeInsets.all(16), + child: Column( + children: [ + ListenableBuilder( + listenable: _nameController, + builder: (context, child) => ImageFormField( + radius: 64, + icon: Icons.group, + color: colorScheme.secondary, + controller: _imageController, + initialImage: widget.group?.picture != null + ? NetworkImage(widget.group!.picture!) + : null, + ), ), - ), - TextFormField( - controller: _nameController, - decoration: InputDecoration( - labelText: l10n.enterGroupName, - suffixIcon: const Icon(Icons.mood), + TextFormField( + controller: _nameController, + decoration: InputDecoration( + labelText: l10n.enterGroupName, + suffixIcon: const Icon(Icons.mood), + ), + maxLength: 32, + maxLengthEnforcement: MaxLengthEnforcement.enforced, + validator: (value) { + if (value == null || value.isEmpty) { + return l10n.enterGroupNamePlease; + } + return null; + }, ), - maxLength: 32, - maxLengthEnforcement: MaxLengthEnforcement.enforced, - validator: (value) { - if (value == null || value.isEmpty) { - return l10n.enterGroupNamePlease; - } - return null; - }, - ), - TextFormField( - controller: _descriptionController, - minLines: 2, - maxLines: 5, - maxLength: 256, - maxLengthEnforcement: MaxLengthEnforcement.enforced, - autocorrect: true, - decoration: InputDecoration( - suffixIcon: const Icon(Icons.description_outlined), - hintText: l10n.enterGroupDescription, - border: const OutlineInputBorder(), + TextFormField( + controller: _descriptionController, + minLines: 2, + maxLines: 5, + maxLength: 256, + maxLengthEnforcement: MaxLengthEnforcement.enforced, + autocorrect: true, + decoration: InputDecoration( + suffixIcon: const Icon(Icons.description_outlined), + hintText: l10n.enterGroupDescription, + border: const OutlineInputBorder(), + ), ), - ), - ], + ], + ), ), ), - ), - Padding( - padding: const EdgeInsets.all(16), - child: FilledButton( - onPressed: () { - if (_formKey.currentState!.validate()) { - final displayName = _nameController.text.trim(); - final description = _descriptionController.text.trim(); - final picture = _imageController.value; + Padding( + padding: const EdgeInsets.all(16), + child: FilledButton( + onPressed: () { + if (_formKey.currentState!.validate()) { + final displayName = _nameController.text.trim(); + final description = _descriptionController.text.trim(); + final picture = _imageController.value; - _formKey.currentState!.save(); - widget.onSave(( - Group( - id: widget.group?.id ?? '', - displayName: displayName, - description: description.isNotEmpty ? description : null, - ), - picture, - )); - } - }, - child: Text( - widget.group != null ? l10n.save : l10n.createNewGroup, + _formKey.currentState!.save(); + widget.onSave(( + Group( + id: widget.group?.id ?? '', + displayName: displayName, + description: description.isNotEmpty + ? description + : null, + ), + picture, + )); + } + }, + child: Text( + widget.group != null ? l10n.save : l10n.createNewGroup, + ), ), ), - ), - ], + ], + ), ), ); } diff --git a/lib/presentation/widgets/group_join.dart b/lib/presentation/widgets/group_join.dart index 6c7da78..77d3cf6 100644 --- a/lib/presentation/widgets/group_join.dart +++ b/lib/presentation/widgets/group_join.dart @@ -36,52 +36,55 @@ class _GroupJoinState extends State { return Form( key: _formKey, - child: Column( - children: [ - Expanded( - child: SingleChildScrollView( - padding: const EdgeInsets.all(16), - child: Column( - children: [ - FormBuilderTextField( - name: 'code', - valueTransformer: (value) => value?.toUpperCase(), - controller: _codeController, - decoration: InputDecoration( - labelText: l10n.enterInviteCode, - suffixIcon: const Icon(Icons.confirmation_num_outlined), - hintText: 'ABCD-1234', + child: SafeArea( + top: false, + child: Column( + children: [ + Expanded( + child: SingleChildScrollView( + padding: const EdgeInsets.all(16), + child: Column( + children: [ + FormBuilderTextField( + name: 'code', + valueTransformer: (value) => value?.toUpperCase(), + controller: _codeController, + decoration: InputDecoration( + labelText: l10n.enterInviteCode, + suffixIcon: const Icon(Icons.confirmation_num_outlined), + hintText: 'ABCD-1234', + ), + inputFormatters: [ + Base32TextInputFormatter(), + LengthLimitingTextInputFormatter(9), + ], + validator: (value) { + if (value == null || value.isEmpty) { + return l10n.enterInviteCodePlease; + } + return null; + }, ), - inputFormatters: [ - Base32TextInputFormatter(), - LengthLimitingTextInputFormatter(9), - ], - validator: (value) { - if (value == null || value.isEmpty) { - return l10n.enterInviteCodePlease; - } - return null; - }, - ), - ], + ], + ), ), ), - ), - Padding( - padding: const EdgeInsets.all(16), - child: ValueListenableBuilder( - valueListenable: _codeController, - builder: (context, value, child) => FilledButton( - onPressed: () { - if (_formKey.currentState!.validate()) { - widget.onJoin(_codeController.text); - } - }, - child: Text(l10n.joinGroup), + Padding( + padding: const EdgeInsets.all(16), + child: ValueListenableBuilder( + valueListenable: _codeController, + builder: (context, value, child) => FilledButton( + onPressed: () { + if (_formKey.currentState!.validate()) { + widget.onJoin(_codeController.text); + } + }, + child: Text(l10n.joinGroup), + ), ), ), - ), - ], + ], + ), ), ); } diff --git a/lib/presentation/widgets/group_members.dart b/lib/presentation/widgets/group_members.dart index 0ab694f..304f03c 100644 --- a/lib/presentation/widgets/group_members.dart +++ b/lib/presentation/widgets/group_members.dart @@ -72,16 +72,19 @@ class GroupMembers extends StatelessWidget { ), ); - return Padding( - padding: const EdgeInsets.symmetric(vertical: 16.0), - child: Column( - children: [ - Expanded(child: topWidget), - FilledButton( - onPressed: () => _showInviteModal(context), - child: Text(l10n.inviteMembersCTA), - ), - ], + return SafeArea( + top: false, + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 16.0), + child: Column( + children: [ + Expanded(child: topWidget), + FilledButton( + onPressed: () => _showInviteModal(context), + child: Text(l10n.inviteMembersCTA), + ), + ], + ), ), ); } diff --git a/lib/presentation/widgets/invite_modal.dart b/lib/presentation/widgets/invite_modal.dart index 05053f8..0dee812 100644 --- a/lib/presentation/widgets/invite_modal.dart +++ b/lib/presentation/widgets/invite_modal.dart @@ -13,52 +13,55 @@ class InviteModal extends StatelessWidget { Widget build(BuildContext context) { final l10n = AppLocalizations.of(context)!; - return Column( - mainAxisSize: MainAxisSize.min, - children: [ - Padding( - padding: const EdgeInsets.all(16.0), - child: Text( - l10n.invite, - style: Theme.of(context).textTheme.titleLarge, - textAlign: TextAlign.center, + return SafeArea( + top: false, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Padding( + padding: const EdgeInsets.all(16.0), + child: Text( + l10n.invite, + style: Theme.of(context).textTheme.titleLarge, + textAlign: TextAlign.center, + ), ), - ), - const Divider(height: 1), - Padding( - padding: const EdgeInsets.symmetric(vertical: 16.0), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - _buildOption( - context, - icon: Icons.email, - label: l10n.contactEmail, - option: InviteOptions.email, - ), - _buildOption( - context, - icon: Icons.phone, - label: l10n.contactPhone, - option: InviteOptions.phone, - ), - if (!kIsWeb) + const Divider(height: 1), + Padding( + padding: const EdgeInsets.symmetric(vertical: 16.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ _buildOption( context, - icon: Icons.contacts, - label: l10n.contacts, - option: InviteOptions.contacts, + icon: Icons.email, + label: l10n.contactEmail, + option: InviteOptions.email, ), - _buildOption( - context, - icon: Icons.person_outline, - label: l10n.guest, - option: InviteOptions.guest, - ), - ], + _buildOption( + context, + icon: Icons.phone, + label: l10n.contactPhone, + option: InviteOptions.phone, + ), + if (!kIsWeb) + _buildOption( + context, + icon: Icons.contacts, + label: l10n.contacts, + option: InviteOptions.contacts, + ), + _buildOption( + context, + icon: Icons.person_outline, + label: l10n.guest, + option: InviteOptions.guest, + ), + ], + ), ), - ), - ], + ], + ), ); } diff --git a/pubspec.yaml b/pubspec.yaml index b1a47f6..1121d49 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -16,7 +16,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html # In Windows, build-name is used as the major, minor, and patch parts # of the product and file versions while build-number is used as the build suffix. -version: 1.7.2+1 +version: 1.7.3+1 environment: sdk: ^3.8.0