added record button behavior to settings

This commit is contained in:
Myzel394 2022-08-25 10:37:35 +02:00
parent b8ad3b8d43
commit ecfe71cfa9
6 changed files with 244 additions and 54 deletions

View File

@ -0,0 +1,15 @@
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:quid_faciam_hodie/enums/record_button_behavior.dart';
Map<RecordButtonBehavior, String> getRecordButtonBehaviorTextMapping(
final BuildContext context) {
final localizations = AppLocalizations.of(context)!;
return {
RecordButtonBehavior.holdRecording:
localizations.enumMapping_RecordButtonBehavior_holdRecording,
RecordButtonBehavior.switchRecording:
localizations.enumMapping_RecordButtonBehavior_switchRecording,
};
}

View File

@ -0,0 +1,4 @@
enum RecordButtonBehavior {
holdRecording,
switchRecording,
}

View File

@ -159,6 +159,7 @@
"settingsScreenDeleteAccountConfirmLabel": "Delete Account now",
"settingsScreenGeneralSectionTitle": "General",
"settingsScreenGeneralSectionQualityLabel": "Quality",
"settingsScreenGeneralSectionRecordButtonBehaviorLabel": "Record Behavior",
"settingsScreenGeneralSectionAskForMemoryAnnotationsLabel": "Ask for memory annotations",
"settingsScreenGeneralSectionStartRecordingOnStartupLabel": "Automatically start recording on startup",
"settingsScreenResetHelpSheetsLabel": "Reset Help Sheets",
@ -194,5 +195,8 @@
"enumMapping_ResolutionPreset_high": "High",
"enumMapping_ResolutionPreset_veryHigh": "Very High",
"enumMapping_ResolutionPreset_ultraHigh": "Ultra High",
"enumMapping_ResolutionPreset_max": "Max"
"enumMapping_ResolutionPreset_max": "Max",
"enumMapping_RecordButtonBehavior_holdRecording": "Hold to record",
"enumMapping_RecordButtonBehavior_switchRecording": "Tap to start recording, tap again to stop "
}

View File

@ -5,29 +5,37 @@ import 'package:collection/collection.dart';
import 'package:flutter/material.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:quid_faciam_hodie/constants/storage_keys.dart';
import 'package:quid_faciam_hodie/enums/record_button_behavior.dart';
import 'package:quid_faciam_hodie/utils/string_to_bool.dart';
const secure = FlutterSecureStorage();
class Settings extends ChangeNotifier {
ResolutionPreset _resolution = ResolutionPreset.max;
RecordButtonBehavior _recordButtonBehavior =
RecordButtonBehavior.holdRecording;
bool _askForMemoryAnnotations = false;
bool _recordOnStartup = false;
Settings(
{final ResolutionPreset? resolution,
Settings({
final ResolutionPreset? resolution,
final RecordButtonBehavior? recordButtonBehavior,
final bool? askForMemoryAnnotations,
final bool? recordOnStartup})
: _resolution = resolution ?? ResolutionPreset.max,
final bool? recordOnStartup,
}) : _resolution = resolution ?? ResolutionPreset.max,
_askForMemoryAnnotations = askForMemoryAnnotations ?? true,
_recordOnStartup = recordOnStartup ?? false;
_recordOnStartup = recordOnStartup ?? false,
_recordButtonBehavior =
recordButtonBehavior ?? RecordButtonBehavior.holdRecording;
ResolutionPreset get resolution => _resolution;
RecordButtonBehavior get recordButtonBehavior => _recordButtonBehavior;
bool get askForMemoryAnnotations => _askForMemoryAnnotations;
bool get recordOnStartup => _recordOnStartup;
Map<String, dynamic> toJSONData() => {
'resolution': _resolution.toString(),
'recordButtonBehavior': _recordButtonBehavior.toString(),
'askForMemoryAnnotations': _askForMemoryAnnotations ? 'true' : 'false',
'recordOnStartup': _recordOnStartup ? 'true' : 'false',
};
@ -52,6 +60,9 @@ class Settings extends ChangeNotifier {
final resolution = ResolutionPreset.values.firstWhereOrNull(
(preset) => preset.toString() == data['resolution'],
);
final recordButtonBehavior = RecordButtonBehavior.values.firstWhereOrNull(
(preset) => preset.toString() == data['recordButtonBehavior'],
);
final askForMemoryAnnotations =
stringToBool(data['askForMemoryAnnotations']);
final recordOnStartup = stringToBool(data['recordOnStartup']);
@ -60,6 +71,7 @@ class Settings extends ChangeNotifier {
resolution: resolution,
askForMemoryAnnotations: askForMemoryAnnotations,
recordOnStartup: recordOnStartup,
recordButtonBehavior: recordButtonBehavior,
);
}
@ -69,6 +81,12 @@ class Settings extends ChangeNotifier {
save();
}
void setRecordButtonBehavior(final RecordButtonBehavior behavior) {
_recordButtonBehavior = behavior;
notifyListeners();
save();
}
void setAskForMemoryAnnotations(final bool askForMemoryAnnotations) {
_askForMemoryAnnotations = askForMemoryAnnotations;
notifyListeners();

View File

@ -7,7 +7,9 @@ import 'package:flutter_platform_widgets/flutter_platform_widgets.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:intl/intl.dart';
import 'package:quid_faciam_hodie/constants/spacing.dart';
import 'package:quid_faciam_hodie/enum_mapping/record_button_behavior/texts.dart';
import 'package:quid_faciam_hodie/enum_mapping/resolution_preset/texts.dart';
import 'package:quid_faciam_hodie/enums/record_button_behavior.dart';
import 'package:quid_faciam_hodie/extensions/snackbar.dart';
import 'package:quid_faciam_hodie/managers/global_values_manager.dart';
import 'package:quid_faciam_hodie/managers/user_help_sheets_manager.dart';
@ -15,10 +17,11 @@ import 'package:quid_faciam_hodie/screens/welcome_screen.dart';
import 'package:quid_faciam_hodie/utils/auth_required.dart';
import 'package:quid_faciam_hodie/utils/loadable.dart';
import 'package:quid_faciam_hodie/utils/theme.dart';
import 'package:quid_faciam_hodie/widgets/cupertino_dropdown.dart';
import 'package:settings_ui/settings_ui.dart';
import 'package:supabase_flutter/supabase_flutter.dart';
import 'settings_screen/dropdown_tile.dart';
final supabase = Supabase.instance.client;
const storage = FlutterSecureStorage();
@ -84,46 +87,6 @@ class _SettingsScreenState extends AuthRequiredState<SettingsScreen>
);
}
Widget getQualityPicker() {
final settings = GlobalValuesManager.settings!;
final resolutionTextMapping = getResolutionTextMapping(context);
final items = ResolutionPreset.values
.map(
(value) => DropdownMenuItem<ResolutionPreset>(
value: value,
child: Text(resolutionTextMapping[value]!),
),
)
.toList();
if (isMaterial(context)) {
return DropdownButtonFormField<ResolutionPreset>(
value: settings.resolution,
onChanged: (value) {
if (value == null) {
return;
}
settings.setResolution(value);
},
items: items,
);
} else {
return CupertinoDropdownButton<ResolutionPreset>(
itemExtent: 30,
onChanged: (value) {
if (value == null) {
return;
}
settings.setResolution(value);
},
value: settings.resolution,
items: items,
);
}
}
@override
Widget build(BuildContext context) {
final settings = GlobalValuesManager.settings!;
@ -202,13 +165,29 @@ class _SettingsScreenState extends AuthRequiredState<SettingsScreen>
title: Text(
localizations.settingsScreenGeneralSectionTitle,
),
tiles: <SettingsTile>[
SettingsTile(
leading: Text(
tiles: [
SettingsDropdownTile<ResolutionPreset>(
leading: const Icon(Icons.high_quality),
title: Text(
localizations
.settingsScreenGeneralSectionQualityLabel,
),
title: getQualityPicker(),
onUpdate: settings.setResolution,
textMapping: getResolutionTextMapping(context),
value: settings.resolution,
values: ResolutionPreset.values,
),
SettingsDropdownTile<RecordButtonBehavior>(
leading: const Icon(Icons.fiber_manual_record),
title: Text(
localizations
.settingsScreenGeneralSectionRecordButtonBehaviorLabel,
),
onUpdate: settings.setRecordButtonBehavior,
textMapping:
getRecordButtonBehaviorTextMapping(context),
value: settings.recordButtonBehavior,
values: RecordButtonBehavior.values,
),
SettingsTile.switchTile(
initialValue: settings.askForMemoryAnnotations,
@ -221,8 +200,10 @@ class _SettingsScreenState extends AuthRequiredState<SettingsScreen>
SettingsTile.switchTile(
initialValue: settings.recordOnStartup,
onToggle: settings.setRecordOnStartup,
title: Text(localizations
.settingsScreenGeneralSectionStartRecordingOnStartupLabel),
title: Text(
localizations
.settingsScreenGeneralSectionStartRecordingOnStartupLabel,
),
),
SettingsTile(
leading: Icon(context.platformIcons.help),

View File

@ -0,0 +1,168 @@
import 'package:flutter/material.dart';
import 'package:settings_ui/settings_ui.dart';
const IN_DURATION = Duration(seconds: 1);
const OUT_DURATION = Duration(milliseconds: 300);
class DropdownTile extends StatefulWidget {
final Widget title;
final Iterable values;
final dynamic value;
final Map<dynamic, String> textMapping;
final void Function(dynamic newValue) onUpdate;
final bool enabled;
final Widget? leading;
final Widget? description;
const DropdownTile({
Key? key,
required this.title,
required this.values,
required this.value,
required this.textMapping,
required this.onUpdate,
this.enabled = true,
this.leading,
this.description,
}) : super(key: key);
@override
State<DropdownTile> createState() => _DropdownTileState();
}
class _DropdownTileState<T> extends State<DropdownTile>
with TickerProviderStateMixin {
late final AnimationController controller;
late final Animation<double> animation;
bool get isExpanding =>
animation.status == AnimationStatus.forward ||
animation.status == AnimationStatus.completed;
@override
void initState() {
super.initState();
controller = AnimationController(
duration: IN_DURATION,
vsync: this,
);
animation = CurvedAnimation(
parent: controller,
curve: Curves.fastLinearToSlowEaseIn,
);
}
expand() {
controller.forward();
}
contract() {
controller.animateBack(
0.0,
duration: OUT_DURATION,
curve: Curves.decelerate,
);
}
toggleContainer() {
if (isExpanding) {
contract();
} else {
expand();
}
setState(() {});
}
@override
void dispose() {
controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
SettingsTile(
leading: widget.leading,
description: widget.description,
enabled: widget.enabled,
title: widget.title,
value: Text(widget.textMapping[widget.value]!),
trailing: AnimatedRotation(
duration: kThemeChangeDuration,
turns: isExpanding ? .5 : 0,
child: const Icon(Icons.arrow_drop_down),
),
onPressed: (_) => toggleContainer(),
),
SizeTransition(
sizeFactor: animation,
axis: Axis.vertical,
child: Column(
children: widget.values
.map(
(value) => RadioListTile<dynamic>(
title: Text(widget.textMapping[value]!),
value: value,
groupValue: widget.value,
onChanged: (value) {
if (value == null) {
return;
}
widget.onUpdate(value);
contract();
},
),
)
.toList(),
),
),
],
);
}
}
class SettingsDropdownTile<T> extends AbstractSettingsTile {
final Widget title;
final Iterable<T> values;
final T value;
final Map<T, String> textMapping;
final void Function(T newValue) onUpdate;
final bool enabled;
final Widget? leading;
final Widget? description;
const SettingsDropdownTile({
Key? key,
required this.title,
required this.values,
required this.value,
required this.textMapping,
required this.onUpdate,
this.enabled = true,
this.leading,
this.description,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return DropdownTile(
title: title,
values: values,
value: value,
textMapping: textMapping,
onUpdate: (value) => onUpdate(value as T),
enabled: enabled,
leading: leading,
description: description,
);
}
}