mirror of
https://github.com/Myzel394/quid_faciam_hodie.git
synced 2025-06-20 16:15:27 +02:00
added adjustable settings
This commit is contained in:
parent
359ed768c5
commit
affac14aba
@ -1 +1,2 @@
|
|||||||
const CACHE_KEY = '_cache';
|
const CACHE_KEY = '_cache';
|
||||||
|
const SETTINGS_KEY = 'settings';
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:quid_faciam_hodie/constants/spacing.dart';
|
||||||
|
|
||||||
final LIGHT_THEME_MATERIAL = ThemeData(
|
final LIGHT_THEME_MATERIAL = ThemeData(
|
||||||
textTheme: ThemeData().textTheme.copyWith(
|
textTheme: ThemeData().textTheme.copyWith(
|
||||||
@ -13,7 +14,7 @@ final LIGHT_THEME_MATERIAL = ThemeData(
|
|||||||
helperMaxLines: 10,
|
helperMaxLines: 10,
|
||||||
errorMaxLines: 10,
|
errorMaxLines: 10,
|
||||||
border: OutlineInputBorder(
|
border: OutlineInputBorder(
|
||||||
borderRadius: BorderRadius.circular(8),
|
borderRadius: BorderRadius.circular(MEDIUM_SPACE),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@ -30,7 +31,7 @@ final DARK_THEME_MATERIAL = ThemeData.dark().copyWith(
|
|||||||
helperMaxLines: 10,
|
helperMaxLines: 10,
|
||||||
errorMaxLines: 10,
|
errorMaxLines: 10,
|
||||||
border: OutlineInputBorder(
|
border: OutlineInputBorder(
|
||||||
borderRadius: BorderRadius.circular(8),
|
borderRadius: BorderRadius.circular(MEDIUM_SPACE),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
19
lib/enum_mapping/resolution_preset/texts.dart
Normal file
19
lib/enum_mapping/resolution_preset/texts.dart
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import 'package:camera/camera.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||||
|
|
||||||
|
Map<ResolutionPreset, String> getResolutionTextMapping(
|
||||||
|
final BuildContext context) {
|
||||||
|
final localizations = AppLocalizations.of(context)!;
|
||||||
|
|
||||||
|
return {
|
||||||
|
ResolutionPreset.low: localizations.enumMapping_ResolutionPreset_low,
|
||||||
|
ResolutionPreset.medium: localizations.enumMapping_ResolutionPreset_medium,
|
||||||
|
ResolutionPreset.high: localizations.enumMapping_ResolutionPreset_high,
|
||||||
|
ResolutionPreset.veryHigh:
|
||||||
|
localizations.enumMapping_ResolutionPreset_veryHigh,
|
||||||
|
ResolutionPreset.ultraHigh:
|
||||||
|
localizations.enumMapping_ResolutionPreset_ultraHigh,
|
||||||
|
ResolutionPreset.max: localizations.enumMapping_ResolutionPreset_max,
|
||||||
|
};
|
||||||
|
}
|
@ -79,5 +79,15 @@
|
|||||||
"settingsScreenDangerSectionTitle": "Gefahrbereich",
|
"settingsScreenDangerSectionTitle": "Gefahrbereich",
|
||||||
"settingsScreenDangerSectionDeleteAccountLabel": "Account löschen",
|
"settingsScreenDangerSectionDeleteAccountLabel": "Account löschen",
|
||||||
"settingsScreenDeleteAccountDescription": "Bist du dir sicher, dass du deinen Account löschen möchtest? Diese Aktion kann nicht rückgangig gemacht werden! Deine Erfahrungen werden ebenfalls gelöscht.",
|
"settingsScreenDeleteAccountDescription": "Bist du dir sicher, dass du deinen Account löschen möchtest? Diese Aktion kann nicht rückgangig gemacht werden! Deine Erfahrungen werden ebenfalls gelöscht.",
|
||||||
"settingsScreenDeleteAccountConfirmLabel": "Account jetzt löschen"
|
"settingsScreenDeleteAccountConfirmLabel": "Account jetzt löschen",
|
||||||
|
"settingsScreenGeneralSectionTitle": "General",
|
||||||
|
"settingsScreenGeneralSectionQualityLabel": "Quality",
|
||||||
|
|
||||||
|
|
||||||
|
"enumMapping_ResolutionPreset_low": "Niedrig",
|
||||||
|
"enumMapping_ResolutionPreset_medium": "Medium",
|
||||||
|
"enumMapping_ResolutionPreset_high": "Hoch",
|
||||||
|
"enumMapping_ResolutionPreset_veryHigh": "Sehr Hoch",
|
||||||
|
"enumMapping_ResolutionPreset_ultraHigh": "Ultra Hoch",
|
||||||
|
"enumMapping_ResolutionPreset_max": "Max"
|
||||||
}
|
}
|
@ -108,5 +108,15 @@
|
|||||||
"settingsScreenDangerSectionTitle": "Danger Zone",
|
"settingsScreenDangerSectionTitle": "Danger Zone",
|
||||||
"settingsScreenDangerSectionDeleteAccountLabel": "Delete Account",
|
"settingsScreenDangerSectionDeleteAccountLabel": "Delete Account",
|
||||||
"settingsScreenDeleteAccountDescription": "Are you sure you want to delete your account? This action cannot be undone! All your memories will be deleted as well.",
|
"settingsScreenDeleteAccountDescription": "Are you sure you want to delete your account? This action cannot be undone! All your memories will be deleted as well.",
|
||||||
"settingsScreenDeleteAccountConfirmLabel": "Delete Account now"
|
"settingsScreenDeleteAccountConfirmLabel": "Delete Account now",
|
||||||
|
"settingsScreenGeneralSectionTitle": "General",
|
||||||
|
"settingsScreenGeneralSectionQualityLabel": "Quality",
|
||||||
|
|
||||||
|
|
||||||
|
"enumMapping_ResolutionPreset_low": "Low",
|
||||||
|
"enumMapping_ResolutionPreset_medium": "Medium",
|
||||||
|
"enumMapping_ResolutionPreset_high": "High",
|
||||||
|
"enumMapping_ResolutionPreset_veryHigh": "Very High",
|
||||||
|
"enumMapping_ResolutionPreset_ultraHigh": "Ultra High",
|
||||||
|
"enumMapping_ResolutionPreset_max": "Max"
|
||||||
}
|
}
|
@ -27,7 +27,7 @@ void main() async {
|
|||||||
DeviceOrientation.portraitDown,
|
DeviceOrientation.portraitDown,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
GlobalValuesManager.initializeServer();
|
GlobalValuesManager.initialize();
|
||||||
|
|
||||||
runApp(const MyApp());
|
runApp(const MyApp());
|
||||||
}
|
}
|
||||||
@ -52,7 +52,7 @@ class _MyAppState extends State<MyApp> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> watchAuthenticationStatus() async {
|
Future<void> watchAuthenticationStatus() async {
|
||||||
await GlobalValuesManager.waitForServerInitialization();
|
await GlobalValuesManager.watchForInitialization();
|
||||||
|
|
||||||
Supabase.instance.client.auth.onAuthStateChange((event, session) {
|
Supabase.instance.client.auth.onAuthStateChange((event, session) {
|
||||||
switch (event) {
|
switch (event) {
|
||||||
|
@ -17,7 +17,7 @@ final supabase = Supabase.instance.client;
|
|||||||
|
|
||||||
class FileManager {
|
class FileManager {
|
||||||
static Future<Memory> getMemoryMetadata(final String id) async {
|
static Future<Memory> getMemoryMetadata(final String id) async {
|
||||||
await GlobalValuesManager.waitForServerInitialization();
|
await GlobalValuesManager.watchForInitialization();
|
||||||
|
|
||||||
final response = await supabase
|
final response = await supabase
|
||||||
.from('memories')
|
.from('memories')
|
||||||
@ -38,7 +38,7 @@ class FileManager {
|
|||||||
final File file, {
|
final File file, {
|
||||||
LocationData? locationData,
|
LocationData? locationData,
|
||||||
}) async {
|
}) async {
|
||||||
await GlobalValuesManager.waitForServerInitialization();
|
await GlobalValuesManager.watchForInitialization();
|
||||||
|
|
||||||
final basename = uuid.v4();
|
final basename = uuid.v4();
|
||||||
final extension = file.path.split('.').last;
|
final extension = file.path.split('.').last;
|
||||||
@ -108,7 +108,7 @@ class FileManager {
|
|||||||
final bool disableDownloadCache = false,
|
final bool disableDownloadCache = false,
|
||||||
final bool disableFileCache = false,
|
final bool disableFileCache = false,
|
||||||
}) async {
|
}) async {
|
||||||
await GlobalValuesManager.waitForServerInitialization();
|
await GlobalValuesManager.watchForInitialization();
|
||||||
|
|
||||||
final tempDirectory = await getTemporaryDirectory();
|
final tempDirectory = await getTemporaryDirectory();
|
||||||
final filename = '${tempDirectory.path}/$path';
|
final filename = '${tempDirectory.path}/$path';
|
||||||
@ -129,7 +129,7 @@ class FileManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static Future<void> deleteFile(final String path) async {
|
static Future<void> deleteFile(final String path) async {
|
||||||
await GlobalValuesManager.waitForServerInitialization();
|
await GlobalValuesManager.watchForInitialization();
|
||||||
|
|
||||||
final response =
|
final response =
|
||||||
await supabase.from('memories').delete().eq('location', path).execute();
|
await supabase.from('memories').delete().eq('location', path).execute();
|
||||||
|
@ -2,15 +2,19 @@ import 'package:camera/camera.dart';
|
|||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:permission_handler/permission_handler.dart';
|
import 'package:permission_handler/permission_handler.dart';
|
||||||
import 'package:quid_faciam_hodie/constants/apis.dart';
|
import 'package:quid_faciam_hodie/constants/apis.dart';
|
||||||
|
import 'package:quid_faciam_hodie/models/settings.dart';
|
||||||
import 'package:supabase_flutter/supabase_flutter.dart';
|
import 'package:supabase_flutter/supabase_flutter.dart';
|
||||||
|
|
||||||
class GlobalValuesManager {
|
class GlobalValuesManager {
|
||||||
static Future? _serverInitializationFuture;
|
static Future? _serverInitializationFuture;
|
||||||
|
static Future? _settingsInitializationFuture;
|
||||||
static bool _isServerInitialized = false;
|
static bool _isServerInitialized = false;
|
||||||
static List<CameraDescription> _cameras = [];
|
static List<CameraDescription> _cameras = [];
|
||||||
|
static Settings? _settings;
|
||||||
|
|
||||||
static List<CameraDescription> get cameras => [..._cameras];
|
static List<CameraDescription> get cameras => [..._cameras];
|
||||||
static bool get isServerInitialized => _isServerInitialized;
|
static bool get isServerInitialized => _isServerInitialized;
|
||||||
|
static Settings? get settings => _settings;
|
||||||
|
|
||||||
static void setCameras(List<CameraDescription> cameras) {
|
static void setCameras(List<CameraDescription> cameras) {
|
||||||
if (_cameras.isNotEmpty) {
|
if (_cameras.isNotEmpty) {
|
||||||
@ -20,7 +24,7 @@ class GlobalValuesManager {
|
|||||||
_cameras = cameras;
|
_cameras = cameras;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void initializeServer() {
|
static void _initializeServer() {
|
||||||
if (_isServerInitialized || _serverInitializationFuture != null) {
|
if (_isServerInitialized || _serverInitializationFuture != null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -35,16 +39,41 @@ class GlobalValuesManager {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<void> waitForServerInitialization() async {
|
static void _initializeSettings() {
|
||||||
|
_settingsInitializationFuture = Settings.restore()
|
||||||
|
..then((settings) {
|
||||||
|
_settings = settings;
|
||||||
|
_settingsInitializationFuture = null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static void initialize() {
|
||||||
|
_initializeServer();
|
||||||
|
_initializeSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
static Future<void> watchForInitialization() async {
|
||||||
|
// Server initialization
|
||||||
if (_serverInitializationFuture == null) {
|
if (_serverInitializationFuture == null) {
|
||||||
if (_isServerInitialized) {
|
if (_isServerInitialized) {
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
throw Exception('Server has not been initialized yet');
|
throw Exception('Server has not been initialized yet');
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
await _serverInitializationFuture;
|
||||||
}
|
}
|
||||||
|
|
||||||
await _serverInitializationFuture;
|
// Settings initialization
|
||||||
|
if (_settingsInitializationFuture == null) {
|
||||||
|
if (_settings == null) {
|
||||||
|
throw Exception('Settings have not been initialized yet');
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
await _settingsInitializationFuture;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<bool> hasGrantedPermissions() async =>
|
static Future<bool> hasGrantedPermissions() async =>
|
||||||
|
@ -109,7 +109,7 @@ class Memories extends PropertyChangeNotifier<String> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _loadInitialData() async {
|
Future<void> _loadInitialData() async {
|
||||||
await GlobalValuesManager.waitForServerInitialization();
|
await GlobalValuesManager.watchForInitialization();
|
||||||
|
|
||||||
final response = await supabase
|
final response = await supabase
|
||||||
.from('memories')
|
.from('memories')
|
||||||
|
52
lib/models/settings.dart
Normal file
52
lib/models/settings.dart
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:camera/camera.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||||
|
import 'package:quid_faciam_hodie/constants/storage_keys.dart';
|
||||||
|
|
||||||
|
const secure = FlutterSecureStorage();
|
||||||
|
|
||||||
|
class Settings extends ChangeNotifier {
|
||||||
|
ResolutionPreset _resolution = ResolutionPreset.high;
|
||||||
|
|
||||||
|
Settings({final ResolutionPreset resolution = ResolutionPreset.high})
|
||||||
|
: _resolution = resolution;
|
||||||
|
|
||||||
|
ResolutionPreset get resolution => _resolution;
|
||||||
|
|
||||||
|
Map<String, dynamic> toJSONData() => {
|
||||||
|
'resolution': _resolution.toString(),
|
||||||
|
};
|
||||||
|
|
||||||
|
Future<void> save() async {
|
||||||
|
final data = toJSONData();
|
||||||
|
|
||||||
|
await secure.write(
|
||||||
|
key: SETTINGS_KEY,
|
||||||
|
value: jsonEncode(data),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Future<Settings> restore() async {
|
||||||
|
final rawData = await secure.read(key: SETTINGS_KEY);
|
||||||
|
|
||||||
|
if (rawData == null) {
|
||||||
|
return Settings();
|
||||||
|
}
|
||||||
|
|
||||||
|
final data = jsonDecode(rawData);
|
||||||
|
final resolution = ResolutionPreset.values.firstWhere(
|
||||||
|
(preset) => preset.toString() == data['resolution'],
|
||||||
|
);
|
||||||
|
return Settings(
|
||||||
|
resolution: resolution,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setResolution(final ResolutionPreset value) {
|
||||||
|
_resolution = value;
|
||||||
|
notifyListeners();
|
||||||
|
save();
|
||||||
|
}
|
||||||
|
}
|
@ -71,6 +71,7 @@ class _MainScreenState extends AuthRequiredState<MainScreen> with Loadable {
|
|||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
|
|
||||||
|
loadSettings();
|
||||||
loadCameras();
|
loadCameras();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,6 +86,18 @@ class _MainScreenState extends AuthRequiredState<MainScreen> with Loadable {
|
|||||||
_updateCamera(state);
|
_updateCamera(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> loadSettings() async {
|
||||||
|
final settings = GlobalValuesManager.settings!;
|
||||||
|
|
||||||
|
settings.addListener(() {
|
||||||
|
if (!mounted || controller == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
onNewCameraSelected(controller!.description);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> loadCameras() async {
|
Future<void> loadCameras() async {
|
||||||
GlobalValuesManager.setCameras(await availableCameras());
|
GlobalValuesManager.setCameras(await availableCameras());
|
||||||
|
|
||||||
@ -116,11 +129,13 @@ class _MainScreenState extends AuthRequiredState<MainScreen> with Loadable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void onNewCameraSelected(final CameraDescription cameraDescription) async {
|
void onNewCameraSelected(final CameraDescription cameraDescription) async {
|
||||||
|
final settings = GlobalValuesManager.settings!;
|
||||||
final previousCameraController = controller;
|
final previousCameraController = controller;
|
||||||
|
|
||||||
// Instantiating the camera controller
|
// Instantiating the camera controller
|
||||||
final CameraController cameraController = CameraController(
|
final CameraController cameraController = CameraController(
|
||||||
cameraDescription,
|
cameraDescription,
|
||||||
ResolutionPreset.high,
|
settings.resolution,
|
||||||
imageFormatGroup: ImageFormatGroup.jpeg,
|
imageFormatGroup: ImageFormatGroup.jpeg,
|
||||||
);
|
);
|
||||||
cameraController.setFlashMode(FlashMode.off);
|
cameraController.setFlashMode(FlashMode.off);
|
||||||
@ -192,13 +207,6 @@ class _MainScreenState extends AuthRequiredState<MainScreen> with Loadable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final file = File((await controller!.takePicture()).path);
|
final file = File((await controller!.takePicture()).path);
|
||||||
LocationData? locationData;
|
|
||||||
|
|
||||||
if (Platform.isAndroid && (await Permission.location.isGranted)) {
|
|
||||||
locationData = await Location().getLocation();
|
|
||||||
|
|
||||||
await tagLocationToImage(file, locationData);
|
|
||||||
}
|
|
||||||
|
|
||||||
setState(() {
|
setState(() {
|
||||||
uploadingPhotoAnimation = file.readAsBytesSync();
|
uploadingPhotoAnimation = file.readAsBytesSync();
|
||||||
@ -209,6 +217,14 @@ class _MainScreenState extends AuthRequiredState<MainScreen> with Loadable {
|
|||||||
message: localizations.mainScreenTakePhotoActionUploadingPhoto,
|
message: localizations.mainScreenTakePhotoActionUploadingPhoto,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
LocationData? locationData;
|
||||||
|
|
||||||
|
if (Platform.isAndroid && (await Permission.location.isGranted)) {
|
||||||
|
locationData = await Location().getLocation();
|
||||||
|
|
||||||
|
await tagLocationToImage(file, locationData);
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await FileManager.uploadFile(_user, file, locationData: locationData);
|
await FileManager.uploadFile(_user, file, locationData: locationData);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
@ -43,7 +43,7 @@ class _ServerLoadingScreenState extends State<ServerLoadingScreen> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
await GlobalValuesManager.waitForServerInitialization();
|
await GlobalValuesManager.watchForInitialization();
|
||||||
|
|
||||||
final memories = context.read<Memories>();
|
final memories = context.read<Memories>();
|
||||||
final session = Supabase.instance.client.auth.session();
|
final session = Supabase.instance.client.auth.session();
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import 'package:camera/camera.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||||
@ -5,7 +6,9 @@ import 'package:flutter_platform_widgets/flutter_platform_widgets.dart';
|
|||||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
import 'package:quid_faciam_hodie/constants/spacing.dart';
|
import 'package:quid_faciam_hodie/constants/spacing.dart';
|
||||||
|
import 'package:quid_faciam_hodie/enum_mapping/resolution_preset/texts.dart';
|
||||||
import 'package:quid_faciam_hodie/extensions/snackbar.dart';
|
import 'package:quid_faciam_hodie/extensions/snackbar.dart';
|
||||||
|
import 'package:quid_faciam_hodie/managers/global_values_manager.dart';
|
||||||
import 'package:quid_faciam_hodie/screens/welcome_screen.dart';
|
import 'package:quid_faciam_hodie/screens/welcome_screen.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';
|
||||||
@ -30,6 +33,18 @@ class _SettingsScreenState extends AuthRequiredState<SettingsScreen>
|
|||||||
with Loadable {
|
with Loadable {
|
||||||
User? user;
|
User? user;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
|
||||||
|
final settings = GlobalValuesManager.settings!;
|
||||||
|
|
||||||
|
// Update UI when settings change
|
||||||
|
settings.addListener(() {
|
||||||
|
setState(() {});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onAuthenticated(Session session) {
|
void onAuthenticated(Session session) {
|
||||||
if (session.user != null) {
|
if (session.user != null) {
|
||||||
@ -68,7 +83,9 @@ class _SettingsScreenState extends AuthRequiredState<SettingsScreen>
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
final settings = GlobalValuesManager.settings!;
|
||||||
final localizations = AppLocalizations.of(context)!;
|
final localizations = AppLocalizations.of(context)!;
|
||||||
|
final resolutionTextMapping = getResolutionTextMapping(context);
|
||||||
|
|
||||||
return PlatformScaffold(
|
return PlatformScaffold(
|
||||||
appBar: PlatformAppBar(
|
appBar: PlatformAppBar(
|
||||||
@ -141,6 +158,36 @@ class _SettingsScreenState extends AuthRequiredState<SettingsScreen>
|
|||||||
)
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
SettingsSection(
|
||||||
|
title: Text(
|
||||||
|
localizations.settingsScreenGeneralSectionTitle,
|
||||||
|
),
|
||||||
|
tiles: <SettingsTile>[
|
||||||
|
SettingsTile(
|
||||||
|
leading: Text(
|
||||||
|
localizations
|
||||||
|
.settingsScreenGeneralSectionQualityLabel,
|
||||||
|
),
|
||||||
|
title: DropdownButtonFormField<ResolutionPreset>(
|
||||||
|
value: settings.resolution,
|
||||||
|
onChanged: (value) async {
|
||||||
|
if (value == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
settings.setResolution(value);
|
||||||
|
},
|
||||||
|
items: ResolutionPreset.values
|
||||||
|
.map((value) =>
|
||||||
|
DropdownMenuItem<ResolutionPreset>(
|
||||||
|
value: value,
|
||||||
|
child: Text(resolutionTextMapping[value]!),
|
||||||
|
))
|
||||||
|
.toList(),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
SettingsSection(
|
SettingsSection(
|
||||||
title: Text(localizations.settingsScreenDangerSectionTitle),
|
title: Text(localizations.settingsScreenDangerSectionTitle),
|
||||||
tiles: <SettingsTile>[
|
tiles: <SettingsTile>[
|
||||||
|
Loading…
x
Reference in New Issue
Block a user