created help sheets; improvements & bugfixes

This commit is contained in:
Myzel394 2022-08-19 19:40:55 +02:00
parent 909d4f8d89
commit 6d28ee51dd
18 changed files with 679 additions and 245 deletions

View File

@ -0,0 +1,4 @@
enum HelpSheetID {
mainScreen,
timelineScreen,
}

View File

@ -1,2 +1,3 @@
const CACHE_KEY = '_cache'; const CACHE_KEY = '_cache';
const SETTINGS_KEY = 'settings'; const SETTINGS_KEY = 'settings';
const USER_HELP_SHEETS_KEY = 'user_help_sheets';

View File

@ -4,6 +4,7 @@
"generalError": "There was an error", "generalError": "There was an error",
"generalCancelButtonLabel": "Cancel", "generalCancelButtonLabel": "Cancel",
"generalContinueButtonLabel": "Continue", "generalContinueButtonLabel": "Continue",
"generalUnderstoodButtonLabel": "OK",
"welcomeScreenDescription": "Find out what you did all the days and unlock moments you completely forgot!", "welcomeScreenDescription": "Find out what you did all the days and unlock moments you completely forgot!",
"welcomeScreenSubtitle": "What did I do today?", "welcomeScreenSubtitle": "What did I do today?",
@ -46,6 +47,10 @@
"mainScreenTakeVideoActionSaveVideo": "Taking video, please hold still...", "mainScreenTakeVideoActionSaveVideo": "Taking video, please hold still...",
"mainScreenTakeVideoActionUploadingVideo": "Uploading video...", "mainScreenTakeVideoActionUploadingVideo": "Uploading video...",
"mainScreenHelpSheetTitle": "Record your best moments in life",
"mainScreenHelpSheetTakePhotoExplanation": "Tap on the shutter button once to take a photo.",
"mainScreenHelpSheetTakeVideoExplanation": "Hold down the shutter button to start recording a video. Leave the button to stop recording.",
"recordingOverlayIsRecording": "Recording", "recordingOverlayIsRecording": "Recording",
@ -153,6 +158,13 @@
"timelineScreenTitle": "Timeline", "timelineScreenTitle": "Timeline",
"timelineScreenHelpSheetTitle": "Welcome to your timeline",
"timelineHelpContentDescription": "Your memories are displayed in chronological order. You can swipe left or right to navigate through the memories of the given day. You can also swipe up or down to navigate through the days of your memories. The timeline automatically progresses through your memories.",
"timelineHelpContentHoldDownExplanation": "Hold down to pause the timeline from progressing to your next memory.",
"timelineHelpContentTapTwiceExplanation": "Tap twice to see more details about your memory.",
"helpSheetDontShowAgain": "Don't show this help sheet again",
"enumMapping_ResolutionPreset_low": "Low", "enumMapping_ResolutionPreset_low": "Low",

View File

@ -85,7 +85,9 @@ class _MyAppState extends State<MyApp> {
TimelineScreen.ID: (context) => const TimelineScreen(), TimelineScreen.ID: (context) => const TimelineScreen(),
GrantPermissionScreen.ID: (context) => const GrantPermissionScreen(), GrantPermissionScreen.ID: (context) => const GrantPermissionScreen(),
CalendarScreen.ID: (context) => const CalendarScreen(), CalendarScreen.ID: (context) => const CalendarScreen(),
ServerLoadingScreen.ID: (context) => const ServerLoadingScreen(), ServerLoadingScreen.ID: (context) => const ServerLoadingScreen(
isInitialLoading: true,
),
EmptyScreen.ID: (context) => const EmptyScreen(), EmptyScreen.ID: (context) => const EmptyScreen(),
SettingsScreen.ID: (context) => const SettingsScreen(), SettingsScreen.ID: (context) => const SettingsScreen(),
}, },

View File

@ -14,12 +14,16 @@ class CacheManager {
final existingEntry = await storage.read(key: cacheKey); final existingEntry = await storage.read(key: cacheKey);
if (existingEntry != null) { if (existingEntry != null) {
try {
final entry = jsonDecode(existingEntry); final entry = jsonDecode(existingEntry);
final DateTime creationDate = DateTime.parse(entry['creationDate']); final DateTime creationDate = DateTime.parse(entry['creationDate']);
// Check if the entry is still valid using CACHE_INVALIDATION_DURATION as the validity duration. // Check if the entry is still valid using CACHE_INVALIDATION_DURATION as the validity duration.
return DateTime.now().difference(creationDate) < return DateTime.now().difference(creationDate) <
CACHE_INVALIDATION_DURATION; CACHE_INVALIDATION_DURATION;
} catch (_) {
return false;
}
} }
return false; return false;

View File

@ -0,0 +1,27 @@
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:quid_faciam_hodie/constants/help_sheet_id.dart';
import 'package:quid_faciam_hodie/constants/storage_keys.dart';
const storage = FlutterSecureStorage();
class UserHelpSheetsManager {
static String _createKey(final HelpSheetID helpID) =>
'$USER_HELP_SHEETS_KEY/$helpID';
static Future<bool> getIfAlreadyShown(final HelpSheetID helpID) async =>
(await storage.read(key: _createKey(helpID))) == 'true';
static Future<void> setAsShown(final HelpSheetID helpID) async =>
storage.write(
key: _createKey(helpID),
value: 'true',
);
static Future<void> deleteAll() async {
const keys = HelpSheetID.values;
for (final key in keys) {
await storage.delete(key: _createKey(key));
}
}
}

View File

@ -94,7 +94,14 @@ class _LoginScreenState extends AuthState<LoginScreen> with Loadable {
} }
if (mounted) { if (mounted) {
Navigator.pushReplacementNamed(context, ServerLoadingScreen.ID); Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ServerLoadingScreen(
nextScreen: MainScreen.ID,
),
),
);
} }
} }

View File

@ -1,25 +1,30 @@
import 'dart:async';
import 'dart:io'; import 'dart:io';
import 'dart:typed_data'; import 'dart:typed_data';
import 'package:camera/camera.dart'; import 'package:camera/camera.dart';
import 'package:expandable_bottom_sheet/expandable_bottom_sheet.dart'; import 'package:expandable_bottom_sheet/expandable_bottom_sheet.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:flutter_platform_widgets/flutter_platform_widgets.dart'; import 'package:flutter_platform_widgets/flutter_platform_widgets.dart';
import 'package:location/location.dart'; import 'package:location/location.dart';
import 'package:permission_handler/permission_handler.dart'; import 'package:permission_handler/permission_handler.dart';
import 'package:quid_faciam_hodie/constants/help_sheet_id.dart';
import 'package:quid_faciam_hodie/constants/spacing.dart'; import 'package:quid_faciam_hodie/constants/spacing.dart';
import 'package:quid_faciam_hodie/constants/values.dart'; import 'package:quid_faciam_hodie/constants/values.dart';
import 'package:quid_faciam_hodie/extensions/snackbar.dart'; import 'package:quid_faciam_hodie/extensions/snackbar.dart';
import 'package:quid_faciam_hodie/managers/file_manager.dart'; import 'package:quid_faciam_hodie/managers/file_manager.dart';
import 'package:quid_faciam_hodie/managers/global_values_manager.dart'; import 'package:quid_faciam_hodie/managers/global_values_manager.dart';
import 'package:quid_faciam_hodie/screens/main_screen/camera_help_content.dart';
import 'package:quid_faciam_hodie/screens/main_screen/settings_button_overlay.dart'; import 'package:quid_faciam_hodie/screens/main_screen/settings_button_overlay.dart';
import 'package:quid_faciam_hodie/utils/auth_required.dart'; import 'package:quid_faciam_hodie/utils/auth_required.dart';
import 'package:quid_faciam_hodie/utils/loadable.dart'; import 'package:quid_faciam_hodie/utils/loadable.dart';
import 'package:quid_faciam_hodie/utils/tag_location_to_image.dart'; import 'package:quid_faciam_hodie/utils/tag_location_to_image.dart';
import 'package:quid_faciam_hodie/widgets/animate_in_builder.dart'; import 'package:quid_faciam_hodie/widgets/animate_in_builder.dart';
import 'package:quid_faciam_hodie/widgets/fade_and_move_in_animation.dart'; import 'package:quid_faciam_hodie/widgets/fade_and_move_in_animation.dart';
import 'package:quid_faciam_hodie/widgets/help_sheet.dart';
import 'package:quid_faciam_hodie/widgets/icon_button_child.dart'; import 'package:quid_faciam_hodie/widgets/icon_button_child.dart';
import 'package:quid_faciam_hodie/widgets/sheet_indicator.dart'; import 'package:quid_faciam_hodie/widgets/sheet_indicator.dart';
import 'package:supabase_flutter/supabase_flutter.dart'; import 'package:supabase_flutter/supabase_flutter.dart';
@ -330,7 +335,11 @@ class _MainScreenState extends AuthRequiredState<MainScreen> with Loadable {
); );
} }
return Container( return HelpSheet(
title: localizations.mainScreenHelpSheetTitle,
helpContent: const CameraHelpContent(),
helpID: HelpSheetID.mainScreen,
child: Container(
color: Colors.black, color: Colors.black,
child: ExpandableBottomSheet( child: ExpandableBottomSheet(
background: SafeArea( background: SafeArea(
@ -400,8 +409,8 @@ class _MainScreenState extends AuthRequiredState<MainScreen> with Loadable {
child: ChangeCameraButton( child: ChangeCameraButton(
disabled: lockCamera || isRecording, disabled: lockCamera || isRecording,
onChangeCamera: () { onChangeCamera: () {
final currentCameraIndex = GlobalValuesManager final currentCameraIndex =
.cameras GlobalValuesManager.cameras
.indexOf(controller!.description); .indexOf(controller!.description);
final availableCameras = final availableCameras =
GlobalValuesManager.cameras.length; GlobalValuesManager.cameras.length;
@ -477,11 +486,13 @@ class _MainScreenState extends AuthRequiredState<MainScreen> with Loadable {
style: ButtonStyle( style: ButtonStyle(
backgroundColor: backgroundColor:
MaterialStateProperty.resolveWith<Color>( MaterialStateProperty.resolveWith<Color>(
(_) => isTorchEnabled ? Colors.white : Colors.black, (_) =>
isTorchEnabled ? Colors.white : Colors.black,
), ),
foregroundColor: foregroundColor:
MaterialStateProperty.resolveWith<Color>( MaterialStateProperty.resolveWith<Color>(
(_) => isTorchEnabled ? Colors.black : Colors.white, (_) =>
isTorchEnabled ? Colors.black : Colors.white,
), ),
), ),
onPressed: () { onPressed: () {
@ -497,8 +508,8 @@ class _MainScreenState extends AuthRequiredState<MainScreen> with Loadable {
}, },
child: IconButtonChild( child: IconButtonChild(
icon: const Icon(Icons.flashlight_on_rounded), icon: const Icon(Icons.flashlight_on_rounded),
label: label: Text(
Text(localizations.mainScreenActionsTorchButton), localizations.mainScreenActionsTorchButton),
), ),
), ),
ElevatedButton( ElevatedButton(
@ -537,6 +548,7 @@ class _MainScreenState extends AuthRequiredState<MainScreen> with Loadable {
), ),
), ),
), ),
),
); );
}(), }(),
), ),

View File

@ -0,0 +1,60 @@
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:quid_faciam_hodie/constants/spacing.dart';
import 'package:quid_faciam_hodie/utils/theme.dart';
import 'package:quid_faciam_hodie/widgets/help_content_text.dart';
class CameraHelpContent extends StatelessWidget {
const CameraHelpContent({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
final localizations = AppLocalizations.of(context)!;
final iconColor = getBodyTextColor(context).withOpacity(.2);
return Column(
children: <Widget>[
HelpContentText(
icon: Stack(
alignment: Alignment.center,
children: <Widget>[
Icon(
Icons.circle_rounded,
color: iconColor,
),
const Icon(
Icons.circle_rounded,
color: Colors.white,
size: 13,
),
],
),
text: localizations.mainScreenHelpSheetTakePhotoExplanation,
),
const SizedBox(height: MEDIUM_SPACE),
HelpContentText(
icon: Stack(
alignment: Alignment.center,
children: <Widget>[
Icon(
Icons.circle_rounded,
color: iconColor,
),
Icon(
Icons.circle_rounded,
color: Colors.white,
size: 19,
),
Icon(
Icons.square_rounded,
color: Colors.red,
size: 10,
),
],
),
text: localizations.mainScreenHelpSheetTakeVideoExplanation,
),
],
);
}
}

View File

@ -5,11 +5,11 @@ import 'package:provider/provider.dart';
import 'package:quid_faciam_hodie/constants/spacing.dart'; import 'package:quid_faciam_hodie/constants/spacing.dart';
import 'package:quid_faciam_hodie/managers/global_values_manager.dart'; import 'package:quid_faciam_hodie/managers/global_values_manager.dart';
import 'package:quid_faciam_hodie/models/memories.dart'; import 'package:quid_faciam_hodie/models/memories.dart';
import 'package:quid_faciam_hodie/screens/grant_permission_screen.dart';
import 'package:quid_faciam_hodie/screens/login_screen.dart'; import 'package:quid_faciam_hodie/screens/login_screen.dart';
import 'package:supabase_flutter/supabase_flutter.dart'; import 'package:supabase_flutter/supabase_flutter.dart';
import 'empty_screen.dart'; import 'empty_screen.dart';
import 'grant_permission_screen.dart';
import 'main_screen.dart'; import 'main_screen.dart';
import 'server_loading_screen/dot_animation.dart'; import 'server_loading_screen/dot_animation.dart';
import 'welcome_screen.dart'; import 'welcome_screen.dart';
@ -18,10 +18,12 @@ class ServerLoadingScreen extends StatefulWidget {
static const ID = '/'; static const ID = '/';
final String? nextScreen; final String? nextScreen;
final bool isInitialLoading;
const ServerLoadingScreen({ const ServerLoadingScreen({
Key? key, Key? key,
this.nextScreen, this.nextScreen,
this.isInitialLoading = false,
}) : super(key: key); }) : super(key: key);
@override @override
@ -33,16 +35,28 @@ class _ServerLoadingScreenState extends State<ServerLoadingScreen> {
void initState() { void initState() {
super.initState(); super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
load(); load();
});
} }
Future<void> load() async { Future<void> load() async {
if (widget.isInitialLoading) {
await Navigator.pushNamed(
context,
WelcomeScreen.ID,
);
return;
}
if (widget.nextScreen != WelcomeScreen.ID) {
while (!(await GlobalValuesManager.hasGrantedPermissions())) { while (!(await GlobalValuesManager.hasGrantedPermissions())) {
await Navigator.pushNamed( await Navigator.pushNamed(
context, context,
GrantPermissionScreen.ID, GrantPermissionScreen.ID,
); );
} }
}
await GlobalValuesManager.waitForInitialization(); await GlobalValuesManager.waitForInitialization();

View File

@ -1,12 +1,15 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:flutter_platform_widgets/flutter_platform_widgets.dart'; import 'package:flutter_platform_widgets/flutter_platform_widgets.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:quid_faciam_hodie/constants/help_sheet_id.dart';
import 'package:quid_faciam_hodie/extensions/date.dart'; import 'package:quid_faciam_hodie/extensions/date.dart';
import 'package:quid_faciam_hodie/models/memories.dart'; import 'package:quid_faciam_hodie/models/memories.dart';
import 'package:quid_faciam_hodie/models/timeline.dart'; import 'package:quid_faciam_hodie/models/timeline.dart';
import 'package:quid_faciam_hodie/screens/timeline_screen/timeline_help_content.dart';
import 'package:quid_faciam_hodie/utils/loadable.dart'; import 'package:quid_faciam_hodie/utils/loadable.dart';
import 'package:quid_faciam_hodie/widgets/help_sheet.dart';
import 'package:supabase_flutter/supabase_flutter.dart'; import 'package:supabase_flutter/supabase_flutter.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'calendar_screen.dart'; import 'calendar_screen.dart';
import 'empty_screen.dart'; import 'empty_screen.dart';
@ -111,6 +114,15 @@ class _TimelineScreenState extends State<TimelineScreen> with Loadable {
return true; return true;
}, },
child: HelpSheet(
title: localizations.timelineScreenHelpSheetTitle,
helpContent: const TimelineHelpContent(),
helpID: HelpSheetID.timelineScreen,
onSheetShown: timeline.pause,
onSheetHidden: () {
timeline.resume();
print("dfsjnifksdf");
},
child: PlatformScaffold( child: PlatformScaffold(
appBar: isCupertino(context) appBar: isCupertino(context)
? PlatformAppBar( ? PlatformAppBar(
@ -138,6 +150,7 @@ class _TimelineScreenState extends State<TimelineScreen> with Loadable {
), ),
), ),
), ),
),
); );
} }
} }

View File

@ -0,0 +1,41 @@
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:quid_faciam_hodie/constants/spacing.dart';
import 'package:quid_faciam_hodie/utils/theme.dart';
import 'package:quid_faciam_hodie/widgets/help_content_text.dart';
class TimelineHelpContent extends StatelessWidget {
const TimelineHelpContent({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
final localizations = AppLocalizations.of(context)!;
final textColor = getBodyTextColor(context);
return Column(
children: <Widget>[
Text(
localizations.timelineHelpContentDescription,
textAlign: TextAlign.center,
style: getBodyTextTextStyle(context),
),
const SizedBox(height: LARGE_SPACE),
HelpContentText(
icon: Icon(
Icons.touch_app_rounded,
color: textColor,
),
text: localizations.timelineHelpContentHoldDownExplanation,
),
const SizedBox(height: MEDIUM_SPACE),
HelpContentText(
icon: Icon(
Icons.align_vertical_bottom_sharp,
color: textColor,
),
text: localizations.timelineHelpContentTapTwiceExplanation,
),
],
);
}
}

View File

@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:flutter_platform_widgets/flutter_platform_widgets.dart'; import 'package:flutter_platform_widgets/flutter_platform_widgets.dart';
import 'package:quid_faciam_hodie/constants/spacing.dart'; import 'package:quid_faciam_hodie/constants/spacing.dart';
import 'package:quid_faciam_hodie/managers/user_help_sheets_manager.dart';
import 'welcome_screen/pages/get_started_page.dart'; import 'welcome_screen/pages/get_started_page.dart';
import 'welcome_screen/pages/guide_page.dart'; import 'welcome_screen/pages/guide_page.dart';
@ -19,6 +20,13 @@ class WelcomeScreen extends StatefulWidget {
class _WelcomeScreenState extends State<WelcomeScreen> { class _WelcomeScreenState extends State<WelcomeScreen> {
final controller = PageController(); final controller = PageController();
@override
void initState() {
super.initState();
UserHelpSheetsManager.deleteAll();
}
@override @override
void dispose() { void dispose() {
controller.dispose(); controller.dispose();

View File

@ -24,9 +24,11 @@ mixin Loadable {
try { try {
await callback(); await callback();
} finally { } finally {
try {
setState(() { setState(() {
_IDs.remove(id ?? _generalLoadingID); _IDs.remove(id ?? _generalLoadingID);
}); });
} catch (error) {}
} }
} }
} }

View File

@ -0,0 +1,34 @@
import 'package:flutter/material.dart';
import 'package:quid_faciam_hodie/utils/theme.dart';
class HelpContentText extends StatelessWidget {
final String text;
final Widget icon;
const HelpContentText({
Key? key,
required this.text,
required this.icon,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Expanded(
flex: 3,
child: icon,
),
const Spacer(flex: 1),
Expanded(
flex: 8,
child: Text(
text,
style: getBodyTextTextStyle(context),
),
),
],
);
}
}

117
lib/widgets/help_sheet.dart Normal file
View File

@ -0,0 +1,117 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_platform_widgets/flutter_platform_widgets.dart';
import 'package:quid_faciam_hodie/constants/help_sheet_id.dart';
import 'package:quid_faciam_hodie/constants/spacing.dart';
import 'package:quid_faciam_hodie/managers/user_help_sheets_manager.dart';
import 'package:quid_faciam_hodie/widgets/help_sheet/help_sheet_form.dart';
class HelpSheet extends StatefulWidget {
final Widget child;
final String title;
final Widget helpContent;
final HelpSheetID helpID;
final bool forceShow;
final VoidCallback? onSheetShown;
final VoidCallback? onSheetHidden;
const HelpSheet({
Key? key,
required this.child,
required this.title,
required this.helpContent,
required this.helpID,
this.forceShow = false,
this.onSheetShown,
this.onSheetHidden,
}) : super(key: key);
@override
State<HelpSheet> createState() => _HelpSheetState();
}
class _HelpSheetState extends State<HelpSheet> {
bool isShowingSheet = false;
@override
void initState() {
super.initState();
if (widget.forceShow) {
showSheet();
} else {
checkIfSheetShouldBeShown();
}
}
void showSheet() {
if (isShowingSheet) {
return;
}
WidgetsBinding.instance.addPostFrameCallback((_) async {
if (!mounted) {
return;
}
setState(() {
isShowingSheet = true;
});
if (widget.onSheetShown != null) {
widget.onSheetShown!();
}
final dontShowSheetAgain = await showPlatformModalSheet(
material: MaterialModalSheetData(
isDismissible: false,
isScrollControlled: true,
backgroundColor: Colors.transparent,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(LARGE_SPACE),
topRight: Radius.circular(LARGE_SPACE),
),
),
),
context: context,
builder: (_) => HelpSheetForm(
helpContent: widget.helpContent,
title: widget.title,
),
);
if (widget.onSheetHidden != null) {
widget.onSheetHidden!();
}
if (mounted) {
setState(() {
isShowingSheet = false;
});
}
if (dontShowSheetAgain) {
await UserHelpSheetsManager.setAsShown(widget.helpID);
}
});
}
Future<void> checkIfSheetShouldBeShown() async {
final hasSheetBeShownAlready =
await UserHelpSheetsManager.getIfAlreadyShown(widget.helpID);
if (!hasSheetBeShownAlready) {
showSheet();
}
}
@override
Widget build(BuildContext context) {
return AnimatedScale(
scale: isShowingSheet ? .99 : 1,
duration: const Duration(milliseconds: 200),
child: widget.child,
);
}
}

View File

@ -0,0 +1,67 @@
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:flutter_platform_widgets/flutter_platform_widgets.dart';
import 'package:quid_faciam_hodie/constants/spacing.dart';
import 'package:quid_faciam_hodie/utils/theme.dart';
import 'package:quid_faciam_hodie/widgets/modal_sheet.dart';
class HelpSheetForm extends StatefulWidget {
final String title;
final Widget helpContent;
const HelpSheetForm({
Key? key,
required this.helpContent,
required this.title,
}) : super(key: key);
@override
State<HelpSheetForm> createState() => _HelpSheetFormState();
}
class _HelpSheetFormState extends State<HelpSheetForm> {
bool dontShowSheetAgain = true;
@override
Widget build(BuildContext context) {
final localizations = AppLocalizations.of(context)!;
return ModalSheet(
child: Column(
children: <Widget>[
Text(
widget.title,
textAlign: TextAlign.center,
style: getTitleTextStyle(context),
),
const SizedBox(height: MEDIUM_SPACE),
widget.helpContent,
const SizedBox(height: LARGE_SPACE),
PlatformElevatedButton(
child: Text(localizations.generalUnderstoodButtonLabel),
onPressed: () => Navigator.pop(context, dontShowSheetAgain),
),
const SizedBox(height: MEDIUM_SPACE),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
PlatformSwitch(
value: dontShowSheetAgain,
onChanged: (value) {
setState(() {
dontShowSheetAgain = value;
});
},
),
const SizedBox(width: SMALL_SPACE),
Text(
localizations.helpSheetDontShowAgain,
style: getBodyTextTextStyle(context),
)
],
),
],
),
);
}
}

View File

@ -1,6 +1,8 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_platform_widgets/flutter_platform_widgets.dart'; import 'package:flutter_platform_widgets/flutter_platform_widgets.dart';
import 'package:quid_faciam_hodie/constants/spacing.dart'; import 'package:quid_faciam_hodie/constants/spacing.dart';
import 'package:quid_faciam_hodie/utils/theme.dart';
class ModalSheet extends StatelessWidget { class ModalSheet extends StatelessWidget {
final Widget child; final Widget child;
@ -12,30 +14,37 @@ class ModalSheet extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Wrap( final innerChild = Padding(
crossAxisAlignment: WrapCrossAlignment.center, padding: const EdgeInsets.symmetric(horizontal: MEDIUM_SPACE),
children: <Widget>[ child: child,
Padding( );
padding:
EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom), return Column(
child: Material( mainAxisSize: MainAxisSize.min,
children: [
PlatformWidget(
material: (_, __) => Container(
decoration: BoxDecoration(
borderRadius: const BorderRadius.only( borderRadius: const BorderRadius.only(
topLeft: Radius.circular(LARGE_SPACE), topLeft: Radius.circular(LARGE_SPACE),
topRight: Radius.circular(LARGE_SPACE), topRight: Radius.circular(LARGE_SPACE),
), ),
color: platformThemeData( color: getSheetColor(context),
context,
material: (data) =>
data.bottomSheetTheme.modalBackgroundColor ??
data.bottomAppBarColor,
cupertino: (data) => data.barBackgroundColor,
), ),
padding: const EdgeInsets.symmetric(vertical: MEDIUM_SPACE),
child: innerChild,
),
cupertino: (_, __) => CupertinoPopupSurface(
isSurfacePainted: false,
child: Container( child: Container(
padding: const EdgeInsets.all(MEDIUM_SPACE), color: Colors.white,
child: child, child: Padding(
padding: const EdgeInsets.symmetric(vertical: LARGE_SPACE),
child: innerChild,
), ),
), ),
), ),
)
], ],
); );
} }