This commit is contained in:
otsmr 2025-04-13 22:12:54 +02:00
parent e59e8d81a2
commit 05368a7ea9
5 changed files with 99 additions and 19 deletions

View file

@ -16,6 +16,7 @@ class UserData {
String? avatarJson; String? avatarJson;
int? avatarCounter; int? avatarCounter;
int? defaultShowTime; int? defaultShowTime;
bool? useHighQuality;
final int userId; final int userId;

View file

@ -14,7 +14,8 @@ UserData _$UserDataFromJson(Map<String, dynamic> json) => UserData(
..avatarSvg = json['avatarSvg'] as String? ..avatarSvg = json['avatarSvg'] as String?
..avatarJson = json['avatarJson'] as String? ..avatarJson = json['avatarJson'] as String?
..avatarCounter = (json['avatarCounter'] as num?)?.toInt() ..avatarCounter = (json['avatarCounter'] as num?)?.toInt()
..defaultShowTime = (json['defaultShowTime'] as num?)?.toInt(); ..defaultShowTime = (json['defaultShowTime'] as num?)?.toInt()
..useHighQuality = json['useHighQuality'] as bool?;
Map<String, dynamic> _$UserDataToJson(UserData instance) => <String, dynamic>{ Map<String, dynamic> _$UserDataToJson(UserData instance) => <String, dynamic>{
'username': instance.username, 'username': instance.username,
@ -23,5 +24,6 @@ Map<String, dynamic> _$UserDataToJson(UserData instance) => <String, dynamic>{
'avatarJson': instance.avatarJson, 'avatarJson': instance.avatarJson,
'avatarCounter': instance.avatarCounter, 'avatarCounter': instance.avatarCounter,
'defaultShowTime': instance.defaultShowTime, 'defaultShowTime': instance.defaultShowTime,
'useHighQuality': instance.useHighQuality,
'userId': instance.userId, 'userId': instance.userId,
}; };

View file

@ -125,6 +125,7 @@
"addDrawing": "Zeichnung", "addDrawing": "Zeichnung",
"addEmoji": "Emoji", "addEmoji": "Emoji",
"toggleFlashLight": "Taschenlampe umschalten", "toggleFlashLight": "Taschenlampe umschalten",
"toggleHighQuality": "Bessere Auflösung umschalten",
"searchUsernameNotFoundLong": "\"{username}\" ist kein twonly-Benutzer. Bitte überprüfe den Benutzernamen und versuche es erneut.", "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.", "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.", "errorBadRequest": "Die Anfrage konnte vom Server aufgrund einer fehlerhaften Syntax nicht verstanden werden. Bitte überprüfe deine Eingabe und versuche es erneut.",

View file

@ -248,6 +248,8 @@
"@addEmoji": {}, "@addEmoji": {},
"toggleFlashLight": "Toggle the flash light", "toggleFlashLight": "Toggle the flash light",
"@toggleFlashLight": {}, "@toggleFlashLight": {},
"toggleHighQuality": "Toggle better resolution",
"@toggleHighQuality": {},
"searchUsernameNotFoundLong": "\"{username}\" is not a twonly user. Please check the username and try again.", "searchUsernameNotFoundLong": "\"{username}\" is not a twonly user. Please check the username and try again.",
"@searchUsernameNotFoundLong": { "@searchUsernameNotFoundLong": {
"placeholders": { "placeholders": {

View file

@ -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/image_editor/action_button.dart';
import 'package:twonly/src/components/media_view_sizing.dart'; import 'package:twonly/src/components/media_view_sizing.dart';
import 'package:twonly/src/components/permissions_view.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'; import 'package:twonly/src/views/camera_to_share/share_image_editor_view.dart';
class CameraPreviewView extends StatefulWidget { class CameraPreviewView extends StatefulWidget {
@ -33,6 +34,7 @@ class _CameraPreviewViewState extends State<CameraPreviewView> {
double basePanY = 0; double basePanY = 0;
double baseScaleFactor = 0; double baseScaleFactor = 0;
bool cameraLoaded = false; bool cameraLoaded = false;
bool useHighQuality = false;
final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>(); final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
late CameraController controller; late CameraController controller;
@ -53,6 +55,17 @@ class _CameraPreviewViewState extends State<CameraPreviewView> {
if (controller.value.isInitialized) takePicture(); 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 @override
@ -123,7 +136,51 @@ class _CameraPreviewViewState extends State<CameraPreviewView> {
}); });
} }
Future<Uint8List?> 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;
}
}
Future takePicture() async { Future takePicture() async {
if (sharePreviewIsShown) return;
late Future<Uint8List?> 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 (isFlashOn) {
if (isFront) { if (isFront) {
setState(() { setState(() {
@ -140,11 +197,9 @@ class _CameraPreviewViewState extends State<CameraPreviewView> {
controller.setFlashMode(isFlashOn ? FlashMode.always : FlashMode.off); controller.setFlashMode(isFlashOn ? FlashMode.always : FlashMode.off);
Future<Uint8List?> imageBytes = screenshotController.capture(pixelRatio: 1); imageBytes = screenshotController.capture(pixelRatio: 1);
}
setState(() {
sharePreviewIsShown = true;
});
bool? shoudReturn = await Navigator.push( bool? shoudReturn = await Navigator.push(
context, context,
PageRouteBuilder( PageRouteBuilder(
@ -163,8 +218,11 @@ class _CameraPreviewViewState extends State<CameraPreviewView> {
return Navigator.pop(context); return Navigator.pop(context);
} }
// does not work?? // does not work??
//await controller.resumePreview(); if (Platform.isIOS) {
await controller.resumePreview();
} else {
selectCamera(0); selectCamera(0);
}
if (context.mounted) { if (context.mounted) {
setState(() { setState(() {
sharePreviewIsShown = false; sharePreviewIsShown = false;
@ -266,6 +324,22 @@ class _CameraPreviewViewState extends State<CameraPreviewView> {
setState(() {}); 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);
}
},
),
], ],
), ),
), ),