mirror of
https://github.com/Myzel394/quid_faciam_hodie.git
synced 2025-06-18 23:35:25 +02:00
added record button behavior to settings
This commit is contained in:
parent
b8ad3b8d43
commit
ecfe71cfa9
15
lib/enum_mapping/record_button_behavior/texts.dart
Normal file
15
lib/enum_mapping/record_button_behavior/texts.dart
Normal 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,
|
||||
};
|
||||
}
|
4
lib/enums/record_button_behavior.dart
Normal file
4
lib/enums/record_button_behavior.dart
Normal file
@ -0,0 +1,4 @@
|
||||
enum RecordButtonBehavior {
|
||||
holdRecording,
|
||||
switchRecording,
|
||||
}
|
@ -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 "
|
||||
}
|
@ -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,
|
||||
final bool? askForMemoryAnnotations,
|
||||
final bool? recordOnStartup})
|
||||
: _resolution = resolution ?? ResolutionPreset.max,
|
||||
Settings({
|
||||
final ResolutionPreset? resolution,
|
||||
final RecordButtonBehavior? recordButtonBehavior,
|
||||
final bool? askForMemoryAnnotations,
|
||||
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();
|
||||
|
@ -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),
|
||||
|
168
lib/screens/settings_screen/dropdown_tile.dart
Normal file
168
lib/screens/settings_screen/dropdown_tile.dart
Normal 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,
|
||||
);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user