diff --git a/lib/src/json_models/userdata.dart b/lib/src/json_models/userdata.dart index 281a928..f9104d3 100644 --- a/lib/src/json_models/userdata.dart +++ b/lib/src/json_models/userdata.dart @@ -16,6 +16,7 @@ class UserData { String? avatarJson; int? avatarCounter; int? defaultShowTime; + bool? useHighQuality; final int userId; diff --git a/lib/src/json_models/userdata.g.dart b/lib/src/json_models/userdata.g.dart index 287ce51..46ddeeb 100644 --- a/lib/src/json_models/userdata.g.dart +++ b/lib/src/json_models/userdata.g.dart @@ -14,7 +14,8 @@ UserData _$UserDataFromJson(Map json) => UserData( ..avatarSvg = json['avatarSvg'] as String? ..avatarJson = json['avatarJson'] as String? ..avatarCounter = (json['avatarCounter'] as num?)?.toInt() - ..defaultShowTime = (json['defaultShowTime'] as num?)?.toInt(); + ..defaultShowTime = (json['defaultShowTime'] as num?)?.toInt() + ..useHighQuality = json['useHighQuality'] as bool?; Map _$UserDataToJson(UserData instance) => { 'username': instance.username, @@ -23,5 +24,6 @@ Map _$UserDataToJson(UserData instance) => { 'avatarJson': instance.avatarJson, 'avatarCounter': instance.avatarCounter, 'defaultShowTime': instance.defaultShowTime, + 'useHighQuality': instance.useHighQuality, 'userId': instance.userId, }; diff --git a/lib/src/localization/app_de.arb b/lib/src/localization/app_de.arb index eebdbe0..46375b7 100644 --- a/lib/src/localization/app_de.arb +++ b/lib/src/localization/app_de.arb @@ -125,6 +125,7 @@ "addDrawing": "Zeichnung", "addEmoji": "Emoji", "toggleFlashLight": "Taschenlampe umschalten", + "toggleHighQuality": "Bessere Auflösung umschalten", "searchUsernameNotFoundLong": "\"{username}\" ist kein twonly-Benutzer. Bitte überprüfe den Benutzernamen und versuche es erneut.", "errorUnknown": "Ein unerwarteter Fehler ist aufgetreten. Bitte versuche es später erneut.", "errorBadRequest": "Die Anfrage konnte vom Server aufgrund einer fehlerhaften Syntax nicht verstanden werden. Bitte überprüfe deine Eingabe und versuche es erneut.", diff --git a/lib/src/localization/app_en.arb b/lib/src/localization/app_en.arb index 75fda96..b1527d9 100644 --- a/lib/src/localization/app_en.arb +++ b/lib/src/localization/app_en.arb @@ -248,6 +248,8 @@ "@addEmoji": {}, "toggleFlashLight": "Toggle the flash light", "@toggleFlashLight": {}, + "toggleHighQuality": "Toggle better resolution", + "@toggleHighQuality": {}, "searchUsernameNotFoundLong": "\"{username}\" is not a twonly user. Please check the username and try again.", "@searchUsernameNotFoundLong": { "placeholders": { diff --git a/lib/src/views/camera_to_share/camera_preview_view.dart b/lib/src/views/camera_to_share/camera_preview_view.dart index 19d5467..6ac27ca 100644 --- a/lib/src/views/camera_to_share/camera_preview_view.dart +++ b/lib/src/views/camera_to_share/camera_preview_view.dart @@ -13,6 +13,7 @@ import 'package:twonly/src/utils/misc.dart'; import 'package:twonly/src/components/image_editor/action_button.dart'; import 'package:twonly/src/components/media_view_sizing.dart'; import 'package:twonly/src/components/permissions_view.dart'; +import 'package:twonly/src/utils/storage.dart'; import 'package:twonly/src/views/camera_to_share/share_image_editor_view.dart'; class CameraPreviewView extends StatefulWidget { @@ -33,6 +34,7 @@ class _CameraPreviewViewState extends State { double basePanY = 0; double baseScaleFactor = 0; bool cameraLoaded = false; + bool useHighQuality = false; final GlobalKey navigatorKey = GlobalKey(); late CameraController controller; @@ -53,6 +55,17 @@ class _CameraPreviewViewState extends State { if (controller.value.isInitialized) takePicture(); }, ); + initAsync(); + } + + void initAsync() async { + final user = await getUser(); + if (user == null) return; + if (user.useHighQuality != null) { + setState(() { + useHighQuality = user.useHighQuality!; + }); + } } @override @@ -123,28 +136,70 @@ class _CameraPreviewViewState extends State { }); } - Future takePicture() async { - if (isFlashOn) { - if (isFront) { - setState(() { - showSelfieFlash = true; - }); - } else { - controller.setFlashMode(FlashMode.torch); - } - await Future.delayed(Duration(milliseconds: 1000)); + Future loadAndDeletePictureFromFile(XFile picture) async { + try { + // Load the image into bytes + final Uint8List imageBytes = await picture.readAsBytes(); + // Remove the image file + await File(picture.path).delete(); + return imageBytes; + } catch (e) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Error loading picture: $e'), + duration: Duration(seconds: 3), + ), + ); + return null; } + } - await controller.pausePreview(); - if (!context.mounted) return; - - controller.setFlashMode(isFlashOn ? FlashMode.always : FlashMode.off); - - Future imageBytes = screenshotController.capture(pixelRatio: 1); + Future takePicture() async { + if (sharePreviewIsShown) return; + late Future imageBytes; setState(() { sharePreviewIsShown = true; }); + + if (useHighQuality) { + if (Platform.isIOS) { + await controller.pausePreview(); + if (!context.mounted) return; + } + try { + // Take the picture + final XFile picture = await controller.takePicture(); + imageBytes = loadAndDeletePictureFromFile(picture); + } catch (e) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Error taking picture: $e'), + duration: Duration(seconds: 3), + ), + ); + return; + } + } else { + if (isFlashOn) { + if (isFront) { + setState(() { + showSelfieFlash = true; + }); + } else { + controller.setFlashMode(FlashMode.torch); + } + await Future.delayed(Duration(milliseconds: 1000)); + } + + await controller.pausePreview(); + if (!context.mounted) return; + + controller.setFlashMode(isFlashOn ? FlashMode.always : FlashMode.off); + + imageBytes = screenshotController.capture(pixelRatio: 1); + } + bool? shoudReturn = await Navigator.push( context, PageRouteBuilder( @@ -163,8 +218,11 @@ class _CameraPreviewViewState extends State { return Navigator.pop(context); } // does not work?? - //await controller.resumePreview(); - selectCamera(0); + if (Platform.isIOS) { + await controller.resumePreview(); + } else { + selectCamera(0); + } if (context.mounted) { setState(() { sharePreviewIsShown = false; @@ -266,6 +324,22 @@ class _CameraPreviewViewState extends State { setState(() {}); }, ), + ActionButton( + Icons.hd_rounded, + tooltipText: context.lang.toggleHighQuality, + color: useHighQuality + ? Colors.white + : const Color.fromARGB(158, 255, 255, 255), + onPressed: () async { + useHighQuality = !useHighQuality; + setState(() {}); + var user = await getUser(); + if (user != null) { + user.useHighQuality = useHighQuality; + updateUser(user); + } + }, + ), ], ), ),