small bug fixes

This commit is contained in:
otsmr 2026-01-23 16:57:29 +01:00
parent fa767977dd
commit f93a337aa9
5 changed files with 77 additions and 60 deletions

View file

@ -24,66 +24,71 @@ class MediaFileService {
} }
static Future<void> purgeTempFolder() async { static Future<void> purgeTempFolder() async {
final tempDirectory = MediaFileService.buildDirectoryPath( try {
'tmp', final tempDirectory = MediaFileService.buildDirectoryPath(
globalApplicationSupportDirectory, 'tmp',
); globalApplicationSupportDirectory,
);
final files = tempDirectory.listSync(); final files = tempDirectory.listSync();
for (final file in files) { for (final file in files) {
final mediaId = basename(file.path).split('.').first; final mediaId = basename(file.path).split('.').first;
// in case the mediaID is unknown the file will be deleted // in case the mediaID is unknown the file will be deleted
var delete = true; var delete = true;
final service = await MediaFileService.fromMediaId(mediaId); final service = await MediaFileService.fromMediaId(mediaId);
if (service != null) { if (service != null) {
if (service.mediaFile.isDraftMedia) { if (service.mediaFile.isDraftMedia) {
delete = false;
}
final messages =
await twonlyDB.messagesDao.getMessagesByMediaId(mediaId);
// in case messages in empty the file will be deleted, as delete is true by default
for (final message in messages) {
if (service.mediaFile.type == MediaType.audio) {
delete = false; // do not delete voice messages
}
if (message.openedAt == null) {
// Message was not yet opened from all persons, so wait...
delete = false; delete = false;
} else if (service.mediaFile.requiresAuthentication || }
service.mediaFile.displayLimitInMilliseconds != null) {
// Message was opened by all persons, and they can not reopen the image. final messages =
// This branch will prevent to reach the next if condition, with would otherwise store the image for two days await twonlyDB.messagesDao.getMessagesByMediaId(mediaId);
// delete = true; // do not overwrite a previous delete = false
// this is just to make it easier to understand :) // in case messages in empty the file will be deleted, as delete is true by default
} else if (message.openedAt!
.isAfter(clock.now().subtract(const Duration(days: 2)))) { for (final message in messages) {
// In case the image was opened, but send with unlimited time or no authentication. if (service.mediaFile.type == MediaType.audio) {
if (message.senderId == null) { delete = false; // do not delete voice messages
delete = false; }
} else {
// Check weather the image was send in a group. Then the images is preserved for two days in case another person stores the image. if (message.openedAt == null) {
// This also allows to reopen this image for two days. // Message was not yet opened from all persons, so wait...
final group = await twonlyDB.groupsDao.getGroup(message.groupId); delete = false;
if (group != null && !group.isDirectChat) { } else if (service.mediaFile.requiresAuthentication ||
delete = false; service.mediaFile.displayLimitInMilliseconds != null) {
} // Message was opened by all persons, and they can not reopen the image.
// This branch will prevent to reach the next if condition, with would otherwise store the image for two days
// delete = true; // do not overwrite a previous delete = false
// this is just to make it easier to understand :)
} else if (message.openedAt!
.isAfter(clock.now().subtract(const Duration(days: 2)))) {
// In case the image was opened, but send with unlimited time or no authentication.
if (message.senderId == null) {
delete = false;
} else {
// Check weather the image was send in a group. Then the images is preserved for two days in case another person stores the image.
// This also allows to reopen this image for two days.
final group =
await twonlyDB.groupsDao.getGroup(message.groupId);
if (group != null && !group.isDirectChat) {
delete = false;
}
}
// In case the app was send in a direct chat, then it can be deleted.
} }
// In case the app was send in a direct chat, then it can be deleted.
} }
} }
}
if (delete) { if (delete) {
Log.info('Purging media file $mediaId'); Log.info('Purging media file $mediaId');
file.deleteSync(); file.deleteSync();
}
} }
} catch (e) {
Log.error(e);
} }
} }

View file

@ -120,10 +120,6 @@ class MainCameraController {
} }
selectedCameraDetails.isZoomAble = false; selectedCameraDetails.isZoomAble = false;
if (selectedCameraDetails.cameraId != cameraId) {
// switched camera so reset the scaleFactor
selectedCameraDetails.scaleFactor = 1;
}
if (cameraController == null) { if (cameraController == null) {
cameraController = CameraController( cameraController = CameraController(
@ -136,14 +132,28 @@ class MainCameraController {
); );
await cameraController?.initialize(); await cameraController?.initialize();
await cameraController?.startImageStream(_processCameraImage); await cameraController?.startImageStream(_processCameraImage);
await cameraController?.setZoomLevel(selectedCameraDetails.scaleFactor);
} else { } else {
await HapticFeedback.lightImpact(); try {
await cameraController?.stopImageStream(); if (!isVideoRecording) {
await cameraController?.stopImageStream();
}
} catch (e) {
Log.info(e);
}
selectedCameraDetails.scaleFactor = 1;
await cameraController?.setZoomLevel(1);
await cameraController?.setDescription(gCameras[cameraId]); await cameraController?.setDescription(gCameras[cameraId]);
await cameraController?.startImageStream(_processCameraImage); try {
if (!isVideoRecording) {
await cameraController?.startImageStream(_processCameraImage);
}
} catch (e) {
Log.info(e);
}
} }
await cameraController?.setZoomLevel(selectedCameraDetails.scaleFactor);
await cameraController await cameraController
?.lockCaptureOrientation(DeviceOrientation.portraitUp); ?.lockCaptureOrientation(DeviceOrientation.portraitUp);
await cameraController?.setFlashMode( await cameraController?.setFlashMode(

View file

@ -5,7 +5,6 @@ import 'dart:collection';
import 'package:drift/drift.dart' show Value; import 'package:drift/drift.dart' show Value;
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:twonly/globals.dart'; import 'package:twonly/globals.dart';
import 'package:twonly/src/database/daos/contacts.dao.dart'; import 'package:twonly/src/database/daos/contacts.dao.dart';

View file

@ -92,8 +92,9 @@ class _MediaViewerViewState extends State<MediaViewerView> {
_noScreenshot.screenshotOn(); _noScreenshot.screenshotOn();
_subscription.cancel(); _subscription.cancel();
downloadStateListener?.cancel(); downloadStateListener?.cancel();
videoController?.dispose(); final tmp = videoController;
videoController = null; videoController = null;
tmp?.dispose();
super.dispose(); super.dispose();
} }

View file

@ -1,5 +1,6 @@
// ignore_for_file: avoid_dynamic_calls // ignore_for_file: avoid_dynamic_calls
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:twonly/src/utils/keyvalue.dart'; import 'package:twonly/src/utils/keyvalue.dart';
import 'package:twonly/src/utils/misc.dart'; import 'package:twonly/src/utils/misc.dart';
@ -30,6 +31,7 @@ class _UserStudyQuestionnaireState extends State<UserStudyQuestionnaire> {
'comp_knowledge': null, 'comp_knowledge': null,
'security_knowledge': null, 'security_knowledge': null,
'messengers': [], 'messengers': [],
'is_release_mode': kReleaseMode,
}; };
final List<String> _messengerOptions = [ final List<String> _messengerOptions = [