This commit is contained in:
otsmr 2025-05-20 22:59:29 +02:00
parent db75b11b75
commit 7a300456a3
4 changed files with 33 additions and 27 deletions

View file

@ -8,7 +8,7 @@
"onboardingE2eBody": "Genieße durch die Ende-zu-Ende-Verschlüsselung die Gewissheit, dass nur du und deine Freunde die geteilten Momente sehen können.", "onboardingE2eBody": "Genieße durch die Ende-zu-Ende-Verschlüsselung die Gewissheit, dass nur du und deine Freunde die geteilten Momente sehen können.",
"onboardingFocusTitle": "Fokussiere dich auf das Teilen von Momenten", "onboardingFocusTitle": "Fokussiere dich auf das Teilen von Momenten",
"onboardingFocusBody": "Verabschiede dich von süchtig machenden Funktionen! twonly wurde für das Teilen von Momenten ohne nutzlose Ablenkungen oder Werbung entwickelt.", "onboardingFocusBody": "Verabschiede dich von süchtig machenden Funktionen! twonly wurde für das Teilen von Momenten ohne nutzlose Ablenkungen oder Werbung entwickelt.",
"onboardingSendTwonliesTitle": "Twonlies senden", "onboardingSendTwonliesTitle": "twonlies senden",
"onboardingSendTwonliesBody": "Teile Momente sicher mit deinem Partner. twonly stellt sicher, dass nur dein Partner sie öffnen kann, sodass deine Momente mit deinem Partner eine two(o)nly Sache bleiben!", "onboardingSendTwonliesBody": "Teile Momente sicher mit deinem Partner. twonly stellt sicher, dass nur dein Partner sie öffnen kann, sodass deine Momente mit deinem Partner eine two(o)nly Sache bleiben!",
"onboardingNotProductTitle": "Du bist nicht das Produkt!", "onboardingNotProductTitle": "Du bist nicht das Produkt!",
"onboardingNotProductBody": "twonly finanziert sich durch eine geringe monatliche Gebühr und nicht durch den Verkauf deiner Daten.", "onboardingNotProductBody": "twonly finanziert sich durch eine geringe monatliche Gebühr und nicht durch den Verkauf deiner Daten.",
@ -35,7 +35,7 @@
"shareImagedEditorSavedImage": "Gespeichert", "shareImagedEditorSavedImage": "Gespeichert",
"shareImagedSelectAll": "Alle auswählen", "shareImagedSelectAll": "Alle auswählen",
"shareImageAllUsers": "Alle Kontakte", "shareImageAllUsers": "Alle Kontakte",
"shareImageAllTwonlyWarning": "Twonlies können nur an verifizierte Kontakte gesendet werden!", "shareImageAllTwonlyWarning": "twonlies können nur an verifizierte Kontakte gesendet werden!",
"shareImageSearchAllContacts": "Alle Kontakte durchsuchen", "shareImageSearchAllContacts": "Alle Kontakte durchsuchen",
"@shareImageSearchAllContacts": {}, "@shareImageSearchAllContacts": {},
"shareImageUserNotVerified": "Benutzer ist nicht verifiziert", "shareImageUserNotVerified": "Benutzer ist nicht verifiziert",

View file

@ -33,7 +33,7 @@ class AppLocalizationsDe extends AppLocalizations {
String get onboardingFocusBody => 'Verabschiede dich von süchtig machenden Funktionen! twonly wurde für das Teilen von Momenten ohne nutzlose Ablenkungen oder Werbung entwickelt.'; String get onboardingFocusBody => 'Verabschiede dich von süchtig machenden Funktionen! twonly wurde für das Teilen von Momenten ohne nutzlose Ablenkungen oder Werbung entwickelt.';
@override @override
String get onboardingSendTwonliesTitle => 'Twonlies senden'; String get onboardingSendTwonliesTitle => 'twonlies senden';
@override @override
String get onboardingSendTwonliesBody => 'Teile Momente sicher mit deinem Partner. twonly stellt sicher, dass nur dein Partner sie öffnen kann, sodass deine Momente mit deinem Partner eine two(o)nly Sache bleiben!'; String get onboardingSendTwonliesBody => 'Teile Momente sicher mit deinem Partner. twonly stellt sicher, dass nur dein Partner sie öffnen kann, sodass deine Momente mit deinem Partner eine two(o)nly Sache bleiben!';
@ -126,7 +126,7 @@ class AppLocalizationsDe extends AppLocalizations {
String get shareImageAllUsers => 'Alle Kontakte'; String get shareImageAllUsers => 'Alle Kontakte';
@override @override
String get shareImageAllTwonlyWarning => 'Twonlies können nur an verifizierte Kontakte gesendet werden!'; String get shareImageAllTwonlyWarning => 'twonlies können nur an verifizierte Kontakte gesendet werden!';
@override @override
String get shareImageUserNotVerified => 'Benutzer ist nicht verifiziert'; String get shareImageUserNotVerified => 'Benutzer ist nicht verifiziert';

View file

@ -1,3 +1,4 @@
import 'dart:collection';
import 'dart:io'; import 'dart:io';
import 'dart:async'; import 'dart:async';
import 'package:camera/camera.dart'; import 'package:camera/camera.dart';
@ -58,6 +59,7 @@ class _ShareImageEditorView extends State<ShareImageEditorView> {
double tabDownPostion = 0; double tabDownPostion = 0;
bool sendingOrLoadingImage = true; bool sendingOrLoadingImage = true;
bool isDisposed = false; bool isDisposed = false;
HashSet<int> selectedUserIds = HashSet();
double widthRatio = 1, heightRatio = 1, pixelRatio = 1; double widthRatio = 1, heightRatio = 1, pixelRatio = 1;
VideoPlayerController? videoController; VideoPlayerController? videoController;
@ -105,6 +107,18 @@ class _ShareImageEditorView extends State<ShareImageEditorView> {
super.dispose(); super.dispose();
} }
void updateStatus(int userId, bool checked) {
if (checked) {
if (_isRealTwonly) {
selectedUserIds.clear();
}
selectedUserIds.add(userId);
} else {
selectedUserIds.remove(userId);
}
setState(() {});
}
Future updateAsync(int userId) async { Future updateAsync(int userId) async {
if (sendNextMediaToUserName != null) return; if (sendNextMediaToUserName != null) return;
Contact? contact = await twonlyDatabase.contactsDao Contact? contact = await twonlyDatabase.contactsDao
@ -241,6 +255,7 @@ class _ShareImageEditorView extends State<ShareImageEditorView> {
if (_isRealTwonly) { if (_isRealTwonly) {
maxShowTime = 12; maxShowTime = 12;
} }
selectedUserIds = HashSet();
setState(() {}); setState(() {});
}, },
), ),
@ -308,7 +323,8 @@ class _ShareImageEditorView extends State<ShareImageEditorView> {
imageBytesFuture: imageBytes, imageBytesFuture: imageBytes,
isRealTwonly: _isRealTwonly, isRealTwonly: _isRealTwonly,
maxShowTime: maxShowTime, maxShowTime: maxShowTime,
preselectedUser: widget.sendTo, selectedUserIds: selectedUserIds,
updateStatus: updateStatus,
videoFilePath: widget.videoFilePath, videoFilePath: widget.videoFilePath,
mirrorVideo: widget.mirrorVideo, mirrorVideo: widget.mirrorVideo,
), ),

View file

@ -24,7 +24,8 @@ class ShareImageView extends StatefulWidget {
required this.isRealTwonly, required this.isRealTwonly,
required this.mirrorVideo, required this.mirrorVideo,
required this.maxShowTime, required this.maxShowTime,
this.preselectedUser, required this.selectedUserIds,
required this.updateStatus,
required this.videoFilePath, required this.videoFilePath,
this.enableVideoAudio}); this.enableVideoAudio});
final Future<Uint8List?> imageBytesFuture; final Future<Uint8List?> imageBytesFuture;
@ -32,8 +33,9 @@ class ShareImageView extends StatefulWidget {
final bool mirrorVideo; final bool mirrorVideo;
final int maxShowTime; final int maxShowTime;
final XFile? videoFilePath; final XFile? videoFilePath;
final Contact? preselectedUser; final HashSet<int> selectedUserIds;
final bool? enableVideoAudio; final bool? enableVideoAudio;
final Function(int, bool) updateStatus;
@override @override
State<ShareImageView> createState() => _ShareImageView(); State<ShareImageView> createState() => _ShareImageView();
@ -47,7 +49,6 @@ class _ShareImageView extends State<ShareImageView> {
Uint8List? imageBytes; Uint8List? imageBytes;
bool sendingImage = false; bool sendingImage = false;
bool hideArchivedUsers = true; bool hideArchivedUsers = true;
final HashSet<int> _selectedUserIds = HashSet<int>();
final TextEditingController searchUserName = TextEditingController(); final TextEditingController searchUserName = TextEditingController();
bool showRealTwonlyWarning = false; bool showRealTwonlyWarning = false;
late StreamSubscription<List<Contact>> contactSub; late StreamSubscription<List<Contact>> contactSub;
@ -57,10 +58,6 @@ class _ShareImageView extends State<ShareImageView> {
void initState() { void initState() {
super.initState(); super.initState();
if (widget.preselectedUser != null) {
_selectedUserIds.add(widget.preselectedUser!.userId);
}
Stream<List<Contact>> allContacts = Stream<List<Contact>> allContacts =
twonlyDatabase.contactsDao.watchContactsForShareView(); twonlyDatabase.contactsDao.watchContactsForShareView();
@ -129,7 +126,7 @@ class _ShareImageView extends State<ShareImageView> {
.where((x) => .where((x) =>
!x.archived || !x.archived ||
!hideArchivedUsers || !hideArchivedUsers ||
_selectedUserIds.contains(x.userId)) widget.selectedUserIds.contains(x.userId))
.toList()); .toList());
return; return;
} }
@ -151,14 +148,7 @@ class _ShareImageView extends State<ShareImageView> {
} }
} }
showRealTwonlyWarning = false; showRealTwonlyWarning = false;
if (checked) { widget.updateStatus(userId, checked);
if (widget.isRealTwonly) {
_selectedUserIds.clear();
}
_selectedUserIds.add(userId);
} else {
_selectedUserIds.remove(userId);
}
setState(() {}); setState(() {});
} }
@ -193,7 +183,7 @@ class _ShareImageView extends State<ShareImageView> {
if (_pinnedContacs.isNotEmpty) const SizedBox(height: 10), if (_pinnedContacs.isNotEmpty) const SizedBox(height: 10),
BestFriendsSelector( BestFriendsSelector(
users: _pinnedContacs, users: _pinnedContacs,
selectedUserIds: _selectedUserIds, selectedUserIds: widget.selectedUserIds,
isRealTwonly: widget.isRealTwonly, isRealTwonly: widget.isRealTwonly,
updateStatus: updateStatus, updateStatus: updateStatus,
title: context.lang.shareImagePinnedContacts, title: context.lang.shareImagePinnedContacts,
@ -201,7 +191,7 @@ class _ShareImageView extends State<ShareImageView> {
const SizedBox(height: 10), const SizedBox(height: 10),
BestFriendsSelector( BestFriendsSelector(
users: _bestFriends, users: _bestFriends,
selectedUserIds: _selectedUserIds, selectedUserIds: widget.selectedUserIds,
isRealTwonly: widget.isRealTwonly, isRealTwonly: widget.isRealTwonly,
updateStatus: updateStatus, updateStatus: updateStatus,
title: context.lang.shareImageBestFriends, title: context.lang.shareImageBestFriends,
@ -250,7 +240,7 @@ class _ShareImageView extends State<ShareImageView> {
Expanded( Expanded(
child: UserList( child: UserList(
List.from(_otherUsers), List.from(_otherUsers),
selectedUserIds: _selectedUserIds, selectedUserIds: widget.selectedUserIds,
isRealTwonly: widget.isRealTwonly, isRealTwonly: widget.isRealTwonly,
updateStatus: updateStatus, updateStatus: updateStatus,
), ),
@ -278,7 +268,7 @@ class _ShareImageView extends State<ShareImageView> {
) )
: FaIcon(FontAwesomeIcons.solidPaperPlane), : FaIcon(FontAwesomeIcons.solidPaperPlane),
onPressed: () async { onPressed: () async {
if (imageBytes == null || _selectedUserIds.isEmpty) { if (imageBytes == null || widget.selectedUserIds.isEmpty) {
return; return;
} }
@ -298,7 +288,7 @@ class _ShareImageView extends State<ShareImageView> {
}); });
sendMediaFile( sendMediaFile(
_selectedUserIds.toList(), widget.selectedUserIds.toList(),
imageBytes!, imageBytes!,
widget.isRealTwonly, widget.isRealTwonly,
widget.maxShowTime, widget.maxShowTime,
@ -322,7 +312,7 @@ class _ShareImageView extends State<ShareImageView> {
EdgeInsets.symmetric(vertical: 10, horizontal: 30), EdgeInsets.symmetric(vertical: 10, horizontal: 30),
), ),
backgroundColor: WidgetStateProperty.all<Color>( backgroundColor: WidgetStateProperty.all<Color>(
imageBytes == null || _selectedUserIds.isEmpty imageBytes == null || widget.selectedUserIds.isEmpty
? Theme.of(context).colorScheme.secondary ? Theme.of(context).colorScheme.secondary
: Theme.of(context).colorScheme.primary, : Theme.of(context).colorScheme.primary,
)), )),